Now tracking irssi

This commit is contained in:
2025-08-15 18:26:12 -04:00
parent 8e1b5c3e07
commit 1752303a00
30 changed files with 14947 additions and 1 deletions

29
home/.irssi/README.md Normal file
View File

@@ -0,0 +1,29 @@
# README #
This README would normally document whatever steps are necessary to get your application up and running.
### What is this repository for? ###
* Quick summary
* Version
* [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo)
### How do I get set up? ###
* Summary of set up
* Configuration
* Dependencies
* Database configuration
* How to run tests
* Deployment instructions
### Contribution guidelines ###
* Writing tests
* Code review
* Other guidelines
### Who do I talk to? ###
* Repo owner or admin
* Other community or team contact

295
home/.irssi/_default.theme Normal file
View File

@@ -0,0 +1,295 @@
# When testing changes, the easiest way to reload the theme is with /RELOAD.
# This reloads the configuration file too, so if you did any changes remember
# to /SAVE it first. Remember also that /SAVE overwrites the theme file with
# old data so keep backups :)
# TEMPLATES:
# The real text formats that irssi uses are the ones you can find with
# /FORMAT command. Back in the old days all the colors and texts were mixed
# up in those formats, and it was really hard to change the colors since you
# might have had to change them in tens of different places. So, then came
# this templating system.
# Now the /FORMATs don't have any colors in them, and they also have very
# little other styling. Most of the stuff you need to change is in this
# theme file. If you can't change something here, you can always go back
# to change the /FORMATs directly, they're also saved in these .theme files.
# So .. the templates. They're those {blahblah} parts you see all over the
# /FORMATs and here. Their usage is simply {name parameter1 parameter2}.
# When irssi sees this kind of text, it goes to find "name" from abstracts
# block below and sets "parameter1" into $0 and "parameter2" into $1 (you
# can have more parameters of course). Templates can have subtemplates.
# Here's a small example:
# /FORMAT format hello {colorify {underline world}}
# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; }
# When irssi expands the templates in "format", the final string would be:
# hello %G%Uworld%U%n
# ie. underlined bright green "world" text.
# and why "$0-", why not "$0"? $0 would only mean the first parameter,
# $0- means all the parameters. With {underline hello world} you'd really
# want to underline both of the words, not just the hello (and world would
# actually be removed entirely).
# COLORS:
# You can find definitions for the color format codes in docs/formats.txt.
# There's one difference here though. %n format. Normally it means the
# default color of the terminal (white mostly), but here it means the
# "reset color back to the one it was in higher template". For example
# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would
# print yellow "foo" (as set with %Y) but "bar" would be green, which was
# set at the beginning before the {foo} template. If there wasn't the %g
# at start, the normal behaviour of %n would occur. If you _really_ want
# to use the terminal's default color, use %N.
#############################################################################
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "-1";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = { "[]=" = "%K$*%n"; };
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
line_start = "%B-%n!%B-%n ";
# timestamp styling, nothing by default
timestamp = "$*";
# any kind of text that needs hilighting, default is to bold
hilight = "%_$*%_";
# any kind of error message, default is bright red
error = "%R$*%n";
# channel name is printed
channel = "%_$*%_";
# nick is printed
nick = "%_$*%_";
# nick host is printed
nickhost = "[$*]";
# server name is printed
server = "%_$*%_";
# some kind of comment is printed
comment = "[$*]";
# reason for something is printed (part, quit, kick, ..)
reason = "{comment $*}";
# mode change is printed ([+o nick])
mode = "{comment $*}";
##
## channel specific messages
##
# highlighted nick/host is printed (joins)
channick_hilight = "%C$*%n";
chanhost_hilight = "{nickhost %c$*%n}";
# nick/host is printed (parts, quits, etc.)
channick = "%c$*%n";
chanhost = "{nickhost $*}";
# highlighted channel name is printed
channelhilight = "%c$*%n";
# ban/ban exception/invite list mask is printed
ban = "%c$*%n";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%K<%n$0$1-%K>%n %|";
# message from you is printed. "ownnick" specifies the styling of the
# nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the
# whole line.
# Example1: You want the message text to be green:
# ownmsgnick = "{msgnick $0 $1-}%g";
# Example2.1: You want < and > chars to be yellow:
# ownmsgnick = "%Y{msgnick $0 $1-%Y}%n";
# (you'll also have to remove <> from replaces list above)
# Example2.2: But you still want to keep <> grey for other messages:
# pubmsgnick = "%K{msgnick $0 $1-%K}%n";
# pubmsgmenick = "%K{msgnick $0 $1-%K}%n";
# pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n";
# ownprivmsgnick = "%K{msgnick $*%K}%n";
# privmsgnick = "%K{msgnick %R$*%K}%n";
# $0 = nick mode, $1 = nick
ownmsgnick = "{msgnick $0 $1-}";
ownnick = "%_$*%n";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "{msgnick $0 $1-}";
pubnick = "%N$*%n";
# public message in channel meant for me, $0 = nick mode, $1 = nick
pubmsgmenick = "{msgnick $0 $1-}";
menick = "%Y$*%n";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
pubmsghinick = "{msgnick $1 $0$2-%n}";
# channel name is printed with message
msgchannel = "%K:%c$*%n";
# private message, $0 = nick, $1 = host
privmsg = "[%R$0%K(%r$1-%K)%n] ";
# private message from you, $0 = "msg", $1 = target nick
ownprivmsg = "[%r$0%K(%R$1-%K)%n] ";
# own private message in query
ownprivmsgnick = "{msgnick $*}";
ownprivnick = "%_$*%n";
# private message in query
privmsgnick = "{msgnick %R$*%n}";
##
## Actions (/ME stuff)
##
# used internally by this theme
action_core = "%_ * $*%n";
# generic one that's used by most actions
action = "{action_core $*} ";
# own action, both private/public
ownaction = "{action $*}";
# own action with target, both private/public
ownaction_target = "{action_core $0}%K:%c$1%n ";
# private action sent by others
pvtaction = "%_ (*) $*%n ";
pvtaction_query = "{action $*}";
# public action sent by others
pubaction = "{action $*}";
##
## other IRC events
##
# whois
whois = "%# $[8]0 : $1-";
# notices
ownnotice = "[%r$0%K(%R$1-%K)]%n ";
notice = "%K-%M$*%K-%n ";
pubnotice_channel = "%K:%m$*";
pvtnotice_host = "%K(%m$*%K)";
servernotice = "%g!$*%n ";
# CTCPs
ownctcp = "[%r$0%K(%R$1-%K)] ";
ctcp = "%g$*%n";
# wallops
wallop = "%_$*%n: ";
wallop_nick = "%n$*";
wallop_action = "%_ * $*%n ";
# netsplits
netsplit = "%R$*%n";
netjoin = "%C$*%n";
# /names list
names_prefix = "";
names_nick = "[%_$0%_$1-] ";
names_nick_op = "{names_nick $*}";
names_nick_halfop = "{names_nick $*}";
names_nick_voice = "{names_nick $*}";
names_users = "[%g$*%n]";
names_channel = "%G$*%n";
# DCC
dcc = "%g$*%n";
dccfile = "%_$*%_";
# DCC chat, own msg/action
dccownmsg = "[%r$0%K($1-%K)%n] ";
dccownnick = "%R$*%n";
dccownquerynick = "%_$*%n";
dccownaction = "{action $*}";
dccownaction_target = "{action_core $0}%K:%c$1%n ";
# DCC chat, others
dccmsg = "[%G$1-%K(%g$0%K)%n] ";
dccquerynick = "%G$*%n";
dccaction = "%_ (*dcc*) $*%n %|";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
sb_background = "%4%w";
window_border = "%4%w";
# default backround for "default" statusbar group
#sb_default_bg = "%4";
# background for prompt / input line
sb_prompt_bg = "%n";
# background for info statusbar
sb_info_bg = "%8";
# background for topicbar (same default)
#sb_topic_bg = "%4";
# text at the beginning of statusbars. "sb" already puts a space there,
# so we don't use anything by default.
sbstart = "";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = " ";
topicsbstart = "{sbstart $*}";
topicsbend = "{sbend $*}";
prompt = "[$*] ";
sb = " %c[%n$*%c]%n";
sbmode = "(%c+%n$*)";
sbaway = " (%GzZzZ%n)";
sbservertag = ":$0 (change with ^X)";
sbnickmode = "$0";
# activity in statusbar
# ',' separator
sb_act_sep = "%c$*";
# normal text
sb_act_text = "%c$*";
# public message
sb_act_msg = "%W$*";
# hilight
sb_act_hilight = "%M$*";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "$0$1-%n";
};

373
home/.irssi/config Normal file
View File

@@ -0,0 +1,373 @@
ignores = ( { level = "JOINS PARTS QUITS"; target = "*"; } );
setting = { };
servers = (
{ address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; },
{
address = "ssl.efnet.org";
chatnet = "EFNet";
port = "9999";
use_tls = "yes";
tls_verify = "no";
},
{
address = "irc.esper.net";
chatnet = "EsperNet";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{
address = "irc.libera.chat";
chatnet = "liberachat";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
autoconnect = "yes";
},
{
address = "irc.gamesurge.net";
chatnet = "GameSurge";
port = "6667";
},
{
address = "ssl.ircnet.ovh";
chatnet = "IRCnet";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{ address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; },
{
address = "irc.ircsource.net";
chatnet = "IRCSource";
port = "6667";
},
{ address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; },
{
address = "irc.oftc.net";
chatnet = "OFTC";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{
address = "irc.quakenet.org";
chatnet = "QuakeNet";
port = "6667";
},
{
address = "irc.rizon.net";
chatnet = "Rizon";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{ address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; },
{
address = "irc.undernet.org";
chatnet = "Undernet";
port = "6667";
}
);
chatnets = {
DALnet = {
type = "IRC";
max_kicks = "4";
max_msgs = "20";
max_whois = "30";
};
EFNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
EsperNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
liberachat = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
sasl_mechanism = "PLAIN";
sasl_username = "th3r00t";
sasl_password = "b2edxfrr1";
};
GameSurge = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
IRCnet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
IRCSource = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
NetFuze = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
OFTC = { type = "IRC"; max_kicks = "1"; max_msgs = "1"; max_whois = "1"; };
QuakeNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
Rizon = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
SILC = { type = "SILC"; };
Undernet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
};
channels = (
{ name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; },
{ name = "#libera"; chatnet = "liberachat"; autojoin = "No"; },
{ name = "#irssi"; chatnet = "liberachat"; autojoin = "No"; },
{ name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; },
{ name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; },
{ name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; },
{ name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; },
{ name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; },
{ name = "silc"; chatnet = "SILC"; autojoin = "No"; },
{ name = "#linux"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#archlinux"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#zig"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#python"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#vimwiki"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#foot"; chatnet = "liberachat"; autojoin = "yes"; }
);
aliases = {
ATAG = "WINDOW SERVER";
ADDALLCHANS = "SCRIPT EXEC foreach my \\$channel (Irssi::channels()) { Irssi::command(\"CHANNEL ADD -auto \\$channel->{visible_name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}";
B = "BAN";
BACK = "AWAY";
BANS = "BAN";
BYE = "QUIT";
C = "CLEAR";
CALC = "EXEC - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi";
CHAT = "DCC CHAT";
CS = "QUOTE CS";
DATE = "TIME";
DEHIGHLIGHT = "DEHILIGHT";
DESCRIBE = "ACTION";
DHL = "DEHILIGHT";
EXEMPTLIST = "MODE $C +e";
EXIT = "QUIT";
GOTO = "SCROLLBACK GOTO";
HIGHLIGHT = "HILIGHT";
HL = "HILIGHT";
HOST = "USERHOST";
INVITELIST = "MODE $C +I";
J = "JOIN";
K = "KICK";
KB = "KICKBAN";
KN = "KNOCKOUT";
LAST = "LASTLOG";
LEAVE = "PART";
M = "MSG";
MS = "QUOTE MS";
MUB = "UNBAN *";
N = "NAMES";
NMSG = "^MSG";
NS = "QUOTE NS";
OS = "QUOTE OS";
P = "PART";
Q = "QUERY";
RESET = "SET -default";
RUN = "SCRIPT LOAD";
SAY = "MSG *";
SB = "SCROLLBACK";
SBAR = "STATUSBAR";
SHELP = "QUOTE HELP";
SIGNOFF = "QUIT";
SV = "MSG * Irssi $J ($V) - https://irssi.org";
T = "TOPIC";
UB = "UNBAN";
UMODE = "MODE $N";
UNSET = "SET -clear";
W = "WHO";
WC = "WINDOW CLOSE";
WG = "WINDOW GOTO";
WJOIN = "JOIN -window";
WI = "WHOIS";
WII = "WHOIS $0 $0";
WL = "WINDOW LIST";
WN = "WINDOW NEW HIDDEN";
WQUERY = "QUERY -window";
WW = "WHOWAS";
statusbar = {
items = {
barstart = "{sbstart}";
barend = "{sbend}";
topicbarstart = "{topicsbstart}";
topicbarend = "{topicsbend}";
time = "{sb $Z}";
user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";
window = "{sb $winref:$tag/$itemname{sbmode $M}}";
window_empty = "{sb $winref{sbservertag $tag}}";
prompt = "{prompt $[.15]itemname}";
prompt_empty = "{prompt $winname}";
topic = " $topic";
topic_empty = " Irssi v$J - https://irssi.org";
lag = "{sb Lag: $0-}";
act = "{sb Act: $0-}";
more = "-- more --";
};
default = {
window = {
disabled = "no";
type = "window";
placement = "bottom";
position = "1";
visible = "active";
items = {
barstart = { priority = "100"; };
time = { };
user = { };
window = { };
window_empty = { };
lag = { priority = "-1"; };
act = { priority = "10"; };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
windowlist = { };
};
};
window_inact = {
type = "window";
placement = "bottom";
position = "1";
visible = "inactive";
items = {
barstart = { priority = "100"; };
window = { };
window_empty = { };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
};
};
prompt = {
type = "root";
placement = "bottom";
position = "100";
visible = "always";
items = {
prompt = { priority = "-1"; };
prompt_empty = { priority = "-1"; };
input = { priority = "10"; };
};
};
topic = {
type = "root";
placement = "top";
position = "1";
visible = "always";
items = {
topicbarstart = { priority = "100"; };
topic = { };
topic_empty = { };
topicbarend = { priority = "100"; alignment = "right"; };
};
};
};
};
settings = {
core = {
real_name = "th3r00t";
user_name = "th3r00t";
nick = "th3r00t";
};
"perl/core/scripts" = { awl_shared_sbar = "OFF"; };
};
};
settings = {
core = {
real_name = "Unknown";
user_name = "th3r00t";
nick = "th3r00t";
};
"perl/core/scripts" = {
awl_shared_sbar = "OFF";
awl_placement = "top";
awl_viewer = "no";
};
"fe-common/core" = { theme = "default"; };
fifo_pipe = "/tmp/irssi_pipe";
};
statusbar = {
default = {
prompt = {
items = {
uberprompt = { priority = "-1"; };
input = { priority = "10"; };
};
position = "100";
};
awl_0 = {
placement = "top";
items = {
barstart = { priority = "100"; };
awl_0 = { };
barend = { priority = "100"; alignment = "right"; };
};
};
};
};
keyboard = (
{ key = "meta-w"; id = "command"; data = "toggle awl_viewer"; },
{
key = "meta-u";
id = "command";
data = "script exec Irssi::Script::tmux_nicklist_portable::toggle_nicklist";
},
{ key = "meta-C"; id = "command"; data = "WINDOW KILL"; },
{ key = "meta-x"; id = "command"; data = "ido_switch_start "; }
);

373
home/.irssi/config.autosave Normal file
View File

@@ -0,0 +1,373 @@
ignores = ( { level = "JOINS PARTS QUITS"; target = "*"; } );
setting = { };
servers = (
{ address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; },
{
address = "ssl.efnet.org";
chatnet = "EFNet";
port = "9999";
use_tls = "yes";
tls_verify = "no";
},
{
address = "irc.esper.net";
chatnet = "EsperNet";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{
address = "irc.libera.chat";
chatnet = "liberachat";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
autoconnect = "yes";
},
{
address = "irc.gamesurge.net";
chatnet = "GameSurge";
port = "6667";
},
{
address = "ssl.ircnet.ovh";
chatnet = "IRCnet";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{ address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; },
{
address = "irc.ircsource.net";
chatnet = "IRCSource";
port = "6667";
},
{ address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; },
{
address = "irc.oftc.net";
chatnet = "OFTC";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{
address = "irc.quakenet.org";
chatnet = "QuakeNet";
port = "6667";
},
{
address = "irc.rizon.net";
chatnet = "Rizon";
port = "6697";
use_tls = "yes";
tls_verify = "yes";
},
{ address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; },
{
address = "irc.undernet.org";
chatnet = "Undernet";
port = "6667";
}
);
chatnets = {
DALnet = {
type = "IRC";
max_kicks = "4";
max_msgs = "20";
max_whois = "30";
};
EFNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
EsperNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
liberachat = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
sasl_mechanism = "PLAIN";
sasl_username = "th3r00t";
sasl_password = "b2edxfrr1";
};
GameSurge = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
IRCnet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
IRCSource = {
type = "IRC";
max_kicks = "1";
max_msgs = "4";
max_whois = "1";
};
NetFuze = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
OFTC = { type = "IRC"; max_kicks = "1"; max_msgs = "1"; max_whois = "1"; };
QuakeNet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
Rizon = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
SILC = { type = "SILC"; };
Undernet = {
type = "IRC";
max_kicks = "1";
max_msgs = "1";
max_whois = "1";
};
};
channels = (
{ name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; },
{ name = "#libera"; chatnet = "liberachat"; autojoin = "No"; },
{ name = "#irssi"; chatnet = "liberachat"; autojoin = "No"; },
{ name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; },
{ name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; },
{ name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; },
{ name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; },
{ name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; },
{ name = "silc"; chatnet = "SILC"; autojoin = "No"; },
{ name = "#linux"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#archlinux"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#zig"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#python"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#vimwiki"; chatnet = "liberachat"; autojoin = "yes"; },
{ name = "#foot"; chatnet = "liberachat"; autojoin = "yes"; }
);
aliases = {
ATAG = "WINDOW SERVER";
ADDALLCHANS = "SCRIPT EXEC foreach my \\$channel (Irssi::channels()) { Irssi::command(\"CHANNEL ADD -auto \\$channel->{visible_name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}";
B = "BAN";
BACK = "AWAY";
BANS = "BAN";
BYE = "QUIT";
C = "CLEAR";
CALC = "EXEC - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi";
CHAT = "DCC CHAT";
CS = "QUOTE CS";
DATE = "TIME";
DEHIGHLIGHT = "DEHILIGHT";
DESCRIBE = "ACTION";
DHL = "DEHILIGHT";
EXEMPTLIST = "MODE $C +e";
EXIT = "QUIT";
GOTO = "SCROLLBACK GOTO";
HIGHLIGHT = "HILIGHT";
HL = "HILIGHT";
HOST = "USERHOST";
INVITELIST = "MODE $C +I";
J = "JOIN";
K = "KICK";
KB = "KICKBAN";
KN = "KNOCKOUT";
LAST = "LASTLOG";
LEAVE = "PART";
M = "MSG";
MS = "QUOTE MS";
MUB = "UNBAN *";
N = "NAMES";
NMSG = "^MSG";
NS = "QUOTE NS";
OS = "QUOTE OS";
P = "PART";
Q = "QUERY";
RESET = "SET -default";
RUN = "SCRIPT LOAD";
SAY = "MSG *";
SB = "SCROLLBACK";
SBAR = "STATUSBAR";
SHELP = "QUOTE HELP";
SIGNOFF = "QUIT";
SV = "MSG * Irssi $J ($V) - https://irssi.org";
T = "TOPIC";
UB = "UNBAN";
UMODE = "MODE $N";
UNSET = "SET -clear";
W = "WHO";
WC = "WINDOW CLOSE";
WG = "WINDOW GOTO";
WJOIN = "JOIN -window";
WI = "WHOIS";
WII = "WHOIS $0 $0";
WL = "WINDOW LIST";
WN = "WINDOW NEW HIDDEN";
WQUERY = "QUERY -window";
WW = "WHOWAS";
statusbar = {
items = {
barstart = "{sbstart}";
barend = "{sbend}";
topicbarstart = "{topicsbstart}";
topicbarend = "{topicsbend}";
time = "{sb $Z}";
user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";
window = "{sb $winref:$tag/$itemname{sbmode $M}}";
window_empty = "{sb $winref{sbservertag $tag}}";
prompt = "{prompt $[.15]itemname}";
prompt_empty = "{prompt $winname}";
topic = " $topic";
topic_empty = " Irssi v$J - https://irssi.org";
lag = "{sb Lag: $0-}";
act = "{sb Act: $0-}";
more = "-- more --";
};
default = {
window = {
disabled = "no";
type = "window";
placement = "bottom";
position = "1";
visible = "active";
items = {
barstart = { priority = "100"; };
time = { };
user = { };
window = { };
window_empty = { };
lag = { priority = "-1"; };
act = { priority = "10"; };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
windowlist = { };
};
};
window_inact = {
type = "window";
placement = "bottom";
position = "1";
visible = "inactive";
items = {
barstart = { priority = "100"; };
window = { };
window_empty = { };
more = { priority = "-1"; alignment = "right"; };
barend = { priority = "100"; alignment = "right"; };
};
};
prompt = {
type = "root";
placement = "bottom";
position = "100";
visible = "always";
items = {
prompt = { priority = "-1"; };
prompt_empty = { priority = "-1"; };
input = { priority = "10"; };
};
};
topic = {
type = "root";
placement = "top";
position = "1";
visible = "always";
items = {
topicbarstart = { priority = "100"; };
topic = { };
topic_empty = { };
topicbarend = { priority = "100"; alignment = "right"; };
};
};
};
};
settings = {
core = {
real_name = "th3r00t";
user_name = "th3r00t";
nick = "th3r00t";
};
"perl/core/scripts" = { awl_shared_sbar = "OFF"; };
};
};
settings = {
core = {
real_name = "Unknown";
user_name = "th3r00t";
nick = "th3r00t";
};
"perl/core/scripts" = {
awl_shared_sbar = "OFF";
awl_placement = "top";
awl_viewer = "no";
};
"fe-common/core" = { theme = "default"; };
fifo_pipe = "/tmp/irssi_pipe";
};
statusbar = {
default = {
prompt = {
items = {
uberprompt = { priority = "-1"; };
input = { priority = "10"; };
};
position = "100";
};
awl_0 = {
placement = "top";
items = {
barstart = { priority = "100"; };
awl_0 = { };
barend = { priority = "100"; alignment = "right"; };
};
};
};
};
keyboard = (
{ key = "meta-w"; id = "command"; data = "toggle awl_viewer"; },
{
key = "meta-u";
id = "command";
data = "script exec Irssi::Script::tmux_nicklist_portable::toggle_nicklist";
},
{ key = "meta-C"; id = "command"; data = "WINDOW KILL"; },
{ key = "meta-x"; id = "command"; data = "ido_switch_start "; }
);

317
home/.irssi/cyanic.theme Normal file
View File

@@ -0,0 +1,317 @@
# :::::::::::::[ irssi theme cyanic v0.1 by bracket ]::::::::::::::
# this theme is still under construction, and i guess it will be
# that way forever. :) this theme will _not_ work on networks which
# support nicknames longer than 9 chars. i made it for myself and
# i use only ircnet.
# you can send any comments, complaints and/or request to
# bracket@welho.com or /msg me on ircnet.
# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "%w";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = { "[]" = "%K$*%w"; };
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
line_start = "%w";
# timestamp styling, nothing by default
timestamp = "%K( %c$*%K";
# any kind of text that needs hilighting, default is to bold
hilight = "%_$*%_";
# any kind of error message, default is bright red
error = "%R$*%w";
# channel name is printed
channel = "%_$*%_";
# nick is printed
nick = "$*";
# nick host is printed
nickhost = "[$*]";
# server name is printed
server = "%_$*%_";
# some kind of comment is printed
comment = "[$*]";
# reason for something is printed (part, quit, kick, ..)
reason = "{comment $*}";
# mode change is printed ([+o nick])
mode = "{comment $*}";
##
## channel specific messages
##
# highlighted nick/host is printed (joins)
channick_hilight = "%C$*%w";
chanhost_hilight = "{nickhost %c$*%w}";
# nick/host is printed (parts, quits, etc.)
channick = "%c$*%w";
chanhost = "{nickhost $*}";
# highlighted channel name is printed
channelhilight = "%c$*%w";
# ban/ban exception/invite list mask is printed
ban = "%r$*%w";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%G$0%C$1 %K) %|%w";
# message from you is printed. "msgownnick" specifies the styling of the
# nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the
# whole line.
# Example1: You want the message text to be green:
# ownmsgnick = "{msgnick $0 $1-}%g";
# Example2.1: You want < and > chars to be yellow:
# ownmsgnick = "%Y{msgnick $0 $1-%Y}%n";
# (you'll also have to remove <> from replaces list above)
# Example2.2: But you still want to keep <> grey for other messages:
# pubmsgnick = "%K{msgnick $0 $1-%K}%n";
# pubmsgmenick = "%K{msgnick $0 $1-%K}%n";
# pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n";
# ownprivmsgnick = "%K{msgnick $*%K}%n";
# privmsgnick = "%K{msgnick %R$*%K}%n";
# $0 = nick mode, $1 = nick
ownmsgnick = "{msgnick $0 $1-}%w";
ownnick = "%W$*%w";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "{msgnick $0 $1-}";
pubnick = "%C$*%w";
# public message in channel meant for me, $0 = nick mode, $1 = nick
pubmsgmenick = "{msgnick $0 $1-}";
menick = "%Y$*%W";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
pubmsghinick = "{msgnick $1 $0$2-%W}%W";
# channel name is printed with message
msgchannel = "%K:%c$*%w";
# private message, $0 = nick, $1 = host
privmsg = "%K[%C$0%K(%c$1-%K)%K] %W";
# private message from you, $0 = "msg", $1 = target nick
ownprivmsg = "%K[%c$0%K(%W$1-%K)%K] %G";
# own private message in query
ownprivmsgnick = "{msgnick %c$*}";
ownprivnick = "%W$*%w";
# private message in query
privmsgnick = "{msgnick %C$*%w}";
##
## Actions (/ME stuff)
##
# used internally by this theme
# action_core = "%W$[-9]0- * %w";
action_core = "%C$0-%w";
# generic one that's used by most actions
action = " %W* %|{action_core %c$*} ";
# own action, both private/public
ownaction = "{action $*}";
# own action with target, both private/public
ownaction_target = "{action_core $0}%K:%c$1%w ";
# private action sent by others
pvtaction = "%W (*) $*%w ";
pvtaction_query = "{action $*}";
# public action sent by others
pubaction = "{action $*}";
##
## other IRC events
##
# whois
whois = "%# $[8]0 : $1-";
# notices
ownnotice = "[%r$0%K(%R$1-%K)]%w ";
notice = "%K-%Y$*%K-%w ";
pubnotice_channel = "%K:%m$*";
pvtnotice_host = "%K(%m$*%K)";
servernotice = "%g!$*%w ";
# CTCPs
ownctcp = "[%r$0%K(%R$1-%K)] ";
ctcp = "%g$*%w";
# wallops
wallop = "%W$*%w: ";
wallop_nick = "%w$*";
wallop_action = "%W * $*%w ";
# netsplits
netsplit = "%R$*%w";
netjoin = "%G$*%w";
# /names list
names_prefix = "";
names_nick = "%K[%_%c$0%_%C$1-%K] %w";
names_nick_op = "{names_nick $*}";
names_nick_halfop = "{names_nick $*}";
names_nick_voice = "{names_nick $*}";
names_users = "[%C$*%w]";
names_channel = "%W$*%w";
# DCC
dcc = "%m$*%n";
dccfile = "%_$*%_";
# DCC chat, own msg/action
dccownmsg = "[%r$0%K($1-%K)%w] ";
dccownnick = "%R$*%w";
dccownquerynick = "%W$*%w";
dccownaction = "{action $*}";
dccownaction_target = "{action_core $0}%K:%c$1%w ";
# DCC chat, others
dccmsg = "[%G$1-%K(%g$0%K)%w] ";
dccquerynick = "%G$*%w";
dccaction = "%W (*dcc*) $*%w %|";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
sb_background = "%6%W";
# default backround for "default" statusbar group
sb_default_bg = "%6";
# background for prompt / input line
sb_prompt_bg = "%k";
# background for info statusbar
sb_info_bg = "%6";
# background for topicbar (same default)
sb_topic_bg = "%6";
# text at the beginning of statusbars. sb-item already puts
# space there,so we don't use anything by default.
sbstart = "";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = " ";
topicsbstart = "{sbstart $*}";
topicsbend = "{sbend $*}";
prompt = "%c[%C$*%c] %W";
sb = " %K[%k$*%K]%w";
sbmode = "%K(%W+%C$*%K)";
sbaway = " %K(%K-%Waway%K-%K)";
sbservertag = ":$0 %K(%Cchange with %W^X%K)";
sbnickmode = "$0";
# activity in statusbar
# ',' separator
sb_act_sep = "%K$*";
# normal text
sb_act_text = "%K$*";
# public message
sb_act_msg = "%C$*";
# hilight
sb_act_hilight = "%Y$*";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "$0$1-%w";
};
formats = {
"fe-common/core" = {
join = "{channick $[-10]0} %G>%n %|{chanhost_hilight $1} has joined {channel $2}";
part = "{channick $[-10]0} %w<%n %|{chanhost $1} has left {channel $2} {reason $3}";
kick = "{channick $[-10]0} %R<%w %|kicked from {channel $1} by {nick $2} {reason $3}";
quit = "{channick $[-10]0} %Rx%n %|{chanhost $1} has quit irc {reason $2}";
quit_once = "{channel $3} {channick $0} {chanhost $1} quit {reason $2}";
nick_changed = "{channick $[-10]0} %W=%w {channick_hilight $1}";
your_nick_changed = "{channick $[-10]0} %W=%w {channick_hilight $1}";
own_msg = "{ownmsgnick $2 {ownnick $[-9]0}}$1";
own_msg_channel = "{ownmsgnick $3 {ownnick $[-9]0}{msgchannel $1}}$2";
pubmsg_me = "{pubmsgmenick $2 {menick $[-9]0}}$1";
pubmsg_me_channel = "{pubmsgmenick $3 {menick $[-9]0}{msgchannel $1}}$2";
pubmsg_hilight = "{pubmsghinick $0 $3 $[-9]1}$2";
pubmsg_hilight_channel = "{pubmsghinick $0 $4 $[-9]1{msgchannel $2}}$3";
pubmsg = "{pubmsgnick $2 {pubnick $[-9]0}}$1";
pubmsg_channel = "{pubmsgnick $3 {pubnick $[-9]0}{msgchannel $1}}$2";
own_msg_private = "{ownprivmsg msg $[-10]0}$1";
own_msg_private_query = "{ownprivmsgnick {ownprivnick $[-10]2}}$1";
msg_private = "{privmsg $[-10]0 $1}$2";
msg_private_query = "{privmsgnick $[-10]0}$2";
new_topic = " %wtopic %W= %|%c'%C$2%c' %won {channel $1}[set by {nick %W$0}]";
daychange = "%K( %Wday changed to %%d %%b %%Y %K)";
};
"fe-common/irc" = {
chanmode_change = " %wmode %W- %|%w({channelhilight $0} {mode $1}%w) by {nick %W$2}";
channel_mode = " %wmode %W- %|%w({channelhilight $0}%K) {mode $1}";
netsplit = "[{netsplit netsplit}] %W/%w %|{server $0} <-> {server $1} quits: %W$2";
netsplit_more = "[{netsplit netsplit}] %W/%w %|{server $0} <-> {server $1} quits: $2 (+$3 more, use /NETSPLIT to show all of them)";
netsplit_join = "[{netjoin netsplit}] %W-%w %|joins: %W$0";
netsplit_join_more = "[{netjoin netsplit}] %W-%w %|over, joins: $0 (+$1 more)";
whois = "%w.-[%C%%]%w- %wthe whois of {nick %W$0} %w-[%C%%]%w- %K)%:| host : {%Wnickhost %W$1@$2} %K)%:|{whois ircname %W$3} %K)";
whowas = "%w.-[%C%%]%w- %wthe whowas of {nick %W$0} %w-[%C%%]%w- %K)%:| host : {%Wnickhost %W$1@$2} %K)%:|{whois ircname %W$3} %K)";
whois_idle = "|{whois idle %|%W$1 %wdays and %W$2%w:%W$3%w:%W$4} %K)";
whois_idle_signon = "|{whois idle %|%W$1 %wdays and %W$2%w:%W$3%w:%W$4 {comment signon: $5}} %K)";
whois_server = "|{whois server %|%W$1 {comment $2}} %K)";
whois_oper = "{whois {hilight $1}}";
whois_registered = "{whois has registered this nick}";
whois_help = "{whois is available for help}";
whois_modes = "{whois modes $1}";
whois_realhost = "{whois hostname $1-}";
whois_usermode = "{whois usermode $1}";
whois_channels = "|{whois channels %|$1}%K)";
whois_away = "|{whois away %|%W$1} %K)";
whois_special = "{whois %|$1}";
whois_extra = "{whois %|$1}";
end_of_whois = "%w`-[%C%%]%w- %wend of whois -[%C%%]%w- %K)";
end_of_whowas = "%w`-[%C%%]%w- %wend of whowas -[%C%%]%w- %K)";
whois_not_found = "There is no such nick $0";
who = "%#{channelhilight $[-10]0} %|{nick $[!9]1} $[!3]2 $[!2]3 $4@$5 {comment {hilight $6}}";
end_of_who = "End of /WHO list";
};
};

1
home/.irssi/default.theme Symbolic link
View File

@@ -0,0 +1 @@
screwer.theme

402
home/.irssi/madcow.theme Executable file
View File

@@ -0,0 +1,402 @@
######################### madcow.theme by dubkat@efnet www.dubkat.org ##################################
# includes formats for scripts such as nact.pl kills.pl and chanact.pl
# this theme may not look too good directly in a term, but looks ok in putty if you have
# 'bolded text as alternate color' checked in your putty window/colours settings
# enjoy.
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "-1";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = {
# "[]" = "%B$*%n";
"!@+" = "%r$*%n";
};
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
line_start = "";
# timestamp styling, nothing by default
timestamp = "%K$*%n";
# any kind of text that needs hilighting, default is to bold
hilight = "%_$*%_";
# any kind of error message, default is bright red
error = "%R$*%n";
# channel name is printed
channel = "%_$*%_";
# nick is printed
nick = "%_$*%_";
# nick host is printed
nickhost = "$*";
# server name is printed
server = "%_$*%_";
# some kind of comment is printed
comment = "%r[%n$*%r]%n";
# reason for something is printed (part, quit, kick, ..)
reason = "{comment %_$*%_}";
# mode change is printed ([+o nick])
mode = "%r$*%n";
##
## channel specific messages
##
# highlighted nick/host is printed (joins)
channick_hilight = "$*";
chanhost_hilight = "{nickhost $*}";
# nick/host is printed (parts, quits, etc.)
channick = "%W$*%n";
chanhost = "{nickhost $*}";
# highlighted channel name is printed
channelhilight = "%R$*%n";
# ban/ban exception/invite list mask is printed
ban = "%r$*%n";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%r<%n%_$0%_$1%r>%n %|";
# message from you is printed. "msgownnick" specifies the styling of the
# nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the
# whole line.
# Example1: You want the message text to be green:
# ownmsgnick = "{msgnick $0 $1-}%g";
# Example2.1: You want < and > chars to be yellow:
# ownmsgnick = "%Y{msgnick $0 $1-%Y}%n";
# (you'll also have to remove <> from replaces list above)
# Example2.2: But you still want to keep <> grey for other messages:
# pubmsgnick = "%K{msgnick $0 $1-%K}%n";
# pubmsgmenick = "%K{msgnick $0 $1-%K}%n";
# pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n";
# ownprivmsgnick = "%K{msgnick $*%K}%n";
# privmsgnick = "%K{msgnick %R$*%K}%n";
# $0 = nick mode, $1 = nick
ownmsgnick = "{msgnick $0 $1-}%W";
ownnick = "%r$*%n";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "{msgnick $0$1-}";
pubnick = "%w$*%n";
# public message in channel meant for me, $0 = nick mode, $1 = nick
pubmsgmenick = "{msgnick $0$1-}";
menick = "%g$*%n";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
pubmsghinick = "{msgnick $1 $0$2-%n}";
# channel name is printed with message
msgchannel = "%r:$*%n";
# private message, $0 = nick, $1 = host
privmsg = "[%w$0!%r$1-%n] ";
# private message from you, $0 = "msg", $1 = target nick
ownprivmsg = "[%r$0%b(%R$1-%b)%n] ";
# own private message in query
ownprivmsgnick = "{msgnick $*}";
ownprivnick = "%r$*%n";
# private message in query
privmsgnick = "{msgnick %w$*%n}";
##
## Actions (/ME stuff)
##
# used internally by this theme
action_core = "%p $*";
# generic one that's used by most actions
action = "{action_core $*} ";
# own action, both private/public
ownaction = "{action %P$*}";
# own action with target, both private/public
ownaction_target = "{action_core $0}%p:%c$1%n ";
# private action sent by others
pvtaction = "%p (*) $*%n ";
pvtaction_query = "{action $* }";
# public action sent by others
pubaction = "{action $*}";
##
## other IRC events
##
# whois
whois = "%r$[-8]0%n | %w$1-%n";
# notices
ownnotice = "[%w$0!%r$1-]%n ";
notice = "[%rnotice%K(%n$*%K)%n] ";
pubnotice_channel = "%R:%R$*";
pvtnotice_host = "!%K$*%n";
servernotice = "[%r$*%n]%B:%n %_";
# CTCPs
ownctcp = "[%w$0!%c$1-] ";
ctcp = "%C$*%n";
# wallops
wallop = "%W$*%n: ";
wallop_nick = "%n$*";
wallop_action = "%W * $*%n ";
# netsplits
netsplit = "%R$*%n";
netjoin = "%G$*%n";
# /names list
names_prefix = "%K>%r>%R>%n ";
names_nick = "%K$0$1-%n ";
names_nick_op = "%G$0%n%_$1-%_ ";
names_nick_halfop = "%g$0%n%_$1-%_ ";
names_nick_voice = "%Y$0%n$1- ";
names_users = "[$*]";
names_channel = "%r$*%n";
# DCC
dcc = "$*";
dccfile = "%_$*%_";
# DCC chat, own msg/action
dccownmsg = "[%w$0!%r$1-%n] ";
dccownnick = "%w$*%n";
dccownquerynick = "%W$*%n";
dccownaction = "{action $*}";
dccownaction_target = "{action_core $0}%B:%c$1%n ";
# DCC chat, others
dccmsg = "[%w$1-!%g$0%n] ";
dccquerynick = "%G$*%n";
dccaction = "%W (*dcc*) $*%n %|";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
sb_background = "%4";
# default backround for "default" statusbar group
sb_default_bg = "%4";
# background for prompt / input line
sb_prompt_bg = "%n";
# background for info statusbar
sb_info_bg = "%4";
# background for topicbar (same default)
sb_topic_bg = "%4";
# text at the beginning of statusbars. sb-item already puts
# space there,so we don't use anything by default.
sbstart = " %W>%n ";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = " %W<%n ";
topicsbstart = "{sbstart $*}";
topicsbend = "{sbend $*}";
prompt = "%w$S%B/%w$*%n%B:%W ";
sb = " %w$*%n";
sbmode = " (+%W$*%n)";
sbaway = " (%Waway%n)";
sbservertag = ":$1";
sbnickmode = "%W$0%n";
# activity in statusbar
# ',' separator
sb_act_sep = "%w$*%n";
# normal text
sb_act_text = "%w$*%n";
# public message
sb_act_msg = "%W$*%n";
# hilight
sb_act_hilight = "%R$*%n";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "$0$1-%n";
#usercount
sb_usercount = "{sb %W[%W$0%n $1-}";
sb_uc_ircops = "%wi/%R$*%n";
sb_uc_ops = "%wo/%G$*%n";
sb_uc_halfops = "%wh/%g$*%n";
sb_uc_voices = "%wv/%Y$*%n";
sb_uc_normal = "%wn/%W$*%W]%n";
sb_uc_space = " ";
#nact
nact_display = "%W(%w$3%n%W)%n$0%G>%W$1%R>%n$2%W(%w$4%W)%n";
};
formats = {
"fe-common/core" = {
pubmsg = "{pubmsgnick $2 {pubnick \00312$[0]0}}$1";
join = " %K>%g>%G>%n {nick %W$0%n}!%n{chanhost_hilight %K$1%n}";
part = " %r<%n {nick %w$0%n}!%n{chanhost_hilight %K$1%n} {reason %K$3%n}%n";
kick = " %R<%r<%K<%n {nick %w$0%n} {reason %w$3%n} %rkicked%n by {nick $2}";
quit = " %K<%n {nick %w$0%n}!%n{chanhost_hilight %K$1%n} {reason %K$2%n}";
nick_changed = " %c~%n {nick %w$0%n} %Nis now {nick %W$1%n}";
new_topic = "%K>%r>%R>%n topic changed by $0: $2";
daychange = " %K-----------------%w-%W-%n Day changed to %%D %W-%w-%K-----------------%n";
own_msg = "{ownmsgnick $2 {ownnick $[-9]0}}$1";
own_msg_channel = "{ownmsgnick $3 {ownnick $[-9]0}{msgchannel $1}}$2";
pubmsg_me = "{pubmsgmenick $2 {menick $[-9]0}}$1";
pubmsg_me_channel = "{pubmsgmenick $3 {menick $[-9]0}{msgchannel $1}}$2";
pubmsg_hilight = "{pubmsghinick $0 $3 $[-9]1}$2";
pubmsg_hilight_channel = "{pubmsghinick $0 $4 $[-9]1{msgchannel $2}}$3";
pubmsg_channel = "{pubmsgnick $3 {pubnick $[-9]0}{msgchannel $1}}$2";
own_msg_private_query = "{ownprivmsgnick {ownprivnick $[-9]2}}$1";
msg_private_query = "{privmsgnick $[-9]0}$2";
your_nick = "%K>%r>%R>%n %_Y%_our nickname is {nick $0}";
your_nick_changed = "%K>%r>%R>%n %_Y%_ou're now known as {nick $1}";
window_name_not_unique = "%K>%r>%R>%n Window names must be unique";
window_level = "%K>%r>%R>%n Window level is now $0";
window_set_immortal = "%K>%r>%R>%n Window is now immortal";
window_unset_immortal = "%K>%r>%R>%n Window isn't immortal anymore";
window_immortal_error = "%K>%r>%R>%n Window is immortal, if you really want to kill it, say /WINDOW IMMORTAL OFF";
windowlist_header = "%#%r,--%wRef%r-%wName%r------------------%wActive item%r-----%wNetwork%r-----------%wLevels%r---->%n";
windowlist_line = "%r|%n%# $[3]0 %|$[20]1 $[15]2 $[15]3 $4";
windowlist_footer = "%r`--------------------------------------------------->%n";
windows_layout_saved = "%K>%r>%R>%n Window Layout has been %_Saved%_";
windows_layout_reset = "%K>%r>%R>%n Womdpw Layout has been returned to %_I%_rssi Defaults";
window_info_header = "%r%#,----%wwindow info%r---->%n";
window_info_footer = "%r%#`----------------------->%n";
window_info_refnum = "%# Window : {hilight #$0}";
window_info_refnum_sticky = "%# Window : {hilight #$0 (sticky)}";
window_info_name = "%# Name : $0";
window_info_history = "%# History : $0";
window_info_immortal = "%# Immortal: yes";
window_info_size = "%# Size : $0x$1";
window_info_level = "%# Level : $0";
window_info_server = "%# Server : $0";
window_info_server_sticky = "%# Server : $0 (sticky)";
window_info_theme = "%# Theme : $0$1";
window_info_items_header = "%#Items : {hilight Name Server tag}";
window_info_item = "%# $[7]0: $[!30]1 $2";
window_info_items_footer = "%r-------------------------------->%n";
};
"fe-common/text" = { window_info_sticky = "%# Sticky : $0"; };
"fe-common/irc" = {
netsplit = "{netsplit } {server $0} %w<-%r\\->%n {server %R$1%n}: [$2]";
netsplit_more = "{netsplit } %K-%w-%W-%n {server $0} %w<-%r\\->%n {server %K$1%n} %W-%w-%K-%n%: %K<<<%n [$2%_+$3 more%_]";
netsplit_join = "{netjoin %G>>>%n} [$0]";
netsplit_join_more = "{netjoin %G>>%n} [$0\012%_+$1 more%_]";
chanmode_change = " $2 sets {mode $1}";
server_chanmode_change = " {nick $2} sets {mode $1}";
own_action = "{ownaction $0}%|$1";
action_public = "{pubaction $0}%|$1";
who = "%#{channelhilight $[-10]0} {nick %n$[9]1%n} $[3]2 $[2]3 {comment {hilight $[10]6}} {comment $[!18]7} {chanhost %n$4@$5}";
whois = "%r,%B----------%r,%w----------%r(%W whois %r)%w--------- %B -%w --- -- %B -%n %: {whois %rnick%n $0}%n %: {whois host $1@$2}%: {whois gecos $3}";
whois_idle = " {whois idle %|$1d $2h $3m $4s}";
whois_idle_signon = " {whois idle %|$1d $2h $3m $4s {comment signon: $5}}";
whois_server = " {whois server %|$1 {comment $2}}";
whois_oper = " {whois operator %W$1-%n}";
whois_registered = " {whois registered}";
whois_help = " {whois is available for help}";
whois_modes = " {whois modes $1}";
whois_realhost = " {whois hostname $1-}";
whois_usermode = " {whois usermode $1}";
whois_channels = " {whois channels %|$1}";
whois_away = " {whois away %|$1}";
whois_special = " {whois info %|$1}";
whois_extra = " {whois extra %|$1}";
end_of_whois = "%r`%B----------%r`%w------ -- --- %B-%w ------ --- %r-- %w- %B-%n";
whois_not_found = "%K>%r>%R>%N There is no such nick $0";
default_event_server = " {whois remote $1 from %K$0%n}";
usermode_change = "%K>%r>%R>%n %_Y%_ou have set user mode {mode $0}";
user_mode = "%K>%r>%R>%n %_Y%_our user mode is {mode $0}";
away = "%K>%r>%R>%n %_Y%_ou have been marked as being %_away%_";
unaway = "%K>%r>%R>%n %_Y%_ou are no longer marked %_away%_, Welcome Back!";
nick_away = "%K>%r>%R>%n {nick $0} is away: $1";
no_such_nick = "%K>%r>%R>%n {nick $0}: No such nickname";
nick_in_use = "%K>%r>%R>%n Nick {nick $0} is already in use";
nick_unavailable = "%K>%r>%R>%n Nick {nick $0} is %_Juped%_";
your_nick_owned = "%K>%r>%R>%n Your nick is Chowned by {nick $3} {comment $1@$2}";
kill = "%r>%r>%r>%n %_Y%_ou were {error killed} by {nick $0} {nickhost $1} {reason $2} {comment Path: $3}";
kill_server = "%r>%r>%r>%n %_Y%_ou were {error killed} by {server $0} {reason $1} {comment Path: $2}";
default_event = "%K>%r>%R>%n $1";
unknown_mode = "%K>%r>%R>%n %_U%_nknown mode character $0";
joinerror_toomany = "%K>%r>%R>%n %_M%_ax Channels Exceeded! Cannot join {channel $0}";
joinerror_full = "%K>%r>%R>%n %_C%_hannel Limit Reached... Cannot join {channel $0}";
joinerror_invite = "%K>%r>%R>%n %_C%_annot join {channel $0} without an %_I%_nvite";
joinerror_banned = "%K>%r>%R>%n %_Y%_ou are %rBANNED%n from {channel $0}";
joinerror_bad_key = "%K>%r>%R>%n %_K%_ey required to join {channel $0}";
joinerror_bad_mask = "%K>%r>%R>%n %_C%_annot join to channel {channel $0} (Bad channel mask)";
joinerror_unavail = "%K>%r>%R>%n {channel $0} is %_JUPED%_ %:%K>%r>%R>%n %_R%_epeated attempts to join {channel $0} could result in a %_k-line%_";
joinerror_duplicate = "%K>%r>%R>%n {channel $0} already exists";
channel_rejoin = "%K>%r>%R>%n {channel $0} is temporarily unavailable, most likely because of a netsplit. %_I%_rssi will now automagicly try to rejoin this channel untill sucessful. %:%K>%r>%R>%n %_A%_uto-rejoin initiated. Use %_/RMREJOINS%_ to abort.";
inviting = "%K>%r>%R>%n %_I%_nviting {nick $0} to {channel $1}";
channel_created = "%K>%r>%R>%n %_T%_his Channel was created on $1";
url = "%K>%r>%R>%n Home page for {channelhilight $0}: $1";
topic = "%K>%r>%R>%n Topic for {channelhilight $0}: $1";
no_topic = "%K>%r>%R>%n No topic set for {channelhilight $0}";
topic_info = "%K>%r>%R>%n Topic set by {nick $0} {nickhost $2} {comment $1}";
bantype = "%K>%r>%R>%n Ban type changed to {channel $0}";
no_bans = "%K>%r>%R>%n No bans in {channel $0}";
banlist = "%K>%r>%R>%n $0 - {channel $1}: ban {ban $2}";
banlist_long = "%K>%r>%R>%n $0 - {channel $1}: ban {ban $2} {comment by {nick $3}, $4 secs ago}";
ebanlist = "%K>%r>%R>%n {channel $0}: ban exception {ban $1}";
ebanlist_long = "%K>%r>%R>%n {channel $0}: ban exception {ban $1} {comment by {nick $2}, $3 secs ago}";
no_invitelist = "%K>%r>%R>%n Invite list is empty for {channel $0}";
invitelist = "%K>%r>%R>%n {channel $0}: invite {ban $1}";
no_such_channel = "%K>%r>%R>%n {channel $0}: No such channel";
channel_synced = "%K>%r>%R>%n Join to {channel $0} was synced in {hilight $1} secs";
ircnet_added = "%K>%r>%R>%n Ircnet $0 saved";
ircnet_removed = "%K>%r>%R>%n Ircnet $0 removed";
ircnet_not_found = "%K>%r>%R>%n Ircnet $0 not found";
ircnet_header = "%#%r,--------------------------( %WNETWORKS %r)--------------------------->";
ircnet_line = "%#%r|%n %_$0%_: $1";
ircnet_footer = "%#%r`------------------------------------------------->";
no_netsplits = "%K>%r>%R>%n No Detected %_N%_etsplits! :)";
netsplits_header = "%#%r,--%WNick%r------%WChannel%r----%WServer%r---------------#WSplit Server%r---->%n";
netsplits_line = "%r|%#%n $[9]0 $[10]1 $[20]2 $3";
netsplits_footer = "%r`-------------------------------------------------->%n";
channel_mode = "%K>%r>%R>%n %_M%_odes for $0 {mode $1}";
};
# kills.pl reformat
"Irssi::Script::kills" = {
kill_public = " %B<<<%n {channick %B$0%n}!{chanhost %K$1%n} {reason %w$4%n} %Bkilled%n by {nick %W$2%n}$3";
};
};

86
home/.irssi/salsa.theme Normal file
View File

@@ -0,0 +1,86 @@
# "Salsa 1.0", a theme for irssi
# xfesty <xfesty@oublinet.net>
# come and join the mockery at #oublinet / irc.oublinet.net
replaces = { "[]<>=" = "%K$0-%n"; };
abstracts = {
line_start = "%Y>>> ";
timestamp = "%K$0-%n";
hilight = "%Y$0-%n";
error = "%R$0-%n";
channel = "%R$0-%n";
nick = "$0-%n";
nickhost = "[$0-]";
server = "%Y$0-%n";
comment = "[%Y$0-%n]";
reason = "{comment $0-}";
mode = "{comment %R$0-}%n";
channick_hilight = "%R$0-";
chanhost_hilight = "{nickhost %r$0-}%R";
channick = "%K$0-%K";
chanhost = "{nickhost %K$0-}%K";
channelhilight = "%Y$0-%n";
ban = "%R$0-%n";
msgnick = "$0$1-%K:%n %|";
ownmsgnick = "{msgnick %K$0 $1-}";
ownnick = "%K$0-%n";
pubmsgnick = "{msgnick %K$0 $1-}";
pubnick = "%m$0-%n";
pubmsgmenick = "{msgnick %K$0%y $1-}%n";
menick = "%Y$0-";
pubmsghinick = "{msgnick $1 $0$2-}";
msgchannel = "%K:%y$0-%n";
privmsg = "[%R$0%K(%r$1-%K)%n] ";
ownprivmsg = "[%r$0%K(%R$1-%K)%n] ";
ownprivmsgnick = "> %W%|";
ownprivnick = "%K$0-%n";
privmsgnick = "{msgnick %m$0-%n}";
action_core = "%Y* %R$0-";
action = "{action_core $0-} ";
ownaction = "{action $0-}";
ownaction_target = "{action_core $0}%K:%Y$1%n ";
pvtaction = "%Y* $0-%n ";
pvtaction_query = "{action $0-}";
pubaction = "{action $0-}";
ownnotice = "%K-%Y$0%K:%Y$1-%K-%n ";
notice = "%K-%Y$0%K%n ";
pubnotice_channel = "%K:%y$0-";
pvtnotice_host = "%Y(%K%r$0-%Y)%Y";
servernotice = "%K-%r$0-%K-%n ";
ownctcp = "%K-%y$0%K:%y$1-%K-%n ";
ctcp = "%g$0-%n";
wallop = "%R$0-:%m";
wallop_nick = "$0-";
wallop_action = "%W * $0-%n ";
netsplit = "%R$0-";
netjoin = "%R$0-";
names_nick = "%K$0%R$1-%Y ";
names_users = "[%K$0-%n]";
names_channel = "%R$0-%n";
dcc = "%K$0-%K";
dccfile = "%K$0-%n";
dccownmsg = "[%r$0%K($1-%K)%n] ";
dccownnick = "%R$0-%n";
dccownaction = "{action $0-}";
dccownaction_target = "{action_core $0}%K:%c$1%n ";
dccmsg = "[%G$1-%K(%g$0%K)%n] ";
dccquerynick = "%G$0-%n";
dccaction = "{action $0-}";
sb_background = "%W%1";
sb_prompt_bg = "%0";
sb_info_bg = "%8";
sbstart = "";
sbend = " ";
prompt = "%r(%R$*%r) ";
sb = "%k[%k$*%k] ";
sbmode = "%R(%W+%n$*%R)";
sbaway = "%W] [%RA";
sbservertag = ":%Y$0%n";
sb_act_sep = "%K$*";
sb_act_text = "%K$*";
sb_act_msg = "%W$*";
sb_act_hilight = "%Y$*";
sb_act_hilight_color = "$0$1-%n";
};
# vim:ft=config

312
home/.irssi/screwer.theme Normal file
View File

@@ -0,0 +1,312 @@
# screwer by ak5
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "-1";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = { "[]():@" = "%K$*%n"; };
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
line_start = "";
# timestamp styling, nothing by default
timestamp = "%K$*%N";
# any kind of text that needs hilighting, default is to bold
hilight = "%_$*%_";
# any kind of error message, default is bright red
error = "%R$*%N";
# channel name is printed
channel = "$*";
# nick is printed
nick = "%_$*%_";
# nick host is printed
nickhost = "[%K$*]";
# server name is printed
server = "%_$*%_";
# some kind of comment is printed
comment = "($*)";
# reason for something is printed (part, quit, kick, ..)
reason = "($*)";
# mode change is printed ([+o nick])
mode = "($*)";
##
## channel specific messages
##
# highlighted nick/host is printed
channick_hilight = "%W$*%N";
chanhost_hilight = "[$*]";
# nick/host is printed (parts, quits, etc.)
channick = "%N$*";
chanhost = "{nickhost $*}";
# highlighted channel name is printed
channelhilight = "%_$*%_";
# ban/ban exception/invite list mask is printed
ban = "$*";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%K<%W$0%N$1%K>%N ";
# $0 = nick mode, $1 = nick
ownmsgnick = "{msgnick $0 $1}";
ownnick = "%W$0%N";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "{msgnick $0 $1}";
pubnick = "%N$0%N";
# public message in channel meant for me, $0 = nick mode, $1 = nick
pubmsgmenick = "{msgnick $0 $1}%W";
menick = "%W$0%N";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
pubmsghinick = "{msgnick $1 $0$2-}";
# channel name is printed with message
msgchannel = "%N:%K$*%N";
# private message, $0 = nick, $1 = host
privmsg = "[$0(%K$1-)] ";
# private message from you, $0 = "msg", $1 = target nick
ownprivmsg = "[%K$0(%N$1-)] ";
# own private message in query
ownprivmsgnick = "{msgnick $*}";
ownprivnick = "%W$*%N";
# private message in query
privmsgnick = "{msgnick %N$*}";
##
## Actions (/ME stuff)
##
# used internally by this theme
action_core = "%W*%N $*";
# generic one that's used by most actions
action = "{action_core $0} ";
# own action, both private/public
ownaction = "{action_core $0} ";
# own action with target, both private/public
ownaction_target = "%W*%N $0:%K$1%N ";
# private action sent by others
pvtaction = " %W*%N $* ";
pvtaction_query = "{action $*}";
# public action sent by others
pubaction = "{action $*}";
##
## other IRC events
##
# whois
whois = "%K$[8]0 :%N $1-";
# notices
ownnotice = "[%K$0>%N$1-] ";
notice = "%W-%N$*%W-%N ";
# notice = "%W-%N$0(
pubnotice_channel = "%N:%g$*";
pvtnotice_host = "(%K$*)";
servernotice = "%K-%N$*%K-%N ";
# CTCPs
ownctcp = "[%K$0($1-)] ";
ctcp = "%N$*";
# wallops
wallop = "%W$*%N: ";
wallop_nick = "%N$*";
wallop_action = "%W * $*%N ";
# netsplits
netsplit = "%w-%W-%K$*%W-%w-%N";
netjoin = "%w-%W-%K$*%W-%w-%N";
# /names list
names_prefix = "";
names_nick = "%K|%W$0%N$1-%N ";
names_nick_op = "{names_nick $*}";
names_nick_halfop = "{names_nick $*}";
names_nick_voice = "{names_nick $*}";
names_users = "%K|>%w>%W>%N $*";
names_channel = "$*";
# DCC
dcc = "$*%N";
dccfile = "%_$*%_";
# DCC chat, own msg/action
dccownmsg = "[$0($1-)] ";
dccownnick = "$*";
dccownquerynick = "%W$*%N";
dccownaction = "%K*%N $* ";
dccownaction_target = "%K*%N $0%K:%K$1%N ";
# DCC chat, others
dccmsg = "[$1-($0)] ";
dccquerynick = "$*";
dccaction = "%K*%N $* ";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
# sb_background = "%9%W";
sb_background = "%N%N";
# default backround for "default" statusbar group
# sb_default_bg = "%0";
sb_default_bg = "%N";
# background for prompt / input line
sb_prompt_bg = "%N";
# background for info statusbar
sb_info_bg = "%N";
# background for topicbar (same default)
sb_topic_bg = "%N";
# text at the beginning of statusbars. sb-item already puts
# space there,so we don't use anything by default.
# sbstart = "%y»)%N";
sbstart = "";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = "%K<«";
# topicsbstart = "{sbstart $*}";
topicsbstart = "%K»>%N";
# topicsbend = "{sbend $*}";
topicsbend = "";
prompt = "%K>%N$*%K: ";
sb = "%K[%N$*%K]%N ";
#custom:
sbtime = "%K$*%N ";
#endcustom
sbmode = "%K/%N+$*%N";
sbaway = " %N(%KzZzZ%N)%N";
sbservertag = "%K:%N $0 %K(%N^X%K)";
# activity in statusbar
# ',' separator
sb_act_sep = "%K$*";
# normal text
sb_act_text = "%N$*";
# public message
sb_act_msg = "%W$*";
# hilight
sb_act_hilight = "%Y$*";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "$0$1-%N";
# sb_act_hilight_color = "$0-%N";
# sb_act_hilight_color = "%Y$1%N";
# userlist.pl settings
sb_usercount = "{sb $0 %K/ $1-}";
sb_uc_ircops = "%K*%N$*";
sb_uc_ops = "%K@%N$*";
sb_uc_halfops = "%K%%%N$*";
sb_uc_voices = "%K+%N$*";
sb_uc_normal = "%N$*";
sb_uc_space = "%K,";
# nact.pl settings
nact_display = "$1%G>%N$0%R>%N$2";
nact_command = "$1: [DN:$0 UP:$2]";
};
formats = {
"fe-common/core" = {
join = "%K»»%N$[-9]0%K» {chanhost $1} %Kjoins $2";
part = "%K««%N$[-9]0%K« {chanhost $1} %Kleaves $2 {reason $3}";
quit = "%K««%N$[-9]0%K« {chanhost $1} %Kquits {reason $2}";
kick = "%R«%r«%N$[-9]0%K was kicked from%N {channel $1} %Kby%N $2 {reason $3}";
own_msg = "{ownmsgnick $2 {ownnick $[0]0}}$1";
own_msg_channel = "{ownmsgnick $3 {ownnick $[-9]0}{msgchannel $1}}$2";
pubmsg_me = "{pubmsgmenick $2 {menick $[-9]0}}$1";
pubmsg_me_channel = "{pubmsgmenick $3 {menick $[-9]0}{msgchannel $1}}$2";
pubmsg_hilight = "{pubmsghinick $0 $3 $[-9]1}$2";
pubmsg_hilight_channel = "{pubmsghinick $0 $4 $[-9]1{msgchannel $2}}$3";
pubmsg = "{pubmsgnick $2 {pubnick \00310$[0]0}}$1";
pubmsg_channel = "{pubmsgnick $3 {pubnick $[-9]0}{msgchannel $1}}$2";
set_item = "$0 %K=%N $1";
line_start_irssi = "{line_start}{hilight %KIrssi:%N }";
nick_changed = "%K--%N{channick $[-9]0}%K- is now known as%N {nick $1}";
your_nick_changed = "%K--%N You're now known as {nick $1}";
daychange = "%K----%N Day changed to %%d %%b %%Y";
};
"fe-common/irc" = {
chanmode_change = "%K--modechange {channel $0}:%N {mode $1} %Kby%N $2";
whois = "%K,-%w-%W-%nWhois%W-%w-%K<%N $0 {chanhost_hilight $1@$2}%n%:%K|%n {whois ircname $3}";
whois_idle = "%K|%n {whois idle %|$1d $2h $3m $4s}";
whois_idle_signon = "%K|%n {whois idle %|$1d $2h $3m $4s {comment signon: $5}}";
whois_server = "%K|%n {whois server %|$1 {comment $2}}";
whois_oper = "%K|%n {whois {hilight $1}}";
whois_registered = "%K|%n {whois has registered this nick}";
whois_help = "%K|%n {whois is available for help}";
whois_modes = "%K|%n {whois modes $1}";
whois_realhost = "%K|%n {whois hostname $1-}";
whois_usermode = "%K|%n {whois usermode $1}";
whois_channels = "%K|%n {whois channels %|$1}";
whois_away = "%K|%n {whois away %|$1}";
whois_special = "%K|%n {whois info %|$1}";
whois_extra = "%K|%n {whois extra %|$1}";
end_of_whois = "%K`---------------- -- --- - - -";
whois_not_found = "%K>%w>%W>%N There is no such nick $0";
# very ugly. But recently some EFNet IRCDs send an annoying
# "actually using host" message along with whois.
default_event_server = "%K|%n {whois ircdmsg $1 [$0]}";
server_chanmode_change = "{netsplit IRCDMode}%K/$0 %n{mode $1} %Kby%N {nick $2}";
own_action = "{ownaction $[-9]0}$1";
action_public = "{pubaction $[-9]0}$1";
action_public_channel = "{pubaction $[-9]0{msgchannel $1}}$2";
channel_created = "%K-- Channel%n $0 %Kcreated%n $1";
topic = "%K-- Topic for %n$0: $1";
no_topic = "%K-- No topic set for %n$0";
topic_info = "%K-- Topic set by%n {nick $0} {nickhost $2} {comment $1}";
channel_synced = "%KJoin to%n {channel $0} %Kwas synced in%n {hilight $1} secs";
};
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
use strict;
use vars qw($VERSION %IRSSI);
$VERSION = '1.3';
%IRSSI = (
authors => 'Tijmen "timing" Ruizendaal & Wilmer van der Gaast',
contact => 'tijmen.ruizendaal@gmail.com',
name => 'BitlBee_tab_completion',
description => 'Intelligent Tab-completion for BitlBee commands.',
license => 'GPLv2',
url => 'http://the-timing.nl/stuff/irssi-bitlbee',
changed => '2009-08-11',
);
my $root_nick = 'root';
my $bitlbee_channel = '&bitlbee';
my $bitlbee_server_tag = 'localhost';
my $get_completions = 0;
my @commands;
Irssi::signal_add_last 'channel sync' => sub {
my( $channel ) = @_;
if( $channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information." ){
$bitlbee_server_tag = $channel->{server}->{tag};
$bitlbee_channel = $channel->{name};
request_completions();
}
};
if (get_channel()) {
request_completions();
}
sub request_completions {
$get_completions = 1;
Irssi::server_find_tag($bitlbee_server_tag)->send_raw( 'COMPLETIONS' );
}
sub get_channel {
my @channels = Irssi::channels();
foreach my $channel(@channels) {
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
$bitlbee_channel = $channel->{name};
$bitlbee_server_tag = $channel->{server}->{tag};
return 1;
}
}
return 0;
}
sub irc_notice {
return unless $get_completions;
my( $server, $msg, $from, $address, $target ) = @_;
if( $msg =~ s/^COMPLETIONS // ) {
$root_nick = $from;
if( $msg eq 'OK' ) {
@commands = ();
}
elsif( $msg eq 'END' ) {
$get_completions = 0;
}
@commands = ( @commands, $msg );
Irssi::signal_stop();
}
}
sub complete_word {
my ($complist, $window, $word, $linestart, $want_space) = @_;
my $channel = $window->get_active_name();
if ($channel eq $bitlbee_channel or $channel eq $root_nick or $linestart =~ /^\/(msg|query) \Q$root_nick\E */i){
$linestart =~ s/^\/(msg|query) \Q$root_nick\E *//i;
$linestart =~ s/^\Q$root_nick\E[:,] *//i;
foreach my $command(@commands) {
if ($command =~ /^$word/i) {
push @$complist, $command;
}
}
}
}
Irssi::signal_add_last('complete word', 'complete_word');
Irssi::signal_add_first('message irc notice', 'irc_notice');

View File

@@ -0,0 +1,115 @@
use strict;
use vars qw($VERSION %IRSSI);
use Irssi;
use Irssi::Irc;
# Usage:
# /script load go.pl
# If you are in #irssi you can type /go #irssi or /go irssi or even /go ir ...
# also try /go ir<tab> and /go <tab> (that's two spaces)
#
# The following settings exist:
#
# /SET go_match_case_sensitive [ON|OFF]
# Match window/item names sensitively (the default). Turning this off
# means e.g. "/go foo" would jump to a window named "Foobar", too.
#
# /SET go_match_anchored [ON|OFF]
# Match window/names only at the start of the word (the default). Turning
# this off will mean that strings can match anywhere in the window/names.
# The leading '#' of channel names is optional either way.
#
# /SET go_complete_case_sensitive [ON|OFF]
# When using tab-completion, match case-insensitively (the default).
# Turning this on means that "/go foo<tab>" will *not* suggest "Foobar".
#
# /SET go_complete_anchored [ON|OFF]
# Match window/names only at the start of the word. The default is 'off',
# which causes completion to match anywhere in the window/names during
# completion. The leading '#' of channel names is optional either way.
#
$VERSION = '1.1.1';
%IRSSI = (
authors => 'nohar',
contact => 'nohar@freenode',
name => 'go to window',
description => 'Implements /go command that activates a window given a name/partial name. It features a nice completion.',
license => 'GPLv2 or later',
changed => '2019-02-25'
);
sub _make_regexp {
my ($name, $ci, $aw) = @_;
my $re = "\Q${name}\E";
$re = "(?i:$re)" unless $ci;
$re = "^#?$re" if $aw;
return $re;
}
sub signal_complete_go {
my ($complist, $window, $word, $linestart, $want_space) = @_;
my $channel = $window->get_active_name();
my $k = Irssi::parse_special('$k');
return unless ($linestart =~ /^\Q${k}\Ego\b/i);
my $re = _make_regexp($word,
Irssi::settings_get_bool('go_complete_case_sensitive'),
Irssi::settings_get_bool('go_complete_anchored'));
@$complist = ();
foreach my $w (Irssi::windows) {
my $name = $w->get_active_name();
if ($word ne "") {
if ($name =~ $re) {
push(@$complist, $name)
}
} else {
push(@$complist, $name);
}
}
Irssi::signal_stop();
};
sub cmd_go
{
my($chan,$server,$witem) = @_;
my $case_sensitive = Irssi::settings_get_bool('go_match_case_sensitive');
my $match_anchored = Irssi::settings_get_bool('go_match_anchored');
$chan =~ s/ *//g;
my $re = _make_regexp($chan, $case_sensitive, $match_anchored);
my @matches;
foreach my $w (Irssi::windows) {
my $name = $w->get_active_name();
if (($case_sensitive && $name eq $chan) ||
(!$case_sensitive && CORE::fc $name eq CORE::fc $chan)) {
$w->set_active();
return;
} elsif ($name =~ /$re/) {
push(@matches, $w);
}
}
if (@matches) {
$matches[0]->set_active();
}
}
Irssi::command_bind("go", "cmd_go");
Irssi::signal_add_first('complete word', 'signal_complete_go');
Irssi::settings_add_bool('go', 'go_match_case_sensitive', 1);
Irssi::settings_add_bool('go', 'go_complete_case_sensitive', 0);
Irssi::settings_add_bool('go', 'go_match_anchored', 1);
Irssi::settings_add_bool('go', 'go_complete_anchored', 0);
# Changelog
#
# 2017-02-02 1.1 martin f. krafft <madduck@madduck.net>
# - made case-sensitivity of match configurable
# - made anchoring of search strings configurable
#
# 2019-02-025 1.1.1 dylan lloyd <dylan@disinclined.org>
# - prefer exact channel matches

View File

@@ -0,0 +1,113 @@
use strict;
use Irssi;
use Irssi::Irc;
use vars qw($VERSION %IRSSI);
$VERSION = "1.0";
%IRSSI = (
"authors" => "Mantis",
"contact" => "mantis\@inta-link.com",
"name" => "highlite",
"description" => "shows events happening in all channels you are in that may concern you",
"url" => "http://www.inta-link.com/",
"license" => "GNU GPL v2",
"changed" => "2003-01-03"
);
sub msg_join
{
my ($server, $channame, $nick, $host) = @_;
$channame =~ s/^://;
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%B%0JOIN : " . $nick . " : " . $channame . " : " . $host, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
sub msg_part
{
my ($server, $channame, $nick, $host) = @_;
$channame =~ s/^://;
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%b%0PART : " . $nick . " : " . $channame . " : " . $host, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
sub msg_quit
{
my ($server, $nick, $host, $quitmsg) = @_;
if (substr($quitmsg, 0, 14) eq "Read error to ")
{
$quitmsg = "[ General Read Error ]";
}
if (substr($quitmsg, 0, 17) eq "Ping timeout for ")
{
$quitmsg = "[ General Ping Timeout Error ]";
}
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%R%0QUIT : " . $nick . " : " . $host . " : " . $quitmsg, MSGLEVEL_CLIENTCRAP) if ($windowname);
$quitmsg = "";
}
sub msg_topic
{
my ($server, $channame, $topicmsg, $nick, $host) = @_;
$channame =~ s/^://;
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%G%0TOPIC : " . $nick . " : " . $channame . " : " . $topicmsg, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
sub msg_nick
{
my ($server, $nick, $old_nick, $host) = @_;
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%m%0NICK : " . $old_nick . " : " . $nick . " : " . $host, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
sub msg_kick
{
my ($server, $channame, $kicked, $nick, $host, $reason) = @_;
$channame =~ s/^://;
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%Y%0KICK : " . $kicked . " : " . $channame . " : " . $nick . " : " . $reason, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
sub sig_printtext {
my ($dest, $text, $stripped) = @_;
if (($dest->{level} & (MSGLEVEL_HILIGHT|MSGLEVEL_MSGS)) && ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0)
{
if ($dest->{level} & MSGLEVEL_PUBLIC)
{
my $windowname = Irssi::window_find_name('highlite');
$windowname->print("%W%0HIGHLITE : " . $dest->{target} . " : " . $text, MSGLEVEL_CLIENTCRAP) if ($windowname);
}
}
}
my $windowname = Irssi::window_find_name('highlite');
if (!$windowname)
{
Irssi::command("window new hidden");
Irssi::command("window name highlite");
}
Irssi::signal_add(
{
'message join' => \&msg_join,
'message part' => \&msg_part,
'message quit' => \&msg_quit,
'message topic' => \&msg_topic,
'print text', 'sig_printtext',
'message nick' => \&msg_nick,
'message kick' => \&msg_kick
}
);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,253 @@
use strict;
use Irssi 20020101.0250 ();
use vars qw($VERSION %IRSSI);
$VERSION = "2.1";
%IRSSI = (
authors => "Timo Sirainen, Ian Peters, David Leadbeater, Bruno Cattáneo",
contact => "tss\@iki.fi",
name => "Nick Color",
description => "assign a different color for each nick",
license => "Public Domain",
url => "http://irssi.org/",
changed => "Mon 08 Jan 21:28:53 BST 2018",
);
# Settings:
# nickcolor_colors: List of color codes to use.
# e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13
# (avoid 8, as used for hilights in the default theme).
#
# nickcolor_enable_prefix: Enables prefix for same nick.
#
# nickcolor_enable_truncate: Enables nick truncation.
#
# nickcolor_prefix_text: Prefix text for succesive messages.
# e.g. /set nickcolor_prefix_text -
#
# nickcolor_truncate_value: Truncate nick value.
# e.g. /set nickcolor_truncate_value -7
# This will truncate nicknames at 7 characters and make them right aligned
my %saved_colors;
my %session_colors = {};
my %saved_nicks; # To store each channel's last nickname
sub load_colors {
open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors";
while (<$color_fh>) {
chomp;
my($nick, $color) = split ":";
$saved_colors{$nick} = $color;
}
}
sub save_colors {
open COLORS, ">", "$ENV{HOME}/.irssi/saved_colors";
foreach my $nick (keys %saved_colors) {
print COLORS "$nick:$saved_colors{$nick}\n";
}
close COLORS;
}
# If someone we've colored (either through the saved colors, or the hash
# function) changes their nick, we'd like to keep the same color associated
# with them (but only in the session_colors, ie a temporary mapping).
sub sig_nick {
my ($server, $newnick, $nick, $address) = @_;
my $color;
$newnick = substr ($newnick, 1) if ($newnick =~ /^:/);
if ($color = $saved_colors{$nick}) {
$session_colors{$newnick} = $color;
} elsif ($color = $session_colors{$nick}) {
$session_colors{$newnick} = $color;
}
}
# This gave reasonable distribution values when run across
# /usr/share/dict/words
sub simple_hash {
my ($string) = @_;
chomp $string;
my @chars = split //, $string;
my $counter;
foreach my $char (@chars) {
$counter += ord $char;
}
my @colors = split / /, Irssi::settings_get_str('nickcolor_colors');
$counter = $colors[$counter % @colors];
return $counter;
}
# process public (others) messages
sub sig_public {
my ($server, $msg, $nick, $address, $target) = @_;
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Set default nick truncate value to 0 if option is disabled
$truncate_value = 0 if (!$enable_truncate);
# Has the user assigned this nick a color?
my $color = $saved_colors{$nick};
# Have -we- already assigned this nick a color?
if (!$color) {
$color = $session_colors{$nick};
}
# Let's assign this nick a color
if (!$color) {
$color = simple_hash $nick;
$session_colors{$nick} = $color;
}
$color = sprintf "\003%02d", $color;
# Optional: We check if it's the same nickname for current target
if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
{
# Grouped message
Irssi::command('/^format pubmsg ' . $prefix_text . '$1');
}
else
{
# Normal message
Irssi::command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$[' . $truncate_value . ']0}}$1');
# Save nickname for next message
$saved_nicks{$tagtarget} = $nick;
}
}
# process public (me) messages
sub sig_me {
my ($server, $msg, $target) = @_;
my $nick = $server->{nick};
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Set default nick truncate value to 0 if option is disabled
$truncate_value = 0 if (!$enable_truncate);
# Optional: We check if it's the same nickname for current target
if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
{
# Grouped message
Irssi::command('/^format own_msg ' . $prefix_text . '$1');
}
else
{
# Normal message
Irssi::command('/^format own_msg {ownmsgnick $2 {ownnick $[' . $truncate_value . ']0}}$1');
# Save nickname for next message
$saved_nicks{$tagtarget} = $nick;
}
}
# process public (others) actions
sub sig_action_public {
my ($server, $msg, $nick, $address, $target) = @_;
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Empty current target nick if prefix option is enabled
$saved_nicks{$tagtarget} = '' if ($enable_prefix);
}
# process public (me) actions
sub sig_action_me {
my ($server, $msg, $target) = @_;
my $nick = $server->{nick};
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Empty current target nick if prefix option is enabled
$saved_nicks{$tagtarget} = '' if ($enable_prefix);
}
sub cmd_color {
my ($data, $server, $witem) = @_;
my ($op, $nick, $color) = split " ", $data;
$op = lc $op;
if (!$op) {
Irssi::print ("No operation given (save/set/clear/list/preview)");
} elsif ($op eq "save") {
save_colors;
} elsif ($op eq "set") {
if (!$nick) {
Irssi::print ("Nick not given");
} elsif (!$color) {
Irssi::print ("Color not given");
} elsif ($color < 2 || $color > 14) {
Irssi::print ("Color must be between 2 and 14 inclusive");
} else {
$saved_colors{$nick} = $color;
}
} elsif ($op eq "clear") {
if (!$nick) {
Irssi::print ("Nick not given");
} else {
delete ($saved_colors{$nick});
}
} elsif ($op eq "list") {
Irssi::print ("\nSaved Colors:");
foreach my $nick (keys %saved_colors) {
Irssi::print (chr (3) . sprintf("%02d", $saved_colors{$nick}) . "$nick" .
chr (3) . "1 ($saved_colors{$nick})");
}
} elsif ($op eq "preview") {
Irssi::print ("\nAvailable colors:");
foreach my $i (2..14) {
Irssi::print (chr (3) . "$i" . "Color #$i");
}
}
}
load_colors;
Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13');
Irssi::settings_add_bool('misc', 'nickcolor_enable_prefix', 0);
Irssi::settings_add_bool('misc', 'nickcolor_enable_truncate', 0);
Irssi::settings_add_str('misc', 'nickcolor_prefix_text' => '- ');
Irssi::settings_add_int('misc', 'nickcolor_truncate_value' => 0);
Irssi::command_bind('color', 'cmd_color');
Irssi::signal_add('message public', 'sig_public');
Irssi::signal_add('message own_public', 'sig_me');
Irssi::signal_add('message irc action', 'sig_action_public');
Irssi::signal_add('message irc own_action', 'sig_action_me');
Irssi::signal_add('event nick', 'sig_nick');

View File

@@ -0,0 +1,248 @@
use Irssi;
use strict;
use FileHandle;
use vars qw($VERSION %IRSSI);
$VERSION = "0.9.8.2";
%IRSSI = (
authors => 'Andreas \'ads\' Scherbaum <ads@wars-nicht.de>',
name => 'screen_away',
description => 'set (un)away, if screen is attached/detached',
license => 'GPL v2',
url => 'none',
);
# screen_away irssi module
#
# written by Andreas 'ads' Scherbaum <ads@ufp.de>
#
# changes:
# 20.12.2014 fix the bug when screenname is changed during the session
# 07.02.2004 fix error with away mode
# thanks to Michael Schiansky for reporting and fixing this one
# 07.08.2004 new function for changing nick on away
# 24.08.2004 fixing bug where the away nick was not storedcorrectly
# thanks for Harald Wurpts for help debugging this one
# 17.09.2004 rewrote init part to use $ENV{'STY'}
# 05.12.2004 add patch for remember away state
# thanks to Jilles Tjoelker <jilles@stack.nl>
# change "chatnet" to "tag"
# 18.05.2007 fix '-one' for SILC networks
#
#
# usage:
#
# put this script into your autorun directory and/or load it with
# /SCRIPT LOAD <name>
#
# there are 5 settings available:
#
# /set screen_away_active ON/OFF/TOGGLE
# /set screen_away_repeat <integer>
# /set screen_away_message <string>
# /set screen_away_window <string>
# /set screen_away_nick <string>
#
# active means, that you will be only set away/unaway, if this
# flag is set, default is ON
# repeat is the number of seconds, after the script will check the
# screen status again, default is 5 seconds
# message is the away message sent to the server, default: not here ...
# window is a window number or name, if set, the script will switch
# to this window, if it sets you away, default is '1'
# nick is the new nick, if the script goes away
# will only be used it not empty
#
# normal you should be able to rename the script to something other
# than 'screen_away' (as example, if you dont like the name) by simple
# changing the 'name' parameter in the %IRSSI hash at the top of this script
# variables
my $timer_name = undef;
my $away_status = 0;
my %old_nicks = ();
my %away = ();
# Register formats
Irssi::theme_register(
[
'screen_away_crap',
'{line_start}{hilight ' . $IRSSI{'name'} . ':} $0'
]);
# if we are running
my $screen_away_used = 0;
# try to find out, if we are running in a screen
# (see, if $ENV{STY} is set
if (!defined($ENV{STY})) {
# just return, we will never be called again
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"could not open status file for parent process (pid: " . getppid() . "): $!");
return;
}
my ($socket_pid, $socket_name, $socket_path);
# search for socket
# normal we could search the socket file, ... if we know the path
# but so we have to call one time the screen executable
# disable locale
# the quotes around C force perl 5.005_03 to use the shell
# thanks to Jilles Tjoelker <jilles@stack.nl> for pointing this out
my $socket = `LC_ALL="C" screen -ls`;
my $running_in_screen = 0;
# locale doesnt seems to be an problem (yet)
if ($socket !~ /^No Sockets found/s) {
# ok, should have only one socket
# $STY won't change if sessionname is changed during session
# therefore first find the pid and use that to find the actual sessionname
$socket_pid = substr($ENV{'STY'}, 0, index($ENV{'STY'}, '.'));
$socket_path = $socket;
$socket_path =~ s/^.*\d+ Sockets? in ([^\n]+)\..*$/$1/s;
$socket_name = $socket;
$socket_name =~ s/^.+?($socket_pid\.\S+).+$/$1/s;
if (length($socket_path) != length($socket)) {
# only activate, if string length is different
# (to make sure, we really got a dir name)
$screen_away_used = 1;
} else {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"error reading screen informations from:");
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"$socket");
return;
}
}
# last check
if ($screen_away_used == 0) {
# we will never be called again
return;
}
# build complete socket name
$socket = $socket_path . "/" . $socket_name;
# register config variables
Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1);
Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5);
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_message', "not here ...");
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_window', "1");
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_nick', "");
# init process
screen_away();
# screen_away()
#
# check, set or reset the away status
#
# parameter:
# none
# return:
# 0 (OK)
sub screen_away {
my ($away, @screen, $screen);
# only run, if activated
if (Irssi::settings_get_bool($IRSSI{'name'} . '_active') == 1) {
if ($away_status == 0) {
# display init message at first time
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds)");
}
# get actual screen status
my @screen = stat($socket);
# 00100 is the mode for "user has execute permissions", see stat.h
if (($screen[2] & 00100) == 0) {
# no execute permissions, Detached
$away = 1;
} else {
# execute permissions, Attached
$away = 2;
}
# check if status has changed
if ($away == 1 and $away_status != 1) {
# set away
if (length(Irssi::settings_get_str($IRSSI{'name'} . '_window')) > 0) {
# if length of window is greater then 0, make this window active
Irssi::command('window goto ' . Irssi::settings_get_str($IRSSI{'name'} . '_window'));
}
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"Set away");
my $message = Irssi::settings_get_str($IRSSI{'name'} . '_message');
if (length($message) == 0) {
# we have to set a message or we wouldnt go away
$message = "not here ...";
}
my ($server);
foreach $server (Irssi::servers()) {
if (!$server->{usermode_away}) {
# user isnt yet away
$away{$server->{'tag'}} = 0;
$server->command("AWAY " . (($server->{chat_type} ne 'SILC') ? "-one " : "") . "$message") if (!$server->{usermode_away});
if (length(Irssi::settings_get_str($IRSSI{'name'} . '_nick')) > 0) {
# only change, if actual nick isnt already the away nick
if (Irssi::settings_get_str($IRSSI{'name'} . '_nick') ne $server->{nick}) {
# keep old nick
$old_nicks{$server->{'tag'}} = $server->{nick};
# set new nick
$server->command("NICK " . Irssi::settings_get_str($IRSSI{'name'} . '_nick'));
}
}
} else {
# user is already away, remember this
$away{$server->{'tag'}} = 1;
}
}
$away_status = $away;
} elsif ($away == 2 and $away_status != 2) {
# unset away
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
"Reset away");
my ($server);
foreach $server (Irssi::servers()) {
if ($away{$server->{'tag'}} == 1) {
# user was already away, dont reset away
$away{$server->{'tag'}} = 0;
next;
}
$server->command("AWAY" . (($server->{chat_type} ne 'SILC') ? " -one" : "")) if ($server->{usermode_away});
if (defined($old_nicks{$server->{'tag'}}) and length($old_nicks{$server->{'tag'}}) > 0) {
# set old nick
$server->command("NICK " . $old_nicks{$server->{'tag'}});
$old_nicks{$server->{'tag'}} = "";
}
}
$away_status = $away;
}
}
# but everytimes install a new timer
register_screen_away_timer();
return 0;
}
# register_screen_away_timer()
#
# remove old timer and install a new one
#
# parameter:
# none
# return:
# none
sub register_screen_away_timer {
if (defined($timer_name)) {
# remove old timer, if defined
Irssi::timeout_remove($timer_name);
}
# add new timer with new timeout (maybe the timeout has been changed)
$timer_name = Irssi::timeout_add(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'screen_away', '');
}

View File

@@ -0,0 +1,433 @@
# based on the nicklist.pl script
################################################################################
# tmux_nicklist.pl
# This script integrates tmux and irssi to display a list of nicks in a
# vertical right pane with 20% width. Right now theres no configuration
# or setup, simply initialize the script with irssi and by default you
# will get the nicklist for every channel(customize by altering
# the regex in /set nicklist_channel_re)
#
# /set nicklist_channel_re <regex>
# * only show on channels matching this regular expression
#
# /set nicklist_max_users <num>
# * only show when the channel has so many users or less (0 = always)
#
# /set nicklist_smallest_main <num>
# * only show when main window is larger than this (0 = always)
#
# /set nicklist_pane_width <num>
# * width of the nicklist pane
#
# /set nicklist_color <ON|OFF>
# * colourise the nicks in the nicklist (required nickcolor script
# with get_nick_color2 and debug_ansicolour functions)
#
# /set nicklist_gone_sort <ON|OFF>
# * sort away people below
#
# It supports mouse scrolling and the following keys:
# k/up arrow: up one line
# j/down arrow: down one line
# u/pageup: up 50% lines
# d/pagedown: down 50% lines
# gg: go to top
# G: go to bottom
#
# For better integration, unrecognized sequences will be sent to irssi and
# its pane will be focused.
#
# to toggle the nicklist if it is in the way you can make a key binding:
# /bind meta-Z /script exec Irssi::Script::tmux_nicklist_portable::toggle_nicklist
################################################################################
use strict;
use warnings;
use IO::Handle;
use IO::Select;
use POSIX;
use File::Temp qw/ :mktemp /;
use File::Basename;
our $VERSION = '0.1.8';
our %IRSSI = (
authors => 'Thiago de Arruda',
contact => 'tpadilha84@gmail.com',
name => 'tmux-nicklist',
description => 'displays a list of nicks in a separate tmux pane',
license => 'WTFPL',
);
# "other" prefixes by danielg4 <daniel@gimpelevich.san-francisco.ca.us>
# added 'd' and 'u' navigation as in vim, by @gerardbm (github)
{ package Irssi::Nick }
if ($#ARGV == -1) {
require Irssi;
my $enabled = 0;
my $nicklist_toggle = 1;
my $script_path = __FILE__;
my $tmpdir;
my $fifo_path;
my $fifo;
my $just_launched;
my $resize_timer;
sub enable_nicklist {
return if ($enabled);
$tmpdir = mkdtemp Irssi::get_irssi_dir()."/nicklist-XXXXXXXX";
$fifo_path = "$tmpdir/fifo";
POSIX::mkfifo($fifo_path, 0600) or die "can't mkfifo $fifo_path: $!";
my $cmd = "perl $script_path $fifo_path $ENV{TMUX_PANE}";
#my $width = Irssi::settings_get_int('nicklist_pane_width');
my $width = 20;
system('tmux', 'split-window', '-dh', '-l', $width, '-t', $ENV{TMUX_PANE}, $cmd);
open_fifo();
Irssi::timeout_remove($just_launched) if defined $just_launched;
$just_launched = Irssi::timeout_add_once(300, sub { $just_launched = undef; }, '');
}
sub open_fifo {
# The next system call will block until the other pane has opened the pipe
# for reading, so synchronization is not an issue here.
open $fifo, ">", $fifo_path or do {
if ($! == 4) {
Irssi::timeout_add_once(300, \&open_fifo, '');
$enabled = -1 unless $enabled;
return;
}
die "can't open $fifo_path: $!";
};
$fifo->autoflush(1);
if ($enabled < -1) {
$enabled = 1;
disable_nicklist();
} elsif ($enabled == -1) {
$enabled = 1;
reset_nicklist("enabled");
} else {
$enabled = 1;
}
}
sub disable_nicklist {
return unless ($enabled);
if ($enabled > 0) {
print $fifo "EXIT\n";
close $fifo;
$fifo = undef;
unlink $fifo_path;
rmdir $tmpdir;
}
$enabled--;
}
sub reset_nicklist {
my $event = shift;
my $active = Irssi::active_win();
my $channel = $active->{active};
return disable_nicklist unless $channel && ref $channel;
if ($event =~ /^nick/) {
# check if that nick event is for the current channel/nicklist
my ($event_channel) = @_;
return unless $channel->{_irssi} == $event_channel->{_irssi};
}
my ($colourer, $ansifier);
if (Irssi::settings_get_bool('nicklist_color')) {
for my $script (sort map { my $z = $_; $z =~ s/::$//; $z } grep { /^nickcolor|nm/ } keys %Irssi::Script::) {
if ($colourer = "Irssi::Script::$script"->can('get_nick_color2')) {
$ansifier = "Irssi::Script::$script"->can('debug_ansicolour');
last;
}
}
}
my $channel_pattern = Irssi::settings_get_str('nicklist_channel_re');
{ local $@;
$channel_pattern = eval { qr/$channel_pattern/ };
$channel_pattern = qr/(?!)/ if $@;
}
my $smallest_main = Irssi::settings_get_int('nicklist_smallest_main');
if (!$nicklist_toggle
|| !$channel || !ref($channel)
|| !$channel->isa('Irssi::Channel')
|| !$channel->{'names_got'}
|| $channel->{'name'} !~ $channel_pattern
|| ($smallest_main && $channel->window->{width} < $smallest_main)) {
disable_nicklist;
} else {
my %colour;
my @nicks = $channel->nicks();
my $max_nicks = Irssi::settings_get_int('nicklist_max_users');
if ($max_nicks && @nicks > $max_nicks) {
disable_nicklist;
} else {
enable_nicklist;
return unless $enabled > 0;
foreach my $nick (sort { $a->{_irssi} <=> $b->{_irssi} } @nicks) {
$colour{$nick->{nick}} = ($ansifier && $colourer) ? $ansifier->($colourer->($active->{active}{server}{tag}, $channel->{name}, $nick->{nick}, 0)) : '';
}
print($fifo "BEGIN\n");
my $gone_sort = Irssi::settings_get_bool('nicklist_gone_sort');
my $prefer_real;
if (exists $Irssi::Script::{'realnames::'}) {
my $code = "Irssi::Script::realnames"->can('use_realnames');
$prefer_real = $code && $code->($channel);
}
my $_real = sub {
my $nick = shift;
$prefer_real && length $nick->{'realname'} ? $nick->{'realname'} : $nick->{'nick'}
};
foreach my $nick (sort {($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':$a->{'other'}>32?'0':'4').($gone_sort?($a->{'gone'}?1:0):'').lc($_real->($a))
cmp ($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':$b->{'other'}>32?'0':'4').($gone_sort?($b->{'gone'}?1:0):'').lc($_real->($b))} @nicks) {
my $colour = $colour{$nick->{nick}} || "\e[39m";
$colour = "\e[37m" if $nick->{'gone'};
print($fifo "NICK");
if ($nick->{'op'}) {
print($fifo "\e[32m\@$colour".$_real->($nick)."\e[39m");
} elsif ($nick->{'halfop'}) {
print($fifo "\e[34m%$colour".$_real->($nick)."\e[39m");
} elsif ($nick->{'voice'}) {
print($fifo "\e[33m+$colour".$_real->($nick)."\e[39m");
} elsif ($nick->{'other'}>32) {
print($fifo "\e[31m".(chr $nick->{'other'})."$colour".$_real->($nick)."\e[39m");
} else {
print($fifo " $colour".$_real->($nick)."\e[39m");
}
print($fifo "\n");
}
print($fifo "END\n");
}
}
}
sub toggle_nicklist {
if ($enabled) {
$nicklist_toggle = undef
} else {
$nicklist_toggle = 1;
}
reset_nicklist("toggle");
}
sub switch_channel {
print $fifo "SWITCH_CHANNEL\n" if $fifo;
&reset_nicklist;
}
sub resized_timed {
Irssi::timeout_remove($resize_timer) if defined $resize_timer;
return if defined $just_launched;
$resize_timer = Irssi::timeout_add_once(1100, \&resized, '');
#resized();
}
sub resized {
$resize_timer = undef;
return if defined $just_launched;
return unless $enabled >= 0;
disable_nicklist;
Irssi::timeout_add_once(200, sub{reset_nicklist("terminal resized")}, '');
}
sub UNLOAD {
disable_nicklist;
}
Irssi::settings_add_str('tmux_nicklist', 'nicklist_channel_re', '.*');
Irssi::settings_add_int('tmux_nicklist', 'nicklist_max_users', 0);
Irssi::settings_add_int('tmux_nicklist', 'nicklist_smallest_main', 0);
Irssi::settings_add_int('tmux_nicklist', 'nicklist_pane_width', 13);
Irssi::settings_add_bool('tmux_nicklist', 'nicklist_color', 1);
Irssi::settings_add_bool('tmux_nicklist', 'nicklist_gone_sort', 0);
Irssi::signal_add_last('window item changed', sub{switch_channel("window item changed",@_)});
Irssi::signal_add_last('window changed', sub{switch_channel("window changed",@_)});
Irssi::signal_add_last('channel joined', sub{switch_channel("channel joined",@_)});
Irssi::signal_add('nicklist new', sub{reset_nicklist("nicklist new",@_)});
Irssi::signal_add('nicklist remove', sub{reset_nicklist("nicklist remove",@_)});
Irssi::signal_add('nicklist changed', sub{reset_nicklist("nicklist changed",@_)});
Irssi::signal_add_first('nick mode changed', sub{reset_nicklist("nick mode changed",@_)});
Irssi::signal_add('gui exit', \&disable_nicklist);
Irssi::signal_add_last('terminal resized', \&resized_timed);
} else {
my $fifo_path = $ARGV[0];
my $irssi_pane = $ARGV[1];
# array to store the current channel nicknames
my @nicknames = ();
# helper functions for manipulating the terminal
# escape sequences taken from
# http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html
sub enable_mouse { print "\e[?1000h"; }
# recognized sequences
my $MOUSE_SCROLL_DOWN="\e[Ma";
my $MOUSE_SCROLL_UP="\e[M`";
my $ARROW_DOWN="\e[B";
my $ARROW_UP="\e[A";
my $DOWN="j";
my $UP="k";
my $PAGE_DOWN="\e[6~";
my $PAGE_UP="\e[5~";
my $PAGE_DOWN_D="d";
my $PAGE_UP_U="u";
my $GO_TOP="gg";
my $GO_BOTTOM="G";
my $current_line = 0;
my $sequence = '';
my ($rows, $cols);
sub term_size {
split ' ', `stty size`;
}
sub redraw {
my $last_nick_idx = @nicknames;
my $last_idx = $current_line + $rows;
# normalize last visible index
if ($last_idx > ($last_nick_idx)) {
$last_idx = $last_nick_idx;
}
# redraw visible nicks
for my $i (reverse 1..$rows) {
print "\e[$i;1H\e[K";
my $idx = $current_line + $i - 1;
if ($idx < $last_idx) {
my $z = 0; my $col = $cols;
for (split /(\e\[(?:\d|;|:|\?|\s)*.)/, $nicknames[$idx]) {
if ($z ^= 1) {
print +(substr $_, 0, $col) if $col > 0;
$col -= length;
} else {
print
}
}
}
}
}
sub move_down {
$sequence = '';
my $count = int $_[0];
my $nickcount = $#nicknames;
return if ($nickcount <= $rows);
if ($count == -1) {
$current_line = $nickcount - $rows + 1;
redraw;
return;
}
my $visible = $nickcount - $current_line - $count + 1;
if ($visible > $rows) {
$current_line += $count;
redraw;
} elsif (($visible + $count) > $rows) {
# scroll the maximum we can
$current_line = $nickcount - $rows + 1;
redraw;
}
}
sub move_up {
$sequence = '';
my $count = int $_[0];
if ($count == -1) {
$current_line = 0;
redraw;
return;
}
return if ($current_line == 0);
$count = 1 if $count == 0;
$current_line -= $count;
$current_line = 0 if $current_line < 0;
redraw;
}
$SIG{INT} = 'IGNORE';
STDOUT->autoflush(1);
# setup terminal so we can listen for individual key presses without echo
`stty -icanon -echo`;
# open named pipe and setup the 'select' wrapper object for listening on both
# fds(fifo and sdtin)
open my $fifo, "<", $fifo_path or die "can't open $fifo_path: $!";
my $select = IO::Select->new();
my @ready;
$select->add($fifo);
$select->add(\*STDIN);
enable_mouse;
system('tput', 'smcup');
print "\e[?7l"; #system('tput', 'rmam');
system('tput', 'civis');
MAIN: {
while (@ready = $select->can_read) {
foreach my $fd (@ready) {
($rows, $cols) = term_size;
if ($fd == $fifo) {
while (<$fifo>) {
my $line = $_;
if ($line =~ /^BEGIN/) {
@nicknames = ();
} elsif ($line =~ /^SWITCH_CHANNEL/) {
$current_line = 0;
} elsif ($line =~ /^NICK(.+)$/) {
push @nicknames, $1;
} elsif ($line =~ /^END$/) {
redraw;
last;
} elsif ($line =~ /^EXIT$/) {
last MAIN;
}
}
} else {
my $key = '';
sysread(STDIN, $key, 1);
$sequence .= $key;
if ($MOUSE_SCROLL_DOWN =~ /^\Q$sequence\E/) {
if ($MOUSE_SCROLL_DOWN eq $sequence) {
move_down 3;
# mouse scroll has two more bytes that I dont use here
# so consume them now to avoid sending unwanted bytes to
# irssi
sysread(STDIN, $key, 2);
}
} elsif ($MOUSE_SCROLL_UP =~ /^\Q$sequence\E/) {
if ($MOUSE_SCROLL_UP eq $sequence) {
move_up 3;
sysread(STDIN, $key, 2);
}
} elsif ($ARROW_DOWN =~ /^\Q$sequence\E/) {
move_down 1 if ($ARROW_DOWN eq $sequence);
} elsif ($ARROW_UP =~ /^\Q$sequence\E/) {
move_up 1 if ($ARROW_UP eq $sequence);
} elsif ($DOWN =~ /^\Q$sequence\E/) {
move_down 1 if ($DOWN eq $sequence);
} elsif ($UP =~ /^\Q$sequence\E/) {
move_up 1 if ($UP eq $sequence);
} elsif ($PAGE_DOWN =~ /^\Q$sequence\E/) {
move_down $rows/2 if ($PAGE_DOWN eq $sequence);
} elsif ($PAGE_UP =~ /^\Q$sequence\E/) {
move_up $rows/2 if ($PAGE_UP eq $sequence);
} elsif ($PAGE_DOWN_D =~ /^\Q$sequence\E/) {
move_down $rows/2 if ($PAGE_DOWN_D eq $sequence);
} elsif ($PAGE_UP_U =~ /^\Q$sequence\E/) {
move_up $rows/2 if ($PAGE_UP_U eq $sequence);
} elsif ($GO_BOTTOM =~ /^\Q$sequence\E/) {
move_down -1 if ($GO_BOTTOM eq $sequence);
} elsif ($GO_TOP =~ /^\Q$sequence\E/) {
move_up -1 if ($GO_TOP eq $sequence);
} else {
# Unrecognized sequences will be send to irssi and its pane
# will be focused
system('tmux', 'send-keys', '-t', $irssi_pane, $sequence);
system('tmux', 'select-pane', '-t', $irssi_pane);
$sequence = '';
}
}
}
}
}
close $fifo;
}

View File

@@ -0,0 +1,606 @@
## trackbar.pl
#
# This little script will do just one thing: it will draw a line each time you
# switch away from a window. This way, you always know just upto where you've
# been reading that window :) It also removes the previous drawn line, so you
# don't see double lines.
#
# redraw trackbar only works on irssi 0.8.17 or higher.
#
##
## Usage:
#
# The script works right out of the box, but if you want you can change
# the working by /set'ing the following variables:
#
# Setting: trackbar_style
# Description: This setting will be the color of your trackbar line.
# By default the value will be '%K', only Irssi color
# formats are allowed. If you don't know the color formats
# by heart, you can take a look at the formats documentation.
# You will find the proper docs on http://www.irssi.org/docs.
#
# Setting: trackbar_string
# Description: This is the string that your line will display. This can
# be multiple characters or just one. For example: '~-~-'
# The default setting is '-'.
# Here are some unicode characters you can try:
# "───" => U+2500 => a line
# "═══" => U+2550 => a double line
# "━━━" => U+2501 => a wide line
# "▭ " => U+25ad => a white rectangle
#
# Setting: trackbar_use_status_window
# Description: If this setting is set to OFF, Irssi won't print a trackbar
# in the statuswindow
#
# Setting: trackbar_ignore_windows
# Description: A list of windows where no trackbar should be printed
#
# Setting: trackbar_print_timestamp
# Description: If this setting is set to ON, Irssi will print the formatted
# timestamp in front of the trackbar.
#
# Setting: trackbar_require_seen
# Description: Only clear the trackbar if it has been scrolled to.
#
# Setting: trackbar_all_manual
# Description: Never clear the trackbar until you do /mark.
#
# /mark is a command that will redraw the line at the bottom.
#
# Command: /trackbar, /trackbar goto
# Description: Jump to where the trackbar is, to pick up reading
#
# Command: /trackbar keep
# Description: Keep this window's trackbar where it is the next time
# you switch windows (then this flag is cleared again)
#
# Command: /mark, /trackbar mark
# Description: Remove the old trackbar and mark the bottom of this
# window with a new trackbar
#
# Command: /trackbar markvisible
# Description: Like mark for all visible windows
#
# Command: /trackbar markall
# Description: Like mark for all windows
#
# Command: /trackbar remove
# Description: Remove this window's trackbar
#
# Command: /trackbar removeall
# Description: Remove all windows' trackbars
#
# Command: /trackbar redraw
# Description: Force redraw of trackbars
#
##
##
#
# For bugreports and other improvements contact one of the authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this script; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
##
use strict;
use warnings;
use vars qw($VERSION %IRSSI);
$VERSION = "2.9"; # a4c78e85092a271
%IRSSI = (
authors => "Peter 'kinlo' Leurs, Uwe Dudenhoeffer, " .
"Michiel Holtkamp, Nico R. Wohlgemuth, " .
"Geert Hauwaerts",
contact => 'peter@pfoe.be',
patchers => 'Johan Kiviniemi (UTF-8), Uwe Dudenhoeffer (on-upgrade-remove-line)',
name => 'trackbar',
description => 'Shows a bar where you have last read a window.',
license => 'GNU General Public License',
url => 'http://www.pfoe.be/~peter/trackbar/',
commands => 'trackbar',
);
## Comments and remarks.
#
# This script uses settings.
# Use /SET to change the value or /TOGGLE to switch it on or off.
#
#
# Tip: The command 'trackbar' is very useful if you bind that to a key,
# so you can easily jump to the trackbar. Please see 'help bind' for
# more information about keybindings in Irssi.
#
# Command: /BIND meta2-P key F1
# /BIND F1 command trackbar
#
##
## Bugfixes and new items in this rewrite.
#
# * Remove all the trackbars before upgrading.
# * New setting trackbar_use_status_window to control the statuswindow trackbar.
# * New setting trackbar_print_timestamp to print a timestamp or not.
# * New command 'trackbar' to scroll up to the trackbar.
# * When resizing your terminal, Irssi will update all the trackbars to the new size.
# * When changing trackbar settings, change all the trackbars to the new settings.
# * New command 'trackbar mark' to draw a new trackbar (The old '/mark').
# * New command 'trackbar markall' to draw a new trackbar in each window.
# * New command 'trackbar remove' to remove the trackbar from the current window.
# * New command 'trackbar removeall' to remove all the trackbars.
# * Don't draw a trackbar in empty windows.
# * Added a version check to prevent Irssi redraw errors.
# * Fixed a bookmark NULL versus 0 bug.
# * Fixed a remove-line bug in Uwe Dudenhoeffer his patch.
# * New command 'help trackbar' to display the trackbar commands.
# * Fixed an Irssi startup bug, now processing each auto-created window.
#
##
## Known bugs and the todolist.
#
# Todo: * Instead of drawing a line, invert the line.
#
##
## Authors:
#
# - Main maintainer & author: Peter 'kinlo' Leurs
# - Many thanks to Timo 'cras' Sirainen for placing me on my way
# - on-upgrade-remove-line patch by Uwe Dudenhoeffer
# - trackbar resizing by Michiel Holtkamp (02 Jul 2012)
# - scroll to trackbar, window excludes, and timestamp options by Nico R.
# Wohlgemuth (22 Sep 2012)
#
##
## Version history:
#
# 2.9: - fix crash on /mark in empty window
# 2.8: - fix /^join bug
# 2.7: - add /set trackbar_all_manual option
# 2.5: - merge back on scripts.irssi.org
# - fix /trackbar redraw broken in 2.4
# - fix legacy encodings
# - add workaround for irssi issue #271
# 2.4: - add support for horizontal splits
# 2.3: - add some features for seen tracking using other scripts
# 2.0: - big rewrite based on 1.4
# * removed /tb, you can have it with /alias tb trackbar if you want
# * subcommand and settings changes:
# /trackbar vmark => /trackbar markvisible
# /trackbar scroll => /trackbar goto (or just /trackbar)
# /trackbar help => /help trackbar
# /set trackbar_hide_windows => /set trackbar_ignore_windows
# /set trackbar_timestamp => /set trackbar_print_timestamp
# * magic line strings were removed, just paste the unicode you want!
# * trackbar_timestamp_styled is not currently supported
# 1.9: - add version guard
# 1.8: - sub draw_bar
# 1.7: - Added /tb scroll, trackbar_hide_windows, trackbar_timestamp_timestamp
# and trackbar_timestamp_styled
# 1.6: - Work around Irssi resize bug, please do /upgrade! (see below)
# 1.5: - Resize trackbars in all windows when terminal is resized
# 1.4: - Changed our's by my's so the irssi script header is valid
# - Removed utf-8 support. In theory, the script should work w/o any
# problems for utf-8, just set trackbar_string to a valid utf-8 character
# and everything *should* work. However, this script is being plagued by
# irssi internal bugs. The function Irssi::settings_get_str does NOT handle
# unicode strings properly, hence you will notice problems when setting the bar
# to a unicode char. For changing your bar to utf-8 symbols, read the line sub.
# 1.3: - Upgrade now removes the trackbars.
# - Some code cleanups, other defaults
# - /mark sets the line to the bottom
# 1.2: - Support for utf-8
# - How the bar looks can now be configured with trackbar_string
# and trackbar_style
# 1.1: - Fixed bug when closing window
# 1.0: - Initial release
#
##
use Irssi;
use Irssi::TextUI;
use Encode;
use POSIX qw(strftime);
sub cmd_help {
my ($args) = @_;
if ($args =~ /^trackbar *$/i) {
print CLIENTCRAP <<HELP
%9Syntax:%9
TRACKBAR
TRACKBAR GOTO
TRACKBAR KEEP
TRACKBAR MARK
TRACKBAR MARKVISIBLE
TRACKBAR MARKALL
TRACKBAR REMOVE
TRACKBAR REMOVEALL
TRACKBAR REDRAW
%9Parameters:%9
GOTO: Jump to where the trackbar is, to pick up reading
KEEP: Keep this window's trackbar where it is the next time
you switch windows (then this flag is cleared again)
MARK: Remove the old trackbar and mark the bottom of this
window with a new trackbar
MARKVISIBLE: Like mark for all visible windows
MARKALL: Like mark for all windows
REMOVE: Remove this window's trackbar
REMOVEALL: Remove all windows' trackbars
REDRAW: Force redraw of trackbars
%9Description:%9
Manage a trackbar. Without arguments, it will scroll up to the trackbar.
%9Examples:%9
/TRACKBAR MARK
/TRACKBAR REMOVE
HELP
}
}
Irssi::theme_register([
'trackbar_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.',
'trackbar_wrong_version', '%R>>%n %_Trackbar:%_ Please upgrade your client to 0.8.17 or above if you would like to use this feature of trackbar.',
'trackbar_all_removed', '%R>>%n %_Trackbar:%_ All the trackbars have been removed.',
'trackbar_not_found', '%R>>%n %_Trackbar:%_ No trackbar found in this window.',
]);
my $old_irssi = Irssi::version < 20140701;
sub check_version {
if ($old_irssi) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_wrong_version');
return;
} else {
return 1;
}
}
sub is_utf8 {
lc Irssi::settings_get_str('term_charset') eq 'utf-8'
}
my (%config, %keep_trackbar, %unseen_trackbar);
sub remove_one_trackbar {
my $win = shift;
my $view = shift || $win->view;
my $line = $view->get_bookmark('trackbar');
if (defined $line) {
my $bottom = $view->{bottom};
$view->remove_line($line);
$win->command('^scrollback end') if $bottom && !$win->view->{bottom};
$view->redraw;
}
}
sub add_one_trackbar_pt1 {
my $win = shift;
my $view = shift || $win->view;
my $last_cur_line = ($view->{buffer}{cur_line}||+{})->{_irssi};
$win->print(line($win->{width}), MSGLEVEL_NEVER);
my $cur_line = ($win->view->{buffer}{cur_line}||+{})->{_irssi}; # get a fresh buffer
($last_cur_line//'') ne ($cur_line//'') # printing was successful
}
sub add_one_trackbar_pt2 {
my $win = shift;
my $view = $win->view;
$view->set_bookmark_bottom('trackbar');
$unseen_trackbar{ $win->{_irssi} } = 1;
Irssi::signal_emit("window trackbar added", $win);
$view->redraw;
}
sub update_one_trackbar {
my $win = shift;
my $view = shift || $win->view;
my $force = shift;
my $ignored = win_ignored($win, $view);
my $success;
$success = add_one_trackbar_pt1($win, $view) ? 1 : 0
if $force || !$ignored;
remove_one_trackbar($win, $view)
if ( $success || !defined $success ) && ( $force || !defined $force || !$ignored );
add_one_trackbar_pt2($win)
if $success;
}
sub win_ignored {
my $win = shift;
my $view = shift || $win->view;
return 1 unless $view->{buffer}{lines_count};
return 1 if $win->{name} eq '(status)' && !$config{use_status_window};
no warnings 'uninitialized';
return 1 if grep { $win->{name} eq $_ || $win->{refnum} eq $_
|| $win->get_active_name eq $_ } @{ $config{ignore_windows} };
return 0;
}
sub sig_window_changed {
my ($newwindow, $oldwindow) = @_;
return unless $oldwindow;
redraw_one_trackbar($newwindow) unless $old_irssi;
trackbar_update_seen($newwindow);
return if delete $keep_trackbar{ $oldwindow->{_irssi} };
trackbar_update_seen($oldwindow);
return if $config{require_seen} && $unseen_trackbar{ $oldwindow->{_irssi } };
return if $config{all_manual};
update_one_trackbar($oldwindow, undef, 0);
}
sub trackbar_update_seen {
my $win = shift;
return unless $win;
return unless $unseen_trackbar{ $win->{_irssi} };
my $view = $win->view;
my $line = $view->get_bookmark('trackbar');
unless ($line) {
delete $unseen_trackbar{ $win->{_irssi} };
Irssi::signal_emit("window trackbar seen", $win);
return;
}
my $startline = $view->{startline};
return unless $startline;
if ($startline->{info}{time} < $line->{info}{time}
|| $startline->{_irssi} == $line->{_irssi}) {
delete $unseen_trackbar{ $win->{_irssi} };
Irssi::signal_emit("window trackbar seen", $win);
}
}
sub screen_length;
{ local $@;
eval { require Text::CharWidth; };
unless ($@) {
*screen_length = sub { Text::CharWidth::mbswidth($_[0]) };
}
else {
*screen_length = sub {
my $temp = shift;
Encode::_utf8_on($temp) if is_utf8();
length($temp)
};
}
}
{ my %strip_table = (
(map { $_ => '' } (split //, '04261537' . 'kbgcrmyw' . 'KBGCRMYW' . 'U9_8I:|FnN>#[' . 'pP')),
(map { $_ => $_ } (split //, '{}%')),
);
sub c_length {
my $o = Irssi::strip_codes($_[0]);
$o =~ s/(%(%|Z.{6}|z.{6}|X..|x..|.))/exists $strip_table{$2} ? $strip_table{$2} :
$2 =~ m{x(?:0[a-f]|[1-6][0-9a-z]|7[a-x])|z[0-9a-f]{6}}i ? '' : $1/gex;
screen_length($o)
}
}
sub line {
my ($width, $time) = @_;
my $string = $config{string};
$string = ' ' unless length $string;
$time ||= time;
Encode::_utf8_on($string) if is_utf8();
my $length = c_length($string);
my $format = '';
if ($config{print_timestamp}) {
$format = $config{timestamp_str};
$format =~ y/%/\01/;
$format =~ s/\01\01/%/g;
$format = strftime($format, localtime $time);
$format =~ y/\01/%/;
}
my $times = $width / $length;
$times += 1 if $times != int $times;
my $style = "$config{style}";
Encode::_utf8_on($style) if is_utf8();
$format .= $style;
$width -= c_length($format);
$string x= $times;
chop $string while length $string && c_length($string) > $width;
return $format . $string;
}
sub remove_all_trackbars {
for my $window (Irssi::windows) {
next unless ref $window;
remove_one_trackbar($window);
}
}
sub UNLOAD {
remove_all_trackbars();
}
sub redraw_one_trackbar {
my $win = shift;
my $view = $win->view;
my $line = $view->get_bookmark('trackbar');
return unless $line;
my $bottom = $view->{bottom};
$win->print_after($line, MSGLEVEL_NEVER, line($win->{width}, $line->{info}{time}),
$line->{info}{time});
$view->set_bookmark('trackbar', $win->last_line_insert);
$view->remove_line($line);
$win->command('^scrollback end') if $bottom && !$win->view->{bottom};
$view->redraw;
}
sub redraw_trackbars {
return unless check_version();
for my $win (Irssi::windows) {
next unless ref $win;
redraw_one_trackbar($win);
}
}
sub goto_trackbar {
my $win = Irssi::active_win;
my $line = $win->view->get_bookmark('trackbar');
if ($line) {
$win->command("scrollback goto ". strftime("%d %H:%M:%S", localtime($line->{info}{time})));
} else {
$win->printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_not_found');
}
}
sub cmd_mark {
update_one_trackbar(Irssi::active_win, undef, 1);
}
sub cmd_markall {
for my $window (Irssi::windows) {
next unless ref $window;
update_one_trackbar($window);
}
}
sub signal_stop {
Irssi::signal_stop;
}
sub cmd_markvisible {
my @wins = Irssi::windows;
my $awin =
my $bwin = Irssi::active_win;
my $awin_counter = 0;
Irssi::signal_add_priority('window changed' => 'signal_stop', -99);
do {
Irssi::active_win->command('window up');
$awin = Irssi::active_win;
update_one_trackbar($awin);
++$awin_counter;
} until ($awin->{refnum} == $bwin->{refnum} || $awin_counter >= @wins);
Irssi::signal_remove('window changed' => 'signal_stop');
}
sub cmd_trackbar_remove_one {
remove_one_trackbar(Irssi::active_win);
}
sub cmd_remove_all_trackbars {
remove_all_trackbars();
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_all_removed');
}
sub cmd_keep_once {
$keep_trackbar{ Irssi::active_win->{_irssi} } = 1;
}
sub trackbar_runsub {
my ($data, $server, $item) = @_;
$data =~ s/\s+$//g;
if ($data) {
Irssi::command_runsub('trackbar', $data, $server, $item);
} else {
goto_trackbar();
}
}
sub update_config {
my $was_status_window = $config{use_status_window};
$config{style} = Irssi::settings_get_str('trackbar_style');
$config{string} = Irssi::settings_get_str('trackbar_string');
$config{require_seen} = Irssi::settings_get_bool('trackbar_require_seen');
$config{all_manual} = Irssi::settings_get_bool('trackbar_all_manual');
$config{ignore_windows} = [ split /[,\s]+/, Irssi::settings_get_str('trackbar_ignore_windows') ];
$config{use_status_window} = Irssi::settings_get_bool('trackbar_use_status_window');
$config{print_timestamp} = Irssi::settings_get_bool('trackbar_print_timestamp');
if (defined $was_status_window && $was_status_window != $config{use_status_window}) {
if (my $swin = Irssi::window_find_name('(status)')) {
if ($config{use_status_window}) {
update_one_trackbar($swin);
}
else {
remove_one_trackbar($swin);
}
}
}
if ($config{print_timestamp}) {
my $ts_format = Irssi::settings_get_str('timestamp_format');
my $ts_theme = Irssi::current_theme->get_format('fe-common/core', 'timestamp');
my $render_str = Irssi::current_theme->format_expand($ts_theme);
(my $ts_escaped = $ts_format) =~ s/([%\$])/$1$1/g;
$render_str =~ s/(?|\$(.)(?!\w)|\$\{(\w+)\})/$1 eq 'Z' ? $ts_escaped : $1/ge;
$config{timestamp_str} = $render_str;
}
redraw_trackbars() unless $old_irssi;
}
Irssi::settings_add_str('trackbar', 'trackbar_string', is_utf8() ? "\x{2500}" : '-');
Irssi::settings_add_str('trackbar', 'trackbar_style', '%K');
Irssi::settings_add_str('trackbar', 'trackbar_ignore_windows', '');
Irssi::settings_add_bool('trackbar', 'trackbar_use_status_window', 1);
Irssi::settings_add_bool('trackbar', 'trackbar_print_timestamp', 0);
Irssi::settings_add_bool('trackbar', 'trackbar_require_seen', 0);
Irssi::settings_add_bool('trackbar', 'trackbar_all_manual', 0);
update_config();
Irssi::signal_add_last( 'mainwindow resized' => 'redraw_trackbars')
unless $old_irssi;
Irssi::signal_register({'window trackbar added' => [qw/Irssi::UI::Window/]});
Irssi::signal_register({'window trackbar seen' => [qw/Irssi::UI::Window/]});
Irssi::signal_register({'gui page scrolled' => [qw/Irssi::UI::Window/]});
Irssi::signal_add_last('gui page scrolled' => 'trackbar_update_seen');
Irssi::signal_add('setup changed' => 'update_config');
Irssi::signal_add_priority('session save' => 'remove_all_trackbars', Irssi::SIGNAL_PRIORITY_HIGH-1);
Irssi::signal_add('window changed' => 'sig_window_changed');
Irssi::command_bind('trackbar goto' => 'goto_trackbar');
Irssi::command_bind('trackbar keep' => 'cmd_keep_once');
Irssi::command_bind('trackbar mark' => 'cmd_mark');
Irssi::command_bind('trackbar markvisible' => 'cmd_markvisible');
Irssi::command_bind('trackbar markall' => 'cmd_markall');
Irssi::command_bind('trackbar remove' => 'cmd_trackbar_remove_one');
Irssi::command_bind('trackbar removeall' => 'cmd_remove_all_trackbars');
Irssi::command_bind('trackbar redraw' => 'redraw_trackbars');
Irssi::command_bind('trackbar' => 'trackbar_runsub');
Irssi::command_bind('mark' => 'cmd_mark');
Irssi::command_bind_last('help' => 'cmd_help');
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trackbar_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors});
# workaround for issue #271
{ package Irssi::Nick }

View File

@@ -0,0 +1,774 @@
=pod
=head1 NAME
uberprompt.pl
=head1 DESCRIPTION
This script replaces the default prompt status-bar item with one capable of
displaying additional information, under either user control or via scripts.
=head1 INSTALLATION
Copy into your F<~/.irssi/scripts/> directory and load with
C</SCRIPT LOAD F<filename>>.
It is recommended that you make it autoload in one of the
L<usual ways|https://github.com/shabble/irssi-docs/wiki/Guide#Autorunning_Scripts>.
=head1 SETUP
If you have a custom prompt format, you may need to copy it to the
uberprompt_format setting. See below for details.
=head1 USAGE
Although the script is designed primarily for other scripts to set
status information into the prompt, the following commands are available:
=over 4
=item * C</prompt set [-inner|-pre|-post|only] E<lt>msgE<gt>>
Sets the prompt to the given argument. Any use of C<$p> in the argument will
be replaced by the original prompt content.
A parameter corresponding to the C<UP_*> constants listed below is required, in
the format C</prompt set -inner Hello!>
=item * C</prompt clear>
Clears the additional data provided to the prompt.
=item * C</prompt on>
Eenables the uberprompt (things may get confused if this is used
whilst the prompt is already enabled)
=item * C</prompt off>
Restore the original irssi prompt and prompt_empty statusbars. unloading the
script has the same effect.
=item * C</help prompt>
show help for uberprompt commands
=back
=head1 SETTINGS
=head2 UBERPROMPT FORMAT
C</set uberprompt_format E<lt>formatE<gt>>
The default is C<[$*$uber]>, which is the same as the default provided in
F<default.theme>.
Changing this setting will update the prompt immediately, unlike editing your theme.
An additional variable available within this format is C<$uber>, which expands to
the content of prompt data provided with the C<UP_INNER> or C</prompt set -inner>
placement argument.
For all other placement arguments, it will expand to the empty string.
B<Note:> This setting completely overrides the C<prompt="...";> line in your
.theme file, and may cause unexpected behaviour if your theme wishes to set a
different form of prompt. It can be simply copied from the theme file into the
above setting.
=head2 OTHER SETTINGS
=over 4
=item * C<uberprompt_autostart>
Boolean value, which determines if uberprompt should enable itself automatically
upon loading. If Off, it must be enabled manually with C</prompt on>. Defaults to On.
=item * C<uberprompt_debug>
Boolean value, which determines if uberprompt should print debugging information.
Defaults to Off, and should probably be left that way unless requested for bug-tracing
purposes.
=item * C<uberprompt_format>
String value containing the format-string which uberprompt uses to display the
prompt. Defaults to "C<[$*$uber] >", where C<$*> is the content the prompt would
normally display, and C<$uber> is a placeholder variable for dynamic content, as
described in the section above.
=item * C<uberprompt_load_hook>
String value which can contain one or more commands to be run whenever the uberprompt
is enabled, either via autostart, or C</prompt on>. Defaults to the empty string, in
which case no commands are run. Some examples include:
C</set uberprompt_load_hook /echo prompt enabled> or
C</^sbar prompt add -after input vim_mode> for those using vim_mode.pl who want
the command status indicator on the prompt line.
=item * C<uberprompt_unload_hook>
String value, defaulting to the empty string, which can contain commands which
are executed when the uberprompt is disabled, either by unloading the script,
or by the command C</prompt off>.
=item * C<uberprompt_use_replaces>
Boolean value, defaults to Off. If enabled, the format string for the prompt
will be subject to the I<replaces> section of the theme. The most obvious
effect of this is that bracket characters C<[ ]> are displayed in a different
colour, typically quite dark.
=back
B<Note:> For both C<uberprompt_*_hook> settings above, multiple commands can
be chained together in the form C</eval /^cmd1 ; /^cmd2>. The C<^> prevents
any output from the commands (such as error messages) being displayed.
=head2 SCRIPTING USAGE
The primary purpose of uberprompt is to be used by other scripts to
display information in a way that is not possible by printing to the active
window or using statusbar items.
The content of the prompt can be set from other scripts via the C<"change prompt">
signal.
For Example:
signal_emit 'change prompt' 'some_string', UberPrompt::UP_INNER;
will set the prompt to include that content, by default 'C<[$* some_string]>'
The possible position arguments are the following strings:
=over 4
=item * C<UP_PRE> - place the provided string before the prompt - C<$string$prompt>
=item * C<UP_INNER> - place the provided string inside the prompt - C<{prompt $* $string}>
=item * C<UP_POST> - place the provided string after the prompt - C<$prompt$string>
=item * C<UP_ONLY> - replace the prompt with the provided string - C<$string>
=back
All strings may use the special variable 'C<$prompt>' to include the prompt
verbatim at that position in the string. It is probably only useful for
the C<UP_ONLY> mode however. '$C<prompt_nt>' will include the prompt, minus any
trailing whitespace.
=head2 CHANGE NOTIFICATIONS
You can also be notified when the prompt changes in response to the previous
signal or manual C</prompt> commands via:
signal_add 'prompt changed', sub { my ($text, $len) = @_; ... do something ... };
This callback will occur whenever the contents of the prompt is changed.
=head2 NOTES FOR SCRIPT WRITERS:
The following code snippet can be used within your own script as a preamble
to ensure that uberprompt is loaded before your script to avoid
any issues with loading order. It first checks if uberprompt is loaded, and
if not, attempts to load it. If the load fails, the script will die
with an error message, otherwise it will call your app_init() function.
I<---- start of snippet ---->
my $DEBUG_ENABLED = 0;
sub DEBUG () { $DEBUG_ENABLED }
# check we have uberprompt loaded.
sub script_is_loaded {
return exists($Irssi::Script::{$_[0] . '::'});
}
if (not script_is_loaded('uberprompt')) {
print "This script requires 'uberprompt.pl' in order to work. "
. "Attempting to load it now...";
Irssi::signal_add('script error', 'load_uberprompt_failed');
Irssi::command("script load uberprompt.pl");
unless(script_is_loaded('uberprompt')) {
load_uberprompt_failed("File does not exist");
}
app_init();
} else {
app_init();
}
sub load_uberprompt_failed {
Irssi::signal_remove('script error', 'load_uberprompt_failed');
print "Script could not be loaded. Script cannot continue. "
. "Check you have uberprompt.pl installed in your path and "
. "try again.";
die "Script Load Failed: " . join(" ", @_);
}
I<---- end of snippet ---->
=head1 AUTHORS
Copyright E<copy> 2011 Tom Feist C<E<lt>shabble+irssi@metavore.orgE<gt>>
=head1 LICENCE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
=head1 BUGS
=over 4
=item *
Resizing the terminal rapidly whilst using this script in debug mode may cause
irssi to crash. See bug report at http://bugs.irssi.org/index.php?do=details&task_id=772 for details.
=back
=head1 TODO
=over 4
=item * report failure (somehow) to clients if hte prompt is disabled.
=item * fix issue at autorun startup with sbar item doesn't exist.
=back
=cut
use strict;
use warnings;
use Irssi;
use Irssi::TextUI;
use Data::Dumper;
{ package Irssi::Nick } # magic.
our $VERSION = "0.2";
our %IRSSI =
(
authors => "shabble",
contact => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode',
name => "uberprompt",
description => "Helper script for dynamically adding text "
. "into the input-bar prompt.",
license => "MIT",
changed => "24/7/2010"
);
my $DEBUG_ENABLED = 0;
sub DEBUG { $DEBUG_ENABLED }
my $prompt_data = '';
my $prompt_data_pos = 'UP_INNER';
my $prompt_last = '';
my $prompt_format = '';
my $prompt_format_empty = '';
# flag to indicate whether rendering of hte prompt should allow the replaces
# theme formats to be applied to the content.
my $use_replaces = 0;
my $trim_data = 0;
my $emit_request = 0;
my $expando_refresh_timer;
my $expando_vars = {};
my $init_callbacks = {load => '', unload => ''};
pre_init();
sub pre_init {
Irssi::command('statusbar prompt reset');
init();
}
sub prompt_subcmd_handler {
my ($data, $server, $item) = @_;
#$data =~ s/\s+$//g; # strip trailing whitespace.
Irssi::command_runsub('prompt', $data, $server, $item);
}
sub _error($) {
my ($msg) = @_;
Irssi::active_win->print($msg, MSGLEVEL_CLIENTERROR);
}
sub _debug_print($) {
return unless DEBUG;
my ($msg) = @_;
Irssi::active_win->print($msg, MSGLEVEL_CLIENTCRAP);
}
sub _print_help {
my ($args) = @_;
if ($args =~ m/^\s*prompt/i) {
my @help_lines =
(
"",
"PROMPT ON",
"PROMPT OFF",
"PROMPT CLEAR",
"PROMPT SET { -pre | -post | -only | -inner } <content>",
"",
"Commands for manipulating the UberPrompt.",
"",
"/PROMPT ON enables uberprompt, replacing the existing prompt ",
" statusbar-item",
"/PROMPT OFF disables it, and restores the original prompt item",
"/PROMPT CLEAR resets the value of any additional data set by /PROMPT SET",
" or a script",
"/PROMPT SET changes the contents of the prompt, according to the mode",
" and content provided.",
" { -inner sets the value of the \$uber psuedo-variable in the",
" /set uberprompt_format setting.",
" | -pre places the content before the current prompt string",
" | -post places the content after the prompt string",
" | -only replaces the entire prompt contents with the given string }",
"",
"See Also:",
'',
'/SET uberprompt_format -- defaults to "[$*$uber] "',
'/SET uberprompt_format_empty -- defaults to "[$*] "',
"/SET uberprompt_autostart -- determines whether /PROMPT ON is run",
" automatically when the script loads",
"/SET uberprompt_use_replaces -- toggles the use of the current theme",
" \"replaces\" setting. Especially",
" noticeable on brackets \"[ ]\" ",
"/SET uberprompt_trim_data -- defaults to off. Removes whitespace from",
" both sides of the \$uber result.",
"",
);
Irssi::print($_, MSGLEVEL_CLIENTCRAP) for @help_lines;
Irssi::signal_stop;
}
}
sub UNLOAD {
deinit();
}
sub exp_lbrace() { '{' }
sub exp_rbrace() { '}' }
sub deinit {
Irssi::expando_destroy('lbrace');
Irssi::expando_destroy('rbrace');
if (Irssi::settings_get_bool('uberprompt_restore_on_exit')) {
# remove uberprompt and return the original ones.
print "Removing uberprompt and restoring original";
restore_prompt_items();
}
}
sub init {
Irssi::statusbar_item_register('uberprompt', 0, 'uberprompt_draw');
# TODO: flags to prevent these from being recomputed?
Irssi::expando_create('lbrace', \&exp_lbrace, {});
Irssi::expando_create('rbrace', \&exp_rbrace, {});
Irssi::settings_add_str ('uberprompt', 'uberprompt_format', '[$*$uber] ');
Irssi::settings_add_str ('uberprompt', 'uberprompt_format_empty', '[$*] ');
Irssi::settings_add_str ('uberprompt', 'uberprompt_load_hook', '');
Irssi::settings_add_str ('uberprompt', 'uberprompt_unload_hook', '');
Irssi::settings_add_bool('uberprompt', 'uberprompt_debug', 0);
Irssi::settings_add_bool('uberprompt', 'uberprompt_autostart', 1);
Irssi::settings_add_bool ('uberprompt', 'uberprompt_restore_on_exit', 1);
Irssi::settings_add_bool('uberprompt', 'uberprompt_use_replaces', 0);
Irssi::settings_add_bool('uberprompt', 'uberprompt_trim_data', 0);
Irssi::command_bind("prompt", \&prompt_subcmd_handler);
Irssi::command_bind('prompt on', \&replace_prompt_items);
Irssi::command_bind('prompt off', \&restore_prompt_items);
Irssi::command_bind('prompt set', \&cmd_prompt_set);
Irssi::command_bind('prompt clear',
sub {
Irssi::signal_emit 'change prompt', '$p', 'UP_POST';
});
my $prompt_set_args_format = "inner pre post only";
Irssi::command_set_options('prompt set', $prompt_set_args_format);
Irssi::command_bind('help', \&_print_help);
Irssi::signal_add('setup changed', \&reload_settings);
# intialise the prompt format.
reload_settings();
# make sure we redraw when necessary.
Irssi::signal_add('window changed', \&uberprompt_refresh);
Irssi::signal_add('window name changed', \&uberprompt_refresh);
Irssi::signal_add('window changed automatic', \&uberprompt_refresh);
Irssi::signal_add('window item changed', \&uberprompt_refresh);
Irssi::signal_add('window item server changed', \&uberprompt_refresh);
Irssi::signal_add('window server changed', \&uberprompt_refresh);
Irssi::signal_add('server nick changed', \&uberprompt_refresh);
Irssi::signal_add('nick mode changed', \&refresh_if_me);
# install our statusbars if required.
if (Irssi::settings_get_bool('uberprompt_autostart')) {
replace_prompt_items();
}
# API signals
Irssi::signal_register({'change prompt' => [qw/string string/]});
Irssi::signal_add('change prompt' => \&change_prompt_handler);
# other scripts (specifically overlay/visual) can subscribe to
# this event to be notified when the prompt changes.
# arguments are new contents (string), new length (int)
Irssi::signal_register({'prompt changed' => [qw/string int/]});
Irssi::signal_register({'prompt length request' => []});
Irssi::signal_add('prompt length request', \&length_request_handler);
}
sub cmd_prompt_set {
my $args = shift;
my @options_list = Irssi::command_parse_options "prompt set", $args;
if (@options_list) {
my ($options, $rest) = @options_list;
my @opt_modes = keys %$options;
if (@opt_modes != 1) {
_error '%_/prompt set%_ must specify exactly one mode of'
. ' {-inner, -only, -pre, -post}';
return;
}
my $mode = 'UP_' . uc($opt_modes[0]);
Irssi::signal_emit 'change prompt', $rest, $mode;
} else {
_error ('%_/prompt set%_ must specify a mode {-inner, -only, -pre, -post}');
}
}
sub refresh_if_me {
my ($channel, $nick) = @_;
return unless $channel and $nick;
my $server = Irssi::active_server;
my $window = Irssi::active_win;
return unless $server and $window;
my $my_chan = $window->{active}->{name};
my $my_nick = $server->parse_special('$N');
return unless $my_chan and $my_nick;
_debug_print "Chan: $channel->{name}, "
. "nick: $nick->{nick}, "
. "me: $my_nick, chan: $my_chan";
if ($my_chan eq $channel->{name} and $my_nick eq $nick->{nick}) {
uberprompt_refresh();
}
}
sub length_request_handler {
$emit_request = 1;
uberprompt_render_prompt();
$emit_request = 0;
}
sub reload_settings {
$use_replaces = Irssi::settings_get_bool('uberprompt_use_replaces');
$DEBUG_ENABLED = Irssi::settings_get_bool('uberprompt_debug');
$init_callbacks = {
load => Irssi::settings_get_str('uberprompt_load_hook'),
unload => Irssi::settings_get_str('uberprompt_unload_hook'),
};
if (DEBUG) {
Irssi::signal_add 'prompt changed', 'debug_prompt_changed';
} else {
Irssi::signal_remove 'prompt changed', 'debug_prompt_changed';
}
my $new = Irssi::settings_get_str('uberprompt_format');
if ($prompt_format ne $new) {
_debug_print("Updated prompt format");
$prompt_format = $new;
$prompt_format =~ s/\$uber/\$\$uber/;
Irssi::abstracts_register(['uberprompt', $prompt_format]);
$expando_vars = {};
# TODO: something clever here to check if we need to schedule
# an update timer or something, rather than just refreshing on
# every possible activity in init()
while ($prompt_format =~ m/(?<!\$)(\$[A-Za-z,.:;][a-z_]*)/g) {
_debug_print("Detected Irssi expando variable $1");
my $var_name = substr $1, 1; # strip the $
$expando_vars->{$var_name} = Irssi::parse_special($1);
}
}
$new = Irssi::settings_get_str('uberprompt_format_empty');
if ($prompt_format_empty ne $new) {
_debug_print("Updated prompt format");
$prompt_format_empty = $new;
$prompt_format_empty =~ s/\$uber/\$\$uber/;
Irssi::abstracts_register(['uberprompt_empty', $prompt_format_empty]);
$expando_vars = {};
# TODO: something clever here to check if we need to schedule
# an update timer or something, rather than just refreshing on
# every possible activity in init()
while ($prompt_format_empty =~ m/(?<!\$)(\$[A-Za-z,.:;][a-z_]*)/g) {
_debug_print("Detected Irssi expando variable $1");
my $var_name = substr $1, 1; # strip the $
$expando_vars->{$var_name} = Irssi::parse_special($1);
}
}
$trim_data = Irssi::settings_get_bool('uberprompt_trim_data');
}
sub debug_prompt_changed {
my ($text, $len) = @_;
$text =~ s/%/%%/g;
print "DEBUG_HANDLER: Prompt Changed to: \"$text\", length: $len";
}
sub change_prompt_handler {
my ($text, $pos) = @_;
# fix for people who used prompt_info and hence the signal won't
# pass the second argument.
$pos = 'UP_INNER' unless defined $pos;
_debug_print("Got prompt change signal with: $text, $pos");
my ($changed_text, $changed_pos);
$changed_text = defined $prompt_data ? $prompt_data ne $text : 1;
$changed_pos = defined $prompt_data_pos ? $prompt_data_pos ne $pos : 1;
$prompt_data = $text;
$prompt_data_pos = $pos;
if ($changed_text || $changed_pos) {
_debug_print("Redrawing prompt");
uberprompt_refresh();
}
}
sub _escape_prompt_special {
my $str = shift;
$str =~ s/\$/\$\$/g;
$str =~ s/\\/\\\\/g;
#$str =~ s/%/%%/g;
$str =~ s/{/\${lbrace}/g;
$str =~ s/}/\${rbrace}/g;
return $str;
}
sub uberprompt_render_prompt {
my $window = Irssi::active_win;
my $prompt_arg = '';
# default prompt sbar arguments (from config)
if (scalar( () = $window->items )) {
$prompt_arg = '$[.15]{itemname}';
} else {
$prompt_arg = '${winname}';
}
my $prompt = ''; # rendered content of the prompt.
my $theme = Irssi::current_theme;
my $arg = $use_replaces ? 0 : Irssi::EXPAND_FLAG_IGNORE_REPLACES;
if ($prompt_data && (!$trim_data || trim($prompt_data))) {
$prompt = $theme->format_expand("{uberprompt $prompt_arg}", $arg);
}
else {
$prompt = $theme->format_expand("{uberprompt_empty $prompt_arg}", $arg);
}
if ($prompt_data_pos eq 'UP_ONLY') {
$prompt =~ s/\$\$uber//; # no need for recursive prompting, I hope.
# TODO: only compute this if necessary?
my $prompt_nt = $prompt;
$prompt_nt =~ s/\s+$//;
my $pdata_copy = $prompt_data;
$pdata_copy =~ s/\$prompt_nt/$prompt_nt/;
$pdata_copy =~ s/\$prompt/$prompt/;
$prompt = $pdata_copy;
} elsif ($prompt_data_pos eq 'UP_INNER' && defined $prompt_data) {
my $esc = _escape_prompt_special($prompt_data);
$esc = $trim_data ? trim($esc) : $esc;
$prompt =~ s/\$\$uber/$esc/;
} else {
# remove the $uber marker
$prompt =~ s/\$\$uber//;
# and add the additional text at the appropriate position.
if ($prompt_data_pos eq 'UP_PRE') {
$prompt = $prompt_data . $prompt;
} elsif ($prompt_data_pos eq 'UP_POST') {
$prompt .= $prompt_data;
}
}
_debug_print("rendering with: $prompt");
if (($prompt ne $prompt_last) or $emit_request) {
# _debug_print("Emitting prompt changed signal");
# my $exp = Irssi::current_theme()->format_expand($text, 0);
my $ps = Irssi::parse_special($prompt);
Irssi::signal_emit('prompt changed', $ps, length($ps));
$prompt_last = $prompt;
}
return $prompt;
}
sub uberprompt_draw {
my ($sb_item, $get_size_only) = @_;
my $prompt = uberprompt_render_prompt();
my $ret = $sb_item->default_handler($get_size_only, $prompt, '', 0);
_debug_print("redrawing with: $prompt");
return $ret;
}
sub uberprompt_refresh {
Irssi::statusbar_items_redraw('uberprompt');
}
sub replace_prompt_items {
# remove existing ones.
_debug_print("Removing original prompt");
_sbar_command('prompt', 'remove', 'prompt');
_sbar_command('prompt', 'remove', 'prompt_empty');
# add the new one.
_sbar_command('prompt', 'add', 'uberprompt',
qw/-alignment left -before input -priority '-1'/);
_sbar_command('prompt', 'position', '100');
my $load_hook = $init_callbacks->{load};
if (defined $load_hook and length $load_hook) {
eval {
Irssi::command($load_hook);
};
if ($@) {
_error("Uberprompt user load-hook command ($load_hook) failed: $@");
}
}
}
sub restore_prompt_items {
_sbar_command('prompt', 'remove', 'uberprompt');
_debug_print("Restoring original prompt");
_sbar_command('prompt', 'reset');
my $unload_hook = $init_callbacks->{unload};
if (defined $unload_hook and length $unload_hook) {
eval {
Irssi::command($unload_hook);
};
if ($@) {
_error("Uberprompt user unload-hook command ($unload_hook) failed: $@");
}
}
}
sub _sbar_command {
my ($bar, $cmd, $item, @args) = @_;
my $args_str = join ' ', @args;
$args_str .= ' ' if length $args_str && defined $item;
my $command = sprintf 'STATUSBAR %s %s %s%s',
$bar, $cmd, $args_str, defined $item ? $item : '';
_debug_print("Running command: $command");
Irssi::command($command);
}
sub trim {
my $string = shift;
$string =~ s/^\s*//;
$string =~ s/\s*$//;
return $string;
}

View File

@@ -0,0 +1,296 @@
use strict;
use warnings;
{ package Irssi::Nick }
# just in case, to avoid Irssi::Nick warnings ( see http://bugs.irssi.org/index.php?do=details&task_id=242 )
use Irssi;
use vars qw($VERSION %IRSSI);
# Thanks to:
# -noi_esportista!#Girona@chathispano for his suggestions about how this script should work.
# -dg!#irssi@freenode (David Leadbeater) for the several code style issues that he pointed out and that helped me to improve my Perl.
$VERSION = '1.6';
%IRSSI = (
authors => 'Pablo Martín Báez Echevarría',
contact => 'pab_24n@outlook.com',
name => 'clones_scanner',
description => 'when a nick joins #channel, notifies you if there is (or there has been) someone in #channel with the same hostname',
license => 'Public Domain',
url => 'http://reirssi.wordpress.com',
changed => '22:30:25, Dec 20th, 2014 UYT',
);
#
# USAGE
# =====
# Copy the script to ~/.irssi/scripts/
#
# In irssi:
# /run clones_scanner
#
#
# OPTIONS
# =======
# Settings can be reset to defaults with /set -default
#
# /set clones_scanner_maxtime <time>
# * This is the maximum time in which the script remembers that a specific hostname
# left a channel because of a PART, QUIT or KICK event (default is 900secs = 15mins).
# For example, suppose it is 1 hour. If someone with mask type nick1!*@host left #channel
# at 11:00 and then comes back at 12:01 with mask type nick2!*@host, you will not be
# notified that 'nick2' was seen earlier in #channel as 'nick1'.
# It must be a time type, that is a series of integers with optional unit specifiers.
# Valid specifiers are:
#
# d[ays]
# h[ours]
# m[inutes]
# s[econds]
# mil[liseconds] | ms[econds]
#
# Any unambiguous part of a specifier can be used, as shown by the strings in braces in
# the above list. Multiple specifiers can be combined, with or without spaces between them.
#
# Examples:
#
# /set clones_scanner_maxtime 1hour30mins
# /set clones_scanner_maxtime 2h
# /set clones_scanner_maxtime 3h 10secs
#
# There must not be a space between the number and the unit specifier.
#
#
# COMMANDS
# ========
# /clones_scanner_size
# * Displays how many entries the data structure where the hosts are stored has, and how much
# memory is used for that purpose.
#
# WARNING: This feature requires Devel::Size module. It seems that when installing Devel::Size
# some tests started to fail since Perl 5.19.3 so if you're using the latest Perl release
# (Perl 5.20.1) you'll have to wait for someone to fix Devel::Size for recent Perl versions.
# See more about this issue at: https://rt.cpan.org/Public/Bug/Display.html?id=95493
# Remeber that you can find out Perl version with
# $ perl -v
# in a terminal or alternatively executing /script exec print $^V in irssi.
#
Irssi::settings_add_time('clones_scanner', 'clones_scanner_maxtime', 900);
# global variables
my $have_devel_size = eval { require Devel::Size };
my %hosts_hash = ();
my $old_maxtime_msecs;
my $old_maxtime_str;
my $total_entries = 0;
##########
sub add_entry {
my ( $network, $channel, $address, $nick ) = @_;
(my $host = $address) =~ s/^[^@]+@//;
if (defined $hosts_hash{$network}{$channel}{$host}) {
my $old_tag = $hosts_hash{$network}{$channel}{$host}[2];
Irssi::timeout_remove( $old_tag );
$total_entries--;
}
my $time = Irssi::settings_get_time("clones_scanner_maxtime");
my @data = ( $network, $channel, $host );
my $tag = Irssi::timeout_add_once($time, "remove_entry", \@data);
my $entry = [$nick, time(), $tag];
$hosts_hash{$network}{$channel}{$host} = $entry;
$total_entries++;
}
sub str_time {
my ( $secs ) = @_;
my $d = int($secs/3600/24);
my $h = int($secs/3600%24);
my $m = int($secs/60%60);
my $s = int($secs%60);
my $d_str = ($d == 1) ? "day": "days";
my $h_str = ($h == 1) ? "hour": "hours";
my $m_str = ($m == 1) ? "minute": "minutes";
my $s_str = ($s == 1) ? "second": "seconds";
my $raw_str = $d.$d_str.", ".$h.$h_str.", ".$m.$m_str.", ".$s.$s_str;
(my $str_res = $raw_str) =~ s/\b0\w+(?:,\s)?//g;
($str_res = $str_res) =~ s/,\s$//;
($str_res = $str_res) =~ s/(\d)([dhms])/$1 $2/g;
return $str_res eq "" ? "less than 1 second" : $str_res;
}
sub remove_entry {
my ( $ref_data ) = @_;
my $network = @{$ref_data}[0];
my $chan = @{$ref_data}[1];
my $host = @{$ref_data}[2];
delete $hosts_hash{$network}{$chan}{$host};
$total_entries--;
delete $hosts_hash{$network}{$chan} if (!keys %{$hosts_hash{$network}{$chan}});
delete $hosts_hash{$network} if (!keys %{$hosts_hash{$network}});
}
sub update_hash {
my ( $nw_maxtime ) = @_;
my $remainder;
my $ni;
my $se;
my $tg;
my $nw_tg;
foreach my $network (keys %hosts_hash) {
foreach my $channel (keys %{$hosts_hash{$network}}) {
foreach my $host (keys %{$hosts_hash{$network}{$channel}}) {
$ni = @{$hosts_hash{$network}{$channel}{$host}}[0];
$se = @{$hosts_hash{$network}{$channel}{$host}}[1];
$tg = @{$hosts_hash{$network}{$channel}{$host}}[2];
Irssi::timeout_remove( $tg );
$remainder = $nw_maxtime - (time() - $se);
if( $remainder > 0 ) {
my @data = ( $network, $channel, $host );
$nw_tg = Irssi::timeout_add_once( $remainder*1000, "remove_entry", \@data);
$hosts_hash{$network}{$channel}{$host} = [$ni, $se, $nw_tg];
} else {
delete $hosts_hash{$network}{$channel}{$host};
$total_entries--;
}
}
delete $hosts_hash{$network}{$channel} if (!keys %{$hosts_hash{$network}{$channel}});
}
delete $hosts_hash{$network} if (!keys %{$hosts_hash{$network}});
}
}
sub setup_changed {
my $new_maxtime_msecs = Irssi::settings_get_time("clones_scanner_maxtime");
if($new_maxtime_msecs < 10) {
Irssi::print("Invalid timestamp (must be >= 10 msecs)", MSGLEVEL_CLIENTERROR);
Irssi::settings_set_time("clones_scanner_maxtime", $old_maxtime_str);
$new_maxtime_msecs = Irssi::settings_get_time("clones_scanner_maxtime");
}
update_hash(int($new_maxtime_msecs/1000)) if ($new_maxtime_msecs != $old_maxtime_msecs);
}
##########
sub part_method {
my ($server, $channel, $nick, $address, $reason) = @_;
add_entry($server->{tag}, $channel, $address, $nick);
}
sub quit_method {
my ($server, $nick, $address, $reason) = @_;
foreach($server->channels()) {
if ($_->nick_find($nick)) {
add_entry($server->{tag}, $_->{name}, $address, $nick);
}
}
}
sub kick_method {
my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
Irssi::signal_stop();
my $kicked_address = $server->channel_find($channel)->nick_find($nick)->{host};
Irssi::signal_continue(@_);
add_entry($server->{tag}, $channel, $kicked_address, $nick);
}
##########
sub join_method {
my ($server, $channel, $nick, $address) = @_;
Irssi::signal_continue(@_);
my $servtag = $server->{tag};
(my $host = $address) =~ s/^[^@]+@//;
my $chan_rec = $server->channel_find($channel);
# ==== find clones ====
my $ni_host;
my $str_clones = "";
my @clones;
foreach my $ni ($chan_rec->nicks()) {
($ni_host = "$ni->{host}") =~ s/^[^@]+@//;
if ( ($ni->{nick} ne $nick)&&($ni_host eq $host) ) {
$str_clones .= "$ni->{nick}".", ";
push @clones, $ni->{nick};
}
}
if( $str_clones ne "") {
($str_clones = $str_clones) =~ s/,\s$//;
$chan_rec->printformat(Irssi::MSGLEVEL_JOINS, "clones_scanner_clones", $nick, $str_clones);
}
# ==== search in %hosts_hash ====
my $exists_nick_in_hash = (defined $hosts_hash{$servtag})&&(defined $hosts_hash{$servtag}{$channel})
&&(defined $hosts_hash{$servtag}{$channel}{$host});
if ($exists_nick_in_hash) {
my @alias = @{ $hosts_hash{$servtag}{$channel}{$host} };
if ( ($nick ne $alias[0]) && (!(grep {$_ eq $alias[0]} @clones)) ) {
my $time = Irssi::settings_get_time("clones_scanner_maxtime");
$chan_rec->printformat( Irssi::MSGLEVEL_JOINS, "clones_scanner_track_nick", $nick, str_time(int($time/1000)),
$alias[0], str_time(time()-$alias[1]));
}
}
}
##########
Irssi::theme_register([
"clones_scanner_clones", 'Clones of {nick $0}: $1',
"clones_scanner_track_nick", '=> {nick $0} was seen during the last $1 as {nick $2} ($3 ago)',
]);
##########
if ($have_devel_size) {
Irssi::command_bind('clones_scanner_size' , sub {
my $bytes = Devel::Size::total_size(\%hosts_hash);
print "Number of entries in \%hosts_hash: ", $total_entries;
print "Size in bytes: ", $bytes;
print int($bytes/1024/1024)."MB ".int($bytes/1024%1024)."kB ".int($bytes%1024)."B of data";
});
} else {
print "Missing Devel::Size module. The command `/clones_scanner_size` will not be available.";
}
Irssi::signal_add_first('message part', \&part_method);
Irssi::signal_add_first('message quit', \&quit_method);
Irssi::signal_add_first('message kick', \&kick_method);
Irssi::signal_add_last('message join', \&join_method);
Irssi::signal_add_last('setup changed', \&setup_changed);
Irssi::signal_add_first('send command',
sub {
$old_maxtime_msecs = Irssi::settings_get_time("clones_scanner_maxtime");
$old_maxtime_str = Irssi::settings_get_str("clones_scanner_maxtime");
});

View File

@@ -0,0 +1,39 @@
use strict;
use Irssi;
use IO::Handle;
use POSIX;
our $pipe_path = "/tmp/irssi_pipe";
our $pipe_fh;
Irssi::settings_add_str('fifo_input', 'fifo_pipe_path', $pipe_path);
sub fifo_input_open {
$pipe_path = Irssi::settings_get_str('fifo_pipe_path');
unless (-p $pipe_path) {
mkfifo($pipe_path, 0700) or die "Cannot create FIFO pipe: $!";
}
open($pipe_fh, '<', $pipe_path) or die "Cannot open FIFO pipe: $!";
$pipe_fh->blocking(0);
Irssi::input_add(fileno($pipe_fh), Irssi::INPUT_READ, \&fifo_input_read, undef);
}
sub fifo_input_read {
while (my $line = <$pipe_fh>) {
chomp $line;
Irssi::command($line);
}
}
sub fifo_input_close {
Irssi::input_remove(fileno($pipe_fh));
close($pipe_fh);
}
Irssi::signal_add('setup changed', \&fifo_input_open);
Irssi::command_bind('fifo_close', \&fifo_input_close);
fifo_input_open();
Irssi::print("FIFO input script loaded. Listening on $pipe_path");

253
home/.irssi/scripts/nickcolor.pl Executable file
View File

@@ -0,0 +1,253 @@
use strict;
use Irssi 20020101.0250 ();
use vars qw($VERSION %IRSSI);
$VERSION = "2.1";
%IRSSI = (
authors => "Timo Sirainen, Ian Peters, David Leadbeater, Bruno Cattáneo",
contact => "tss\@iki.fi",
name => "Nick Color",
description => "assign a different color for each nick",
license => "Public Domain",
url => "http://irssi.org/",
changed => "Mon 08 Jan 21:28:53 BST 2018",
);
# Settings:
# nickcolor_colors: List of color codes to use.
# e.g. /set nickcolor_colors 2 3 4 5 6 7 9 10 11 12 13
# (avoid 8, as used for hilights in the default theme).
#
# nickcolor_enable_prefix: Enables prefix for same nick.
#
# nickcolor_enable_truncate: Enables nick truncation.
#
# nickcolor_prefix_text: Prefix text for succesive messages.
# e.g. /set nickcolor_prefix_text -
#
# nickcolor_truncate_value: Truncate nick value.
# e.g. /set nickcolor_truncate_value -7
# This will truncate nicknames at 7 characters and make them right aligned
my %saved_colors;
my %session_colors = {};
my %saved_nicks; # To store each channel's last nickname
sub load_colors {
open my $color_fh, "<", "$ENV{HOME}/.irssi/saved_colors";
while (<$color_fh>) {
chomp;
my($nick, $color) = split ":";
$saved_colors{$nick} = $color;
}
}
sub save_colors {
open COLORS, ">", "$ENV{HOME}/.irssi/saved_colors";
foreach my $nick (keys %saved_colors) {
print COLORS "$nick:$saved_colors{$nick}\n";
}
close COLORS;
}
# If someone we've colored (either through the saved colors, or the hash
# function) changes their nick, we'd like to keep the same color associated
# with them (but only in the session_colors, ie a temporary mapping).
sub sig_nick {
my ($server, $newnick, $nick, $address) = @_;
my $color;
$newnick = substr ($newnick, 1) if ($newnick =~ /^:/);
if ($color = $saved_colors{$nick}) {
$session_colors{$newnick} = $color;
} elsif ($color = $session_colors{$nick}) {
$session_colors{$newnick} = $color;
}
}
# This gave reasonable distribution values when run across
# /usr/share/dict/words
sub simple_hash {
my ($string) = @_;
chomp $string;
my @chars = split //, $string;
my $counter;
foreach my $char (@chars) {
$counter += ord $char;
}
my @colors = split / /, Irssi::settings_get_str('nickcolor_colors');
$counter = $colors[$counter % @colors];
return $counter;
}
# process public (others) messages
sub sig_public {
my ($server, $msg, $nick, $address, $target) = @_;
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Set default nick truncate value to 0 if option is disabled
$truncate_value = 0 if (!$enable_truncate);
# Has the user assigned this nick a color?
my $color = $saved_colors{$nick};
# Have -we- already assigned this nick a color?
if (!$color) {
$color = $session_colors{$nick};
}
# Let's assign this nick a color
if (!$color) {
$color = simple_hash $nick;
$session_colors{$nick} = $color;
}
$color = sprintf "\003%02d", $color;
# Optional: We check if it's the same nickname for current target
if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
{
# Grouped message
Irssi::command('/^format pubmsg ' . $prefix_text . '$1');
}
else
{
# Normal message
Irssi::command('/^format pubmsg {pubmsgnick $2 {pubnick ' . $color . '$[' . $truncate_value . ']0}}$1');
# Save nickname for next message
$saved_nicks{$tagtarget} = $nick;
}
}
# process public (me) messages
sub sig_me {
my ($server, $msg, $target) = @_;
my $nick = $server->{nick};
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
my $enable_truncate = Irssi::settings_get_bool('nickcolor_enable_truncate');
my $prefix_text = Irssi::settings_get_str('nickcolor_prefix_text');
my $truncate_value = Irssi::settings_get_int('nickcolor_truncate_value');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Set default nick truncate value to 0 if option is disabled
$truncate_value = 0 if (!$enable_truncate);
# Optional: We check if it's the same nickname for current target
if ($saved_nicks{$tagtarget} eq $nick && $enable_prefix)
{
# Grouped message
Irssi::command('/^format own_msg ' . $prefix_text . '$1');
}
else
{
# Normal message
Irssi::command('/^format own_msg {ownmsgnick $2 {ownnick $[' . $truncate_value . ']0}}$1');
# Save nickname for next message
$saved_nicks{$tagtarget} = $nick;
}
}
# process public (others) actions
sub sig_action_public {
my ($server, $msg, $nick, $address, $target) = @_;
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Empty current target nick if prefix option is enabled
$saved_nicks{$tagtarget} = '' if ($enable_prefix);
}
# process public (me) actions
sub sig_action_me {
my ($server, $msg, $target) = @_;
my $nick = $server->{nick};
my $enable_prefix = Irssi::settings_get_bool('nickcolor_enable_prefix');
# Reference for server/channel
my $tagtarget = "$server->{tag}/$target";
# Empty current target nick if prefix option is enabled
$saved_nicks{$tagtarget} = '' if ($enable_prefix);
}
sub cmd_color {
my ($data, $server, $witem) = @_;
my ($op, $nick, $color) = split " ", $data;
$op = lc $op;
if (!$op) {
Irssi::print ("No operation given (save/set/clear/list/preview)");
} elsif ($op eq "save") {
save_colors;
} elsif ($op eq "set") {
if (!$nick) {
Irssi::print ("Nick not given");
} elsif (!$color) {
Irssi::print ("Color not given");
} elsif ($color < 2 || $color > 14) {
Irssi::print ("Color must be between 2 and 14 inclusive");
} else {
$saved_colors{$nick} = $color;
}
} elsif ($op eq "clear") {
if (!$nick) {
Irssi::print ("Nick not given");
} else {
delete ($saved_colors{$nick});
}
} elsif ($op eq "list") {
Irssi::print ("\nSaved Colors:");
foreach my $nick (keys %saved_colors) {
Irssi::print (chr (3) . sprintf("%02d", $saved_colors{$nick}) . "$nick" .
chr (3) . "1 ($saved_colors{$nick})");
}
} elsif ($op eq "preview") {
Irssi::print ("\nAvailable colors:");
foreach my $i (2..14) {
Irssi::print (chr (3) . "$i" . "Color #$i");
}
}
}
load_colors;
Irssi::settings_add_str('misc', 'nickcolor_colors', '2 3 4 5 6 7 9 10 11 12 13');
Irssi::settings_add_bool('misc', 'nickcolor_enable_prefix', 0);
Irssi::settings_add_bool('misc', 'nickcolor_enable_truncate', 0);
Irssi::settings_add_str('misc', 'nickcolor_prefix_text' => '- ');
Irssi::settings_add_int('misc', 'nickcolor_truncate_value' => 0);
Irssi::command_bind('color', 'cmd_color');
Irssi::signal_add('message public', 'sig_public');
Irssi::signal_add('message own_public', 'sig_me');
Irssi::signal_add('message irc action', 'sig_action_public');
Irssi::signal_add('message irc own_action', 'sig_action_me');
Irssi::signal_add('event nick', 'sig_nick');

828
home/.irssi/scripts/nicklist.pl Executable file
View File

@@ -0,0 +1,828 @@
# This script adds a nicklist to the right of irssi
# for documentation: see http://wouter.coekaerts.be/site/irssi/nicklist
# Copyright (C) 2002-2007 Wouter Coekaerts <coekie@irssi.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
use Irssi;
use strict;
use IO::Handle; # for (auto)flush
use Fcntl; # for sysopen
use vars qw($VERSION %IRSSI);
$VERSION = '0.4.12';
%IRSSI = (
authors => 'Wouter Coekaerts',
contact => 'coekie@irssi.org',
name => 'nicklist',
description => 'draws a nicklist to another terminal, or at the right of your irssi in the same terminal',
license => 'GPLv2',
url => 'http://wouter.coekaerts.be/irssi',
changed => '2018-10-02'
);
sub cmd_help {
print ( <<EOF
Commands:
NICKLIST HELP
NICKLIST SCROLL <nr of lines>
NICKLIST SCREEN
NICKLIST FIFO
NICKLIST ON
NICKLIST OFF
NICKLIST TOGGLE
NICKLIST UPDATE
For help see: http://wouter.coekaerts.be/site/irssi/nicklist
in short:
1. FIFO MODE
- in irssi: /NICKLIST FIFO (only the first time, to create the fifo)
- in a shell, in a window where you want the nicklist: cat ~/.irssi/nicklistfifo
- back in irssi:
/SET nicklist_heigth <height of nicklist>
/SET nicklist_width <width of nicklist>
/NICKLIST FIFO
2. SCREEN MODE
- start irssi inside screen ("screen irssi")
- /NICKLIST SCREEN
EOF
);
}
my $prev_lines = 0; # number of lines in previous written nicklist
my $scroll_pos = 0; # scrolling position
my $cursor_line; # line the cursor is currently on
my ($OFF, $SCREEN, $FIFO) = (0,1,2); # modes
my $mode = $OFF; # current mode
my $need_redraw = 0; # nicklist needs redrawing
my $screen_resizing = 0; # terminal is being resized
my $active_channel; # (REC)
my @nicklist=(); # array of hashes, containing the internal nicklist of the active channel
# nick => realnick
# modeflag => '@', '%', '+', or other mode char
# modepos => number representing the position in which to sort nicks with that mode
# status => (not used yet...)
# text => text to be printed
# cmp => text used to compare (sort) nicks
# 'cached' settings
my ($screen_prefix, $irssi_width, %prefix_mode, @prefix_status, $height, $nicklist_width, $check_friends, @prefix_friends);
sub read_settings {
($screen_prefix = Irssi::settings_get_str('nicklist_screen_prefix')) =~ s/\\e/\033/g;
($prefix_mode{'@'} = Irssi::settings_get_str('nicklist_prefix_mode_op')) =~ s/\\e/\033/g;
($prefix_mode{'%'} = Irssi::settings_get_str('nicklist_prefix_mode_halfop')) =~ s/\\e/\033/g;
($prefix_mode{'+'} = Irssi::settings_get_str('nicklist_prefix_mode_voice')) =~ s/\\e/\033/g;
($prefix_mode{' '} = Irssi::settings_get_str('nicklist_prefix_mode_normal')) =~ s/\\e/\033/g;
(my $prefix_mode_other = Irssi::settings_get_str('nicklist_prefix_mode_other')) =~ s/\\e/\033/g;
foreach my $p (split (/ /, $prefix_mode_other)) {
next if $p eq '';
if ($p !~ /(.)=(.*)/) {
Irssi::print("Could not parse nicklist_prefix_mode_other part '$p'. Expected space separated list of <mode character>=<prefix>");
last;
} else {
$prefix_mode{$1} = $2;
}
}
(my $prefix_friends = Irssi::settings_get_str('nicklist_prefix_friends')) =~ s/\\e/\033/g;
foreach my $p (split (/ /, $prefix_friends)) {
next if $p eq '';
if ($p !~ /(.+?)=(.*)/) {
Irssi::print("Could not parse nicklist_prefix_friends part '$p'. Expected space separated list of <flags>=<prefix>");
last;
} else {
push @prefix_friends, {'flags' => $1, 'prefix' => $2};
}
}
$check_friends = ($prefix_friends ne '');
if ($mode != $SCREEN) {
$height = Irssi::settings_get_int('nicklist_height');
}
my $new_nicklist_width = Irssi::settings_get_int('nicklist_width');
if ($new_nicklist_width != $nicklist_width && $mode == $SCREEN) {
sig_terminal_resized();
}
$nicklist_width = $new_nicklist_width;
}
sub update {
read_settings();
make_nicklist();
}
##################
##### OUTPUT #####
##################
### on ###
sub cmd_on {
if (uc(Irssi::settings_get_str('nicklist_automode')) eq 'SCREEN') {
cmd_screen_start();
} elsif (uc(Irssi::settings_get_str('nicklist_automode')) eq 'FIFO') {
cmd_fifo_start();
}
}
### off ###
sub cmd_off {
if ($mode == $SCREEN) {
screen_stop();
} elsif ($mode == $FIFO) {
fifo_stop();
}
}
### toggle ###
sub cmd_toggle {
if ($mode == $OFF) {
cmd_on();
} else {
cmd_off();
}
}
### fifo ###
sub cmd_fifo_start {
read_settings();
my $path = Irssi::settings_get_str('nicklist_fifo_path');
unless (-p $path) { # not a pipe
if (-e _) { # but a something else
die "$0: $path exists and is not a pipe, please remove it\n";
} else {
require POSIX;
POSIX::mkfifo($path, 0666) or die "can\'t mkfifo $path: $!";
Irssi::print("Fifo created. Start reading it (\"cat $path\") and try again.");
return;
}
}
if (!sysopen(FIFO, $path, O_WRONLY | O_NONBLOCK)) { # or die "can't write $path: $!";
Irssi::print("Couldn\'t write to the fifo ($!). Please start reading the fifo (\"cat $path\") and try again.");
return;
}
FIFO->autoflush(1);
print FIFO "\033[2J\033[1;1H"; # erase screen & jump to 0,0
$cursor_line = 0;
if ($mode == $SCREEN) {
screen_stop();
}
$mode = $FIFO;
make_nicklist();
}
sub fifo_stop {
close FIFO;
$mode = $OFF;
Irssi::print("Fifo closed.");
}
### screen ###
sub cmd_screen_start {
if (!defined($ENV{'STY'})) {
Irssi::print 'screen not detected, screen mode only works inside screen';
return;
}
read_settings();
if ($mode == $SCREEN) {return;}
if ($mode == $FIFO) {
fifo_stop();
}
$mode = $SCREEN;
Irssi::signal_add_last('gui print text finished', \&sig_gui_print_text_finished);
Irssi::signal_add_last('gui page scrolled', \&sig_page_scrolled);
Irssi::signal_add('terminal resized', \&sig_terminal_resized);
screen_size();
make_nicklist();
}
sub screen_stop {
$mode = $OFF;
Irssi::signal_remove('gui print text finished', \&sig_gui_print_text_finished);
Irssi::signal_remove('gui page scrolled', \&sig_page_scrolled);
Irssi::signal_remove('terminal resized', \&sig_terminal_resized);
system 'screen -x '.$ENV{'STY'}.' -X fit';
# we wait a second to make sure the fit command was processed
Irssi::timeout_add_once(1000, \&screen_size, []);
}
#sub screen_size_real {
sub screen_size {
if ($mode != $SCREEN) {
return;
}
$screen_resizing = 1;
# fit screen
system 'screen -x '.$ENV{'STY'}.' -X fit';
# get size (from perldoc -q size)
my ($winsize, $row, $col, $xpixel, $ypixel);
eval 'use Term::ReadKey; ($col, $row, $xpixel, $ypixel) = GetTerminalSize';
# require Term::ReadKey 'GetTerminalSize';
# ($col, $row, $xpixel, $ypixel) = Term::ReadKey::GetTerminalSize;
#};
if ($@) { # no Term::ReadKey, try the ugly way
eval {
require 'sys/ioctl.ph';
# without this reloading doesn't work. workaround for some unknown bug
do 'asm/ioctls.ph';
};
# ugly way not working, let's try something uglier, the dg-hack(tm) (constant for linux only?)
if($@) { no strict 'refs'; *TIOCGWINSZ = sub { return 0x5413 } }
unless (defined &TIOCGWINSZ) {
die "Term::ReadKey not found, and ioctl 'workaround' failed. Install the Term::ReadKey perl module to use screen mode.\n";
}
open(TTY, "+<","/dev/tty") or die "No tty: $!";
unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
die "Term::ReadKey not found, and ioctl 'workaround' failed ($!). Install the Term::ReadKey perl module to use screen mode.\n";
}
close(TTY);
($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
}
# set screen width
$irssi_width = $col-$nicklist_width-1;
$height = $row-1;
system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $irssi_width;
# wait another second for the resizing, and then redraw.
Irssi::timeout_add_once(1000,sub {$screen_resizing = 0; redraw()}, []);
}
sub sig_terminal_resized {
if ($screen_resizing) {
return;
}
$screen_resizing = 1;
Irssi::timeout_add_once(1000,\&screen_size,[]);
}
### both ###
sub nicklist_write_start {
if ($mode == $SCREEN) {
print STDERR "\033P\0337\033\\"; # save cursor
}
}
sub nicklist_write_end {
if ($mode == $SCREEN) {
print STDERR "\033P\0338\033\\"; # restore cursor
}
}
sub nicklist_write_line {
my ($line, $data) = @_;
if ($mode == $SCREEN) {
print STDERR "\033P\033[" . ($line+1) . ';'. ($irssi_width+1) .'H'. $screen_prefix . $data . "\033\\";
} elsif ($mode == $FIFO) {
$data = "\033[m$data"; # reset color
if ($line == $cursor_line+1) {
$data = "\n$data"; # next line
} elsif ($line == $cursor_line) {
$data = "\033[1G".$data; # back to beginning of line
} else {
$data = "\033[".($line+1).";0H".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
}
}
sub calc_prefix_friends {
my ($nick) = @_;
return '' unless $check_friends
&& $nick->{'host'}
&& is_friend($active_channel->{'server'}->{'chatnet'}, $active_channel->{'name'}, $nick->{'nick'}, $nick->{'host'});
my $flags = get_flags($active_channel->{'server'}->{'chatnet'}, $active_channel->{'name'}, $nick->{'nick'}, $nick->{'host'});
my $prefix;
foreach my $prefix_friend (@prefix_friends) {
if ($prefix_friend->{'flags'} eq 'noflag') {
if ($flags eq '') {
$prefix = $prefix_friend->{'prefix'};
last;
}
} elsif (check_modes($flags, $prefix_friend->{'flags'})) {
$prefix = $prefix_friend->{'prefix'};
}
}
return $prefix ? $prefix : '';
}
# recalc the text of the nicklist item
sub calc_text {
my ($nick) = @_;
my $tmp = $nicklist_width-3;
(my $text = $nick->{'nick'}) =~ s/^(.{$tmp})..+$/$1\033[34m~/; # strip nick if too long
my $prefix_mode = $prefix_mode{$nick->{'modeflag'}};
if (! defined($prefix_mode) ) {
$prefix_mode = $nick->{'modeflag'};
}
my $prefix_friends = calc_prefix_friends($nick);
$nick->{'text'} =
$prefix_mode .
$prefix_friends .
$text .
(' ' x ($nicklist_width-length($nick->{'nick'})-1)) .
"\033[m"; # reset
$nick->{'cmp'} = $nick->{'modepos'}.lc($nick->{'nick'});
}
# redraw the given nick (nr) if it is visible
sub redraw_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line >= 0 && $line < $height) {
nicklist_write_line($line, $nicklist[$nr]->{'text'});
}
}
# nick was inserted, redraw area if necessary
sub draw_insert_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line < 0) { # nick is inserted above visible area
$scroll_pos++; # 'scroll' down :)
} elsif ($line < $height) { # line is visible
if ($mode == $SCREEN) {
need_redraw();
} elsif ($mode == $FIFO) {
my $data = "\033[m\033[L". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
if ($line == $cursor_line) {
$data = "\033[1G".$data; # back to beginning of line
} else {
$data = "\033[".($line+1).";1H".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
if ($prev_lines < $height) {
$prev_lines++; # the nicklist has one line more
}
}
}
}
sub draw_remove_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line < 0) { # nick removed above visible area
$scroll_pos--; # 'scroll' up :)
} elsif ($line < $height) { # line is visible
if ($mode == $SCREEN) {
need_redraw();
} elsif ($mode == $FIFO) {
#my $data = "\033[m\033[L[i$line]". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
my $data = "\033[M"; # delete line
if ($line != $cursor_line) {
$data = "\033[".($line+1)."d".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
if (@nicklist-$scroll_pos >= $height) {
redraw_nick_nr($scroll_pos+$height-1);
}
}
}
}
# redraw the whole nicklist
sub redraw {
$need_redraw = 0;
#make_nicklist();
nicklist_write_start();
my $line = 0;
### draw nicklist ###
for (my $i=$scroll_pos;$line < $height && $i < @nicklist; $i++) {
nicklist_write_line($line++, $nicklist[$i]->{'text'});
}
### clean up other lines ###
my $real_lines = $line;
while($line < $prev_lines) {
nicklist_write_line($line++,' ' x $nicklist_width);
}
$prev_lines = $real_lines;
nicklist_write_end();
}
# redraw (with little delay to avoid redrawing to much)
sub need_redraw {
if(!$need_redraw) {
$need_redraw = 1;
Irssi::timeout_add_once(10,\&redraw,[]);
}
}
sub sig_page_scrolled {
$prev_lines = $height; # we'll need to redraw everything if he scrolled up
need_redraw;
}
# redraw (with delay) if the window is visible (only in screen mode)
sub sig_gui_print_text_finished {
if ($need_redraw) { # there's already a redraw 'queued'
return;
}
my $window = @_[0];
if ($window->{'refnum'} == Irssi::active_win->{'refnum'} || Irssi::settings_get_str('nicklist_screen_split_windows') eq '*') {
need_redraw;
return;
}
foreach my $win (split(/[ ,]/, Irssi::settings_get_str('nicklist_screen_split_windows'))) {
if ($window->{'refnum'} == $win || $window->{'name'} eq $win) {
need_redraw;
return;
}
}
}
###################
##### FRIENDS #####
###################
# checks if $has_modes is in $need_modes, copied from trigger.pl
sub check_modes {
my ($has_modes, $need_modes) = @_;
my $matches;
my $switch = 1; # if a '-' if found, will be 0 (meaning the modes should not be set)
foreach my $need_mode (split /&/,$need_modes) {
$matches = 0;
foreach my $char (split //,$need_mode) {
if ($char eq '-') {
$switch = 0;
} elsif ($char eq '+') {
$switch = 1;
} elsif ((index($has_modes,$char) != -1) == $switch) {
$matches = 1;
last;
}
}
if (!$matches) {
return 0;
}
}
return 1;
}
# get someones flags from people.pl or friends(_shasta).pl, copied from trigger.pl
sub get_flags {
my ($chatnet, $channel, $nick, $address) = @_;
my $flags;
no strict 'refs';
if (%{ 'Irssi::Script::people::' }) {
if (defined ($channel)) {
$flags = (&{ 'Irssi::Script::people::find_local_flags' }($chatnet,$channel,$nick,$address));
} else {
$flags = (&{ 'Irssi::Script::people::find_global_flags' }($chatnet,$nick,$address));
}
$flags = join('',keys(%{$flags}));
} else {
my $shasta;
if (%{ 'Irssi::Script::friends_shasta::' }) {
$shasta = 'friends_shasta';
} elsif (defined &{ 'Irssi::Script::friends::get_idx' }) {
$shasta = 'friends';
}
if (!$shasta) {
return undef;
}
my $idx = (&{ 'Irssi::Script::'.$shasta.'::get_idx' }($nick,$address));
if ($idx == -1) {
return '';
}
$flags = (&{ 'Irssi::Script::'.$shasta.'::get_friends_flags' }($idx,undef));
if ($channel) {
$flags .= (&{ 'Irssi::Script::'.$shasta.'::get_friends_flags' }($idx,$channel));
}
}
return $flags;
}
sub is_friend {
my ($chatnet, $channel, $nick, $address) = @_;
no strict 'refs';
if (%{ 'Irssi::Script::people::' }) {
return (() != &{'Irssi::Script::people::find_users'}($chatnet, $nick, $address));
my $flags;
if (defined ($channel)) {
$flags = (&{ 'Irssi::Script::people::find_local_flags' }($chatnet,$channel,$nick,$address));
} else {
$flags = (&{ 'Irssi::Script::people::find_global_flags' }($chatnet,$nick,$address));
}
return ($flags ne ''); # TODO: test this
} else {
my $shasta;
if (%{ 'Irssi::Script::friends_shasta::' }) {
$shasta = 'friends_shasta';
} elsif (defined &{ 'Irssi::Script::friends::get_idx' }) {
$shasta = 'friends';
}
if (!$shasta) {
return undef;
}
my $idx = (&{ 'Irssi::Script::'.$shasta.'::get_idx' }($nick,$address));
return ($idx != -1);
}
}
####################
##### NICKLIST #####
####################
# returns the position of the given nick(as string) in the (internal) nicklist
sub find_nick {
my ($nick) = @_;
for (my $i=0;$i < @nicklist; $i++) {
if ($nicklist[$i]->{'nick'} eq $nick) {
return $i;
}
}
return -1;
}
# find position where nick should be inserted into the list
sub find_insert_pos {
my ($cmp)= @_;
for (my $i=0;$i < @nicklist; $i++) {
if ($nicklist[$i]->{'cmp'} gt $cmp) {
return $i;
}
}
return scalar(@nicklist); #last
}
# make the (internal) nicklist (@nicklist)
sub make_nicklist {
@nicklist = ();
$scroll_pos = 0;
### get & check channel ###
my $channel = Irssi::active_win->{active};
if (!$channel || (ref($channel) ne 'Irssi::Irc::Channel' && ref($channel) ne 'Irssi::Silc::Channel' && ref($channel) ne 'Irssi::Xmpp::Channel') || $channel->{'type'} ne 'CHANNEL' || ($channel->{chat_type} ne 'SILC' && !$channel->{'names_got'}) ) {
$active_channel = undef;
# no nicklist
} else {
$active_channel = $channel;
### make nicklist ###
foreach my $nick ($channel->nicks()) {
my $thisnick = {'nick' => $nick->{'nick'}};
recalc_nick($thisnick, $nick);
push @nicklist, $thisnick;
}
@nicklist = sort {$a->{'cmp'} cmp $b->{'cmp'}} @nicklist;
}
need_redraw();
}
# insert nick(as hash) into nicklist
# pre: cmp has to be calculated
sub insert_nick {
my ($nick) = @_;
my $nr = find_insert_pos($nick->{'cmp'});
splice @nicklist, $nr, 0, $nick;
draw_insert_nick_nr($nr);
}
# remove nick(as nr) from nicklist
sub remove_nick {
my ($nr) = @_;
splice @nicklist, $nr, 1;
draw_remove_nick_nr($nr);
}
# update the mode and cmp of a nick, based on a nickrec from irssi
sub recalc_nick {
my ($nick, $nickrec) = @_;
if (! $nickrec) {
$nickrec = $active_channel->nick_find($nick->{'nick'});
}
my $nickflags = $active_channel->{'server'}->get_nick_flags() . ' ';
my $flag = (
$nickrec->{'op'} ? '@' :
$nickrec->{'halfop'} ? '%' :
$nickrec->{'voice'} ? '+' :
' '
);
if ($nickrec->{'other'} && index($nickflags, $nick->{'other'}) < index($nickflags, $flag)) {
$flag = chr($nickrec->{'other'});
}
$nick->{'modepos'} = index($nickflags, $flag);
$nick->{'modeflag'} = $flag;
$nick->{'host'} = $nickrec->{'host'};
calc_text($nick);
}
###################
##### ACTIONS #####
###################
# scroll the nicklist, arg = number of lines to scroll, positive = down, negative = up
sub cmd_scroll {
my $channel = Irssi::active_win->{active};
if (!$channel || !$channel->can('nicks')) { # active window is not a channel
return;
}
my @nicks = $channel->nicks;
my $nick_count = scalar(@nicks)+0;
if (!$active_channel) { # not a channel active
return;
}
if (!$channel || $channel->{type} ne 'CHANNEL' || !$channel->{names_got} || $nick_count <= $height) {
return;
}
if ($nick_count <= Irssi::settings_get_int('nicklist_height')) {
return;
}
$scroll_pos += @_[0];
if ($scroll_pos > $nick_count - $height) {
$scroll_pos = $nick_count - $height;
}
if ($scroll_pos <= 0) {
$scroll_pos = 0;
}
need_redraw();
}
sub is_active_channel {
my ($server,$channel) = @_; # (channel as string)
return ($server && $server->{'tag'} eq $active_channel->{'server'}->{'tag'} && $server->channel_find($channel) && $active_channel && $server->channel_find($channel)->{'name'} eq $active_channel->{'name'});
}
sub sig_channel_wholist { # this is actualy a little late, when the names are received would be better
my ($channel) = @_;
if (Irssi::active_win->{'active'} && Irssi::active_win->{'active'}->{'name'} eq $channel->{'name'}) { # the channel joined is active
make_nicklist
}
}
sub sig_join {
my ($server,$channel,$nick,$address) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $newnick = {'nick' => $nick};
recalc_nick($newnick);
insert_nick($newnick);
}
sub sig_kick {
my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $nr = find_nick($nick);
if ($nr == -1) {
Irssi::print("nicklist warning: $nick was kicked from $channel, but not found in nicklist");
} else {
remove_nick($nr);
}
}
sub sig_part {
my ($server,$channel,$nick,$address, $reason) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $nr = find_nick($nick);
if ($nr == -1) {
Irssi::print("nicklist warning: $nick has parted $channel, but was not found in nicklist");
} else {
remove_nick($nr);
}
}
sub sig_quit {
my ($server,$nick,$address, $reason) = @_;
if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
return;
}
my $nr = find_nick($nick);
if ($nr != -1) {
remove_nick($nr);
}
}
sub sig_nick {
my ($server, $newnick, $oldnick, $address) = @_;
if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
return;
}
my $nr = find_nick($oldnick);
if ($nr != -1) { # if nick was found (nickchange is in current channel)
my $nick = $nicklist[$nr];
remove_nick($nr);
$nick->{'nick'} = $newnick;
calc_text($nick);
insert_nick($nick);
}
}
sub sig_mode {
my ($channel, $nick, $setby, $mode, $type) = @_; # (nick and channel as rec)
if ($channel->{'server'}->{'tag'} ne $active_channel->{'server'}->{'tag'} || $channel->{'name'} ne $active_channel->{'name'}) {
return;
}
my $nr = find_nick($nick->{'nick'});
if ($nr == -1) {
Irssi::print("nicklist warning: $nick->{'nick'} had mode set on $channel->{'name'}, but was not found in nicklist");
} else {
my $nicklist_item = $nicklist[$nr];
remove_nick($nr);
recalc_nick($nicklist_item, $nick);
insert_nick($nicklist_item);
}
}
##### command binds #####
Irssi::command_bind 'nicklist' => sub {
my ( $data, $server, $item ) = @_;
$data =~ s/\s+$//g;
Irssi::command_runsub ('nicklist', $data, $server, $item ) ;
};
Irssi::signal_add_first 'default command nicklist' => sub {
# gets triggered if called with unknown subcommand
cmd_help();
};
Irssi::command_bind('nicklist update',\&update);
Irssi::command_bind('nicklist help',\&cmd_help);
Irssi::command_bind('nicklist scroll',\&cmd_scroll);
Irssi::command_bind('nicklist fifo',\&cmd_fifo_start);
Irssi::command_bind('nicklist screen',\&cmd_screen_start);
Irssi::command_bind('nicklist screensize',\&screen_size);
Irssi::command_bind('nicklist on',\&cmd_on);
Irssi::command_bind('nicklist off',\&cmd_off);
Irssi::command_bind('nicklist toggle',\&cmd_toggle);
##### signals #####
Irssi::signal_add_last('window item changed', \&make_nicklist);
Irssi::signal_add_last('window changed', \&make_nicklist);
Irssi::signal_add_last('channel wholist', \&sig_channel_wholist);
Irssi::signal_add_first('message join', \&sig_join); # first, to be before ignores
Irssi::signal_add_first('message part', \&sig_part);
Irssi::signal_add_first('message kick', \&sig_kick);
Irssi::signal_add_first('message quit', \&sig_quit);
Irssi::signal_add_first('message nick', \&sig_nick);
Irssi::signal_add_first('message own_nick', \&sig_nick);
Irssi::signal_add_first('nick mode changed', \&sig_mode);
Irssi::signal_add('setup changed', \&read_settings);
##### settings #####
Irssi::settings_add_str('nicklist', 'nicklist_screen_prefix', '\e[m ');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_op', '\e[32m@\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_halfop', '\e[34m%\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_voice', '\e[33m+\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_normal', ' ');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_other', '&=\e[31m&\e[39m ~=\e[35m~\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_friends', 'o=\e[32m v=\e[33m noflag=\e[1m');
Irssi::settings_add_int('nicklist', 'nicklist_width',11);
Irssi::settings_add_int('nicklist', 'nicklist_height',24);
Irssi::settings_add_str('nicklist', 'nicklist_fifo_path', Irssi::get_irssi_dir . '/nicklistfifo');
Irssi::settings_add_str('nicklist', 'nicklist_screen_split_windows', '');
Irssi::settings_add_str('nicklist', 'nicklist_automode', '');
read_settings();
cmd_on();

View File

@@ -0,0 +1,83 @@
##
## Put me in ~/.irssi/scripts, and then execute the following in irssi:
##
## /load perl
## /script load notify
##
use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
use HTML::Entities;
$VERSION = "0.5";
%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => 'lewk@csh.rit.edu, stickster@gmail.com',
name => 'notify.pl',
description => 'Use D-Bus to alert user to hilighted messages',
license => 'GNU General Public License',
url => 'http://code.google.com/p/irssi-libnotify',
);
Irssi::settings_add_str('notify', 'notify_remote', '');
sub sanitize {
my ($text) = @_;
encode_entities($text,'\'<>&');
my $apos = "&#39;";
my $aposenc = "\&apos;";
$text =~ s/$apos/$aposenc/g;
$text =~ s/"/\\"/g;
return $text;
}
sub notify {
my ($server, $summary, $message) = @_;
# Make the message entity-safe
$summary = sanitize($summary);
$message = sanitize($message);
my $cmd = "EXEC - " .
"notify-send -a irssi -- '" . $summary . "' '". $message . "'";
$server->command($cmd);
my $remote = Irssi::settings_get_str('notify_remote');
if ($remote ne '') {
my $cmd = "EXEC - ssh -q " . $remote .
"notify-send -a irssi -- '" . $summary . "' '". $message . "'";
$server->command($cmd);
}
}
sub print_text_notify {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};
#my $channel = $dest->{channel};
return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
my $sender = $stripped;
$sender =~ s/^\<?(.+?)\>? .*/\1/ ;
$stripped =~ s/^.+? +(.*)/\1/ ;
notify($server, $sender, $stripped);
}
sub message_private_notify {
my ($server, $msg, $nick, $address) = @_;
return if (!$server);
notify($server, "PM from ".$nick, $msg);
}
sub dcc_request_notify {
my ($dcc, $sendaddr) = @_;
my $server = $dcc->{server};
return if (!$dcc);
notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}
Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');

View File

@@ -0,0 +1,84 @@
##
## Put me in ~/.irssi/scripts, and then execute the following in irssi:
##
## /load perl
## /script load notify
##
use strict;
use Irssi;
use vars qw($VERSION %IRSSI);
use HTML::Entities;
$VERSION = "0.5";
%IRSSI = (
authors => 'Luke Macken, Paul W. Frields',
contact => 'lewk@csh.rit.edu, stickster@gmail.com',
name => 'notify.pl',
description => 'Use D-Bus to alert user to hilighted messages',
license => 'GNU General Public License',
url => 'http://code.google.com/p/irssi-libnotify',
);
Irssi::settings_add_str('notify', 'notify_remote', '');
sub sanitize {
my ($text) = @_;
encode_entities($text,'\'<>&');
my $apos = "&#39;";
my $aposenc = "\&apos;";
$text =~ s/$apos/$aposenc/g;
$text =~ s/"/\\"/g;
return $text;
}
sub notify {
my ($server, $summary, $message) = @_;
# Make the message entity-safe
$summary = sanitize($summary);
$message = sanitize($message);
my $cmd = "EXEC - " .
"notify-send -a irssi -- '" . $summary . "' '". $message . "'";
$server->command($cmd);
my $remote = Irssi::settings_get_str('notify_remote');
if ($remote ne '') {
my $cmd = "EXEC - ssh -q " . $remote .
"notify-send -a irssi -- '" . $summary . "' '". $message . "'";
$server->command($cmd);
}
}
sub print_text_notify {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};
#my $channel = $dest->{channel};
return if (!$server || !($dest->{level} & MSGLEVEL_HILIGHT));
my $sender = $stripped;
$sender =~ s/^\<?(.+?)\>? .*/\1/ ;
$stripped =~ s/^.+? +(.*)/\1/ ;
notify($server, $sender, $stripped);
}
sub message_private_notify {
my ($server, $msg, $nick, $address) = @_;
return if (!$server);
notify($server, "PM from ".$nick, $msg);
}
sub dcc_request_notify {
my ($dcc, $sendaddr) = @_;
my $server = $dcc->{server};
return if (!$dcc);
notify($server, "DCC ".$dcc->{type}." request", $dcc->{nick});
}
Irssi::signal_add('print text', 'print_text_notify');
Irssi::signal_add('message private', 'message_private_notify');
Irssi::signal_add('dcc request', 'dcc_request_notify');

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
# Copyright (C) 2015 Felipe F. Tonello <eu@felipetonello.com>
#
# Based on fnotify.pl 0.0.5 by Thorsten Leemhuis, James Shubin and
# Serge van Ginderachter
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# NOTE:
# This program requires libnotify, perl-glib-object-introspection and
# perl-html-parser packages
use strict;
use Irssi;
use HTML::Entities;
use Glib::Object::Introspection; # Ignore 'late INIT' warning message if autoloading
use Encode;
our $VERSION = '1.0.1';
our %IRSSI = (
authors => 'Felipe F. Tonello',
contact => 'eu@felipetonello.com',
name => 'desktop-notify',
description => 'Sends notification using the Desktop Notifications Specification.',
license => 'GPL v3+',
);
# /set notify_icon <icon-name>
# List of standard icons can be found here:
# http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#names
my $notify_icon;
my $term_charset;
my $help = '
/set notify_icon <icon-name>
Change notificationicon (default is mail-message-new). A complete list of standard ' .
'icons can be found here: ' .
'http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html#names
';
sub init {
Glib::Object::Introspection->setup(
basename => 'Notify',
version => '0.7',
package => 'Notify');
Notify::init('Irssi');
}
sub UNLOAD {
Notify::uninit();
}
sub setup_changed {
$notify_icon = Irssi::settings_get_str('notify_icon');
$term_charset = Irssi::settings_get_str('term_charset');
}
sub priv_msg {
my ($server, $msg, $nick, $address) = @_;
my $window = Irssi::active_win();
# We shouldn't notify if active window is the same as the private message
if ($window->{active}->{name} eq $nick) {
return;
}
my $msg = HTML::Entities::encode_entities(Irssi::strip_codes($msg), "\<>&'");
my $network = $server->{tag};
my $noti = Notify::Notification->new($nick . '@' . $network, decode($term_charset, $msg), $notify_icon);
$noti->show();
}
sub hilight {
my ($dest, $text, $stripped) = @_;
my $server = $dest->{server};
my $window = Irssi::active_win();
# Check if we should notify user of message:
# * if message is notice or highligh type
# * if the channel belongs to the current server
# * if the user is not focused on the channel window
if (!($server &&
$dest->{level} & (MSGLEVEL_HILIGHT | MSGLEVEL_NOTICES) &&
$server->ischannel($dest->{target}) &&
$window->{refnum} != $dest->{window}->{refnum})) {
return;
}
my $network = $server->{tag};
my $msg = HTML::Entities::encode_entities($stripped, "\'<>&");
my $noti = Notify::Notification->new($dest->{target} . '@' . $network, decode($term_charset, $msg), $notify_icon);
$noti->show();
}
Irssi::settings_add_str('desktop-notify', 'notify_icon', 'mail-message-new');
Irssi::signal_add('setup changed' => \&setup_changed);
Irssi::signal_add_last('message private' => \&priv_msg);
Irssi::signal_add_last('print text' => \&hilight);
Irssi::command_bind('help', sub {
if ($_[0] eq $IRSSI{name}) {
Irssi::print($help, MSGLEVEL_CLIENTCRAP);
Irssi::signal_stop();
}
}
);
init();
setup_changed();

View File

@@ -0,0 +1,828 @@
# This script adds a nicklist to the right of irssi
# for documentation: see http://wouter.coekaerts.be/site/irssi/nicklist
# Copyright (C) 2002-2007 Wouter Coekaerts <coekie@irssi.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
use Irssi;
use strict;
use IO::Handle; # for (auto)flush
use Fcntl; # for sysopen
use vars qw($VERSION %IRSSI);
$VERSION = '0.4.12';
%IRSSI = (
authors => 'Wouter Coekaerts',
contact => 'coekie@irssi.org',
name => 'nicklist',
description => 'draws a nicklist to another terminal, or at the right of your irssi in the same terminal',
license => 'GPLv2',
url => 'http://wouter.coekaerts.be/irssi',
changed => '2018-10-02'
);
sub cmd_help {
print ( <<EOF
Commands:
NICKLIST HELP
NICKLIST SCROLL <nr of lines>
NICKLIST SCREEN
NICKLIST FIFO
NICKLIST ON
NICKLIST OFF
NICKLIST TOGGLE
NICKLIST UPDATE
For help see: http://wouter.coekaerts.be/site/irssi/nicklist
in short:
1. FIFO MODE
- in irssi: /NICKLIST FIFO (only the first time, to create the fifo)
- in a shell, in a window where you want the nicklist: cat ~/.irssi/nicklistfifo
- back in irssi:
/SET nicklist_heigth <height of nicklist>
/SET nicklist_width <width of nicklist>
/NICKLIST FIFO
2. SCREEN MODE
- start irssi inside screen ("screen irssi")
- /NICKLIST SCREEN
EOF
);
}
my $prev_lines = 0; # number of lines in previous written nicklist
my $scroll_pos = 0; # scrolling position
my $cursor_line; # line the cursor is currently on
my ($OFF, $SCREEN, $FIFO) = (0,1,2); # modes
my $mode = $OFF; # current mode
my $need_redraw = 0; # nicklist needs redrawing
my $screen_resizing = 0; # terminal is being resized
my $active_channel; # (REC)
my @nicklist=(); # array of hashes, containing the internal nicklist of the active channel
# nick => realnick
# modeflag => '@', '%', '+', or other mode char
# modepos => number representing the position in which to sort nicks with that mode
# status => (not used yet...)
# text => text to be printed
# cmp => text used to compare (sort) nicks
# 'cached' settings
my ($screen_prefix, $irssi_width, %prefix_mode, @prefix_status, $height, $nicklist_width, $check_friends, @prefix_friends);
sub read_settings {
($screen_prefix = Irssi::settings_get_str('nicklist_screen_prefix')) =~ s/\\e/\033/g;
($prefix_mode{'@'} = Irssi::settings_get_str('nicklist_prefix_mode_op')) =~ s/\\e/\033/g;
($prefix_mode{'%'} = Irssi::settings_get_str('nicklist_prefix_mode_halfop')) =~ s/\\e/\033/g;
($prefix_mode{'+'} = Irssi::settings_get_str('nicklist_prefix_mode_voice')) =~ s/\\e/\033/g;
($prefix_mode{' '} = Irssi::settings_get_str('nicklist_prefix_mode_normal')) =~ s/\\e/\033/g;
(my $prefix_mode_other = Irssi::settings_get_str('nicklist_prefix_mode_other')) =~ s/\\e/\033/g;
foreach my $p (split (/ /, $prefix_mode_other)) {
next if $p eq '';
if ($p !~ /(.)=(.*)/) {
Irssi::print("Could not parse nicklist_prefix_mode_other part '$p'. Expected space separated list of <mode character>=<prefix>");
last;
} else {
$prefix_mode{$1} = $2;
}
}
(my $prefix_friends = Irssi::settings_get_str('nicklist_prefix_friends')) =~ s/\\e/\033/g;
foreach my $p (split (/ /, $prefix_friends)) {
next if $p eq '';
if ($p !~ /(.+?)=(.*)/) {
Irssi::print("Could not parse nicklist_prefix_friends part '$p'. Expected space separated list of <flags>=<prefix>");
last;
} else {
push @prefix_friends, {'flags' => $1, 'prefix' => $2};
}
}
$check_friends = ($prefix_friends ne '');
if ($mode != $SCREEN) {
$height = Irssi::settings_get_int('nicklist_height');
}
my $new_nicklist_width = Irssi::settings_get_int('nicklist_width');
if ($new_nicklist_width != $nicklist_width && $mode == $SCREEN) {
sig_terminal_resized();
}
$nicklist_width = $new_nicklist_width;
}
sub update {
read_settings();
make_nicklist();
}
##################
##### OUTPUT #####
##################
### on ###
sub cmd_on {
if (uc(Irssi::settings_get_str('nicklist_automode')) eq 'SCREEN') {
cmd_screen_start();
} elsif (uc(Irssi::settings_get_str('nicklist_automode')) eq 'FIFO') {
cmd_fifo_start();
}
}
### off ###
sub cmd_off {
if ($mode == $SCREEN) {
screen_stop();
} elsif ($mode == $FIFO) {
fifo_stop();
}
}
### toggle ###
sub cmd_toggle {
if ($mode == $OFF) {
cmd_on();
} else {
cmd_off();
}
}
### fifo ###
sub cmd_fifo_start {
read_settings();
my $path = Irssi::settings_get_str('nicklist_fifo_path');
unless (-p $path) { # not a pipe
if (-e _) { # but a something else
die "$0: $path exists and is not a pipe, please remove it\n";
} else {
require POSIX;
POSIX::mkfifo($path, 0666) or die "can\'t mkfifo $path: $!";
Irssi::print("Fifo created. Start reading it (\"cat $path\") and try again.");
return;
}
}
if (!sysopen(FIFO, $path, O_WRONLY | O_NONBLOCK)) { # or die "can't write $path: $!";
Irssi::print("Couldn\'t write to the fifo ($!). Please start reading the fifo (\"cat $path\") and try again.");
return;
}
FIFO->autoflush(1);
print FIFO "\033[2J\033[1;1H"; # erase screen & jump to 0,0
$cursor_line = 0;
if ($mode == $SCREEN) {
screen_stop();
}
$mode = $FIFO;
make_nicklist();
}
sub fifo_stop {
close FIFO;
$mode = $OFF;
Irssi::print("Fifo closed.");
}
### screen ###
sub cmd_screen_start {
if (!defined($ENV{'STY'})) {
Irssi::print 'screen not detected, screen mode only works inside screen';
return;
}
read_settings();
if ($mode == $SCREEN) {return;}
if ($mode == $FIFO) {
fifo_stop();
}
$mode = $SCREEN;
Irssi::signal_add_last('gui print text finished', \&sig_gui_print_text_finished);
Irssi::signal_add_last('gui page scrolled', \&sig_page_scrolled);
Irssi::signal_add('terminal resized', \&sig_terminal_resized);
screen_size();
make_nicklist();
}
sub screen_stop {
$mode = $OFF;
Irssi::signal_remove('gui print text finished', \&sig_gui_print_text_finished);
Irssi::signal_remove('gui page scrolled', \&sig_page_scrolled);
Irssi::signal_remove('terminal resized', \&sig_terminal_resized);
system 'screen -x '.$ENV{'STY'}.' -X fit';
# we wait a second to make sure the fit command was processed
Irssi::timeout_add_once(1000, \&screen_size, []);
}
#sub screen_size_real {
sub screen_size {
if ($mode != $SCREEN) {
return;
}
$screen_resizing = 1;
# fit screen
system 'screen -x '.$ENV{'STY'}.' -X fit';
# get size (from perldoc -q size)
my ($winsize, $row, $col, $xpixel, $ypixel);
eval 'use Term::ReadKey; ($col, $row, $xpixel, $ypixel) = GetTerminalSize';
# require Term::ReadKey 'GetTerminalSize';
# ($col, $row, $xpixel, $ypixel) = Term::ReadKey::GetTerminalSize;
#};
if ($@) { # no Term::ReadKey, try the ugly way
eval {
require 'sys/ioctl.ph';
# without this reloading doesn't work. workaround for some unknown bug
do 'asm/ioctls.ph';
};
# ugly way not working, let's try something uglier, the dg-hack(tm) (constant for linux only?)
if($@) { no strict 'refs'; *TIOCGWINSZ = sub { return 0x5413 } }
unless (defined &TIOCGWINSZ) {
die "Term::ReadKey not found, and ioctl 'workaround' failed. Install the Term::ReadKey perl module to use screen mode.\n";
}
open(TTY, "+<","/dev/tty") or die "No tty: $!";
unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
die "Term::ReadKey not found, and ioctl 'workaround' failed ($!). Install the Term::ReadKey perl module to use screen mode.\n";
}
close(TTY);
($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
}
# set screen width
$irssi_width = $col-$nicklist_width-1;
$height = $row-1;
system 'screen -x '.$ENV{'STY'}.' -X width -w ' . $irssi_width;
# wait another second for the resizing, and then redraw.
Irssi::timeout_add_once(1000,sub {$screen_resizing = 0; redraw()}, []);
}
sub sig_terminal_resized {
if ($screen_resizing) {
return;
}
$screen_resizing = 1;
Irssi::timeout_add_once(1000,\&screen_size,[]);
}
### both ###
sub nicklist_write_start {
if ($mode == $SCREEN) {
print STDERR "\033P\0337\033\\"; # save cursor
}
}
sub nicklist_write_end {
if ($mode == $SCREEN) {
print STDERR "\033P\0338\033\\"; # restore cursor
}
}
sub nicklist_write_line {
my ($line, $data) = @_;
if ($mode == $SCREEN) {
print STDERR "\033P\033[" . ($line+1) . ';'. ($irssi_width+1) .'H'. $screen_prefix . $data . "\033\\";
} elsif ($mode == $FIFO) {
$data = "\033[m$data"; # reset color
if ($line == $cursor_line+1) {
$data = "\n$data"; # next line
} elsif ($line == $cursor_line) {
$data = "\033[1G".$data; # back to beginning of line
} else {
$data = "\033[".($line+1).";0H".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
}
}
sub calc_prefix_friends {
my ($nick) = @_;
return '' unless $check_friends
&& $nick->{'host'}
&& is_friend($active_channel->{'server'}->{'chatnet'}, $active_channel->{'name'}, $nick->{'nick'}, $nick->{'host'});
my $flags = get_flags($active_channel->{'server'}->{'chatnet'}, $active_channel->{'name'}, $nick->{'nick'}, $nick->{'host'});
my $prefix;
foreach my $prefix_friend (@prefix_friends) {
if ($prefix_friend->{'flags'} eq 'noflag') {
if ($flags eq '') {
$prefix = $prefix_friend->{'prefix'};
last;
}
} elsif (check_modes($flags, $prefix_friend->{'flags'})) {
$prefix = $prefix_friend->{'prefix'};
}
}
return $prefix ? $prefix : '';
}
# recalc the text of the nicklist item
sub calc_text {
my ($nick) = @_;
my $tmp = $nicklist_width-3;
(my $text = $nick->{'nick'}) =~ s/^(.{$tmp})..+$/$1\033[34m~/; # strip nick if too long
my $prefix_mode = $prefix_mode{$nick->{'modeflag'}};
if (! defined($prefix_mode) ) {
$prefix_mode = $nick->{'modeflag'};
}
my $prefix_friends = calc_prefix_friends($nick);
$nick->{'text'} =
$prefix_mode .
$prefix_friends .
$text .
(' ' x ($nicklist_width-length($nick->{'nick'})-1)) .
"\033[m"; # reset
$nick->{'cmp'} = $nick->{'modepos'}.lc($nick->{'nick'});
}
# redraw the given nick (nr) if it is visible
sub redraw_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line >= 0 && $line < $height) {
nicklist_write_line($line, $nicklist[$nr]->{'text'});
}
}
# nick was inserted, redraw area if necessary
sub draw_insert_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line < 0) { # nick is inserted above visible area
$scroll_pos++; # 'scroll' down :)
} elsif ($line < $height) { # line is visible
if ($mode == $SCREEN) {
need_redraw();
} elsif ($mode == $FIFO) {
my $data = "\033[m\033[L". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
if ($line == $cursor_line) {
$data = "\033[1G".$data; # back to beginning of line
} else {
$data = "\033[".($line+1).";1H".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
if ($prev_lines < $height) {
$prev_lines++; # the nicklist has one line more
}
}
}
}
sub draw_remove_nick_nr {
my ($nr) = @_;
my $line = $nr - $scroll_pos;
if ($line < 0) { # nick removed above visible area
$scroll_pos--; # 'scroll' up :)
} elsif ($line < $height) { # line is visible
if ($mode == $SCREEN) {
need_redraw();
} elsif ($mode == $FIFO) {
#my $data = "\033[m\033[L[i$line]". $nicklist[$nr]->{'text'}; # reset color & insert line & write nick
my $data = "\033[M"; # delete line
if ($line != $cursor_line) {
$data = "\033[".($line+1)."d".$data; # jump
}
$cursor_line=$line;
print(FIFO $data) or fifo_stop();
if (@nicklist-$scroll_pos >= $height) {
redraw_nick_nr($scroll_pos+$height-1);
}
}
}
}
# redraw the whole nicklist
sub redraw {
$need_redraw = 0;
#make_nicklist();
nicklist_write_start();
my $line = 0;
### draw nicklist ###
for (my $i=$scroll_pos;$line < $height && $i < @nicklist; $i++) {
nicklist_write_line($line++, $nicklist[$i]->{'text'});
}
### clean up other lines ###
my $real_lines = $line;
while($line < $prev_lines) {
nicklist_write_line($line++,' ' x $nicklist_width);
}
$prev_lines = $real_lines;
nicklist_write_end();
}
# redraw (with little delay to avoid redrawing to much)
sub need_redraw {
if(!$need_redraw) {
$need_redraw = 1;
Irssi::timeout_add_once(10,\&redraw,[]);
}
}
sub sig_page_scrolled {
$prev_lines = $height; # we'll need to redraw everything if he scrolled up
need_redraw;
}
# redraw (with delay) if the window is visible (only in screen mode)
sub sig_gui_print_text_finished {
if ($need_redraw) { # there's already a redraw 'queued'
return;
}
my $window = @_[0];
if ($window->{'refnum'} == Irssi::active_win->{'refnum'} || Irssi::settings_get_str('nicklist_screen_split_windows') eq '*') {
need_redraw;
return;
}
foreach my $win (split(/[ ,]/, Irssi::settings_get_str('nicklist_screen_split_windows'))) {
if ($window->{'refnum'} == $win || $window->{'name'} eq $win) {
need_redraw;
return;
}
}
}
###################
##### FRIENDS #####
###################
# checks if $has_modes is in $need_modes, copied from trigger.pl
sub check_modes {
my ($has_modes, $need_modes) = @_;
my $matches;
my $switch = 1; # if a '-' if found, will be 0 (meaning the modes should not be set)
foreach my $need_mode (split /&/,$need_modes) {
$matches = 0;
foreach my $char (split //,$need_mode) {
if ($char eq '-') {
$switch = 0;
} elsif ($char eq '+') {
$switch = 1;
} elsif ((index($has_modes,$char) != -1) == $switch) {
$matches = 1;
last;
}
}
if (!$matches) {
return 0;
}
}
return 1;
}
# get someones flags from people.pl or friends(_shasta).pl, copied from trigger.pl
sub get_flags {
my ($chatnet, $channel, $nick, $address) = @_;
my $flags;
no strict 'refs';
if (%{ 'Irssi::Script::people::' }) {
if (defined ($channel)) {
$flags = (&{ 'Irssi::Script::people::find_local_flags' }($chatnet,$channel,$nick,$address));
} else {
$flags = (&{ 'Irssi::Script::people::find_global_flags' }($chatnet,$nick,$address));
}
$flags = join('',keys(%{$flags}));
} else {
my $shasta;
if (%{ 'Irssi::Script::friends_shasta::' }) {
$shasta = 'friends_shasta';
} elsif (defined &{ 'Irssi::Script::friends::get_idx' }) {
$shasta = 'friends';
}
if (!$shasta) {
return undef;
}
my $idx = (&{ 'Irssi::Script::'.$shasta.'::get_idx' }($nick,$address));
if ($idx == -1) {
return '';
}
$flags = (&{ 'Irssi::Script::'.$shasta.'::get_friends_flags' }($idx,undef));
if ($channel) {
$flags .= (&{ 'Irssi::Script::'.$shasta.'::get_friends_flags' }($idx,$channel));
}
}
return $flags;
}
sub is_friend {
my ($chatnet, $channel, $nick, $address) = @_;
no strict 'refs';
if (%{ 'Irssi::Script::people::' }) {
return (() != &{'Irssi::Script::people::find_users'}($chatnet, $nick, $address));
my $flags;
if (defined ($channel)) {
$flags = (&{ 'Irssi::Script::people::find_local_flags' }($chatnet,$channel,$nick,$address));
} else {
$flags = (&{ 'Irssi::Script::people::find_global_flags' }($chatnet,$nick,$address));
}
return ($flags ne ''); # TODO: test this
} else {
my $shasta;
if (%{ 'Irssi::Script::friends_shasta::' }) {
$shasta = 'friends_shasta';
} elsif (defined &{ 'Irssi::Script::friends::get_idx' }) {
$shasta = 'friends';
}
if (!$shasta) {
return undef;
}
my $idx = (&{ 'Irssi::Script::'.$shasta.'::get_idx' }($nick,$address));
return ($idx != -1);
}
}
####################
##### NICKLIST #####
####################
# returns the position of the given nick(as string) in the (internal) nicklist
sub find_nick {
my ($nick) = @_;
for (my $i=0;$i < @nicklist; $i++) {
if ($nicklist[$i]->{'nick'} eq $nick) {
return $i;
}
}
return -1;
}
# find position where nick should be inserted into the list
sub find_insert_pos {
my ($cmp)= @_;
for (my $i=0;$i < @nicklist; $i++) {
if ($nicklist[$i]->{'cmp'} gt $cmp) {
return $i;
}
}
return scalar(@nicklist); #last
}
# make the (internal) nicklist (@nicklist)
sub make_nicklist {
@nicklist = ();
$scroll_pos = 0;
### get & check channel ###
my $channel = Irssi::active_win->{active};
if (!$channel || (ref($channel) ne 'Irssi::Irc::Channel' && ref($channel) ne 'Irssi::Silc::Channel' && ref($channel) ne 'Irssi::Xmpp::Channel') || $channel->{'type'} ne 'CHANNEL' || ($channel->{chat_type} ne 'SILC' && !$channel->{'names_got'}) ) {
$active_channel = undef;
# no nicklist
} else {
$active_channel = $channel;
### make nicklist ###
foreach my $nick ($channel->nicks()) {
my $thisnick = {'nick' => $nick->{'nick'}};
recalc_nick($thisnick, $nick);
push @nicklist, $thisnick;
}
@nicklist = sort {$a->{'cmp'} cmp $b->{'cmp'}} @nicklist;
}
need_redraw();
}
# insert nick(as hash) into nicklist
# pre: cmp has to be calculated
sub insert_nick {
my ($nick) = @_;
my $nr = find_insert_pos($nick->{'cmp'});
splice @nicklist, $nr, 0, $nick;
draw_insert_nick_nr($nr);
}
# remove nick(as nr) from nicklist
sub remove_nick {
my ($nr) = @_;
splice @nicklist, $nr, 1;
draw_remove_nick_nr($nr);
}
# update the mode and cmp of a nick, based on a nickrec from irssi
sub recalc_nick {
my ($nick, $nickrec) = @_;
if (! $nickrec) {
$nickrec = $active_channel->nick_find($nick->{'nick'});
}
my $nickflags = $active_channel->{'server'}->get_nick_flags() . ' ';
my $flag = (
$nickrec->{'op'} ? '@' :
$nickrec->{'halfop'} ? '%' :
$nickrec->{'voice'} ? '+' :
' '
);
if ($nickrec->{'other'} && index($nickflags, $nick->{'other'}) < index($nickflags, $flag)) {
$flag = chr($nickrec->{'other'});
}
$nick->{'modepos'} = index($nickflags, $flag);
$nick->{'modeflag'} = $flag;
$nick->{'host'} = $nickrec->{'host'};
calc_text($nick);
}
###################
##### ACTIONS #####
###################
# scroll the nicklist, arg = number of lines to scroll, positive = down, negative = up
sub cmd_scroll {
my $channel = Irssi::active_win->{active};
if (!$channel || !$channel->can('nicks')) { # active window is not a channel
return;
}
my @nicks = $channel->nicks;
my $nick_count = scalar(@nicks)+0;
if (!$active_channel) { # not a channel active
return;
}
if (!$channel || $channel->{type} ne 'CHANNEL' || !$channel->{names_got} || $nick_count <= $height) {
return;
}
if ($nick_count <= Irssi::settings_get_int('nicklist_height')) {
return;
}
$scroll_pos += @_[0];
if ($scroll_pos > $nick_count - $height) {
$scroll_pos = $nick_count - $height;
}
if ($scroll_pos <= 0) {
$scroll_pos = 0;
}
need_redraw();
}
sub is_active_channel {
my ($server,$channel) = @_; # (channel as string)
return ($server && $server->{'tag'} eq $active_channel->{'server'}->{'tag'} && $server->channel_find($channel) && $active_channel && $server->channel_find($channel)->{'name'} eq $active_channel->{'name'});
}
sub sig_channel_wholist { # this is actualy a little late, when the names are received would be better
my ($channel) = @_;
if (Irssi::active_win->{'active'} && Irssi::active_win->{'active'}->{'name'} eq $channel->{'name'}) { # the channel joined is active
make_nicklist
}
}
sub sig_join {
my ($server,$channel,$nick,$address) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $newnick = {'nick' => $nick};
recalc_nick($newnick);
insert_nick($newnick);
}
sub sig_kick {
my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $nr = find_nick($nick);
if ($nr == -1) {
Irssi::print("nicklist warning: $nick was kicked from $channel, but not found in nicklist");
} else {
remove_nick($nr);
}
}
sub sig_part {
my ($server,$channel,$nick,$address, $reason) = @_;
if (!is_active_channel($server,$channel)) {
return;
}
my $nr = find_nick($nick);
if ($nr == -1) {
Irssi::print("nicklist warning: $nick has parted $channel, but was not found in nicklist");
} else {
remove_nick($nr);
}
}
sub sig_quit {
my ($server,$nick,$address, $reason) = @_;
if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
return;
}
my $nr = find_nick($nick);
if ($nr != -1) {
remove_nick($nr);
}
}
sub sig_nick {
my ($server, $newnick, $oldnick, $address) = @_;
if ($server->{'tag'} ne $active_channel->{'server'}->{'tag'}) {
return;
}
my $nr = find_nick($oldnick);
if ($nr != -1) { # if nick was found (nickchange is in current channel)
my $nick = $nicklist[$nr];
remove_nick($nr);
$nick->{'nick'} = $newnick;
calc_text($nick);
insert_nick($nick);
}
}
sub sig_mode {
my ($channel, $nick, $setby, $mode, $type) = @_; # (nick and channel as rec)
if ($channel->{'server'}->{'tag'} ne $active_channel->{'server'}->{'tag'} || $channel->{'name'} ne $active_channel->{'name'}) {
return;
}
my $nr = find_nick($nick->{'nick'});
if ($nr == -1) {
Irssi::print("nicklist warning: $nick->{'nick'} had mode set on $channel->{'name'}, but was not found in nicklist");
} else {
my $nicklist_item = $nicklist[$nr];
remove_nick($nr);
recalc_nick($nicklist_item, $nick);
insert_nick($nicklist_item);
}
}
##### command binds #####
Irssi::command_bind 'nicklist' => sub {
my ( $data, $server, $item ) = @_;
$data =~ s/\s+$//g;
Irssi::command_runsub ('nicklist', $data, $server, $item ) ;
};
Irssi::signal_add_first 'default command nicklist' => sub {
# gets triggered if called with unknown subcommand
cmd_help();
};
Irssi::command_bind('nicklist update',\&update);
Irssi::command_bind('nicklist help',\&cmd_help);
Irssi::command_bind('nicklist scroll',\&cmd_scroll);
Irssi::command_bind('nicklist fifo',\&cmd_fifo_start);
Irssi::command_bind('nicklist screen',\&cmd_screen_start);
Irssi::command_bind('nicklist screensize',\&screen_size);
Irssi::command_bind('nicklist on',\&cmd_on);
Irssi::command_bind('nicklist off',\&cmd_off);
Irssi::command_bind('nicklist toggle',\&cmd_toggle);
##### signals #####
Irssi::signal_add_last('window item changed', \&make_nicklist);
Irssi::signal_add_last('window changed', \&make_nicklist);
Irssi::signal_add_last('channel wholist', \&sig_channel_wholist);
Irssi::signal_add_first('message join', \&sig_join); # first, to be before ignores
Irssi::signal_add_first('message part', \&sig_part);
Irssi::signal_add_first('message kick', \&sig_kick);
Irssi::signal_add_first('message quit', \&sig_quit);
Irssi::signal_add_first('message nick', \&sig_nick);
Irssi::signal_add_first('message own_nick', \&sig_nick);
Irssi::signal_add_first('nick mode changed', \&sig_mode);
Irssi::signal_add('setup changed', \&read_settings);
##### settings #####
Irssi::settings_add_str('nicklist', 'nicklist_screen_prefix', '\e[m ');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_op', '\e[32m@\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_halfop', '\e[34m%\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_voice', '\e[33m+\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_normal', ' ');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_mode_other', '&=\e[31m&\e[39m ~=\e[35m~\e[39m');
Irssi::settings_add_str('nicklist', 'nicklist_prefix_friends', 'o=\e[32m v=\e[33m noflag=\e[1m');
Irssi::settings_add_int('nicklist', 'nicklist_width',11);
Irssi::settings_add_int('nicklist', 'nicklist_height',24);
Irssi::settings_add_str('nicklist', 'nicklist_fifo_path', Irssi::get_irssi_dir . '/nicklistfifo');
Irssi::settings_add_str('nicklist', 'nicklist_screen_split_windows', '');
Irssi::settings_add_str('nicklist', 'nicklist_automode', '');
read_settings();
cmd_on();

524
home/.irssi/termi.theme Normal file
View File

@@ -0,0 +1,524 @@
# vim: set expandtab:
# vim: filetype=perl
# (Adapted from solarized-universal theme by Huy Z: https://github.com/huyz/irssi-colors-solarized)
# Adaped by: Paul Saunders https://github.com/darac/irssi-powerline
# later adapted by: terminaldweller(https://terminaldweller.com)
# When testing changes, the easiest way to reload the theme is with /RELOAD.
# This reloads the configuration file too, so if you did any changes remember
# to /SAVE it first. Remember also that /SAVE overwrites the theme file with
# old data so keep backups.
# TEMPLATES:
# The real text formats that irssi uses are the ones you can find with
# /FORMAT command. Back in the old days all the colors and texts were mixed
# up in those formats, and it was really hard to change the colors since you
# might have had to change them in tens of different places. So, then came
# this templating system.
# Now the /FORMATs don't have any colors in them, and they also have very
# little other styling. Most of the stuff you need to change is in this
# theme file. If you can't change something here, you can always go back
# to change the /FORMATs directly, they're also saved in these .theme files.
# So .. the templates. They're those {blahblah} parts you see all over the
# /FORMATs and here. Their usage is simply {name parameter1 parameter2}.
# When irssi sees this kind of text, it goes to find "name" from abstracts
# block below and sets "parameter1" into $0 and "parameter2" into $1 (you
# can have more parameters of course). Templates can have subtemplates.
# Here's a small example:
# /FORMAT format hello {colorify {underline world}}
# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; }
# When irssi expands the templates in "format", the final string would be:
# hello %G%Uworld%U%n
# ie. underlined bright green "world" text.
# and why "$0-", why not "$0"? $0 would only mean the first parameter,
# $0- means all the parameters. With {underline hello world} you'd really
# want to underline both of the words, not just the hello (and world would
# actually be removed entirely).
# COLORS:
# You can find definitions for the color format codes in docs/formats.txt.
# There's one difference here though. %n format. Normally it means the
# default color of the terminal (white mostly), but here it means the
# "reset color back to the one it was in higher template". For example
# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would
# print yellow "foo" (as set with %Y) but "bar" would be green, which was
# set at the beginning before the {foo} template. If there wasn't the %g
# at start, the normal behaviour of %n would occur. If you _really_ want
# to use the terminal's default color, use %N.
#############################################################################
# https://irssi.org/documentation/settings/#a_d
# default foreground color (%N) - -1 is the "default terminal color"
default_color = "-1";
# print timestamp/servertag at the end of line, not at beginning
info_eol = "false";
# these characters are automatically replaced with specified color
# (dark grey by default)
replaces = { "[]=" = "%Z0087ff$*%n"; };
abstracts = {
##
## generic
##
# text to insert at the beginning of each non-message line
# %N = terminal default (e.g. white on transparent)
# %G = brightgreen (Solarized: base01, i.e. darkest gray)
#line_start = "%N%W %N";
line_start = "%N";
# timestamp styling, nothing by default
# %N%8 = reverse normal (to match line_start)
timestamp = "%N%k%z005f87$*%N%Z005f87%n";
# any kind of text that needs hilighting, default is to bold
hilight = "$*";
# any kind of error message
error = "%Zff8700$*%n";
# channel name is printed
channel = "%Z00af00$*%n";
# nick is printed
# nick = "%z005f87%Zeeeeee{nickcolor $*}";
nick = "%Zeeeeee{nickcolor $*}";
mynick = "%Zeeeeee{nickcolor $*}";
inick = "%Zeeeeee{nickcolor $*}";
# Inverted
imynick = "%Zeeeeee{nickcolor $*}";
# Inverted
# nick host is printed
# (that's the "email" address of a user)
nickhost = "%Z005f5f$*";
# server name is printed
server = "%Z00af00$*";
iserver = "%Zeeeeee%z00af00$*%n";
# some kind of comment is printed
comment = "%Zff8700  %N $*";
# reason for something is printed (part, quit, kick, ..)
reason = "$*";
# mode change is printed ([+o nick])
mode = "%N%0%p$*%n";
##
## channel specific messages
##
# highlighted nick/host is printed (joins)
# %c = cyan (Solarized: cyan)
# %G = brightgreen (Solarized: base01)
# NOTE: %n doesn't work in irssi v0.8.15 for some reason. So we have to end with the same color as line_start
channick_hilight = "%Z00af00$*%G";
chanhost_hilight = "%Z00af00{nickhost $*}%N";
# nick/host is printed (parts, quits, etc.)
channick = "%Z00af00$*%G";
chanhost = "%Z00af5f{nickhost $*}%N";
# highlighted channel name is printed
# SOLARIZED: Channels are Green
channelhilight = "%N%0%g$*%N";
ichannelhilight = "%z005f87$*%n%0";
# ban/ban exception/invite list mask is printed
# %R = brightred (Solarized: orange)
# %n = return
ban = "%zff5f00$*%0%Zff5f00%n";
##
## messages
##
# the basic styling of how to print message, $0 = nick mode, $1 = nick
msgnick = "%Z005f00%Zeeeeee{nick $0$1-}%N%Z005f00%0%Z005f5f";
# message from you is printed. "msgownnick" specifies the styling of the
# nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the
# whole line.
# Example1: You want the message text to be green:
# ownmsgnick = "{msgnick $0 $1-}%g";
# Example2.1: You want < and > chars to be yellow:
# ownmsgnick = "%Y{msgnick $0 $1-%Y}%n";
# (you'll also have to remove <> from replaces list above)
# Example2.2: But you still want to keep <> grey for other messages:
# pubmsgnick = "%K{msgnick $0 $1-%K}%n";
# pubmsgmenick = "%K{msgnick $0 $1-%K}%n";
# pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n";
# ownprivmsgnick = "%K{msgnick $*%K}%n";
# privmsgnick = "%K{msgnick %R$*%K}%n";
# $0 = nick mode, $1 = nick
# %3 = yellow
# ownmsgnick = "%z5f5fff%k{%z5f5fff $0$1-}%N%0%Z5f5fff %Z005f5f";
ownmsgnick = "%z005f5f%k%Zeeeeee%k$chatnet%Z005f5f%z5f8787%k$C%z5f5fff%Z5f8787%Zeeeeee%9{%Zeeeeee%z5f5fffmsgnick $0$1-}%N%Z5f5fff%z5f8787%Z5f8787%z005f5f%Z005f5f%0%N %Z005f5f";
ownnick = "%Zeeeeee$* %Z005f5f";
# public message in channel, $0 = nick mode, $1 = nick
pubmsgnick = "%z005f5f%k%Zeeeeee%k$chatnet%Z005f5f%z5f8787%k$C%z005f87%Z5f8787%Zeeeeee{%Zeeeeee%z005f87msgnick $0$1-}%N%Z005f87%z5f8787%Z5f8787%z005f5f%Z005f5f%0%N %Z005f5f";
pubnick = "%Zeeeeee$* %Z005f5f";
# public message in channel meant for me, $0 = nick mode, $1 = nick
# %5 = magenta
# pubmsgmenick = "%Z005f00%z005f00%k$chatnet$C{msgnick $0$1-}%N%Z005f00 %Z005f5f";
pubmsgmenick = "%z005f5f%k%Zeeeeee%k$chatnet%Z005f5f%z5f8787%k$C%z005f00%Z5f8787%Zeeeeee%9$0$1%Z005f00%z5f8787%N%Z5f8787%z005f5f%Z005f5f%0%N %Z005f5f";
menick = "%Zeeeeee$* %Z005f5f";
# public highlighted message in channel
# $0 = highlight color, $1 = nick mode, $2 = nick
# pubmsghinick = " %z005f87%k%z005f87$chatnet/$C/{%Zeeeeee%z005f87msgnick$1 %Zeeeeee$2-}%N%Z005f87 %Z005f5f";
pubmsghinick = " %z005f5f%k%Zeeeeee%k$chatnet%Z005f5f%z5f8787%k$C%z005f87%Z5f8787%Zeeeeee{%Zeeeeee%z005f87msgnick $0$1 %Zeeeeee$2-}%N%Z005f87%z5f8787%Z5f8787%z005f5f%Z005f5f%0%N %Z005f5f";
# channel name is printed with message
# This is printed whenever the channel name is printed for disambiguation, e.g.
# while there is a query in the same window. Example: <+funnyuser:#test> hello
msgchannel = "%z005f5f%k:$*%n";
# private message, $0 = nick, $1 = host
# TODO: To test for Solarized
privmsg = " %Z005f00$0%G<%n$1-%G>%n %Z005f87";
# private message from you, $0 = "msg", $1 = target nick
# TODO: To test for Solarized
ownprivmsg = " %Z005f87$0%G<%Z005f87$1-%G>%n %Z005f87";
# own private message in query
ownprivmsgnick = "%z5f5fff%k{%z5f5fff $*}%N%Z5f5fff %Z005f87";
ownprivnick = "%k$*";
# private message in query
# NOTE: for some reason, we gotta handle both the nick & msg on in this line
# privmsgnick = "%5%k{ %5%k msgnick %m%0%N $*}%N%m %n";
privmsgnick = "%z005f00%k{%z005f00%k %z005f00%k $*}%N%Z005f00 %n %Z005f87";
##
## Actions (/ME stuff)
##
# used internally by this theme
action_core = "%N%k%z5f8787 %9$*%Z5f8787";
# generic one that's used by most actions
action = "{action_core $*%n} ";
# own action, both private/public
ownaction = "%N%k%z5f8787 %9{mynick $0}%N%Z5f8787%N$1-";
# own action with target, both private/public
# NOTE: to test: /action NICK farted. (This will tell NICK that you farted)
# This is like a /me but only you and NICK will see
ownaction_target = "{action_core $0}%G:%y$1%n ";
# private action sent by others
# %M = brightmagenta (Solarized: violet)
pvtaction = "%Z5f875f (*) $*%N ";
pvtaction_query = "{action $*}";
# public action sent by others
pubaction = "%N%Z5f875f {nick $0}%N%Z5f875f $1-";
##
## other IRC events
##
# whois
whois = "%k%z005f87WHOIS %0%Z005f87%N%#%N $[8]0  %Y$1-";
# notices
ownnotice = "%z5f87af%k %k$0 %k%z5f87af%8%0%9 {ichannelhilight $1-} %k%Z00af5f ";
notice = "%z5f87af%k %k$0- %Z5f87af%0%N ";
# notice = "%1%w %W$* %k%8%n ";
# pubnotice_channel = "{ichannelhighlight $*}";
pubnotice_channel = "%G%n$*";
# the typo is intentional
pvtnotice_host = " %k%n %9{hickhost $*} ";
servernotice = "%z5f87af%k %9%k!$* %k%8%n ";
# CTCPs
ownctcp = "%k%z005f87 %k$0%G %N%Z005f87 %Z005f87$1-%G  ";
ctcp = "%N%k%z5f5f00%Z5f5f00%0%n %Zeeeeee$*%z5f5f00%k%Z5f5f00%0%n";
# wallops
wallop = "%k%4%9 $*%0%b%N ";
wallop_nick = "%z00afff%b%9%k$* %4%Z00afff ";
wallop_action = "%Z005f00%Z00afff * $*%N ";
# netsplits
netsplit = "%z5f5fd7$*%n";
netjoin = "%g$*%n";
# /names list
names_prefix = "%N%k%n";
names_nick = " %G$0$1-%N  ";
names_nick_op = " %g$0$_$1-%n  ";
names_nick_halfop = " %Y$_$0$_$1-%n  ";
names_nick_voice = " %C$_$0$_$1-%n  ";
names_users = "%k%z005f87 $* %Z005f87%0%n";
names_channel = " %k$*";
# DCC
dcc = "%N%k%n %g$*%n";
dccfile = "$*";
# DCC chat, own msg/action
dccownmsg = "[[%Z005f87$0%G($1-%G)%n]] ";
dccownnick = "%Z005f87$*%n";
dccownquerynick = "%c$*%n";
dccownaction = "{action $*}";
dccownaction_target = "{action_core $0}%G:%c$1%n ";
# DCC chat, others
dccmsg = " %g$1-%G($0%G)%n ";
dccquerynick = "%g$*%n";
dccaction = "%c (*dcc*) $*%n %|";
##
## statusbar
##
# default background for all statusbars. You can also give
# the default foreground color for statusbar items.
# NOTE: if all the other overriding settings below are set, this only seems to affect
# the content parts of the adv_windowlist. Default seems to be blue
# NOTE: if not set, the default background seems to be %w%4 = white on blue
sb_background = "%k%z1c1c1c";
# default backround for "default" statusbar group
# NOTE: this impacts the statusbar of an inactive window and the edges of adv_windowlist
# %7 = white (wich looks gray on a regular terminal with white bg)
sb_default_bg = "%Z005fff";
# background for topicbar at the top (defaults to sb_default_bg)
sb_topic_bg = "%W%0";
# background for the statusbar of active window. You can also give
# the foreground color.
# %2 = green
sb_window_bg = "%k%0";
# background for prompt / input line
sb_prompt_bg = "%k";
# background for info statusbar
# %8 = reverse window
# TODO: To test for Solarized
sb_info_bg = "%z1c1c1c";
# text at the beginning of statusbars. sb-item already puts
# space there,so we don't use anything by default.
sbstart = "%z005f00";
# text at the end of statusbars. Use space so that it's never
# used for anything.
sbend = "%n";
topicsbstart = "{sbstart $*}";
topicsbend = "{sbend $*}";
prompt = "%k%z005f87%9$c $*%w%k$R%w%k$S%w%k$N%w%k$T %N%Z005f87%n ";
# This controls each part of a statusbar, including the outer brackets of adv_windowlist
sb = "$*";
# The mode is next to your NICK and the channel
sbmode = "%Z5f5fff$*%k";
sbaway = "%Z00af00%k%z00af00 zZzZzZzZ %Z00af00%0";
sbservertag = "%Z00af00 $0 %Z005f87(change with ^X)%n";
sbnickmode = "%Zeeeeee$0";
# activity in statusbar
# ',' separator between the window numbers
# %g = green (same color as the active statusbar so we dont' see it)
sb_act_sep = "%Z005fff%9/";
# sb_act_sep = "%Z005f00";
# normal text
# This also affects the color of the window with activity in adv_windowlist
sb_act_text = "%C$*";
# public message (ordinary messages)
sb_act_msg = "%c$*";
# hilight (when people actually chat)
# This also affects the color of the window with direct message in adv_windowlist
sb_act_hilight = "%N%Z5f5fff%9$*%N";
# hilight with specified color, $0 = color, $1 = text
sb_act_hilight_color = "%N$0$1-%N";
# For usercount.pl script
sb_usercount = "%Z000000%z005faf%Z000000%z005faf{sb $0 nicks %Zeeeeee %Z000000$1-%Z005faf%z000000}%N";
sb_uc_ircops = "%Z000000%z005faf*$*";
sb_uc_ops = "%Z000000%z005faf@$*";
sb_uc_halfops = "%Z000000%z005faf%%$*";
sb_uc_voices = "%Z000000%z005faf+$*";
sb_uc_normal = "$*";
sb_uc_space = " ";
# For adv_windowlist.pl script
# Mentioned in adv_windowlist but not default_theme
sb_act_none = "%K$*";
# for dcc stats
# $0 = sb_ds_short(_waiting)/sb_ds_normal(_waiting)
sb_dccstat = "{sb $0-}";
# $0 = G/S
# $1 = filename
# $2 = transfer speed
# $3 = percent
# $4 = progressbar
sb_ds_short = "$0%G:%n$1%Y@%n$2kB/s%G:%n$4%G:%n$3";
# $0 = G/S
# $1 = filename
# $2 = to/from
# $3 = nick
sb_ds_short_waiting = "$0%G:%n$1 $2 $3 waiting";
# $0 = GET/SEND
# $1 = nick
# $2 = filename
# $3 = transferred amount
# $4 = full filesize
# $5 = percent
# $6 = speed
# $7 = ETA
# $8 = progressbar
# $9 = rotator thingy :)
sb_ds_normal = "$0 $1: '$2' $3 of $4 [$8] $9 ($5) $6kB/s ETA: $7";
# $0 = GET/SEND
# $1 = nick
# $2 = filename
# $3 = full filesize
# $4 = to/from
# $5 = nick
sb_ds_normal_waiting = "$0 $1: '$2' $3 $4 $5 waiting";
sb_ds_separator = "  ";
};
formats = {
"fe-text" = {
lastlog_start = "%Zaf5f5f%zaf5f5f%k%9Lastlog%9%Zaf5f5f%0";
lastlog_end = "%Zaf5f5f%0%zaf5f5f%k%9Lastlog%9%0%Zaf5f5f";
lastlog_separator = "%Zaf5f5f%zaf5f5f%k%Zaf5f5f%0";
lastlog_date = "%g<<%%F>> ";
};
"fe-common/core" = {
daychange = " %Zd7ff5f%0%zd7ff5f%k%Zd7ff5f%0%k%zd7ff5f %9 Day changed to %%D %9 %Zd7ff5f%0%zd7ff5f%k%Zd7ff5f%0";
join = "%k%z00af5fJOIN %8 {ichannelhilight $2} %0%Z00d700%0 {inick $0}%0 %N {chanhost_hilight $1}";
line_start_irssi = "%k%z5f5fd7IRSSI%N%Z5f5fd7 %N";
new_topic = "%k%z00afffTOPIC %8 {ichannelhilight $1} %wby {inick $0} %N%9%Z5f5fd7  $2";
nick_changed = "%k%z00d700RENAME %Z00d700%0 %k%z005f87{nick $0} %Zff8700 {nick $1}%Z005f87%0%N";
part = "%K%Z00d700%k%z00d700PART %8 {ichannelhilight $2}%N %0%Z005f87 %N{inick $0}%0 %Z005f87%Zeeeeee {reason $3}";
quit = "%0%Z005f00%k%z005f00QUIT %N {inick $0}%0%Z005f87 %N%n%k%N {reason $2}";
your_nick_changed = "%k%z00d700RENAME %Z00d700%0 %k%z005f87{mynick $0} %Zff8700 {mynick $1}%Z005f87%0%N";
own_msg = "$nickcolor$nickalign{ownmsgnick $2 {ownnick $[.15]0}}$1";
own_msg_channel = "$nickcolor$nickalign{ownmsgnick $3 {ownnick $[.15]0}{msgchannel $1}}$2";
own_msg_private_query = "$nickcolor$nickalign{ownprivmsgnick {ownprivnick $2}}$1";
pubmsg_me = "$nickalign{pubmsgmenick $2 {menick $[.15]0}}$1";
pubmsg_me_channel = "$nickalign{pubmsgmenick $3 {menick $[.15]0}{msgchannel $1}}$2";
pubmsg_hilight = "$nickalign{pubmsghinick $0 $3 $[.15]1}$2";
pubmsg_hilight_channel = "$nickalign{pubmsghinick $0 $4 $[.15]1{msgchannel $2}}$3";
pubmsg = "{pubmsgnick $2 {pubnick \00309$[0]0}}$1";
pubmsg_channel = "$nickcolor$nickalign{pubmsgnick $3 {pubnick $[.15]0}{msgchannel $1}}$2";
msg_private_query = "$nickcolor$nickalign{privmsgnick $0}$2";
servertag = "%k%z008787%9$0%0%Z008787%N ";
tls_ephemeral_key = "EDH Key:%Z5f87ff {hilight $0} bit {hilight $1}";
tls_ephemeral_key_unavailable = "EDH Key: %Z5f87ff{error N/A}";
tls_pubkey = "Public Key: %Z5f87ff{hilight $0} bit {hilight $1}, valid from {hilight $2} to {hilight $3}";
tls_cert_header = "Certificate Chain:";
tls_cert_subject = " Subject: %Z5f87ff{hilight $0}";
tls_cert_issuer = " Issuer: %Z5f87ff {hilight $0}";
tls_pubkey_fingerprint = "Public Key Fingerprint: %Z5f87ff {hilight $0} ({hilight $1})";
tls_cert_fingerprint = "Certificate Fingerprint: %Z5f87ff{hilight $0} ({hilight $1})";
tls_protocol_version = "Protocol: %Z5f87ff{hilight $0} ({hilight $1} bit, {hilight $2})";
};
"fe-common/irc" = {
away = "%k%z00d700AWAY %Z00d700%0%N";
banlist = "%k%z005f00BANS %z005f00 $[-3]0 %8 %z005f00{ichannelhilight $1} %k%N {ban $2}";
banlist_long = "%k%z005f00BANS %z005f00 $[-3]0 %8 %z005f00{ichannelhilight $1} {comment by {inick $3}%0%k,%Z005f00 $4 secs ago} %N {ban $2}";
chanmode_change = "%k%z00af87MODE %N%Z00af87%N {channelhilight $0} %Zeeeeee%n {mode $1}%n by {nick $2}";
channel_created = "%k%N Channel {channelhilight $0} created $1";
channel_mode = "%k%N mode/{channelhilight $0} {mode $1}";
ctcp_default_reply = "%W%0%N $0- ";
ctcp_ping_reply = "%k%z005f87 CTCP {hilight PING} reply %n%Z005f87%N {nick $0} %y%N%n $1.$[-3.0]2 seconds ";
ctcp_reply = "%k%z005f87 CTCP {hilight $0} reply %n%Z005f87%N {nick $1} %y%N $2 ";
ctcp_reply_channel = "%k%z005f87 CTCP {hilight $0} reply %n%Z005f87%N {nick $1} %y%N {channel $3} %y%N $2";
ctcp_requested = "%k%z005f87%8%8 CTCP {hilight $2} from {mynick $4} %n%Z005f87%N by {hilight $0} {comment $1} %y%N $3";
default_event = "%N%k %N%n$1";
default_event_server = "%k%z00d700$0 %N%k %N%n$1";
ebanlist = "%k%z005f00BANS %k exception %8 %z005f00{ichannelhilight $0} %N {ban $1}";
ebanlist_long = "%k%z005f00BANS %k exception %8 {ichannelhilight $0} %z005f00{comment by {inick $2}%0%k, $3 secs ago} %N {ban $1}";
end_of_who = "%z00d700%kWHO %Z00d700%0%N END";
end_of_whois = "%z00d700%kWHOIS %Z00d700%0%N END";
end_of_whowas = "%z00d700%kWHOWAS %Z00d700%0%N END";
netsplit = "%0%Z8787ff%z8787ff%k NETSPLIT %z8787ff%Z00af00%z00af00%k {iserver $0}  {iserver $1} %Z00af00%0%Z8787ff Quits: $2";
netsplit_join = "%k%z8787ff NETSPLIT %k%8%N Joins: $0";
netsplit_join_more = "%k%z8787ff NETSPLIT %k%8%N Joins: $0 (+$1 more)";
netsplit_more = "%0%Z8787ff%z8787ff%k NETSPLIT %z8787ff%Z00af00%z00af00%k {iserver $0}  {iserver $1} %Z00af00%0%Z8787ff Quits: $2 (+$3 more, use /NETSPLIT to show all of them)";
no_topic = "%k%N No topic set for {channelhilight $0}";
own_ctcp = "%k%z005f87 CTCP {hilight $2-}  {inick $0} %n%Z005f87%N";
server_chanmode_change = "%k%z8787ff SERVERMODE %k%8%N%g {channelhilight $0} %g {mode $1} by {nick $2}";
topic = "%k%z00d700TOPIC %Z00d700%0%N {channel $0}%N  $1";
topic_info = "%k%z00d700TOPIC %Z00d700%0%N {nick $0}%N {nickhost $2}  $1";
unaway = "%k%z00d700AWAY %Z00d700%0%N END";
usermode_change = "%k%z5fafd7%ZeeeeeeMODE %N%Z5fafd7%N {mode $0}%N for %0{mynick $1}%N";
who = "%z00d700%kWHO %Z00d700%z005f87 %z005f87%k{inick $[!9]1} %Z005f87%2 %k$0 %0%g Status: $[!3]2  $[-2]3 hops %N%g%N {nickhost $4@$5} {comment $6}";
whois = "%z00d700%kWHOIS %Z00d700%z005f87 {nick $0} %Z005f87%0 {nickhost $1@$2}%:{whois ircname $3}";
whowas = "%z00d700%kWHOWAS %Z00d700%z005f87 {nick $0} %Z005f87%0 {nickhost $1@$2}%:{whois was $3}";
own_action = "$nickalign{ownaction $0$nicktrunc}$1";
action_private = "$nickalign{pvtaction $[.15]0$nicktrunc}$2";
action_private_query = "$nickalign{pvtaction_query $[.15]0$nicktrunc}$2";
action_public = "$nickalign{pubaction $[.15]0$nicktrunc}$1";
notice_server = "{servernotice $0}$1";
notice_public = "{notice $0{pubnotice_channel $1}}$2";
notice_private = "{notice $0{pvtnotice_host $1}}%Z00af87$2%N";
};
"Irssi::Script::adv_windowlist" = {
awl_display_header = "";
awl_display_key = "%0%Z005fff$N  $H[$Q]$C$S %N";
awl_display_key_active = "%9%k%z005f00 $N $H[$Q]$C$S %N%Z005f00%N";
awl_display_key_visible = "%k%z005fff $N  $H[$Q]$C$S %N%Z005fff%N";
awl_display_nokey = "%0%Z005faf$N  $H[$Q]$C$S %N";
awl_display_nokey_active = "%9%k%z005f87 $N $H[$Q]$C$S %N%Z005f87%N";
awl_display_nokey_visible = "%k%z005fff $N  $H[$Q]$C$S %N%Z005fff%N";
awl_separator = "";
};
"Irssi::Script::usercount" = {
sb_usercount = "%9%z00af5f{sb $0 nicks ($1-)}";
sb_uc_ircops = "%9%z00d787*$*";
sb_uc_ops = "%9%z00d787@$*";
sb_uc_halfops = "%9%z00d787%%$*";
sb_uc_voices = "%9%z00af5f+$*";
sb_uc_normal = "$*";
sb_uc_space = " ";
};
"Irssi::Script::nm2" = {
neat_pad_char = " ";
neat_style = ",cpt,,,,,,,";
neat_custom_modes = "&%B&%n%Zeeeeee | @%g@%n%Zeeeeee | +%y+%n%Zeeeeee";
neat_truncate_char = "~";
neat_notruncate_char = "";
};
"Irssi::Script::mh_sbsplitmode" = {
mh_sbsplitmode_line = "%Zaf5f87{server $0}: $1 {comment $2}";
mh_sbsplitmode_line_no_detail = "%Zaf5f87{server $0}: %Zaf5f87 {error $1}";
mh_sbsplitmode_info = "%Zaf5f87{server $0} $1 {hilight splitmode}";
mh_sbsplitmode_info_details = "%Zaf5f87{server $0} $1 {hilight splitmode} {comment $2}";
mh_sbsplitmode_error = "%Zaf5f87{error $0}";
};
"otr/core" = {
otr_stb_plaintext = "{sb %yplaintext%N}";
otr_stb_finished = "{sb %yfinished%n}";
otr_stb_unknown = "{sb {hilight state unknown (BUG!)}}";
otr_stb_untrusted = "{sb %pOTR%n (%runverified%n)}";
otr_stb_trust = "{sb %GOTR%n}";
};
};