dotfiles

<-- duh.
Log | Files | Refs | LICENSE

commit c9bda683cd996f6d8fb8f3fddeb37cd414498606
parent d26a8018f60c72f00895e7436608d27272ea93fd
Author: hhvn <hayden@haydenvh.com>
Date:   Sat, 30 Jan 2021 14:57:49 +0000

.config/irssi/*: copy over config from server

Diffstat:
M.config/irssi/config | 482++++++++++++++++++++++++++++++-------------------------------------------------
A.config/irssi/default.theme | 833+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M.config/irssi/fctcplist | 6+++---
M.config/irssi/keepnick | 18++++++++++--------
A.config/irssi/log2ansi.pl | 412+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.config/irssi/modules/libtheme_indent.so | 0
M.config/irssi/pipeline.theme | 84+++++++++++++++++++++++++++++++++++++++++++------------------------------------
A.config/irssi/saved_nick_colors | 11679+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
D.config/irssi/scripts/README | 21---------------------
D.config/irssi/scripts/adv_windowlist.pl | 2954-------------------------------------------------------------------------------
D.config/irssi/scripts/ascii.pl | 405-------------------------------------------------------------------------------
D.config/irssi/scripts/autonickprefix.pl | 39---------------------------------------
M.config/irssi/scripts/autorun/adv_windowlist.pl | 2+-
M.config/irssi/scripts/autorun/nickcolor.pl | 17+++++++----------
M.config/irssi/scripts/autorun/nm2.pl | 77++++++++++++++++++++++++-----------------------------------------------------
D.config/irssi/scripts/cmdind.pl | 61-------------------------------------------------------------
D.config/irssi/scripts/ctcpspoof.pl | 277-------------------------------------------------------------------------------
D.config/irssi/scripts/dim_nicks.pl | 431-------------------------------------------------------------------------------
D.config/irssi/scripts/ls.pl | 51---------------------------------------------------
D.config/irssi/scripts/nickcolor.pl | 1123-------------------------------------------------------------------------------
D.config/irssi/scripts/nojointext.pl | 35-----------------------------------
D.config/irssi/scripts/tmux-nicklist-portable.pl | 432-------------------------------------------------------------------------------
D.config/irssi/scripts/tmux_away.pl | 202-------------------------------------------------------------------------------
D.config/irssi/scripts/trackbar.pl | 606-------------------------------------------------------------------------------
D.config/irssi/scripts/trigger.pl | 1257-------------------------------------------------------------------------------
D.config/irssi/scripts/uberprompt.pl | 774-------------------------------------------------------------------------------
D.config/irssi/scripts/vim_mode.pl | 3781-------------------------------------------------------------------------------
M.config/irssi/startup | 1+
M.config/irssi/triggers | 50++++++++++++++++++++++++++++++++++++++++++++++++++
29 files changed, 13249 insertions(+), 12861 deletions(-)

diff --git a/.config/irssi/config b/.config/irssi/config @@ -15,38 +15,39 @@ servers = ( chatnet = "hlircnet"; port = "6697"; use_tls = "yes"; - tls_verify = "yes"; - tls_capath = "/etc/ssl/certs"; + tls_verify = "no"; }, { address = "efnet.port80.se"; chatnet = "efnet"; port = "6667"; }, { address = "irc.sdf.org"; chatnet = "sdf"; port = "6667"; }, { address = "irc.unix.chat"; chatnet = "unix"; port = "6667"; }, { address = "irc.oscss.eu"; chatnet = "oscss"; port = "6667"; }, { - address = "irc.unrealircd.org"; - use_tls = "yes"; - tls_verify = "yes"; - chatnet = "unrealircd"; - port = "6697"; - }, - { - address = "irc.2f30.org"; + address = "irc.cyberia.is"; use_tls = "yes"; chatnet = "cyberia"; port = "6697"; }, - { - address = "irc.darkscience.net"; - chatnet = "darkscience"; - use_tls = "yes"; - port = "6697"; - }, { address = "genoce.org"; chatnet = "genoce"; port = "6667"; }, { address = "irc.dataswamp.org"; chatnet = "dataswamp"; port = "6697"; use_tls = "yes"; + }, + { + address = "localhost"; + chatnet = "bitlbee-matrix"; + port = "6667"; + use_tls = "no"; + tls_verify = "no"; + }, + { + address = "localhost"; + chatnet = "matrix.haydenvh.com"; + port = "15558"; + password = "W3YLmjluCiO"; + use_tls = "no"; + tls_verify = "no"; } ); chatnets = { @@ -55,41 +56,24 @@ chatnets = { nick = "hhvn"; autosendcmd = "/exec - -msg NickServ dpass irc.rizon.net identify; /mode hhvn -x; wait 5000"; }; - hlircnet = { - type = "IRC"; - autosendcmd = "/oper haydenh !!!; wait 2500; /cycle #users; /cycle #service;"; - }; - sdf = { type = "IRC"; autosendcmd = "/mode haydenh -x; wait 2000"; }; - efnet = { type = "IRC"; }; - unix = { - type = "IRC"; - autosendcmd = "/exec - -msg NickServ dpass unix.chat identify; /mode haydenh -x; wait 5000"; - }; - darkscience = { - type = "IRC"; - autosendcmd = "/exec - -msg NickServ dpass irc.darkscience.net identify; /mode haydenh -x; wait 2000;"; - }; + hlircnet = { type = "IRC"; autosendcmd = "/oper haydenh !!!"; }; + sdf = { type = "IRC"; }; + efnet = { type = "IRC"; nick = "hhvn"; alternative_nick = "h_hvn"; }; + unix = { type = "IRC"; }; nebulacentre = { type = "IRC"; }; cyberia = { type = "IRC"; }; - genoce = { type = "IRC"; autosendcmd = "/mode haydenh -x"; }; + genoce = { type = "IRC"; }; freenode = { + nick = "fr3en0de"; + alternate_nick = "fr3e-estn0de"; type = "IRC"; - autosendcmd = "/exec - -msg NickServ dpass irc.freenode.net identify; wait 5000"; - }; - oscss = { - type = "IRC"; - autosendcmd = "wait 5000; /vhost haydenh ccyHFEyE7$3*NmmBmg2NssX^~kdcNlzMIP@"; - }; - unrealircd = { - type = "IRC"; - autosendcmd = "/mode haydenh -x; wait 2000"; - }; - dataswamp = { - type = "IRC"; - autosendcmd = "/mode hhvn -C"; - nick = "hhvn"; + autosendcmd = "/exec - -msg NickServ dpass irc.freenode.net identify haydenh; wait 10000"; }; + oscss = { type = "IRC"; }; + dataswamp = { type = "IRC"; }; hlircnettor = { type = "IRC"; }; + "bitlbee-matrix" = { type = "IRC"; }; + "matrix.haydenvh.com" = { type = "IRC"; }; }; aliases = { ATAG = "WINDOW SERVER"; @@ -105,7 +89,6 @@ aliases = { CUBES = "SCRIPT EXEC Irssi::active_win->print(\"%_bases\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x0\\${_}0\\$_\" } '0'..'9','A'..'F' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_cubes\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { my \\$y = \\$_*6 \\; join '', map { my \\$x = \\$_ \\; map { \"%x\\$x\\$_\\$x\\$_\" } @{['0'..'9','A'..'Z']}[\\$y .. \\$y+5] } 1..6 }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) for 0..5 \\; Irssi::active_win->print(\"%_grays\", MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print( do { join '', map { \"%x7\\${_}7\\$_\" } 'A'..'X' }, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; Irssi::active_win->print(\"%_mIRC extended colours\", MSGLEVEL_CLIENTCRAP) \\; my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 0..15 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) \\; for my \\$z (0..6) { my \\$x \\; \\$x .= sprintf \"\00399,%02d%02d\",\\$_,\\$_ for 16+(\\$z*12)..16+(\\$z*12)+11 \\; Irssi::active_win->print(\\$x, MSGLEVEL_NEVER | MSGLEVEL_CLIENTCRAP) }"; DATE = "TIME"; DEHIGHLIGHT = "DEHILIGHT"; - DESCRIBE = "/nick $0; /me $1-; /nick haydenh"; DHL = "DEHILIGHT"; EXEMPTLIST = "MODE $C +e"; EXIT = "try //exit"; @@ -260,7 +243,6 @@ aliases = { dehalfop = "/mode * -h $0"; vm_add = " /^statusbar prompt add -after input -alignment right more; /^statusbar prompt add -after input -alignment right vim_cmd_mode"; vm_del = "/^statusbar prompt remove vim_cmb_mode; /^statusbar prompt remove more"; - haydenh = "me"; chanhold = "^msg chanhold"; boxx = "say \\ _\\ \\ \\ _\\ \\ \\ _\\ \\ \\ _\\ \\ \\ _; say |_| |_| |_| |_| |_|"; kline = "quote KLINE"; @@ -284,7 +266,6 @@ aliases = { arep = "/ACMSG $, $*"; AAAA = "SAY \\\\0/;SAY |;SAY / \\\\"; matrix = "SAY I'd like to interject for a moment, what you're referring to as Matrix, is in fact GNU/matrix, or as I've recently taken to calling it, GNU+matrix. Matrix is not an ideology unto itself, but rather another free component of a fully functioning method of thought."; - quickcon = "/connect sdf; /connect darkscience; /connect rizon; /connect unix; /connect efnet; /connect genoce; /connect hlircnet; /connect dataswamp; /connect unrealircd; /connect cyberia"; rules = "/quote rules"; mkpasswd = "/quote mkpasswd"; vhost = "/quote vhost"; @@ -301,18 +282,35 @@ aliases = { smotd = "/quote smotd"; sadmin = "/quote admin"; ping = "/quote ping"; - awl_sbar = "/script load autorun/adv_windowlist; /set awl_viewer off; /format awl_display_nokey %m$$N$n$$H$$C$$S; /format awl_display_key %m$$Q%n$$H$$C$$S; /format awl_display_nokey_active %m$$N%K$$C; /format awl_display_key_active %m$$Q%K$$C; /format awl_display_header %K[%m$$C%K]"; - awl_nosbar = "/script load autorun/adv_windowlist; /set awl_viewer on; /format awl_display_nokey %N $$H$$C$$S %N$$N; /format awl_display_key %N $$H$$C$$S%N %mM-$$Q; /format awl_display_nokey_active %N%K $$C %N$$N; /format awl_display_key_active %N%K $$C %mM-$$Q; /format awl_display_header %1 %Y$$C ($${N}); /format awl_display_nokey_visible %N%K $$C %N$$N; /format awl_display_key_visible %N%K $$C %mM-$$Q"; + awl_nosbar = "/script load autorun/adv_windowlist; /format awl_display_nokey %N$$H$$C$$S %N$$N; /format awl_display_key %N$$H$$C$$S%N %mM-$$Q; /format awl_display_nokey_active %N%K>%N$$C %N$$N; /format awl_display_key_active %N%K>%N$$C %mM-$$Q; /format awl_display_header %1 %Y$$C ($${N}); /format awl_display_nokey_visible %N%K<%N$$C %N$$N; /format awl_display_key_visible %N%K<%N$$C %mM-$$Q; /rm_awl_sbar"; sajoin = "/quote sajoin"; chgident = "/quote chgident"; shrug = "/SAY . _0_ .; SAY \\ ` | `; SAY \\ \\ \\ |; SAY \\ \\ / \\\\"; plop = "/SAY | \\ \\ \\ \\ |; SAY |~~-.-|; SAY | 0 \\ .|; SAY |o \\ . |; SAY |_____|"; ll = "/lastlog"; llc = "/lastlog -clear"; - quickconn = "/connect nebulacentre; connect sdf; connect unrealircd; connect unix; connect Rizon; connect cyberia; connect genoce; connect darkscience; connect efnet; connect hlircnet"; + quickconn = "/connect unix; /connect dataswamp; /connect sdf; /connect freenode; /connect hlircnet; /connect cyberia; /connect nebulacentre; /connect efnet"; "expose-self" = "/mode $N -x"; - rm_awl_sbar = "/sbar modify -disable awl_0; sbar modify -disable awl_1; sbar modify -disable awl_2; sbar modify -disable awl_3"; + rm_awl_sbar = "/sbar modify -disable awl_0; sbar modify -disable awl_1; sbar modify -disable awl_2; sbar modify -disable awl_3; sbar modify -disable awl_4; sbar modify -disable awl_5"; decloak = "mode $N -x"; + 2say = "SAY $*; SAY $*"; + 4say = "2say $*; 2say $*"; + 8say = "4say $*; 4say $*"; + 16say = "8say $*; 8say $*"; + 32say = "16say $*; wait 5000; 16say $*"; + 64say = "32say $*; wait 20000; 32say $*"; + 2colsay = "colsay $*; colsay $*"; + 4colsay = "2colsay $*; 2colsay $*"; + 8colsay = "4colsay $*; 4colsay $*"; + 16colsay = "8colsay $*; 8colsay $*"; + 32colsay = "16colsay $*; wait 5000; 16colsay $*"; + 64colsay = "32colsay $*; wait 20000; 32say $*"; + winhilight = "/window show 4; /window size 8"; + art = "/exec - -out cat /srv/storage/art.tmp"; + quit = "/echo no"; + net = "/echo $chatnet"; + wh0 = "who 0"; + alright = "/exec - -out echo Alright, I $$(shuf < /usr/share/dict/british-english 2>/dev/null | grep -v 'ed$$' 2>/dev/null | head -n 1 2>/dev/null)."; }; statusbar = { items = { @@ -330,8 +328,8 @@ statusbar = { lag = "{sb Lag: $0-}"; act = "{sb Act: $0-}"; more = "{sb3 {sbmore}}"; - end = "%N%K%_───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; - inact = "%N%G%_────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; + end = "%N%K%_──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; + inact = "%N%G%_──────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; none = " "; }; default = { @@ -365,6 +363,14 @@ statusbar = { topicend = { alignment = "right"; }; }; }; + awl_2 = { + items = { + barstart = { priority = "100"; }; + awl_2 = { }; + barend = { priority = "100"; alignment = "right"; }; + }; + disabled = "yes"; + }; awl_3 = { items = { barstart = { priority = "100"; }; @@ -373,6 +379,30 @@ statusbar = { }; disabled = "yes"; }; + awl_4 = { + items = { + barstart = { priority = "100"; }; + awl_4 = { }; + barend = { priority = "100"; alignment = "right"; }; + }; + disabled = "yes"; + }; + awl_5 = { + items = { + barstart = { priority = "100"; }; + awl_5 = { }; + barend = { priority = "100"; alignment = "right"; }; + }; + disabled = "yes"; + }; + awl_6 = { + items = { + barstart = { priority = "100"; }; + awl_6 = { }; + barend = { priority = "100"; alignment = "right"; }; + }; + disabled = "yes"; + }; prompt = { items = { uberprompt = { priority = "-1"; }; @@ -387,14 +417,15 @@ statusbar = { awl_0 = { }; barend = { priority = "100"; alignment = "right"; }; }; + disabled = "yes"; }; }; }; settings = { core = { - real_name = "\002:: \00314Fanatic Romanticist \017\002::\017"; - user_name = "Fanatic"; - nick = "haydenh"; + real_name = "gopher://haydenvh.com"; + user_name = "h"; + nick = "hhvn"; recode_transliterate = "no"; timestamp_format = "%H:%M:%S"; hostname = ""; @@ -403,7 +434,7 @@ settings = { resolve_prefer_ipv6 = "no"; awaylog_file = "~/.cache/irc/away.log"; chanmode_expando_strip = "yes"; - server_reconnect_time = "5secs"; + server_reconnect_time = "2m"; server_connect_timeout = "20secs"; rawlog_lines = "10000"; }; @@ -428,8 +459,8 @@ settings = { emphasis = "yes"; emphasis_multiword = "yes"; emphasis_replace = "no"; - window_default_level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - autolog_path = "~/.cache/irc/$tag/$0.log"; + window_default_level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + autolog_path = "~/.cache/irclogs/$tag-$0/%d-%m-%y.log"; autolog_level = "all"; autolog_colors = "yes"; completion_keep_privates = "50"; @@ -443,7 +474,7 @@ settings = { awl_shared_sbar = "OFF"; awl_block = "25"; awl_sort = "active/server/tag"; - trackbar_string = "─"; + trackbar_string = "──────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"; trackbar_style = "%g%_"; trackbar_print_timestamp = "no"; uberprompt_load_hook = "/^vm_add"; @@ -452,11 +483,11 @@ settings = { cmdind_text = "%g%_CMD: "; tmux_away_window = ""; tmux_away_message = "(set away by a script)"; - neat_colors = "RX4CX6CX5EX3CX2DX2JX1CGX1UcX1ZBX3HX2TX3MX25X4NX3AX4GX42X63X6BX6HX51"; + neat_colors = "X40RX4CX5CX6CX5EX3CX2DX2JX3PX1CGcX1ZBX3HX2TX3MX25X2BX4NX6AX3AX4GX42X63X6BX6HX6NX51"; hilightwin_show_network = "yes"; hilightwin_showprivmsg = "no"; neat_history = "10000000"; - neat_truncate_nick = "no"; + neat_truncate_nick = "yes"; title_screen_window = "yes"; vim_mode_map_leader = ";"; dim_nicks_ignore_hilights = "no"; @@ -468,15 +499,18 @@ settings = { ascii_default_kickreason = "irssi script :)"; trackbar_ignore_windows = "[control-panel] [hilights]"; hilightwin_ignore_targets = "#users #service"; + awl_height_adjust = "0"; }; "irc/core" = { - alternate_nick = "hhvn"; + alternate_nick = "h_hvn"; ctcp_version_reply = "UNIVERSE v42"; ctcp_userinfo_reply = "gopher://haydenvh.com:73"; part_message = "pain is temporary"; split_line_start = ""; usermode = "+iw"; join_auto_chans_on_invite = "yes"; + cmd_queue_speed = "790msec"; + auto_whowas = "no"; }; proxy = { irssiproxy_password = "awDhuK15^"; @@ -521,9 +555,8 @@ keyboard = ( { key = "meta-."; id = "change_window"; data = "38"; }, { key = "meta-/"; id = "change_window"; data = "39"; }, { key = "^I"; id = "key"; data = "tab"; }, - { key = "^Y"; id = "command"; data = "awl_sbar "; }, { - key = "^U"; + key = "^Y"; id = "command"; data = "script unload adv_windowlist"; }, @@ -540,39 +573,24 @@ keyboard = ( id = "multi"; data = "erase_line;insert_text /window server "; }, - { key = "^D"; id = "multi"; data = "erase_line"; } + { key = "^D"; id = "scroll_forward"; data = ""; }, + { key = "^U"; } ); hilights = ( { text = "haydenh"; nick = "yes"; word = "yes"; }, { text = "hayden"; nick = "yes"; word = "yes"; }, - { text = "hhvn"; nick = "yes"; word = "yes"; } + { text = "hhvn"; nick = "yes"; word = "yes"; }, + { text = "fr3en0de"; nick = "yes"; word = "yes"; } ); channels = ( - { - name = "#hlircnet"; - chatnet = "hlircnet"; - autojoin = "yes"; - autosendcmd = "WAIT 5000; MODE #hlircnet +q haydenh"; - }, + { name = "#hlircnet"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#GNU/matrix"; chatnet = "hlircnet"; autojoin = "yes"; }, - { - name = "#help"; - chatnet = "hlircnet"; - autojoin = "yes"; - autosendcmd = "WAIT 5000; MODE #help +q haydenh"; - }, + { name = "#help"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#gopher"; chatnet = "hlircnet"; autojoin = "yes"; }, - { - name = "#vhosts"; - chatnet = "hlircnet"; - autojoin = "yes"; - autosendcmd = "WAIT 5000; MODE #vhosts +q haydenh"; - }, + { name = "#vhosts"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#opers"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#users"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#service"; chatnet = "hlircnet"; autojoin = "yes"; }, - { name = "#cgo"; chatnet = "hlircnet"; autojoin = "yes"; }, - { name = "#hlfm"; chatnet = "hlircnet"; autojoin = "yes"; }, { name = "#darkscience"; chatnet = "darkscience"; autojoin = "yes"; }, { name = "#asciiart"; chatnet = "efnet"; autojoin = "yes"; }, { name = "#unix"; chatnet = "unix"; autojoin = "yes"; }, @@ -586,24 +604,13 @@ channels = ( { name = "#gopher"; chatnet = "sdf"; autojoin = "yes"; }, { name = "#sdf"; chatnet = "sdf"; autojoin = "yes"; }, { name = "#helpdesk"; chatnet = "sdf"; autojoin = "yes"; }, - { - name = "#unreal-support"; - chatnet = "unrealircd"; - autojoin = "yes"; - }, - { name = "#unreal-devel"; chatnet = "unrealircd"; autojoin = "yes"; }, - { - name = "#movies"; - chatnet = "darkscience"; - autojoin = "yes"; - autosendcmd = "WAIT 5000; JOIN #movies"; - }, - { name = "#test"; chatnet = "hlircnet"; autojoin = "yes"; }, - { name = "#2f30"; chatnet = "cyberia"; autojoin = "yes"; }, - { name = "#cyberia"; chatnet = "cyberia"; autojoin = "yes"; }, { name = "#dataswamp"; chatnet = "dataswamp"; autojoin = "yes"; }, { name = "#political"; chatnet = "efnet"; autojoin = "yes"; }, - { name = "#LRH"; chatnet = "efnet"; autojoin = "yes"; } + { name = "#LRH"; chatnet = "efnet"; autojoin = "yes"; }, + { name = "#thepiratebay.org"; chatnet = "efnet"; autojoin = "yes"; }, + { name = "#2f30"; chatnet = "cyberia"; autojoin = "yes"; }, + { name = "#shadow"; chatnet = "hlircnet"; autojoin = "yes"; }, + { name = "#cyberia"; chatnet = "cyberia"; autojoin = "yes"; } ); completions = { hubus = { value = "hub.us.hlircnet."; }; @@ -617,12 +624,17 @@ completions = { }; ignores = ( { mask = "ARS"; level = "NOTICES"; }, - { level = "NO_ACT ALL"; channels = ( "#service" ); }, - { level = "NO_ACT ALL"; channels = ( "#users" ); }, { mask = "[control-panel]"; level = "NO_ACT ALL"; }, { mask = "[hilights]"; level = "NO_ACT ALL"; }, - { level = "NO_ACT ALL"; servertag = "hlircnettor"; } + { mask = "BASHy2-EU"; level = "MSGS"; }, + { mask = "freenode-connect"; level = "ALL"; }, + { mask = "P80drone"; level = "ALL"; }, + { mask = "dmonp80"; level = "ALL"; }, + { level = "NO_ACT ALL"; channels = ( "#service" ); }, + { level = "NO_ACT ALL"; channels = ( "#users" ); }, + { mask = "BASHy2"; level = "MSGS"; } ); +notifies = { "creep^ltx!*" = { ircnets = ( "freenode" ); }; incal = { }; }; windows = { 1 = { immortal = "yes"; @@ -633,72 +645,71 @@ windows = { immortal = "yes"; name = "[notices]"; servertag = "hlircnet"; - level = "PUBLICS NOTICES SNOTES ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS WALLOPS INVITES NICKS"; + level = "SNOTES WALLOPS"; }; 3 = { immortal = "yes"; name = "[msgs]"; - servertag = "hlircnet"; - level = "MSGS NOTICES CTCPS ACTIONS KICKS TOPICS NICKS DCC DCCMSGS"; + level = "MSGS NOTICES CTCPS ACTIONS KICKS TOPICS INVITES NICKS DCC DCCMSGS"; }; 4 = { name = "[hilights]"; servertag = "hlircnet"; level = "HILIGHTS"; }; 5 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#opers"; - tag = "hlircnet"; + name = "#2f30"; + tag = "cyberia"; } ); }; 6 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#GNU/matrix"; - tag = "hlircnet"; + name = "#cyberia"; + tag = "cyberia"; } ); }; 7 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#help"; - tag = "hlircnet"; + name = "#gopher"; + tag = "sdf"; } ); }; 8 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( - { + { type = "CHANNEL"; chat_type = "IRC"; - name = "#gopher"; - tag = "hlircnet"; + name = "#sdf"; + tag = "sdf"; } ); }; 9 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#vhosts"; - tag = "hlircnet"; + name = "#helpdesk"; + tag = "sdf"; } ); }; 10 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; @@ -709,303 +720,176 @@ windows = { ); }; 11 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#users"; + name = "#GNU/matrix"; tag = "hlircnet"; } ); }; 12 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#service"; + name = "#help"; tag = "hlircnet"; } ); }; 13 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#cgo"; + name = "#gopher"; tag = "hlircnet"; } ); }; 14 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#hlfm"; + name = "#vhosts"; tag = "hlircnet"; } ); }; 15 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#test"; + name = "#opers"; tag = "hlircnet"; } ); }; 16 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#unix"; - tag = "unix"; + name = "#users"; + tag = "hlircnet"; } ); }; 17 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#general"; - tag = "nebulacentre"; + name = "#service"; + tag = "hlircnet"; } ); }; 18 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#gopher"; - tag = "sdf"; + name = "#unix"; + tag = "unix"; } ); }; 19 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( - { + { type = "CHANNEL"; chat_type = "IRC"; - name = "#sdf"; - tag = "sdf"; + name = "#dataswamp"; + tag = "dataswamp"; } ); }; 20 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#helpdesk"; - tag = "sdf"; + name = "#general"; + tag = "nebulacentre"; } ); }; 21 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#/g/technology"; - tag = "Rizon"; + name = "#asciiart"; + tag = "efnet"; } ); }; 22 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#uk"; - tag = "Rizon"; - } - ); - }; - 23 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#/tech/"; - tag = "Rizon"; - } - ); - }; - 24 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#8chan"; - tag = "Rizon"; - } - ); - }; - 25 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#books"; - tag = "genoce"; - } - ); - }; - 26 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#general"; - tag = "genoce"; - } - ); - }; - 27 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#2f30"; - tag = "cyberia"; - } - ); - }; - 28 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#cyberia"; - tag = "cyberia"; - } - ); - }; - 29 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#unreal-support"; - tag = "unrealircd"; - } - ); - }; - 30 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#unreal-devel"; - tag = "unrealircd"; - } - ); - }; - 31 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#darkscience"; - tag = "darkscience"; - } - ); - }; - 32 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#movies"; - tag = "darkscience"; - } - ); - }; - 33 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; - items = ( - { - type = "CHANNEL"; - chat_type = "IRC"; - name = "#dataswamp"; - tag = "dataswamp"; + name = "#political"; + tag = "efnet"; } ); }; - 34 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + 23 = { + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#asciiart"; + name = "#LRH"; tag = "efnet"; } ); }; - 35 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + 24 = { + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#political"; + name = "#thepiratebay.org"; tag = "efnet"; } ); }; - 36 = { - level = "MSGS PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; + 25 = { + level = "PUBLICS NOTICES CTCPS ACTIONS JOINS PARTS QUITS KICKS MODES TOPICS NICKS"; items = ( { type = "CHANNEL"; chat_type = "IRC"; - name = "#LRH"; - tag = "efnet"; + name = "#shadow"; + tag = "hlircnet"; } ); }; }; mainwindows = { - 10 = { - first_line = "10"; - lines = "43"; - first_column = "0"; - columns = "161"; - }; - 4 = { + 1 = { first_line = "0"; - lines = "10"; + lines = "90"; first_column = "0"; - columns = "161"; + columns = "349"; }; }; diff --git a/.config/irssi/default.theme b/.config/irssi/default.theme @@ -0,0 +1,833 @@ +# 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"; +}; +formats = { + "fe-common/irc/notifylist" = { + notify_join = "{nick $0} [$1@$2] [{hilight $3}] has joined to $4"; + notify_part = "{nick $0} has left $4"; + notify_away = "{nick $0} [$5] [$1@$2] [{hilight $3}] is now away: $4"; + notify_unaway = "{nick $0} [$4] [$1@$2] [{hilight $3}] is now unaway"; + notify_online = "On $0: {hilight $1}"; + notify_offline = "Offline: $0"; + notify_list = "$0: $1 $2"; + notify_list_empty = "The notify list is empty"; + }; + "fe-common/core" = { + line_start = "{line_start}"; + line_start_irssi = "{line_start}{hilight Irssi:} "; + timestamp = "{timestamp $Z} "; + servertag = "[$0] "; + daychange = "Day changed to %%d %%b %%Y"; + talking_with = "You are now talking with {nick $0}"; + refnum_too_low = "Window number must be greater than 1"; + error_server_sticky = "Window's server is sticky and it cannot be changed without -unsticky option"; + set_server_sticky = "Window's server set sticky"; + unset_server_sticky = "Window's server isn't sticky anymore"; + window_name_not_unique = "Window names must be unique"; + window_level = "Window level is now $0"; + window_set_immortal = "Window is now immortal"; + window_unset_immortal = "Window isn't immortal anymore"; + window_immortal_error = "Window is immortal, if you really want to close it, say /WINDOW IMMORTAL OFF"; + windowlist_header = "%#Ref Name Active item Server Level"; + windowlist_line = "%#$[4]0 %|$[20]1 $[15]2 $[15]3 $4"; + windowlist_footer = ""; + windows_layout_saved = "Layout of windows is now remembered"; + windows_layout_reset = "Layout of windows reset to defaults"; + window_info_header = ""; + window_info_footer = ""; + 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_bound_items_header = "%#Bounds : {hilight Name Server tag}"; + window_info_bound_item = "%# : $[!30]0 $[!15]1 $2"; + window_info_bound_items_footer = ""; + window_info_items_header = "%#Items : {hilight Name Server tag}"; + window_info_item = "%# $[7]0: $[!30]1 $2"; + window_info_items_footer = ""; + looking_up = "Looking up {server $0}"; + connecting = "Connecting to {server $0} [$1] port {hilight $2}"; + reconnecting = "Reconnecting to {server $0} [$1] port {hilight $2} - use /RMRECONNS to abort"; + connection_established = "Connection to {server $0} established"; + cant_connect = "Unable to connect server {server $0} port {hilight $1} {reason $2}"; + connection_lost = "Connection lost to {server $0}"; + lag_disconnected = "No PONG reply from server {server $0} in $1 seconds, disconnecting"; + disconnected = "Disconnected from {server $0} {reason $1}"; + server_quit = "Disconnecting from server {server $0}: {reason $1}"; + server_changed = "Changed to {hilight $2} server {server $1}"; + unknown_server_tag = "Unknown server tag {server $0}"; + no_connected_servers = "Not connected to any servers"; + server_list = "{server $0}: $1:$2 ($3)"; + server_lookup_list = "{server $0}: $1:$2 ($3) (connecting...)"; + server_reconnect_list = "{server $0}: $1:$2 ($3) ($5 left before reconnecting)"; + server_reconnect_removed = "Removed reconnection to server {server $0} port {hilight $1}"; + server_reconnect_not_found = "Reconnection tag {server $0} not found"; + setupserver_added = "Server {server $0} saved"; + setupserver_removed = "Server {server $0} removed"; + setupserver_not_found = "Server {server $0} not found"; + your_nick = "Your nickname is {nick $0}"; + join = "{channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}"; + part = "{channick $0} {chanhost $1} has left {channel $2} {reason $3}"; + kick = "{channick $0} was kicked from {channel $1} by {nick $2} {reason $3}"; + quit = "{channick $0} {chanhost $1} has quit {reason $2}"; + quit_once = "{channel $3} {channick $0} {chanhost $1} has quit {reason $2}"; + invite = "{nick $0} invites you to {channel $1}"; + not_invited = "You have not been invited to a channel!"; + new_topic = "{nick $0} changed the topic of {channel $1} to: $2"; + topic_unset = "Topic unset by {nick $0} on {channel $1}"; + your_nick_changed = "You're now known as {nick $1}"; + nick_changed = "{channick $0} is now known as {channick_hilight $1}"; + talking_in = "You are now talking in {channel $0}"; + not_in_channels = "You are not on any channels"; + current_channel = "Current channel {channel $0}"; + names = "{names_users Users {names_channel $0}}"; + names_prefix = "%#{names_prefix $0}"; + names_nick_op = "{names_nick_op $0 $1}"; + names_nick_halfop = "{names_nick_halfop $0 $1}"; + names_nick_voice = "{names_nick_voice $0 $1}"; + names_nick = "{names_nick $0 $1}"; + endofnames = "{channel $0}: Total of {hilight $1} nicks {comment {hilight $2} ops, {hilight $3} halfops, {hilight $4} voices, {hilight $5} normal}"; + chanlist_header = "%#You are on the following channels:"; + chanlist_line = "%#{channel $[-10]0} %|+$1 ($2): $3"; + chansetup_not_found = "Channel {channel $0} not found"; + chansetup_added = "Channel {channel $0} saved"; + chansetup_removed = "Channel {channel $0} removed"; + chansetup_header = "%#Channel Network Password Settings"; + chansetup_line = "%#{channel $[15]0} %|$[10]1 $[10]2 $3"; + chansetup_footer = ""; + own_msg = "{ownmsgnick $2 {ownnick $0}}$1"; + own_msg_channel = "{ownmsgnick $3 {ownnick $0}{msgchannel $1}}$2"; + own_msg_private = "{ownprivmsg msg $0}$1"; + own_msg_private_query = "{ownprivmsgnick {ownprivnick $2}}$1"; + pubmsg_me = "{pubmsgmenick $2 {menick $0}}$1"; + pubmsg_me_channel = "{pubmsgmenick $3 {menick $0}{msgchannel $1}}$2"; + pubmsg_hilight = "{pubmsghinick $0 $3 $1}$2"; + pubmsg_hilight_channel = "{pubmsghinick $0 $4 $1{msgchannel $2}}$3"; + pubmsg = "{pubmsgnick $2 {pubnick $0}}$1"; + pubmsg_channel = "{pubmsgnick $3 {pubnick $0}{msgchannel $1}}$2"; + msg_private = "{privmsg $0 $1}$2"; + msg_private_query = "{privmsgnick $0}$2"; + no_msgs_got = "You have not received a message from anyone yet"; + no_msgs_sent = "You have not sent a message to anyone yet"; + query_start = "Starting query in {server $1} with {nick $0}"; + query_stop = "Closing query with {nick $0}"; + no_query = "No query with {nick $0}"; + query_server_changed = "Query with {nick $0} changed to server {server $1}"; + hilight_header = "%#Highlights:"; + hilight_line = "%#$[-4]0 $1 $2 $3$4"; + hilight_footer = ""; + hilight_not_found = "Highlight not found: $0"; + hilight_removed = "Highlight removed: $0"; + alias_added = "Alias $0 added"; + alias_removed = "Alias $0 removed"; + alias_not_found = "No such alias: $0"; + aliaslist_header = "%#Aliases:"; + aliaslist_line = "%#$[10]0 $1"; + aliaslist_footer = ""; + log_opened = "Log file {hilight $0} opened"; + log_closed = "Log file {hilight $0} closed"; + log_create_failed = "Couldn't create log file {hilight $0}: $1"; + log_locked = "Log file {hilight $0} is locked, probably by another running Irssi"; + log_not_open = "Log file {hilight $0} not open"; + log_started = "Started logging to file {hilight $0}"; + log_stopped = "Stopped logging to file {hilight $0}"; + log_list_header = "%#Logs:"; + log_list = "%#$0 $1: $2 $3$4$5"; + log_list_footer = ""; + windowlog_file = "Window LOGFILE set to $0"; + windowlog_file_logging = "Can't change window's logfile while log is on"; + no_away_msgs = "No new messages in awaylog"; + away_msgs = "{hilight $1} new messages in awaylog:"; + module_header = "%#Module Type Submodules"; + module_line = "%#$[!20]0 $[7]1 $2"; + module_footer = ""; + module_already_loaded = "Module {hilight $0/$1} already loaded"; + module_not_loaded = "Module {hilight $0/$1} is not loaded"; + module_load_error = "Error loading module {hilight $0/$1}: $2"; + module_version_mismatch = "{hilight $0/$1} is ABI version $2 but Irssi is version $abiversion, cannot load"; + module_invalid = "{hilight $0/$1} isn't Irssi module"; + module_loaded = "Loaded module {hilight $0/$1}"; + module_unloaded = "Unloaded module {hilight $0/$1}"; + command_unknown = "Unknown command: $0"; + command_ambiguous = "Ambiguous command: $0"; + option_unknown = "Unknown option: $0"; + option_ambiguous = "Ambiguous option: $0"; + option_missing_arg = "Missing required argument for: $0"; + not_enough_params = "Not enough parameters given"; + not_connected = "Not connected to server"; + not_joined = "Not joined to any channel"; + chan_not_found = "Not joined to such channel"; + chan_not_synced = "Channel not fully synchronized yet, try again after a while"; + illegal_proto = "Command isn't designed for the chat protocol of the active server"; + not_good_idea = "Doing this is not a good idea. Add -YES option to command if you really mean it"; + invalid_number = "Invalid number"; + invalid_time = "Invalid timestamp"; + invalid_level = "Invalid message level"; + invalid_size = "Invalid size"; + invalid_charset = "Invalid charset: $0"; + invalid_choice = "Invalid choice, must be one of $0"; + eval_max_recurse = "/eval hit maximum recursion limit"; + program_not_found = "Could not find file or file is not executable"; + no_server_defined = "No servers defined for this network, see /help server for how to add one"; + theme_saved = "Theme saved to $0"; + theme_save_failed = "Error saving theme to $0: $1"; + theme_not_found = "Theme {hilight $0} not found"; + theme_changed = "Now using theme {hilight $0} ($1)"; + window_theme = "Using theme {hilight $0} in this window"; + window_theme_default = "No theme is set for this window"; + window_theme_changed = "Now using theme {hilight $0} ($1) in this window"; + window_theme_removed = "Removed theme from this window"; + format_title = "%:[{hilight $0}] - [{hilight $1}]%:"; + format_subtitle = "[{hilight $0}]"; + format_item = "$0 = $1"; + ignored = "Ignoring {hilight $1} from {nick $0}"; + ignored_options = "Ignoring {hilight $1} from {nick $0} {comment $2}"; + unignored = "Unignored {nick $0}"; + ignore_not_found = "{nick $0} is not being ignored"; + ignore_no_ignores = "There are no ignores"; + ignore_header = "%#Ignore List:"; + ignore_line = "%#$[-4]0 $1: $2 $3 $4"; + ignore_footer = ""; + not_channel_or_query = "The current window is not a channel or query window"; + conversion_added = "Added {hilight $0}/{hilight $1} to conversion database"; + conversion_removed = "Removed {hilight $0} from conversion database"; + conversion_not_found = "{hilight $0} not found in conversion database"; + conversion_no_translits = "Transliterations not supported in this system"; + recode_header = "%#Target Character set"; + recode_line = "%#%|$[!30]0 $1"; + unknown_chat_protocol = "Unknown chat protocol: $0"; + unknown_chatnet = "Unknown chat network: $0 (create it with /NETWORK ADD)"; + not_toggle = "Value must be either ON, OFF or TOGGLE"; + perl_error = "Perl error: $0"; + bind_header = "%#Key Action"; + bind_list = "%#$[!20]0 $1 $2"; + bind_command_list = "$[!30]0 $1"; + bind_footer = ""; + bind_unknown_id = "Unknown bind action: $0"; + config_saved = "Saved configuration to file $0"; + config_reloaded = "Reloaded configuration"; + config_modified = "Configuration file was modified since irssi was last started - do you want to overwrite the possible changes?"; + glib_error = "{error $0} $1"; + overwrite_config = "Overwrite config (y/N)?"; + set_title = "[{hilight $0}]"; + set_item = "$[-!32]0 %_$1"; + set_unknown = "Unknown setting $0"; + set_not_boolean = "Setting {hilight $0} isn't boolean, use /SET"; + no_completions = "There are no completions"; + completion_removed = "Removed completion $0"; + completion_header = "%#Key Value Auto"; + completion_line = "%#$[10]0 $[!40]1 $2"; + completion_footer = ""; + capsicum_enabled = "Capability mode enabled"; + capsicum_disabled = "Capability mode not enabled"; + capsicum_failed = "Capability mode failed: $0"; + tls_ephemeral_key = "EDH Key: {hilight $0} bit {hilight $1}"; + tls_ephemeral_key_unavailable = "EDH Key: {error N/A}"; + tls_pubkey = "Public Key: {hilight $0} bit {hilight $1}, valid from {hilight $2} to {hilight $3}"; + tls_cert_header = "Certificate Chain:"; + tls_cert_subject = " Subject: {hilight $0}"; + tls_cert_issuer = " Issuer: {hilight $0}"; + tls_pubkey_fingerprint = "Public Key Fingerprint: {hilight $0} ({hilight $1})"; + tls_cert_fingerprint = "Certificate Fingerprint: {hilight $0} ({hilight $1})"; + tls_protocol_version = "Protocol: {hilight $0} ({hilight $1} bit, {hilight $2})"; + }; + "fe-common/irc/dcc" = { + own_dcc = "{dccownmsg dcc {dccownnick $1}}$2"; + own_dcc_action = "{dccownaction_target $0 $1}$2"; + own_dcc_action_query = "{dccownaction $0}$2"; + own_dcc_ctcp = "{ownctcp ctcp $0}$1 $2"; + dcc_msg = "{dccmsg dcc $0}$1"; + action_dcc = "{dccaction $0}$1"; + action_dcc_query = "{dccaction $0}$1"; + own_dcc_query = "{ownmsgnick {dccownquerynick $0}}$2"; + dcc_msg_query = "{privmsgnick $0}$1"; + dcc_ctcp = "{dcc >>> DCC CTCP {hilight $1} received from {hilight $0}: $2}"; + dcc_chat = "{dcc DCC CHAT from {nick $0} [$1 port $2]}"; + dcc_chat_channel = "{dcc DCC CHAT from {nick $0} [$1 port $2] requested in channel {channel $3}}"; + dcc_chat_not_found = "{dcc No DCC CHAT connection open to {nick $0}}"; + dcc_chat_connected = "{dcc DCC CHAT connection with {nick $0} [$1 port $2] established}"; + dcc_chat_disconnected = "{dcc DCC lost chat to {nick $0}}"; + dcc_send = "{dcc DCC SEND from {nick $0} [$1 port $2]: $3 [$4]}"; + dcc_send_channel = "{dcc DCC SEND from {nick $0} [$1 port $2]: $3 [$4 bytes] requested in channel {channel $5}}"; + dcc_send_exists = "{dcc DCC already sending file {dccfile $0} for {nick $1}}"; + dcc_send_no_route = "{dcc DCC route lost to nick {nick $0} when trying to send file {dccfile $1}}"; + dcc_send_not_found = "{dcc DCC not sending file {dccfile $1} to {nick $0}}"; + dcc_send_file_open_error = "{dcc DCC can't open file {dccfile $0}: $1}"; + dcc_send_connected = "{dcc DCC sending file {dccfile $0} for {nick $1} [$2 port $3]}"; + dcc_send_complete = "{dcc DCC sent file {dccfile $0} [{hilight $1}] for {nick $2} in {hilight $3} [{hilight $4kB/s}]}"; + dcc_send_aborted = "{dcc DCC aborted sending file {dccfile $0} for {nick $1}}"; + dcc_get_not_found = "{dcc DCC no file offered by {nick $0}}"; + dcc_get_connected = "{dcc DCC receiving file {dccfile $0} from {nick $1} [$2 port $3]}"; + dcc_get_complete = "{dcc DCC received file {dccfile $0} [$1] from {nick $2} in {hilight $3} [$4kB/s]}"; + dcc_get_aborted = "{dcc DCC aborted receiving file {dccfile $0} from {nick $1}}"; + dcc_get_write_error = "{dcc DCC error writing to file {dccfile $0}: {comment $1}"; + dcc_unknown_ctcp = "{dcc DCC unknown ctcp {hilight $0} from {nick $1} [$2]}"; + dcc_unknown_reply = "{dcc DCC unknown reply {hilight $0} from {nick $1} [$2]}"; + dcc_unknown_type = "{dcc DCC unknown type {hilight $0}}"; + dcc_invalid_ctcp = "{dcc DCC received CTCP {hilight $0} with invalid parameters from {nick $1}}"; + dcc_connect_error = "{dcc DCC can't connect to {hilight $0} port {hilight $1}}"; + dcc_cant_create = "{dcc DCC can't create file {dccfile $0}: $1}"; + dcc_rejected = "{dcc DCC $0 was rejected by {nick $1} [{hilight $2}]}"; + dcc_request_send = "{dcc DCC $0 request sent to {nick $1}: $2"; + dcc_close = "{dcc DCC $0 close for {nick $1} [{hilight $2}]}"; + dcc_lowport = "{dcc Warning: Port sent with DCC request is a lowport ({hilight $0, $1}) - this isn't normal. It is possible the address/port is faked (or maybe someone is just trying to bypass firewall)}"; + dcc_list_header = "{dcc DCC connections}"; + dcc_list_line_chat = "{dcc $0 $1}"; + dcc_list_line_file = "{dcc $0 $1: %|$2 of $3 ($4%%) - $5kB/s - ETA $7 - $6}"; + dcc_list_line_queued_send = "{dcc - $0 $2 (queued)}"; + dcc_list_footer = ""; + dcc_list_line_server = "{dcc $0: Port($1) - Send($2) - Chat($3) - Fserve($4)}"; + dcc_server_started = "{dcc DCC SERVER started on port {hilight $0}}"; + dcc_server_closed = "{dcc DCC SERVER on port {hilight $0} closed}"; + }; + "fe-common/irc" = { + netsplit = "{netsplit Netsplit} {server $0} <-> {server $1} quits: $2"; + netsplit_more = "{netsplit Netsplit} {server $0} <-> {server $1} quits: $2 (+$3 more, use /NETSPLIT to show all of them)"; + netsplit_join = "{netjoin Netsplit} over, joins: $0"; + netsplit_join_more = "{netjoin Netsplit} over, joins: $0 (+$1 more)"; + no_netsplits = "There are no net splits"; + netsplits_header = "%#Nick Channel Server Split server"; + netsplits_line = "%#$[9]0 $[10]1 $[20]2 $3"; + netsplits_footer = ""; + network_added = "Network $0 saved"; + network_removed = "Network $0 removed"; + network_not_found = "Network $0 not found"; + network_header = "%#Networks:"; + network_line = "%#$0: $1"; + network_footer = ""; + setupserver_header = "%#Server Port Network Settings"; + setupserver_line = "%#%|$[!20]0 $[5]1 $[10]2 $3"; + setupserver_footer = ""; + sasl_success = "SASL authentication succeeded"; + sasl_error = "Cannot authenticate via SASL ($0)"; + cap_req = "Capabilities requested: $0"; + cap_ls = "Capabilities supported: $0"; + cap_ack = "Capabilities acknowledged: $0"; + cap_nak = "Capabilities refused: $0"; + cap_list = "Capabilities currently enabled: $0"; + cap_new = "Capabilities now available: $0"; + cap_del = "Capabilities removed: $0"; + joinerror_toomany = "Cannot join to channel {channel $0} (You have joined to too many channels)"; + joinerror_full = "Cannot join to channel {channel $0} (Channel is full)"; + joinerror_invite = "Cannot join to channel {channel $0} (You must be invited)"; + joinerror_banned = "Cannot join to channel {channel $0} (You are banned)"; + joinerror_bad_key = "Cannot join to channel {channel $0} (Bad channel key)"; + joinerror_bad_mask = "Cannot join to channel {channel $0} (Bad channel mask)"; + joinerror_unavail = "Cannot join to channel {channel $0} (Channel is temporarily unavailable)"; + joinerror_duplicate = "Channel {channel $0} already exists - cannot create it"; + channel_rejoin = "Channel {channel $0} is temporarily unavailable, this is normally because of netsplits. Irssi will now automatically try to rejoin back to this channel until the join is successful. Use /RMREJOINS command if you wish to abort this."; + inviting = "Inviting {nick $0} to {channel $1}"; + channel_created = "Channel {channelhilight $0} created $1"; + url = "Home page for {channelhilight $0}: $1"; + topic = "Topic for {channelhilight $0}: $1"; + no_topic = "No topic set for {channelhilight $0}"; + topic_info = "Topic set by {nick $0} {nickhost $2} {comment $1}"; + chanmode_change = "mode/{channelhilight $0} {mode $1} by {nick $2}"; + server_chanmode_change = "{netsplit ServerMode}/{channelhilight $0} {mode $1} by {nick $2}"; + channel_mode = "mode/{channelhilight $0} {mode $1}"; + bantype = "Ban type changed to {channel $0}"; + no_bans = "No bans in channel {channel $0}"; + banlist = "$0 - {channel $1}: ban {ban $2}"; + banlist_long = "$0 - {channel $1}: ban {ban $2} {comment by {nick $3}, $4 secs ago}"; + ebanlist = "{channel $0}: ban exception {ban $1}"; + ebanlist_long = "{channel $0}: ban exception {ban $1} {comment by {nick $2}, $3 secs ago}"; + no_invitelist = "Invite list is empty in channel {channel $0}"; + invitelist = "{channel $0}: invite {ban $1}"; + invitelist_long = "{channel $0}: invite {ban $1} {comment by {nick $2}, $3 secs ago}"; + no_such_channel = "{channel $0}: No such channel"; + channel_synced = "Join to {channel $0} was synced in {hilight $1} secs"; + usermode_change = "Mode change {mode $0} for user {nick $1}"; + user_mode = "Your user mode is {mode $0}"; + away = "You have been marked as being away"; + unaway = "You are no longer marked as being away"; + nick_away = "{nick $0} is away: $1"; + no_such_nick = "{nick $0}: No such nick/channel"; + nick_in_use = "Nick {nick $0} is already in use"; + nick_unavailable = "Nick {nick $0} is temporarily unavailable"; + your_nick_owned = "Your nick is owned by {nick $3} {comment $1@$2}"; + whois = "{nick $0} {nickhost $1@$2}%:{whois ircname $3}"; + whowas = "{nick $0} {nickhost $1@$2}%:{whois was $3}"; + whois_idle = "{whois idle %|$1 days $2 hours $3 mins $4 secs}"; + whois_idle_signon = "{whois idle %|$1 days $2 hours $3 mins $4 secs {comment signon: $5}}"; + whois_server = "{whois server %|$1 {comment $2}}"; + whois_oper = "{whois {hilight $1}}"; + 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 %|$1}"; + whois_extra = "{whois account %|$1}"; + end_of_whois = "End of WHOIS"; + end_of_whowas = "End of WHOWAS"; + 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"; + own_notice = "{ownnotice notice $0}$1"; + own_action = "{ownaction $0}$1"; + own_action_target = "{ownaction_target $0 $2}$1"; + own_ctcp = "{ownctcp ctcp $0}$1 $2"; + notice_server = "{servernotice $0}$1"; + notice_public = "{notice $0{pubnotice_channel $1}}$2"; + notice_private = "{notice $0{pvtnotice_host $1}}$2"; + action_private = "{pvtaction $0}$2"; + action_private_query = "{pvtaction_query $0}$2"; + action_public = "{pubaction $0}$1"; + action_public_channel = "{pubaction $0{msgchannel $1}}$2"; + ctcp_reply = "CTCP {hilight $0} reply from {nick $1}: $2"; + ctcp_reply_channel = "CTCP {hilight $0} reply from {nick $1} in channel {channel $3}: $2"; + ctcp_ping_reply = "CTCP {hilight PING} reply from {nick $0}: $1.$[-3.0]2 seconds"; + ctcp_requested = "{ctcp {hilight $0} {comment $1} requested CTCP {hilight $2} from {nick $4}}: $3"; + ctcp_requested_unknown = "{ctcp {hilight $0} {comment $1} requested unknown CTCP {hilight $2} from {nick $4}}: $3"; + online = "Users online: {hilight $0}"; + pong = "PONG received from $0: $1"; + wallops = "{wallop WALLOP {wallop_nick $0}} $1"; + action_wallops = "{wallop WALLOP {wallop_action $0}} $1"; + kill = "You were {error killed} by {nick $0} {nickhost $1} {reason $2} {comment Path: $3}"; + kill_server = "You were {error killed} by {server $0} {reason $1} {comment Path: $2}"; + error = "{error ERROR} $0"; + unknown_mode = "Unknown mode character $0"; + default_event = "$1"; + default_event_server = "[$0] $1"; + silenced = "Silenced {nick $0}"; + unsilenced = "Unsilenced {nick $0}"; + silence_line = "{nick $0}: silence {ban $1}"; + ask_oper_pass = "Operator password:"; + accept_list = "Accepted users: {hilight $0}"; + }; + "fe-common/perl" = { + script_not_found = "Script {hilight $0} not found"; + script_not_loaded = "Script {hilight $0} is not loaded"; + script_loaded = "Loaded script {hilight $0}"; + script_unloaded = "Unloaded script {hilight $0}"; + no_scripts_loaded = "No scripts are loaded"; + script_list_header = "%#Loaded scripts:"; + script_list_line = "%#$[!15]0 $1"; + script_list_footer = ""; + script_error = "{error Error in script {hilight $0}:}"; + }; + "Irssi::Script::ctcpspoof" = { + fctcp_info = " # ctcpitem ctcpreply"; + fctcp_empty = "%R>>%n %_FCTCP:%_ Your fake ctcp list is empty."; + fctcp_added = "%R>>%n %_FCTCP:%_ Added %_$0%_ ($1) to the fake ctcp list."; + fctcp_replaced = "%R>>%n %_FCTCP:%_ Replaced the old fake reply %_$0%_ with the new one ($1)"; + fctcp_delled = "%R>>%n %_FCTCP:%_ Deleted %_$0%_ from the fake ctcp list."; + fctcp_nfound = "%R>>%n %_FCTCP:%_ Can't find $0 in the fake ctcp list."; + fctcp_delusage = "%R>>%n %_FCTCP:%_ Usage: /FCTCP -del <ctcp-item>"; + fctcp_usage = "%R>>%n %_FCTCP:%_ Usage: /FCTCP -add <ctcp-item> <ctcp-reply>"; + fctcp_repusage = "%R>>%n %_FCTCP:%_ Usage: /FCTCP -replace <ctcp-item> <ctcp-reply>"; + fctcp_nload = "%R>>%n %_FCTCP:%_ Could not load the fake ctcp list."; + fctcp_request = "%R>>%n %_FCTCP:%_ Used the fake reply %_$1%_ on %_$0%_"; + fctcp_loaded = "%R>>%n %_FCTCP:%_ The fake reply %_$0%_ already exists, use %_/FCTCP -del $0%_ to remove it from the list."; + fctcp_print = "$[!-2]0 $[20]1 $2"; + fctcp_help = "$0"; + loaded = "%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2."; + }; + "Irssi::Script::tmux_away" = { + tmux_away_crap = "{line_start}{hilight tmux_away:} $0"; + }; + "Irssi::Script::ascii" = { + ascii_not_connected = "%_$0:%_ You're not connected to server"; + ascii_not_window = "%_$0:%_ Not joined to any channel or query window"; + ascii_not_chanwindow = "%_$0:%_ Not joined to any channel"; + ascii_not_chanop = "%_$0:%_ You're not channel operator in {hilight $1}"; + ascii_figlet_notfound = "%_Ascii:%_ Cannot execute {hilight $0} - file not found or bad permissions"; + ascii_figlet_notset = "%_Ascii:%_ Cannot find external program %_figlet%_, usign /SET ascii_figlet_path [path], to set it"; + ascii_cmd_syntax = "%_$0:%_ $1, usage: $2"; + ascii_figlet_error = "%_Ascii: Figlet returns error:%_ $0-"; + ascii_fontlist = "%_Ascii:%_ Available fonts [in $0]: $1 ($2)"; + ascii_empty_fontlist = "%_Ascii:%_ Cannot find figlet fonts in $0"; + ascii_unknown_fontdir = "%_Ascii:%_ Cannot find figlet fontdir"; + ascii_show_line = "$0-"; + }; + "Irssi::Script::trackbar" = { + 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."; + }; + "Irssi::Script::adv_windowlist" = { + awl_display_nokey = "$N${cumode_space}$H$C$S"; + awl_display_key = "$Q${cumode_space}$H$C$S"; + awl_display_nokey_visible = "%2$N${cumode_space}$H$C$S"; + awl_display_key_visible = "%2$Q${cumode_space}$H$C$S"; + awl_display_nokey_active = "%1$N${cumode_space}$H$C$S"; + awl_display_key_active = "%1$Q${cumode_space}$H$C$S"; + awl_display_header = "%8$C|${N}"; + awl_name_display = "$0"; + awl_separator = " "; + awl_separator2 = ""; + awl_abbrev_chars = "~〜"; + awl_viewer_item_bg = "%0"; + awl_title = "\\Vawl\\:"; + }; + "Irssi::Script::trigger" = { + trigger_header = "Triggers:"; + trigger_line = "%#$[-4]0 $1"; + trigger_added = "Trigger $0 added: $1"; + trigger_not_found = "Trigger {hilight $0} not found"; + trigger_saved = "Triggers saved to $0"; + trigger_loaded = "Triggers loaded from $0"; + }; + "fe-text" = { + lastlog_too_long = "/LASTLOG would print $0 lines. If you really want to print all these lines use -force option."; + lastlog_count = "{hilight Lastlog}: $0 lines"; + lastlog_start = "{hilight Lastlog}:"; + lastlog_end = "{hilight End of Lastlog}"; + lastlog_separator = "--"; + lastlog_date = "%%F "; + refnum_not_found = "Window number $0 not found"; + window_too_small = "Not enough room to resize this window"; + cant_hide_last = "You can't hide the last window"; + cant_hide_sticky_windows = "You can't hide sticky windows (use /SET autounstick_windows ON)"; + cant_show_sticky_windows = "You can't show sticky windows (use /SET autounstick_windows ON)"; + window_not_sticky = "Window is not sticky"; + window_set_sticky = "Window set sticky"; + window_unset_sticky = "Window is not sticky anymore"; + window_info_sticky = "%#Sticky : $0"; + window_info_scroll = "%#Scroll : $0"; + window_scroll = "Window scroll mode is now $0"; + window_scroll_unknown = "Unknown scroll mode $0, must be ON, OFF or DEFAULT"; + window_hidelevel = "Window hidden level is now $0"; + statusbar_list_header = "%#Name Type Placement Position Visible"; + statusbar_list_footer = ""; + statusbar_list = "%#$[30]0 $[6]1 $[9]2 $[8]3 $4"; + statusbar_info_name = "%#Statusbar: {hilight $0}"; + statusbar_info_type = "%#Type : $0"; + statusbar_info_placement = "%#Placement: $0"; + statusbar_info_position = "%#Position : $0"; + statusbar_info_visible = "%#Visible : $0"; + statusbar_info_item_header = "%#Items : Name Priority Alignment"; + statusbar_info_item_footer = ""; + statusbar_info_item_name = "%# : $[35]0 $[9]1 $2"; + statusbar_not_found = "Statusbar is disabled: $0"; + statusbar_item_not_found = "Statusbar item doesn't exist: $0"; + statusbar_unknown_command = "Unknown statusbar command: $0"; + statusbar_unknown_type = "Statusbar type must be 'window' or 'root'"; + statusbar_unknown_placement = "Statusbar placement must be 'top' or 'bottom'"; + statusbar_unknown_visibility = "Statusbar visibility must be 'always', 'active' or 'inactive'"; + paste_warning = "Pasting $0 lines to $1. Press Ctrl-K if you wish to do this or Ctrl-C to cancel."; + paste_prompt = "Hit Ctrl-K to paste, Ctrl-C to abort?"; + irssi_banner = " ___ _%:|_ _|_ _ _____(_)%: | || '_(_-<_-< |%:|___|_| /__/__/_|%:Irssi v$J - https://irssi.org"; + welcome_firsttime = "- - - - - - - - - - - - - - - - - - - - - - - - - - - -\012Hi there! If this is your first time using Irssi, you%:might want to go to our website and read the startup%:documentation to get you going.%:%:Our community and staff are available to assist you or%:to answer any questions you may have.%:%:Use the /HELP command to get detailed information about%:the available commands.%:%:For Debian specific help type \"/connect OFTC\" and%:\"/join #debian\" (without the quotes) and ask your%:question.%:- - - - - - - - - - - - - - - - - - - - - - - - - - - -"; + welcome_init_settings = "The following settings were initialized"; + }; + "Irssi::Script::keepnick" = { + keepnick_crap = "{line_start}{hilight Keepnick:} $0"; + keepnick_add = "{line_start}{hilight Keepnick:} Now keeping {nick $0} on [$1]"; + keepnick_remove = "{line_start}{hilight Keepnick:} Stopped trying to keep {nick $0} on [$1]"; + keepnick_hold = "{line_start}{hilight Keepnick:} Nickkeeping deactivated on [$1]"; + keepnick_unhold = "{line_start}{hilight Keepnick:} Nickkeeping reactivated on [$1]"; + keepnick_list_empty = "{line_start}{hilight Keepnick:} No nicks in keep list"; + keepnick_list_header = ""; + keepnick_list_line = "{line_start}{hilight Keepnick:} Keeping {nick $0} in [$1] ($2)"; + keepnick_list_footer = ""; + keepnick_got_nick = "{hilight Keepnick:} Nickstealer left [$1], got {nick $0} back"; + }; + "Irssi::Script::nm2" = { + neat_style = " , , p , , c , t , , , "; + neat_action_style = " , p , , t , "; + neat_pad_char = "%K."; + neat_truncate_char = "%m+"; + neat_notruncate_char = ""; + neat_custom_modes = "&%B&%n | @%g@%n | +%y+%n"; + }; +}; diff --git a/.config/irssi/fctcplist b/.config/irssi/fctcplist @@ -1,9 +1,9 @@ time Time to get a watch -advert Server: hlirc.haydenvh.com, port: 6667, 6697 hitthisoneifyouareaflooder fuck off -version git://haydenvh.com/dotfiles (.config/irssi) away I dunno - might be away, might not be... you know, these aren't programmable they're just a string, heheheh -clientinfo PING VERSION TIME CLIENTINFO USERINFO WHOAMI ADVERT AWAY ping ~1958345676742784768726452647 whoami Why would I know? fuckoff no you +advert Server: irc.hlirc.net, port: 6667, 6697 +version Something better than what you have +clientinfo PING VERSION TIME CLIENTINFO WHOAMI ADVERT AWAY FUCKOFF diff --git a/.config/irssi/keepnick b/.config/irssi/keepnick @@ -1,9 +1,11 @@ -darkscience haydenh -efnet haydenh -freenode haydenh -genoce haydenh -hlircnet haydenh -nebulacentre haydenh +cyberia hhvn +dataswamp hhvn +efnet hhvn +freenode fr3en0de +genoce hhvn +hlircnet hhvn +nebulacentre hhvn rizon hhvn -sdf haydenh -unix haydenh +sdf hhvn +unix hhvn +unrealircd hhvn diff --git a/.config/irssi/log2ansi.pl b/.config/irssi/log2ansi.pl @@ -0,0 +1,412 @@ +#! /usr/bin/perl +# +# Copyright (C) 2002-2019 by Peder Stray <peder.stray@gmail.com> +# +# This is a standalone perl program and not intended to run within +# irssi, it will complain if you try to... + +use strict; +use Getopt::Long; +use Encode; +use Pod::Usage; + +use vars qw(%ansi %base %attr %old); +use vars qw(@bols @nums @mirc @irssi @mc @mh @ic @ih @cn); +use vars qw($class $oldclass); + +use vars qw{$VERSION %IRSSI}; +($VERSION) = '$Revision: 1.10 $' =~ / (\d+\.\d+) /; +%IRSSI = ( + name => 'log2ansi', + authors => 'Peder Stray', + contact => 'peder.stray@gmail.com', + url => 'https://github.com/pstray/irssi-log2ansi', + license => 'GPL', + description => 'Convert various color codes to ANSI colors, useful for log filtering and viewing.', + ); + +if (__PACKAGE__ =~ /^Irssi/) { + # we are within irssi... die! + Irssi::print("%RWarning:%n log2ansi should not run from within irssi"); + die "Suicide to prevent loading\n"; +} + +my $opt_clear = 0; +my $opt_html = 0; +my $opt_utf8 = 0; +my $opt_help = 0; + +GetOptions( + 'c|clear!' => \$opt_clear, + 'h|html!' => \$opt_html, + 'u|utf8!' => \$opt_utf8, + 'help' => sub { $opt_help = 1 }, + 'full-help' => sub { $opt_help = 2 }, + ) or pod2usage(2); + +# show some help if stdin is a tty and no files +$opt_help = 1 if !$opt_help && -t 0 && !@ARGV; + +pod2usage(-verbose => $opt_help, + -exitval => 0, + ) if $opt_help; + +for (@ARGV) { + if (/\.xz$/) { + $_ = "unxz < '$_' |"; + } + elsif (/\.bz2$/) { + $_ = "bunzip2 < '$_' |"; + } + elsif (/\.gz$/) { + $_ = "gunzip < '$_' |"; + } + elsif (/\.lzma$/) { + $_ = "unlzma < '$_' |"; + } +} + +my($n) = 0; +%ansi = map { $_ => $n++ } split //, 'krgybmcw'; + +@bols = qw(bold underline blink reverse fgh bgh); +@nums = qw(fgc bgc); + +@base{@bols} = qw(1 4 5 7 1 5); +@base{@nums} = qw(30 40); + +@mirc = split //, 'WkbgRrmyYGcCBMKw'; +@irssi = split //, 'kbgcrmywKBGCRMYW'; + +@mc = map {$ansi{lc $_}} @mirc; +@mh = map {$_ eq uc $_} @mirc; + +@ic = map {$ansi{lc $_}} @irssi; +@ih = map {$_ eq uc $_} @irssi; + +@cn = qw(black dr dg dy db dm dc lgray dgray lr lg ly lb lm lc white); + +sub defc { + my($attr) = shift || \%attr; + $attr->{fgc} = $attr->{bgc} = -1; + $attr->{fgh} = $attr->{bgh} = 0; +} + +sub defm { + my($attr) = shift || \%attr; + $attr->{bold} = $attr->{underline} = + $attr->{blink} = $attr->{reverse} = 0; +} + +sub def { + my($attr) = shift || \%attr; + defc($attr); + defm($attr); +} + +sub setold { + %old = %attr; +} + +sub emit { + my($str) = @_; + my(%elem,@elem); + + if ($opt_clear) { + # do nothing + } + else { + + if ($opt_html) { + my %class; + + for (@bols) { + $class{$_}++ if $attr{$_}; + } + + for (qw(fg bg)) { + my $h = delete $class{"${_}h"}; + my $n = $attr{"${_}c"}; + next unless $n >= 0; + $class{"$_$cn[$n + 8 * $h]"}++; + } + + $class = join " ", sort keys %class; + + print qq{</span>} if $oldclass; + print qq{<span class="$class">} if $class; + $oldclass = $class; + } + else { + my(@clear) = ( (grep { $old{$_} > $attr{$_} } @bols), + (grep { $old{$_}>=0 && $attr{$_}<0 } @nums) + ); + + $elem{0}++ if @clear; + + for (@bols) { + $elem{$base{$_}}++ + if $attr{$_} && ($old{$_} != $attr{$_} || $elem{0}); + } + + for (@nums) { + $elem{$base{$_}+$attr{$_}}++ + if $attr{$_} >= 0 && ($old{$_} != $attr{$_} || $elem{0}); + } + + @elem = sort {$a<=>$b} keys %elem; + + if (@elem) { + @elem = () if @elem == 1 && !$elem[0]; + printf "\e[%sm", join ";", @elem; + } + } + } + + if ($opt_html) { + for ($str) { + s/&/&amp;/g; + s/</&lt;/g; + s/>/&gt;/g; + } + } + + print $str; + + setold; +} + +if ($opt_html) { + print qq{<div class="loglines">\n}; +} + +if ($opt_utf8) { + binmode STDIN, ':bytes'; #encoding(cp1252)'; + binmode STDOUT, ':utf8'; +} + +while (<>) { + if ($opt_utf8) { + my $line; + while (length) { + $line .= decode("utf8", $_, Encode::FB_QUIET); + $line .= substr $_, 0, 1, ""; + } + $_ = $line; + } + + chomp; + + def; + setold; + + if ($opt_html) { + printf qq{<div class="logline">}; + } + + while (length) { + if (s/^\cB//) { + # toggle bold + $attr{bold} = !$attr{bold}; + + } elsif (s/^\cC//) { + # mirc colors + + if (/^[^\d,]/) { + defc; + } else { + + if (s/^(\d\d?)//) { + $attr{fgc} = $mc[$1 % 16]; + $attr{fgh} = $mh[$1 % 16]; + } + + if (s/^,//) { + if (s/^(\d\d?)//) { + $attr{bgc} = $mc[$1 % 16]; + $attr{bgh} = $mh[$1 % 16]; + } else { + $attr{bgc} = -1; + $attr{bgh} = 0; + } + } + } + + } elsif (s/^\cD//) { + # irssi format + + if (s/^a//) { + $attr{blink} = !$attr{blink}; + } elsif (s/^b//) { + $attr{underline} = !$attr{underline}; + } elsif (s/^c//) { + $attr{bold} = !$attr{bold}; + } elsif (s/^d//) { + $attr{reverse} = !$attr{reverse}; + } elsif (s/^e//) { + # indent + } elsif (s/^f([^,]*),//) { + # indent_func + } elsif (s/^g//) { + def; + } elsif (s/^h//) { + # cleol + } elsif (s/^i//) { + # monospace + } else { + s/^(.)(.)//; + my($f,$b) = map { ord($_)-ord('0') } $1, $2; + if ($f<0) { +# $attr{fgc} = -1; $attr{fgh} = 0; + } else { + # c>7 => bold, c -= 8 if c>8 + $attr{fgc} = $ic[$f]; + $attr{fgh} = $ih[$f]; + } + if ($b<0) { +# $attr{bgc} = -1; $attr{bgh} = 0; + } else { + # c>7 => blink, c -= 8 + $attr{bgc} = $ic[$b]; + $attr{bgh} = $ih[$b]; + } + } + + } elsif (s/^\cF//) { + # blink + $attr{blink} = !$attr{blink}; + + } elsif (s/^\cO//) { + def; + + } elsif (s/^\cV//) { + $attr{reverse} = !$attr{reverse}; + + } elsif (s/^\c[\[([^m]*)m//) { + my(@ansi) = split ";", $1; + my(%a); + + push @ansi, 0 unless @ansi; + + for my $code (@ansi) { + if ($code == 0) { + def(\%a); + } elsif ($code == $base{bold}) { + $a{bold} = 1; + } elsif ($code == $base{underline}) { + $a{underline} = 1; + } elsif ($code == $base{blink}) { + $a{underline} = 1; + } elsif ($code == $base{reverse}) { + $a{reverse} = 1; + } elsif ($code => 30 && $code <= 37) { + $a{fgc} = $code - 30; + } elsif ($code => 40 && $code <= 47) { + $a{bgc} = $code - 40; + } else { + $a{$code} = 1; + } + } + + if ($a{fgc} >= 0 && $a{bold}) { + $a{fgh} = 1; + $a{bold} = 0; + } + + if ($a{bgc} >= 0 && $a{blink}) { + $a{bgh} = 1; + $a{blink} = 0; + } + + for my $key (keys %a) { + $attr{$key} = $a{$key}; + } + + } elsif (s/^\c_//) { + $attr{underline} = !$attr{underline}; + + } else { + s/^(.[^\cB\cC\cD\cF\cO\cV\c[\c_]*)//; + emit $1; + } + } + + def; + emit ""; + if ($opt_html) { + print "</div>"; + } + print "\n"; +} + +if ($opt_html) { + print "</div>\n"; +} + +__END__ + +=head1 NAME + +log2ansi - Convert foo various color escape codes to ANSI (or strip them) + +=head1 SYNOPSIS + +B<log2ansi> +[B<-c>|B<--clear>] +[B<-h>|B<--html>] +[B<-u>|B<--utf8>] +[B<--help>] +[I<logfile ...>] + +=head1 OPTIONS + +=over + +=item B<-c>, B<--clear> + +Instructs B<log2ansi> to clear all formatting and output plain text logs. + +=item B<-h>, B<--html> + +Instructs B<log2ansi> to output a HTML fragment instead of ANSI text. + +The whole log will be wrapped in a div with class C<loglines>, each line +of the log in a div with class C<logline>. Colors are wrapped in spans, +with a class name consisting of C<fg> or C<bg>, concatenated with the +color name, either C<black> or C<white>, or C<r>, C<g>, C<b>, C<c>, +C<m>, C<y>, or C<gray> prefixed with either C<l> for light, or C<d> for +dark. + +You have to include appropriate CSS yourself to get any colors at all +when viewing the log. + +=item B<-u>, B<--utf8> + +This forces output to be UTF-8, and does input decoding of UTF-8 with +fallback to ISO-8859-1. Use this if your input logs have mixed UTF-8 +and ISO-8859-1. + +=item B<--help>, B<--full-help> + +Show help, either just option descriptions or a full man page. + +=back + +=head1 DESCRIPTION + +Use B<log2ansi> to convert logfiles from Irssi with internal escape +codes, mIRC color codes or ANSI escapes to plain text with ANSI +formatted color codes for viewing in a terminal. + +Use the B<--clear> option to strip all formatting escapes and output +just plain text. + +You can supply input on standard input, or as filenames on the command +line. Any file ending in B<.gz>, B<.bz2>, B<.xz> or B<.lzma> will be +uncompressed automatically before processing. + +=head1 AUTHORS + + Peder Stray <peder.stray@gmail.com> + +=cut diff --git a/.config/irssi/modules/libtheme_indent.so b/.config/irssi/modules/libtheme_indent.so Binary files differ. diff --git a/.config/irssi/pipeline.theme b/.config/irssi/pipeline.theme @@ -15,6 +15,7 @@ abstracts = { # abstracts that do not take arguments - only for replicating certain text line_start = ""; timestamp = "%G%%H:%%M%b "; + pad = " "; # usage agnostic text hilighting hilight = "%_$*%_"; @@ -39,11 +40,11 @@ abstracts = { # hilighting with nickcolor-expando.pl pubnick = "%w$nickcolor$*"; # constructs for basic message - msgnick = "$0$1%K %_|%_%N "; - himsg = "$0$1%K %_#%_%N "; + msgnick = "$0$1%K %_│%_%N "; + himsg = "$0$1%M %_#%_%N "; nticenick = "$0$1%K %_:%_%N "; askctcp = "$0$1%K %_?%_%N%_ "; - ansctcp = "$0$1%K %_A%_%N%_ "; + ansctcp = "$0$1%M %_A%_%N%_ "; # msgs ownmsgnick = "{msgnick $0 $1-}"; @@ -52,24 +53,24 @@ abstracts = { ownprivmsgnick = "{msgnick $*}"; privmsgnick = "{msgnick $*}"; privmsg = "{himsg %R<---$0}$1}"; - ownprivmsg = "{msgnick $0%K--->$1}$2}"; + ownprivmsg = "{msgnick %K--->$1}$2}"; ownprivnick = "%W$0%n%w"; # used internally for actions - action_core = " %w*%w%_$0%_ $1"; + action_core = "{pad}%w*%w %K│ %_$0%_ $1"; action_nsp = "%w*%w%_$0%_ $1"; # actions pvaction = "%R<---{action_nsp $0 $1}"; - ownaction_target = "$0%K--->$1{action_nsp $0}"; + ownaction_target = "%K--->$1{action_nsp $0}"; # notices - ownnotice = "{nticenick $0%K--->$1}$2}"; - notice = " {nticenick {nick $*}}%N"; + ownnotice = "{nticenick %K--->$1}$2}"; + notice = " {nticenick $nickcolor$*}%N"; servernotice = "%w!$*%n "; # CTCPs - ownctcp = "{askctcp {ownnick $N}%K--->$0}$1"; + ownctcp = "{askctcp %K--->$0}$1"; ctcp = "{ansctcp %R<---$1}$0:%_ $2-"; rctcp = "{askctcp %R<---$0}$1"; @@ -116,11 +117,12 @@ abstracts = { sb_uc_voices = "%_.+%_%G/%Y$*%n"; sb_uc_normal = "%_.%_%G/%W$*%n"; sb_uc_space = " "; - sb_act_hilight = "%M$*"; - sb_act_hilight_color = "$0$1-%n"; - sb_act_sep = "%c$*"; - sb_act_text = "%c$*"; - sb_act_msg = "%W$*"; + sb_act_hilight = "%M%_X%_%N$*"; + sb_act_hilight_color = "%M%%%N$*"; + sb_act_sep = "%N$*"; + sb_act_text = "%c-%N$*"; + sb_act_msg = "%W*%N$*"; + sb_act_none = " $*"; sb_topic = "%0$* "; # other @@ -128,27 +130,33 @@ abstracts = { whois = "| $[8]0 : $1-"; whowas_begin = "|-WHOWAS---:-------------------------->"; who___end = "'----------'-------------------------->"; + # keepnick + keepnick = "{line_start} {hilight Keepnick} %K│%N $*"; + + # indent (https://github.com/irssi-import/modules/blob/master/theme-indent.c) + indent_default = " {pad} %K│ "; + level_hilight = " {pad} %M# "; }; # %r%n%_$0%_$1%K |%n %| formats = { "fe-common/core" = { # excuse the ugly as hell formats here, blame nm2.pl - pubmsg = "$nickalign{pubmsgnick %G$2 {pubnick $0}$nicktrunc}$1"; - join = "%_%W+{pubnick %_$0%_}!$1"; - part = "%_%G-%_{pubnick %_$0%_}!$1 {reason $3}"; - kick = "%_%G!%_$0 %n%wby {pubnick $2}, {reason $3}, from $1"; - quit = "%_%G<%_{pubnick %_$0%_}!$1 {reason $2}"; - own_msg = "$nickalign{ownmsgnick %G$2 {ownnick $0}$nicktrunc}$1"; - own_msg_channel = "$nickalign{ownmsgnick %G$3 {ownnick $0}$nicktrunc{msgchannel $1}}$2"; - pubmsg_me = "$nickalign{pubmsgmenick %G$2 {pubnick $0}$nicktrunc}$1"; - pubmsg_me_channel = "$nickalign{pubmsgmenick %G$3 {pubnick $0}$nicktrunc{msgchannel $1}}$2"; - pubmsg_hilight = "$nickalign{pubmsgmenick %G$3 {pubnick $1}$nicktrunc}$2"; - pubmsg_channel = "$nickalign{pubmsgnick %G$4 {pubnick $0}$nicktrunc{msgchannel $1}}$2"; + pubmsg = "$nickalign{pubmsgnick %G$2 {pubnick $[.9]0}$nicktrunc}$1"; + join = "{pad}%_%W+ %K│ {pubnick %_$0%_}!$1"; + part = "{pad}%_%G-%_ %K│ {pubnick %_$0%_}!$1 {reason $3}"; + kick = "{pad}%_%G!%_ %K│ $0 %n%wby {pubnick $2}, {reason $3}, from $1"; + quit = "{pad}%_%G<%_ %K│ {pubnick %_$0%_}!$1 {reason $2}"; + own_msg = "$nickalign{ownmsgnick %G$2 {ownnick $[.10]0}$nicktrunc}$1"; + own_msg_channel = "$nickalign{ownmsgnick %G$3 {ownnick $[.10]0}$nicktrunc{msgchannel $1}}$2"; + pubmsg_me = "$nickalign{pubmsgmenick %G$2 {pubnick $[.9]0}$nicktrunc}$1"; + pubmsg_me_channel = "$nickalign{pubmsgmenick %G$3 {pubnick $[.9]0}$nicktrunc{msgchannel $1}}$2"; + pubmsg_hilight = "$nickalign{pubmsgmenick %G$3 {pubnick $[.9]1}$nicktrunc}$2"; + pubmsg_channel = "$nickalign{pubmsgnick %G$4 {pubnick $[.9]0}$nicktrunc{msgchannel $1}}$2"; chanmode_change = " {$channel $1} {nick $2} %nsets mode %W{$mode $1}"; channel_mode = " {$channel $0} {nick $2} %nsets mode %W{$mode $1}"; - nick_changed = "{pubnick $0}%w %_-->%_ $1"; + nick_changed = "{pad} %K│ {pubnick $0}%w %_-->%_ $1"; # names endofnames = "{channel $0}: {hilight $1} nicks ({comment @/{hilight $2} +/{hilight $3} -/{hilight $4}})"; @@ -158,7 +166,7 @@ formats = { line_start = "{line_start}"; line_start_irssi = "{hilight}"; servertag = "[$0] "; - daychange = " %_----%_ %%d %%b %%Y %_----%_"; + daychange = " {pad} %K│ %_----%_ %%d %%b %%Y %_----%_"; talking_with = "You are now talking with {nick $0}"; # windows @@ -199,7 +207,7 @@ formats = { # servers looking_up = "Looking up {server $0}"; - connecting = "Connecting to {server $0} [$1] port {hilight $2}"; + connecting = "Connecting to {server $0} [$1] port {hilight $2} -- Remember: on irc nobody knows you're a dog"; reconnecting = "Reconnecting to {server $0} [$1] port {hilight $2} - use /RMRECONNS to abort"; connection_established = "Connection to {server $0} established"; cant_connect = "Unable to connect server {server $0} port {hilight $1} {reason $2}"; @@ -246,7 +254,7 @@ formats = { chansetup_footer = ""; own_msg_private = "{ownprivmsg {ownnick $N} {pubnick $0} $1}"; own_msg_private_query = "{ownprivmsgnick {ownprivnick $2}}$1"; - pubmsg_hilight_channel = "$nickalign{pubmsgmenick %G$4 {pubnick $1$nicktrunc{msgchannel $2}}$3"; + pubmsg_hilight_channel = "$nickalign{pubmsgmenick %G$4 {pubnick $[.9]1$nicktrunc{msgchannel $2}}$3"; msg_private = "{privmsg {pubnick $0}}$2"; msg_private_query = "{privmsgnick $0}$2"; no_msgs_got = "You have not received a message from anyone yet"; @@ -385,8 +393,8 @@ formats = { whois = "{whois_begin}%:{whois nick %|{hilight $0}}%:{whois host %|$2}%:{whois ident $|$1}%:{whois comment %|$3}"; server_chanmode_change = "%RServermode: {mode $1} by {server $2}"; whois_server = "{whois server %|$1 ({comment $2})}"; - own_action = "$nickalign{action_core {ownnick $0$nicktrunc}}$1"; - action_public = "$nickalign{action_core {pubnick $0$nicktrunc}}$1"; + own_action = "{action_core {ownnick $0$nicktrunc}}$1"; + action_public = "{action_core {pubnick $0$nicktrunc}}$1"; away = "%_%G----->"; unaway = "%_%W<-----"; end_of_whois = "{who___end}"; @@ -496,13 +504,13 @@ formats = { accept_list = "Accepted users: {hilight $0}"; }; "Irssi::Script::adv_windowlist" = { - awl_display_nokey = "%N $H$C$S %N$N"; - awl_display_key = "%N $H$C$S%N %mM-$Q"; - awl_display_nokey_active = "%N%K $C %N$N"; - awl_display_key_active = "%N%K $C %mM-$Q"; + awl_display_nokey = "%N$H$C$S %N$N"; + awl_display_key = "%N$H$C$S%N %mM-$Q"; + awl_display_nokey_active = "%N%K>%N$C %N$N"; + awl_display_key_active = "%N%K>%N$C %mM-$Q"; awl_display_header = "%1 %Y$C (${N})"; - awl_display_nokey_visible = "%N%K $C %N$N"; - awl_display_key_visible = "%N%K $C %mM-$Q"; + awl_display_nokey_visible = "%N%K<%N$C %N$N"; + awl_display_key_visible = "%N%K<%N$C %mM-$Q"; awl_name_display = "$0"; awl_separator = " "; awl_separator2 = ""; @@ -684,7 +692,7 @@ formats = { keepnick_list_header = ""; keepnick_list_line = "{line_start}{hilight Keepnick:} Keeping {nick $0} in [$1] ($2)"; keepnick_list_footer = ""; - keepnick_got_nick = "%N{hilight Keepnick:} Nickstealer left [$1], got {nick $0} back"; + keepnick_got_nick = "{keepnick Nickstealer left [$1], got {nick $0} back}"; }; "Irssi::Script::nm2" = { neat_style = " , p , , , , , t , , ,"; diff --git a/.config/irssi/saved_nick_colors b/.config/irssi/saved_nick_colors @@ -0,0 +1,11679 @@ +[set] +/:1Z +/408AAAAA7:4G +/408AAAAAG:3A +/92AABC12T:0A +/A0c:3H +/AAAAAAAAAAAAAAAAAAAAAAAAAA:0D +/AAAAAAAAAAAAAAAAAAAAAAAAAAAA:4C +/AAAAAAAAAAAAAAAAAAAAAAAAAAAAA:25 +/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:42 +/AAAAAAAAAAB:03 +/AAG:1U +/AARRSS:3M +/ACGZ:2T +/ADL:6C +/AG:3A +/AG15:1C +/AG4:4G +/AGG:3H +/AG_:51 +/AIM:1C +/AJ:40 +/AKP:42 +/AK_47:3A +/AL:51 +/ALAKTORN:4N +/ANCAP95:3C +/ANNA:4N +/ANNA-:3P +/ANNA_:2D +/ANNA`:4N +/ANNa:3C +/AOC:4C +/AOC_:6B +/ARS:2T +/ARSE:6C +/ARSv2:3C +/ATMOS:2D +/ATMOS|2:63 +/ATMOS|3:0A +/ATMOS|4:5E +/ATMOS|41:4N +/AV3NG3R:3H +/AYC:6H +/AYYYYYYYYYLMAO:0C +/AaThai:4N +/Aaaaand:3A +/Aakoy:6H +/Aayush:1C +/AbigailK:0A +/Absalom:3H +/Acer_:25 +/Acer__:03 +/AdDeRaLL:4N +/Adam:03 +/Addgg:3M +/Addie:1C +/Adie:1C +/Adiemus:03 +/Adle:0C +/Admin:3A +/AdminServ:2T +/AdmiraL:09 +/Adra:4G +/AdrameleK:42 +/AdrameleK_:25 +/AdrianDX:40 +/Adrian_DX:6A +/AePhi:3A +/Aecait:42 +/Aecheu:0C +/Aefeic:3C +/Aekae:51 +/Aenri:1C +/Aenri1:25 +/Aequer:6H +/Aeres:4G +/Aeres-:25 +/AfroJack:09 +/AfroNigga:42 +/AfroNukka:6C +/Afrteen:3C +/Agadashi:0A +/Agadashi_:09 +/Agarian79:4G +/Agbalu:1U +/AhHsajJAf:4N +/Ahcho:1C +/Ahgeo:25 +/AhmedDsa:1Z +/Ahmedkh:2D +/Ahmos:5E +/Ahnberg:2J +/Ahosh:6C +/Ahqui:3A +/AiChup:1C +/AiRah:0A +/Aide:6H +/AifieW:63 +/Aifiw:63 +/Aijaki:2T +/AimHere:0A +/Aipahh:3C +/Airplane:09 +/Aishah:6H +/Ajannie:0C +/Aki-lucky:5E +/AkibaDeep:6H +/AlLMfryoE:4N +/Alaura:0A +/AlbertEncode:2J +/AlbertEncode2:6B +/AlbozZ:6H +/Alchemica:09 +/Alchemical:3C +/AlexBigCheese:0D +/AlexBigCheese3:3A +/AlexBigCheese4:2J +/AlexBigCheese5:1C +/AlexBigCheese53:6C +/AlexBigCheese7:3M +/AlexBigCheese8:4N +/AlexBigCheese9:6C +/AlexBigCheese98:2D +/AlexC:1C +/AlexCato:4G +/AlexCato_:3A +/Alfah:0D +/Alga:3M +/Alhazred:42 +/Alhazred_:0D +/Alice_:51 +/Alien88:4C +/Alina25:4G +/Alives:03 +/AlkaSeltzer:4N +/AllY0urB4:51 +/Alliance1911:6B +/Aloui:5E +/AlphaChadBro:0C +/Alpherior:2T +/Alphi:0D +/Alphminster:0D +/AlrightIconcede:2T +/AltOption:5E +/AltaVista:4G +/AlterEgo_:0D +/AlterEgo__:03 +/Altey:6B +/Am:6C +/Amanda:3A +/AmandaB:1C +/AmberJ_:0C +/Amethyst:1C +/Amiga600:2D +/AmigaGod:09 +/AmorPropa:3C +/AmputatedFatGoose:4G +/Amsterdam:1C +/An01nt3d_0n3_:2D +/AnEnemySpotted:6C +/Ana:25 +/Anayx:03 +/Ancient:0A +/AndChat|479316:6H +/AndChat|730100:6H +/Andrey:3M +/AndroSyn:1C +/AndroUser:3C +/AndroUser2:0C +/AndroidHackedBy-maph3r1us:51 +/AndroidUS:63 +/AndyPratt:09 +/Anemone:5E +/Ann:4N +/Anna:0A +/AnnaCutas:4N +/AnnaDina:1C +/AnnaFiona:42 +/AnnaGames20:3C +/AnnaGr:1Z +/AnnaHater:0C +/AnnaRizona:4N +/AnnaSex:63 +/Annette:3C +/Anon-a-mo:03 +/Anon7of10:5E +/Anon7of11:5E +/AnonRadio_|43832:5E +/AnonRadio_|62947:63 +/Anon_7424:0C +/Anonamoos:63 +/Anonymoos:1Z +/Anonymou1:0D +/Anonymous:1Z +/Anselmo:4N +/Ansikteoolo:03 +/Anth0mk:2T +/Anthony:63 +/Antipeace:6C +/Anubis169:6B +/Anubis169|Away:63 +/Anymouse:3C +/Anzerfaus:6C +/Anzrael:1Z +/Aocho:3C +/Aoyagi:09 +/Aoyagi_mehtop:42 +/Aoyagi_raventop:4N +/Apenasvejo:51 +/Aph3x:4C +/Apocalypse:6B +/Apostata:4G +/Appb:3C +/April26:5E +/AqTVUxSmx:3H +/Aqua:3C +/Aragon:4C +/Arbit3r:4N +/Arbiter:1Z +/Architect:3C +/Arden:0D +/AreH:6B +/Area66:1C +/Argetlam:5E +/Ariana:09 +/Ariana16:3M +/ArianaGrande:6B +/Arirang:09 +/Arirang_:51 +/Arisu_:42 +/Arizu:4C +/Armageddon:2J +/Armando:25 +/ArmedRobbo:6B +/Armen:09 +/Armen138:09 +/Armen8:6B +/Arnie:2T +/Arohyn:0A +/Arohyn3:0D +/Arohyn42:3M +/Arohyn420:6C +/Arohyn_J2081q:0A +/Arragon:4N +/Arthas:4N +/Aruseus:6B +/As:0C +/Asds:2J +/Asg23:6B +/Ashey:09 +/AshleyMoorz:4C +/Ashura666:25 +/Ashy:3A +/Asian:3A +/AspieAdie:6C +/Asriel:3C +/AssignedMale:42 +/Assivity:2T +/Astr1:2J +/Astr1_:03 +/AstroAI:51 +/AtHKvrpAR:6N +/Ataego:03 +/Atari:3C +/Atheri:0A +/Atlantic:6C +/Atlas:2T +/Atomen:42 +/Audasity:0C +/Audasity_:42 +/Audi:09 +/AudioRCA:3C +/Audi|Away:4C +/Austin^:25 +/Austo1212:6N +/AvVW:3M +/AverageJo:6H +/Avery:6C +/AvrilLavigne:03 +/AwayLurker:3C +/AwooRallyINC:3C +/AwoooooRallyINC:42 +/Axujen:3H +/Ayirog:03 +/Ayrton:3M +/Az:1Z +/Azelphur:0A +/Azero87:4N +/Azonic:0D +/Azrael:03 +/Aztec03:1U +/Aztec03_:6C +/Azyi:42 +/B:6C +/B1GSQU1D:6C +/B1ngIt:3P +/BASEMENT:51 +/BASEMENT_:03 +/BASHy2:03 +/BASHy2-EU:3H +/BBC:6C +/BCMCCMMNX:25 +/BEASTFACE:1C +/BHnL:3A +/BIALAS:3M +/BIRTHDAYchrissy:1Z +/BLM:2J +/BLMhater:1Z +/BLkx:4C +/BOMBA-FAT:5E +/BONKSCOUT:0A +/BOSSHAWG:3C +/BOSSHAWG_:40 +/BOSSHOG:3P +/BRAGG:6H +/BRB:51 +/BSHk:0A +/BUNDT_CAKE:2D +/BUNDT_CAKE_:42 +/BaBe:51 +/BaD_BoY:03 +/BackupBackupNickname:2D +/BadASS:6H +/BadBoneMoFo:0C +/Bahpur:2T +/Bahzi:42 +/Bakersfie:63 +/BallSac:0C +/Ballz:3M +/Balthazar:0C +/Balthazar_Bath_Bazaar:51 +/Balthazar_Destoryer:3M +/Balthazar_Destroyer:4C +/Barack:5E +/Baradium:0A +/Baron:2D +/Barry:3A +/Barry_:2J +/BasedAfrican:3C +/BasedDecoyPrincessKitana:4G +/Bashout:3H +/Basilisk:4G +/Batman:25 +/Bay-Guy:1C +/BeAsTaH:09 +/Beas:63 +/Beast:4C +/Beast_:51 +/Beauty:5E +/Beck:42 +/BeeNeeZ:6B +/BeefEats:4N +/BeefMode:4G +/Bekzz:6H +/Beleth:03 +/Belial:5E +/Bella26:3M +/BelugaChan:3H +/Belzebub:6C +/Ben:2D +/BenBernanke:6C +/BenBernanke414:4C +/BenLand100:2D +/Bender:1C +/Benett:03 +/Benjamin:51 +/Beran:2J +/Berger:0D +/Berger_:4C +/Bernard:2D +/Berserker:0C +/Bertha:51 +/Bertie^Wooster:3C +/Beth:3M +/Bethany:6C +/Betrachtu:3C +/Betrayedu:25 +/Betty:09 +/BeyoundCringePubeFace:1C +/Bifrost:3C +/BigD:6H +/BigDadE:4G +/Big_M:1C +/Bigphin:4C +/Bigphin_:6B +/Bilirubin:6B +/BillGates:4G +/BingIt:1Z +/BitBot:4N +/BitSplash:3A +/Bitch:0C +/BitcoinFo:1C +/BitcoinMarkets:2D +/BitconFox:42 +/Biznz:51 +/Bizooga:63 +/BlAkDogg:3A +/Black-Mug:51 +/BlackAss`:42 +/BlackMug:3H +/BlackSails:09 +/BlackSails_:6H +/Blackhawk:51 +/Blackwhite:6B +/Blaine:2T +/Blanker:1Z +/Blanker3:1U +/Blanker37:6C +/BlinkinFl:4C +/Blode:5E +/Blossy:2J +/Blossy_:0A +/Blue:09 +/BlueOystr:6H +/Blumpkin:5E +/Blumpkin_:42 +/BoBeR:3A +/BoBeR182:1C +/Bobby:2T +/BobbyBoulders:0A +/Bobo_36_M:1Z +/Bohyi:3C +/Bolero:6H +/Bollox:0D +/Bollox_:1C +/Bollox__:42 +/BonafideL:09 +/Bones:42 +/Bones_:0A +/BonnGerm:2T +/Boolz:2J +/BootlegJo:4N +/Botnet:4N +/Botsen:2D +/BottyMcBotface:4G +/Botulf:42 +/Bourbon:09 +/Bovdin:5E +/Bowery:0C +/Bozg:63 +/BradCoom:25 +/Bradley:63 +/Brag:6H +/Brainium:4C +/BreannaTa:4G +/Brenda:2T +/BrewerKit:5E +/Brewster:0A +/Brewster_the_chicken:5E +/Briana:6H +/Broken_pi:2D +/Brooklyn:3M +/Bruce:2J +/BruceL:3C +/Bruh:4N +/BruntLIVE:4N +/Buckeyes:3P +/Bulgarian:3C +/BurnZeZ:2J +/Busterx:1Z +/ButchDeLoria:4N +/Buttercrotch:6C +/Butterscotch:03 +/Buvahf:25 +/Buzzard:3C +/Buzzard_:4C +/Buzzy:25 +/ByteLawd:4G +/ByteLord:1C +/BzbV:6H +/C0d3X:40 +/C0m|ck:42 +/C1YNkXaf:25 +/C1v1l:1Z +/C1v|l:4C +/CAP1891:6H +/CAP4567:2J +/CAPdaFLAG:0A +/CATS:6C +/CC66:1C +/CCFL_Man:6C +/CCP:4C +/CDEFG:1C +/CDPervert58:51 +/CG-Office-2:6C +/CHAN_FIX:6B +/CHARLES:3H +/CHOMODEL:09 +/CIAnigger:51 +/CMJk:2J +/CMvt:2D +/COOL_MAN_:40 +/CORVID-19:63 +/CORY^1981:03 +/COVID19:3C +/CRISPR:2J +/CRImier:5E +/CT:25 +/CYbEwznGT:3P +/C_Monster:42 +/CaNNoN:4C +/CaNNoN_:0C +/CaPiTaN:6C +/Caku:63 +/Callabro:3A +/CamVal3:09 +/Canadian:2D +/Canadoey:4G +/CannaCo:0C +/Cano:3C +/CapCIAS_:6C +/CapOOF:2J +/CapOOF_:6C +/CapOOF__:25 +/CapablePresident:4N +/Capheind:1Z +/CapitalGain:09 +/Captain4LK:3H +/CaptainJack:03 +/Captain_Homosexxor:3C +/Carbone5:42 +/Cardinal_:3C +/CarlosHe:2D +/Carp:03 +/Casey:3H +/Cassim:51 +/CatMan:6B +/CatSlayer:6H +/CatValentine:5E +/Cat_hunter:25 +/Catherine:3C +/CatoAlex:3C +/Caz81:25 +/CcOFjf4:6H +/CcxWrk:4C +/CeVVaL-c:09 +/CeeCha:6C +/CeeChu:6C +/Celebrity:6B +/Celelibi:09 +/Celine:2T +/Celine_:6B +/Cenbe:09 +/Ceq:3C +/Cequel:4G +/CertifiedRapist:2D +/Chad_Thundercock:6H +/ChanHold:51 +/ChanServ:42 +/ChanStat:2T +/Chandra:4C +/Chang:2T +/Chang_:6C +/Chang__:25 +/Chang___:6B +/Charles:3A +/ChatBottl:0C +/CheRRy218:3A +/CheRRy2fl:2D +/CheRRy2fly21:03 +/CheeseNCrackers:0D +/Cheeseman:5E +/Cherub:3A +/ChewBaka:6C +/Chewy:6H +/Chex:4N +/Chex_:3H +/Chicanx:42 +/Chickadee:1Z +/ChimpNayshYall:09 +/ChipsHandon:09 +/ChipsMusicVonTrappeHandon:25 +/Choco:63 +/ChocolateServ:4G +/Christine:3H +/Christistheway:0D +/Christopher:3C +/Chriz:42 +/Chromanin:3H +/Chuckie:6B +/Chucks:3C +/Chungos:09 +/CiaPh:0C +/Cinderella_Man:4G +/Cinderfel:1C +/Civ1l:03 +/Civil:6H +/Civil-:25 +/Civil_:0A +/Civ|l:2D +/Cjefke:2J +/ClZy:5E +/Clamkin:3H +/Clamkin-:51 +/Clarence:3A +/Claudine:6H +/Clefairy:51 +/Clevela17:2T +/Cleveland:4N +/Clockweig:3C +/ClockworkCoder:6B +/CloroxMan:2B +/ClownPoss:09 +/Co-Op:2J +/CoCaInE-:3C +/CoDeInE:25 +/CoDeInE-:2T +/CoMBo:5E +/CoViD-:3C +/CoViD_:09 +/Cockroach:6C +/Cockzilla:3A +/CodeMasta:3A +/Code_Red:1C +/Codemaste:6C +/Codexx:51 +/Codexx_:63 +/Coffee:1C +/CoffeeInc:1Z +/Cog:63 +/Cogitabun:42 +/ColDecker:4G +/Coldblack:4N +/ColeSlaw:0C +/ComfortablyDumb:3M +/ComfortablyNumb:6B +/Communist:3H +/Computer-:4N +/ComputerTech:3A +/ComputerTech_:0D +/Computer^:25 +/Computersarebadat:5E +/Computer|:63 +/ConEdison:1Z +/ConEdison2:2T +/ConEdison5:4C +/Connie:03 +/ConnorWil:25 +/ConnorWilliams:2T +/ConsmueristProvocateur:3A +/ConspiracyProof:0A +/ConsumeristProvocateur:4G +/Coonyarro:6B +/Corazoni:2D +/CorbinDallas:2D +/Core5113:3H +/CoreDuo:0D +/CoronaCri:1C +/CosmicRay:5E +/Cosmicjoker:4N +/Cosmicjoker_:4G +/Cr0no:0A +/Cr0no-:2D +/Cragnathar:0C +/Crapwrongnick:3C +/CrashTM:51 +/CrazyPal:3A +/CrazyPale:3H +/CrazyRobLolzors:2J +/CrazyRoboCrumbs:51 +/Crazyout:0A +/Creator:3H +/CrepeMake:4N +/CrimisoK:3C +/Crissy:6C +/CrocSmith:6C +/Crocodile:3M +/Cromu`:09 +/Cron0:63 +/Crono:1C +/Crono-:2T +/Crono--:2D +/Crono\:4G +/Crono_:3H +/Cronoli:1C +/Cronus:2J +/Crow:6C +/Crow-:3H +/Crow_:0C +/Crow_0:4G +/Crow_1:2D +/Crow_2:3M +/Crow_3:6C +/Crow_6:1C +/Crow_8:6B +/CrtxReavr:4G +/Crust:2D +/Crustie:4G +/Crustie_:3H +/CryMaster:6B +/Crystal:6B +/CrystalSoldier:03 +/Ctrl:2J +/Cuckoo:1Z +/Cuonee:6H +/Cyb3RALis:3M +/Cybaria:6B +/CyberBit:63 +/CyberGlo:3M +/CyberManifest:0A +/CyberOne:3A +/CyberOne_:1Z +/CyberOnne:1C +/CyberThre:6B +/CyberTrekker:4N +/CyberTwo:6B +/CyborgPerson:2D +/Cyosc:09 +/Cypher:3M +/CypherBlo:25 +/Cyrus:51 +/CythSide:2T +/Cythraul:3M +/Cythside:0D +/D:4G +/D00:6H +/D0m3r:4C +/D4nny:6N +/D8RainA:25 +/DAJlKjaXG:2D +/DASPRiD1:1C +/DBoyz:4G +/DBoyz[A]:03 +/DG:51 +/DIARRHEA_GARGLER_69:51 +/DJTrump:2T +/DJ_AA:4G +/DNX2JNLIG:2J +/DNuD:5E +/DOGWATER:63 +/DOX_SALE:25 +/DOYouNo:09 +/DPA:0C +/DPA-:0C +/DRUGS:2J +/DSyndrome:6C +/DTales:5E +/DZLFKNWZL:6H +/DZLWZL:4G +/D_A_N:2J +/D_A_N_:03 +/DaCeige:3M +/DaCe|ge:4G +/Da_KO:4C +/DadBundy:6B +/DaddyState:42 +/Daemonk:1C +/Dajjal_1:1Z +/Dak22:4C +/Daler:0C +/DanLeroux:0C +/DanMatrix:3M +/Dangelo54:1Z +/Daniel:2T +/Danny:6A +/Daria11:1Z +/Darius:1Z +/DarkCider:5E +/DarkHelp:5E +/DarkLore:03 +/DarkV3n:0A +/Darn:3H +/Darn_:4G +/Darn__:3C +/Darn___:6B +/Darnme:2T +/Darnn:1C +/Darnn_:09 +/Darnn__:3M +/Darnn___:40 +/Darnwise:0A +/DarwinElf:3A +/DasBot:4G +/DateMasamune2000:6C +/DaveCafe:0A +/Dave_2794:6A +/David:51 +/DavidDuke:25 +/Dbsy:2D +/Deadpool:2D +/Deaht_Syn:1C +/Dean:3A +/Death_Syn:03 +/Deborah:1C +/Debra:0C +/DecadePlus:3M +/DedBundy:2T +/DedBundy_:63 +/Def_Starr:3H +/DefuserKi:4G +/Deliveran:4C +/Democrat:3M +/DeppaMann:1C +/Depressionfries:1C +/DerMann:0D +/Derecho:3H +/DerpGusta:09 +/Derp_:6C +/Deryk:4G +/Desire:2J +/Dessimat0r:0C +/Destoya:4G +/DeusVult:42 +/Deus_Vult:4G +/Develon:3C +/DeviL:1C +/Deviance-:51 +/Deviancee:0A +/DevilFox:3P +/Dflp:6H +/Dgby714:2T +/Dghjjb:25 +/Dhejavu_:0C +/DiamondTiara:03 +/DiamondTiara1:3M +/Diamondtiara:3M +/Diana:6H +/Diannao:3C +/Diavolo:2J +/DickInHand:3H +/Dicksucker:2D +/DieLi:42 +/Diego:1Z +/DigDug:0D +/Digerati:5E +/DijaVooD:0C +/Dildo:6B +/Dildo_Dad:3M +/Diocletian:03 +/Dionysus:6B +/Disciple:25 +/Diviny:4G +/DoYouKno:03 +/DoYouKnow:1Z +/DoYouNo:4G +/DoctorGoatLips:4G +/DoctorKit:2J +/DoctorROBotnik:0D +/Doctor_Balthazar_Bath_Bazaar:4C +/Dog:2T +/Dog_slayer:1C +/Dog_slayer13:3M +/Doggo:3M +/Dojo:6B +/DolphinKun:0D +/Dominator:4G +/DonQuixot:2J +/Donald:3C +/Donger:2D +/Dongrito:51 +/Donnie:63 +/Doo:3C +/Doo___:51 +/DoomSquirrel:1Z +/Doonald:42 +/Doopool:1C +/Doormat:2D +/Dora28:1C +/Dorian:25 +/Doris10:3A +/Doris14:25 +/Dorothy:03 +/DosAmp:3M +/DoubleT7:2D +/Douglas:3C +/DpEpsilon:2D +/DpyXkevhG:63 +/Dr-G:3H +/Dr00:3C +/DrBovdin:4C +/DrD33M:6B +/DrD33M_:2J +/DrDixzzle:0A +/DrDizle:3H +/DrDizzle:4N +/DrGod:1C +/DrGood:2J +/DrNizzle:2J +/DrTooCool:1C +/DrToronto:6H +/DrTucker:1Z +/DrTucler:09 +/Dr_Rebec:5C +/Dragon:3H +/DragonEyes:0C +/DragonGeo2:09 +/DragonGlo:2T +/DreadPirateRoberts:3A +/Dreda:4N +/DrestGlas:6H +/Drew:09 +/Drew`:0C +/Drewsh:42 +/Droz:5E +/DrunkKit:6C +/Duailibe:3A +/DudeBruh:25 +/Dude_:2T +/Dude__:4C +/Dugnuts:3H +/DunkinDKNY:5E +/Duranix:2T +/Durvin:51 +/DustinFea:1C +/DvineLord:4C +/Dwaine:1U +/Dwaine_:3A +/Dwarf:3H +/Dworin:1C +/DxaQJGzTC:6C +/Dyke_:25 +/DynamiteDan:0A +/DzHH:42 +/EARS:51 +/EC:09 +/EChoh:3M +/EGH:4N +/EKcryptor:2J +/ERR_NOPRIVILEGES:3C +/ETtpRAi:3H +/ET|ufo:51 +/E_Martin:4G +/Earth:5C +/Easymone-:42 +/Easymoney:2T +/EatL0de:0A +/EaterofCuteKittens:2D +/Eboj:4C +/EcOB:6C +/EcStAsY:1C +/EcStAsY-:25 +/EcToPlAsM:2J +/Ecchan:3M +/EchoShun:09 +/Echo_C:3C +/Echo_Chidori:0C +/Ediyeu:3H +/Eefasa:3A +/Eewigo:4C +/EghFNgF:6C +/Egyptian_Revolutionary:25 +/EiLSEL:1C +/EicooV:3A +/Eilahs:0A +/Eingua:51 +/Eismc2:2T +/El3ktra:3C +/ElHumppa:2D +/ElRatonAzul:25 +/El_Zilcho:1C +/Elara:3P +/ElectRo`:03 +/Eliza:25 +/Elizabeth:03 +/Ellen:2T +/Elusiv3:3A +/Elusive:6B +/Eman:6H +/Emi:4N +/Emi_:0A +/Emily:3P +/Emily____:09 +/Emma:5E +/Emma03:2D +/Emma17:3C +/EmmaHater:09 +/EmmaL:25 +/EmmaLouise:2D +/EmmaYuh:2T +/Emmaa38:6B +/Emmaa61:25 +/Emmae:3C +/EmoFear:25 +/Emsixteen:2T +/End3r:3M +/EndItAll:0C +/EndaEnDag:3P +/Eneerge:1U +/Eneerge_:0C +/Engai:3A +/Entitlement:4G +/Enton:0C +/Enui:3C +/Enui_:3C +/Era:3C +/Era_:63 +/Eri:1Z +/EricYuzo:3H +/Eric_Blair:4G +/Eric_Blair2:3A +/Erik:4N +/Erika11:2D +/Erika_16:0D +/ErisX:4N +/ErkanINNE:6C +/Esa__:3C +/Estella:03 +/Estella-:09 +/Etamin:3M +/Etamin_:51 +/Eternal_Blizzard:4C +/Eunice^44:6H +/Euroob:2D +/Euthanizer:6B +/Euyee:2T +/EvAs:3C +/Evelyn:0A +/Evil0ne:3M +/EvilB:42 +/Evil_Bob:5E +/Ewmr:25 +/Excelium:42 +/Excellsio:2D +/Extreme25:3M +/ExtremelyOldPerson:2T +/Extynct:0C +/F-ck_NKJ:4G +/F0FFF0:4N +/F0FFFF:6H +/FAT-BOMBA:3H +/FAXn:2J +/FBI:42 +/FBIGov:4N +/FBIServ:2T +/FBIpedos:42 +/FFoD:6C +/FGhuorfiu:4C +/FJD:3C +/FKKCyprus:2D +/FREAKUser:2T +/FSgX:0C +/FUCK:2D +/FUCK_SWEDEN:2D +/FUPA:09 +/FUPA-:0C +/F_JUNK_DUMP:4N +/Fabio:3M +/Fabulous:3M +/FactorOfX:25 +/FaggotHunter:6C +/FahTe:4N +/FairsAreDumb:6H +/FalconKirtaran:2T +/Fallinglights:3A +/Fallinglights4:09 +/Fallinglights7:1Z +/Fallinglights8:63 +/FarAway:5E +/FarAway-:3A +/FarAway`:6C +/FarmerKit:2T +/Fasiha:4N +/FatBob:2D +/Fatphin_:2J +/Fatty:1C +/FbmBdgkHC:3C +/FeNTaNyL:4C +/FeNTaNyL-:1Z +/Fear:1C +/Fear-:09 +/Fear--:3A +/FearIsMAD:1C +/FearKild:2T +/FearUSA_:2B +/Fearf:42 +/Fearful:4G +/Fearkille:1U +/Fearl:6A +/Fearsum:03 +/Fear|:1C +/FederalReserve:3H +/Feero:2T +/Ferris:5E +/Fez:2D +/FiErYGT:51 +/FiErYGT-:09 +/FiReYGT:3H +/Fiegaa:6C +/Fierak:51 +/Fierra200:51 +/Fighting:03 +/FiloDough:2T +/FilthNSW:2T +/FinalX:4G +/Finger:51 +/FinnaDeli:2D +/Firefox_:3H +/Fishmongering:3H +/Fiver:0A +/FiyoC:63 +/Fjear:6H +/Fjr1dcCP:4C +/Flattie:3P +/Flo56456:1Z +/Flo6786:2D +/Floyd:1C +/Fly:25 +/FlynnTaggart:3A +/FlynnTaggart41:25 +/FlynnTaggart55:2D +/FncyPnts:51 +/FncyPnts_:1C +/Forest:6C +/ForexT:4N +/ForexTrad:3H +/Fortex:2D +/FoundingF:51 +/Four20:51 +/Four20gottalight:25 +/FoxSteals:6C +/Fox_:1C +/Foxie__:0C +/Foxtrot:4C +/Foxy:51 +/Foxy`:5E +/FqKM:3A +/Fr0stina:4G +/Fr0sty:0D +/Fr0styy:0D +/Fragile:09 +/Fragile_:5E +/Frances:2D +/Francy:1C +/Frankencookie:0C +/Frax:6B +/Freak_:0A +/Freakish:4G +/Frederick:3A +/Freedumb:5E +/FreshColegeGirl:63 +/FreshcollegeGir:2J +/FrostRanger[m]:63 +/FuOtGMjne:40 +/FuZzCasT:1Z +/FuZzCasT1:3M +/FunkyStickman:2D +/Fusl:4N +/Fusspils:09 +/G-:09 +/G-Flex:0A +/G0D:3M +/G0jQ:51 +/GCHQ:09 +/GCY:25 +/GDX:3H +/GEORGEFLOYD:4G +/GERMANSARELAME:5E +/GG:63 +/GGMethos:0C +/GIGACHAD:25 +/GISdPSGFL:25 +/GI_Jack:4N +/GI_X_JACK:6H +/GK-Deacon:4N +/GOD:1Z +/GOD_:1C +/GRNRJJD:51 +/GTAXL:3H +/G_Love:6H +/GaAdaNama:6B +/GaMbiTo:1Z +/GaMbiTo-:2T +/GaMbiTo_:0C +/Gabriel:03 +/Gabriel3:4N +/Gabriel30:3H +/Gabriel53:0A +/Gabriel62:6H +/Gabriel67:6H +/Gabriel76:6H +/Gabriel79:6H +/Gabriel84:5E +/Gadzooki:03 +/Galactic:3A +/Galactic_:63 +/Galeliw:5E +/Gamayun:5E +/Gandhi:0C +/Gandoon:2D +/GarcaMan611548282:3A +/GarcaMan6115482821:3A +/GarcaMan6115482826:0C +/GarcaMan61154828264:03 +/GarcaMan611548282643:3C +/GarcaMan6115482826434:1C +/GarcaMan61154828264340:03 +/GarcaMan61154828264341:2D +/GarcaMan61154828264342:4N +/GarcaMan61154828264343:25 +/GarcaMan61154828264344:6B +/GarcaMan61154828264345:3C +/GarcaMan61154828264346:1Z +/GarcaMan611548282643460:0C +/GarcaMan611548282643461:3M +/GarcaMan611548282643462:42 +/GarcaMan611548282643463:25 +/GarcaMan611548282643464:2D +/GarcaMan611548282643465:3C +/GarcaMan611548282643466:4C +/GarcaMan611548282643467:1Z +/GarcaMan611548282643468:3C +/GarcaMan611548282643469:1Z +/GarcaMan61154828264349:5E +/GarcaMan61154828265:1C +/GarcaMan61154828267:3A +/GarcaMan61154828268:3A +/GarcaMan6115482828:4C +/Gargoyle:6C +/Garr:3H +/Garry94:03 +/GaryGranite:2T +/Gary`Oak:0A +/Gasoline:5E +/Gaspar:2T +/GavinCool:25 +/GavinK00l:51 +/GavinWool:03 +/Gavriel:6B +/GavrielK:2T +/Gavrl:4N +/GayRage:09 +/GayestYeen:51 +/Gbyo:4C +/Geeze:40 +/Gemini:2T +/GenTsoChk:09 +/Genesis`:51 +/GenomeX:2J +/GensENVY:6H +/Gentleman:1U +/GentlyCaressedYouth:2T +/Gentlye10net:0A +/Gentoo:3H +/Gentoo_:25 +/George:03 +/George42:2D +/GermanWra:1Z +/German_aryan:2T +/Germania:6B +/Gerula:51 +/GhoGl:09 +/GholG:2D +/GholG_:6C +/Gholg:4N +/GhosT_:2D +/Ghoul:42 +/Ghoul_:5E +/Ghoul|bbl:0C +/GideonShimshelewitz:09 +/GilesCorey:63 +/Gilgamesh:1C +/Gilli:3M +/Gin:63 +/Girl44_:09 +/GirlScout:4C +/Glenn:51 +/Glider-IR:40 +/Glider_IR:4G +/Gloria:2J +/GnuPlusLinux:0A +/GoCommitSuicide:6B +/GoCommitSuicideFaggot:3C +/GoLdShLaG:3C +/GodDr:2J +/God_:40 +/Godmau5:0C +/GodokaHomuHomu:3M +/Gof:3H +/GoldState:6C +/GoodSir:03 +/GoogleMother:1C +/Googlebot:1Z +/GooseTheDuck:2D +/Gordan_Proprietary_Man:3C +/GorillaDr:3C +/Goriya:42 +/Goriyafixd:2D +/Gosha:4C +/GothAlice:3C +/Gottem:3C +/Gough:2J +/Governador:3C +/Goyo:3C +/Goyo_:09 +/Gq:2T +/Gqbriele:0C +/Grahm:6B +/Grande:3H +/Grapejuice:6B +/Grav2:3C +/Grav2_:51 +/GravitaZ3:2T +/Gravitas:3A +/GreasyBob:3A +/Greatest:6C +/GreenArch:63 +/GretaThunberg:4N +/GreyBeard:6N +/Grimmgrey:2T +/Grizo:63 +/Gron:09 +/Grounded0:6B +/GsC_RuL3Z:3M +/Gudey:0A +/Guest:0C +/Guest0000:3M +/Guest10:5E +/Guest1000:3C +/Guest10184:2J +/Guest10223:3A +/Guest10671:2J +/Guest10849:2T +/Guest10963:6B +/Guest11087:42 +/Guest12:0D +/Guest12122:2T +/Guest12335:03 +/Guest12714:42 +/Guest13:4G +/Guest13211:51 +/Guest13899:42 +/Guest14060:2T +/Guest14144:6B +/Guest14711:0D +/Guest1497:6C +/Guest15:6B +/Guest15653:0A +/Guest15656:03 +/Guest1665:3M +/Guest17191:2T +/Guest1731:5E +/Guest17367:4G +/Guest17981:51 +/Guest20010:63 +/Guest20154:5E +/Guest21270:2T +/Guest22129:0C +/Guest2249:03 +/Guest22875:25 +/Guest23695:25 +/Guest24875:42 +/Guest25:0D +/Guest25036:6B +/Guest25083:6B +/Guest25125:3C +/Guest25232:0C +/Guest25281:2D +/Guest25614:09 +/Guest25944:3M +/Guest25989:2T +/Guest26728:3M +/Guest26868:0A +/Guest2687:3C +/Guest27:63 +/Guest27254:6C +/Guest27913:51 +/Guest28:6B +/Guest28225:63 +/Guest28409:51 +/Guest28567:25 +/Guest28734:5E +/Guest29:2T +/Guest29069:6H +/Guest29184:3C +/Guest29251:63 +/Guest29606:3C +/Guest29675:3M +/Guest3:3M +/Guest30024:2D +/Guest30558:2D +/Guest31448:3C +/Guest31663:3M +/Guest31889:3H +/Guest32:42 +/Guest32429:2J +/Guest32951:3H +/Guest33156:09 +/Guest33287:63 +/Guest3350:1Z +/Guest33840:3M +/Guest34098:42 +/Guest34254:2J +/Guest34328:2T +/Guest34857:4G +/Guest35081:3C +/Guest35098:3C +/Guest35447:25 +/Guest35500:51 +/Guest35998:0D +/Guest36062:09 +/Guest36634:6C +/Guest36954:6C +/Guest36970:1C +/Guest3732:4N +/Guest37403:3H +/Guest38002:6B +/Guest38339:42 +/Guest38656:6H +/Guest3875:3A +/Guest39435:3M +/Guest3970:2D +/Guest39750:42 +/Guest39835:2D +/Guest40011:25 +/Guest40085:2D +/Guest40699:2J +/Guest40971:1Z +/Guest41151:25 +/Guest41342:25 +/Guest42243:4G +/Guest4246:09 +/Guest42783:42 +/Guest42937:3H +/Guest43:0C +/Guest43271:3A +/Guest43871:4G +/Guest43995:5E +/Guest44017:0A +/Guest44200:3M +/Guest44347:3C +/Guest44388:3M +/Guest44597:5E +/Guest44638:4G +/Guest44817:03 +/Guest45311:03 +/Guest4556:4G +/Guest45699:2T +/Guest45737:3M +/Guest45920:2J +/Guest46535:5E +/Guest46659:63 +/Guest46883:4G +/Guest47:25 +/Guest47029:2T +/Guest47501:2J +/Guest47709:3M +/Guest47829:09 +/Guest49205:4G +/Guest49765:6C +/Guest50163:6C +/Guest50388:09 +/Guest5047:6B +/Guest51478:3C +/Guest51526:03 +/Guest51921:4N +/Guest52145:4C +/Guest52914:25 +/Guest53046:09 +/Guest53501:3H +/Guest53651:2T +/Guest53930:63 +/Guest55056:51 +/Guest55331:42 +/Guest55812:1C +/Guest55842:4G +/Guest55858:1Z +/Guest56:1U +/Guest57:5E +/Guest57478:2D +/Guest5780:09 +/Guest57867:63 +/Guest57923:3C +/Guest58502:1C +/Guest58741:3M +/Guest59883:0A +/Guest6:5E +/Guest60108:1C +/Guest60528:09 +/Guest606:3C +/Guest60916:3C +/Guest60940:2T +/Guest61126:42 +/Guest61706:3M +/Guest61815:51 +/Guest61820:63 +/Guest6184:4N +/Guest62193:63 +/Guest62256:2D +/Guest62562:09 +/Guest62896:63 +/Guest62903:3M +/Guest63433:6B +/Guest63556:1Z +/Guest64:5E +/Guest64207:5E +/Guest64609:6C +/Guest64762:2T +/Guest6538:0D +/Guest6730:3A +/Guest68:0A +/Guest6969:4N +/Guest7:25 +/Guest72:2D +/Guest7288:4C +/Guest7340:4N +/Guest7529:03 +/Guest77:3P +/Guest78:6C +/Guest80:6C +/Guest8014:4G +/Guest82:2D +/Guest8387:25 +/Guest85:1Z +/Guest8539:6B +/Guest92:3A +/Guest924:03 +/Guest9273:2T +/Guest9338:3C +/Guest969:1C +/Guest98:1Z +/Guest989:3C +/Gumbie:5E +/Gun_Bunny:2D +/GunnerJon:51 +/GuntherDW:1C +/Gus:0C +/GuyCornoa:0C +/Guyver2:1C +/Guyver2_:1C +/GwooLad:03 +/H0m3r:63 +/HAILSATAN:4N +/HAL_7000:3P +/HAPM:42 +/HARLIE-shelden:0C +/HAUAH:3A +/HAUAH3d1n:0C +/HAUAH6bjd:4G +/HAUAH7664:4C +/HAUAH9uh0:1C +/HAUAHbu6p:6H +/HAUAHcqo6:6B +/HAUAHcv97:3M +/HAUAHdaye:51 +/HAUAHegvu:3H +/HAUAHewnu:2T +/HAUAHgc2k:63 +/HAUAHi4pv:0A +/HAUAHirfo:3M +/HAUAHjv6l:6B +/HAUAHkple:3H +/HAUAHmboq:4G +/HAUAHpl7v:3C +/HAUAHpp3y:3A +/HAUAHtb2n:1C +/HAUAHtztj:0C +/HAUAHueg5:1Z +/HAUAHx5b8:25 +/HAUAHzhcz:3C +/HAUAHzle9:51 +/HGM:3C +/HGMic:6H +/HHHMMMHHH:63 +/HIVlntin-:63 +/HIVlntine:4G +/HKM:4G +/HLiwsYRMI:40 +/HNRMR:1C +/HRMKTH:2T +/HRNRMTY:3H +/HSH:42 +/HTML5CAR:25 +/HTYTTMKR:5E +/HWWIS:3C +/Hachi-chan:3A +/HackerII:3A +/Hackerpc1:2T +/Hackerpcs:3A +/HaeB:0C +/HaeKie:6H +/Haeloi:3H +/Hafera:03 +/Hahsh:51 +/Hairy:03 +/HairyLegs:51 +/Haiti:3C +/Hajmola:5E +/Hal`d`Hal:09 +/HamAdams:2J +/Hamburger:2T +/Han`:09 +/Hana:0C +/Hank_Hill:2J +/HanyuuChama:3H +/HappyTime:0C +/Happy_Dog:3A +/Hard-Sexpalace:5E +/HardDisk:6H +/Harold:4N +/Harry:4C +/HaruKid:4C +/Haruhiro:4N +/Harzilein:4G +/HasanAbi:4N +/HashNuke:5E +/Havok:5E +/Hawk:6C +/Haxxor:4N +/Hayro:25 +/Hazbyn:3A +/Hazel:0C +/HeIs0x:6H +/HeLLsOwN:3M +/HeeSha:25 +/Hefohp:2T +/HelderHeid:1Z +/Helenah:63 +/HellSpaw-:1Z +/HellSpawn:0C +/Hellbilly:09 +/Hellor:09 +/Helsinki:4C +/Henry151:42 +/Henry151_:0C +/Hero101:2D +/Hextor:0D +/Hexx:6C +/Hexxx:2D +/HeyHackers:25 +/Heyy:6B +/Hi_tler:3C +/Hi_tler25:2D +/Hi_tler39:3M +/Hide:1C +/Hideki:03 +/Hideki_:6C +/Highdra1:3M +/Highdra1`:1C +/Hillbilly:6C +/Himmler:63 +/Hitten:25 +/HlloGrlz:2D +/Hobbyboy:3M +/HoloIRCUser:03 +/Holo|server:2J +/HolySog:6H +/Holz:1C +/Homura_:1Z +/Honky:6C +/HonkyKill:3C +/HonkyStom:5E +/Hoosilon:4G +/Hora:2D +/HornyCow:3A +/HorzA:3C +/HorzA_:4C +/HotPacket:3M +/HotStud4u:3H +/Howard:6H +/Hp_:51 +/Huff:03 +/Huntyz:1Z +/Hush:40 +/Hydrastra:25 +/Hydraxis:6C +/Hyperjag:3A +/Hz0:2T +/I017OBt0l:2D +/IBBR:42 +/IDoNotKnow:0C +/IGQN:4G +/III111II-:2T +/IRCStat41:3H +/IRS:63 +/IRSGov:4G +/IRSSucks:4N +/IRSSux:4N +/IRS_CDC:0C +/ISIS:0C +/ISIS_GENERAL:3A +/ITechGeek:4C +/IWJe0rCGJ:1C +/IX:25 +/I`im`a`guest:3M +/Iajea:2J +/IamJustTooSmart:51 +/IamNotGayIswearPleaseDontRape:2D +/IamVerySmart:2D +/IamVerySmart22:6H +/IamVerySmart30:51 +/IamVerySmart49:63 +/IamVerySmart86:3H +/IamVerySmart89:3M +/Iamum:4C +/Iblis:6N +/Ice:6C +/IceCold2000:03 +/IceMan66:0D +/Ice_Dragon:3C +/Ice`:3M +/Iciest`:2J +/IdUS:25 +/Idywild:2D +/Iebuci:25 +/IfADog:2T +/IfaDog:3H +/IgnatiousIgneous:3H +/Ikeing:1Z +/Ikon:2J +/Ikoru:3M +/Ikoru1:1C +/Ikoru3:3C +/Ikoru6:3A +/IlIlIllllIIIIllIIIllIIl:3A +/IlikeTHISsuperLONGnick:6B +/IllusiveM:63 +/Illusive_:3H +/IloveMYsIster:3H +/Immortal-Crypto-Boomer:03 +/Imperator:2D +/Implant:2T +/Impulsief:63 +/Impulsif:1C +/IndexMatch:4G +/IndexMatch56:4G +/IndianBoss:1C +/Indian_Boss:0A +/Induus:3C +/IneedHelp:63 +/Innmntvs:03 +/Innmntvs_:3A +/Inspiral:3C +/Inspiral_:2D +/Internet:6H +/InternetBestFriend:5E +/Internets:0D +/IoZuwe:4N +/IocQ:2D +/Ionizer:3M +/Irish:3M +/Irkutsk:6B +/Isabel25:4C +/Isimud:1Z +/Iskander:0C +/Iskander_:09 +/Isuzu:09 +/It:2T +/Ithah:5E +/Iushu:4N +/Ivan:51 +/Iyeole:0C +/Iz:4G +/J-yd-n:09 +/J0P3YE:5E +/J3rsey:6H +/JAMIE{1977}:1C +/JAMy:3M +/JAPX4556:2J +/JAzy:6C +/JCwEWXj:3A +/JEWS:0A +/JFK:2J +/JGR:0A +/JJH:03 +/JManalFatty:6C +/JNmO8I:4G +/JWST_:42 +/JaVa_:3C +/Jack4ss:2T +/Jack_:42 +/Jack__:2T +/Jake_:4N +/JamalCoal:3M +/James:0C +/JamesDeSanta:42 +/James_F:6C +/Jamezz:2T +/Jan:4G +/JanBrady:0A +/Jan_:5E +/Janet:03 +/Jaquilah:6C +/Jaquilahs_dog:25 +/Jarsto:1Z +/Jason:25 +/Jason3456:5E +/Jasons:1Z +/Jasons7:3C +/Jasper[m]:3C +/Jax:3A +/JaxOff:0C +/JayCe:0C +/Jayden:2T +/Jayden,aldcor:2D +/Jayden04966912:4G +/Jayden12:6H +/JediM:1C +/JediM_:4N +/JediM__:42 +/Jefreymon:1C +/JekuTheSneku:2T +/Jekuthesneku:0D +/Jellis:0D +/Jenetrix:42 +/Jenetrizx:0A +/Jennifer:0D +/Jenny:1C +/Jenny-:0D +/Jenova:25 +/Jerome:09 +/Jerry^:6B +/Jesseca:3H +/Jessica:4G +/JessicaP:3H +/JessicaTurino:6B +/Jestua_becha:42 +/JewB1rd:4G +/Jew_Bird:1C +/Jibbler:4N +/JigBooze:0C +/Jigsaw:1C +/Jigsaw_:6A +/Jigsaww:4C +/Jigsaww__:5E +/Jim:3H +/JimBrass:2T +/Jimbeazy:4N +/Jimboskee:4G +/Jimmy:63 +/JimmyHoffa:09 +/Jimster480-W10:6B +/Jinx:0C +/JkI5_:03 +/Jmtrix:1C +/JntPtAKjj:42 +/Joan:2J +/Jobe:3H +/Jobe1986:51 +/JochanMahlzan93:0C +/Joe-Biden:4G +/JoeAverag:6H +/JoeBiden:03 +/JoeBidenn:4N +/JoeHiden:6H +/JoeTheRapist:25 +/Joe_Biden:6N +/Joelixny:51 +/Joey:3C +/JoeyBiden:0C +/JofTrades:6H +/JohnDerp:6B +/JohnDerp_:0C +/JohnGalt:1C +/John^:6H +/Johnny:03 +/JohnnyBon:42 +/Jokk55:2D +/Jokkelol:1Z +/JollyRoge:03 +/Jonas:3M +/Jonaz:42 +/Jordan:25 +/Jordan_:51 +/Jordan_0:0C +/Jordan_0_:6C +/Jordan_O:4G +/Jordizle:4N +/Jorduck:6B +/Jose:4G +/JoseAlPaca:4C +/Joseph:4N +/JuanSoup:63 +/Jubi:3A +/Jubileu:6C +/Juchi:0C +/Judenras:1Z +/Julian:2D +/Juliet14:3M +/Julius5_1:4G +/Julius6_1:09 +/Julius6_2:2D +/Jupey:63 +/JustAPerson:3A +/Justasperg:1Z +/Justin:63 +/JustinBaeverRompeSkraever:03 +/Justin_T:3H +/JuttyMire:09 +/K0ISS3R:3C +/K0mpromat:3H +/K1smet:6H +/K8wb8zOd:6H +/KAMALA:3M +/KAREN:2T +/KB:3A +/KFC:3C +/KForKende:4N +/KGWo:6B +/KING_JAFFE_JOFFER:2T +/KKK:51 +/KKKman:6C +/KLaus:2T +/KLwu:0C +/KN1FE:2J +/KO:09 +/KOKOKO:4G +/KO_:0D +/KXTgYW:63 +/Kabe:3M +/Kabewaki:6B +/Kaffeine:6C +/KaiLikesLinux:4G +/KaitoDaumoto:2J +/Kaivo:6H +/Kaivo_:6H +/Kale:03 +/Kali:0A +/KaliEMO:2D +/Kaliuna:6B +/Kamping_Kaiser:0A +/Kanabit:2T +/Kaorub:03 +/Karen:0C +/Kasm279:51 +/Katou:6C +/Kcznsk:6C +/Kcznsk1:09 +/Keb:51 +/Kebo:3A +/Kebolio:42 +/Kebolio_:63 +/Kefka:2B +/KeiCha:4G +/Keik0s:3C +/KeiraT:0C +/Keivi:25 +/Keiya:3H +/Kemwer:03 +/Kenneth_Andersson:3M +/Ketchup901:1Z +/Kettering:2T +/Keven:2D +/Kevlar_Noir:0D +/Khaotic:0D +/KhashayaR:3A +/Khea:6C +/Khea_:3C +/KiGv:1C +/Kiitt:2J +/Kijt:0C +/KillMePlease:25 +/KillaH:6B +/KindOne:5E +/KindOne_:1C +/KindTwo:42 +/KineticUser-1729:63 +/King:63 +/King20:51 +/KingNick:3H +/KingNickl:42 +/KingOfKings:2J +/KingTuT:3A +/Kirakishou:3C +/Kirakishou_:4N +/Kirk:1Z +/Kirkland_Signature:51 +/Kirtaner:0C +/Kirtide:0D +/Kirtide_:0C +/Kiss:0D +/Kiss_:6H +/Kiss__:3A +/Kit:1Z +/KitAgain:63 +/KitFlamin:3M +/KitMega:25 +/KitPro:3H +/KitSet:4N +/KitSet_:51 +/KitSn00p:63 +/KitTheMer:0C +/KitUltima:3M +/KitWisdom:42 +/Kitt:09 +/Kitty:51 +/KittyKatt:51 +/Kitu:51 +/Kiva:2J +/Klaatu:25 +/Klaus:1C +/Kliment:1Z +/KnVnpWRXL:0C +/Knackwurst:0D +/Knicks-Fan:4G +/Knobio:40 +/KnuX:5E +/KnuX[absent]:2J +/Kobe-24:0D +/Kobe1Keno:3A +/Koduck:0C +/Koi:0D +/Kompromat:2T +/Konox1337:3M +/Koragg:6C +/KornKage:1Z +/Korthrun:0C +/Kotomi:0C +/KravMAGA:42 +/Kristal:63 +/Kristin:6C +/Kritnich:6C +/Krunge:42 +/KrysGaleh:0C +/KtDarwin:3H +/Kujata:25 +/KuluBot:0D +/Kumool:3C +/KuppyKeKs:0A +/Kuro-chan:2J +/Kuro-chan_:4N +/Kuroi:3H +/Kurokin:25 +/Kutgebruiker9000:1C +/Kye:1C +/Kyle:3H +/Kyoon:1C +/Kzer-Za:6C +/L0DESCLIT:25 +/L0deStink:42 +/L0j1k:6C +/L0j1k_:3A +/L1CABA:3A +/L4MvgGh:63 +/LB:25 +/LEB1969:0A +/LEB2000:2D +/LHI:6B +/LHI[AFK]:1C +/LOL_WUT:63 +/LOQUILLO:03 +/LOQUILLO_:2J +/LOVE:3C +/LOVE-:3H +/LOVESCiENCE:0C +/LOVESHAC1:0C +/LOVESHACK:63 +/LUKS:42 +/LaRose_Bleu:5E +/Lab:5E +/Laceless:09 +/Lacer:5E +/Lad-Russo:0C +/Lady_D:1Z +/Laegha:42 +/Laekon:1Z +/Lahey:6H +/Lahey-:0A +/Lakereke:0C +/Lama^jo:3H +/LambastMo:3M +/Lamontcol:2D +/Laphroaig:3H +/Laris:3M +/Laris-:4C +/Lasall:5E +/LaserEyess:1C +/LatinLover:03 +/Laurie:2D +/LaydGirLL:63 +/LazyMouse:6A +/Le:6C +/LeBlueMice:3M +/Le_Coyote:6C +/Lebbe:40 +/Lebluemice:4N +/Lebluemouse:3M +/Leeloo:2D +/Left`ie:3C +/Leila:3A +/Leissi:3C +/Leissi_:09 +/Leito:0C +/Lemon__:25 +/Lenore_Nevermore:3M +/Leslie:2J +/Leslie_:0D +/Lestat:25 +/LestatC6:2D +/LestatCap:6C +/LetsDie:25 +/LetsLive:5E +/LetsSolve:3C +/LiCeUser1:0D +/LiCeUser4:0D +/LiL-FeLLa:40 +/LiQWuD:03 +/Libram:6B +/Librarian:3C +/Libre___:4G +/LieNdre:42 +/LiftLeft:6B +/LikMYoung:63 +/LilNigBoy:03 +/LilNikita:4G +/LimitServ:1C +/Linda:1Z +/Link:2J +/LinoYeen:51 +/Lions:25 +/Lions_:2D +/Liothen:51 +/LiqWuD:6N +/LisaPregg:3M +/LittleWytch:3H +/Livestradamus:2J +/Llllllllll:1C +/LloydC88:51 +/Lm4:4G +/LmaoPubeBoyFailedStartup:3H +/Lmouse:09 +/LoKii:0D +/LoKii_:4G +/LoL-BooBs:09 +/LoLa_BuNNy:63 +/Lolipop:0D +/LoneWolf367:3A +/Loner:25 +/Long_distance_M:09 +/Lord255:2T +/Lord255_:0A +/LordKing:09 +/LordOfValhalla:2D +/LordToValhalla:25 +/Lord_KO:3C +/Lorn:6C +/LostBiT:4G +/Louella:2J +/Loyalist:63 +/Lthere:25 +/LuShang:2J +/Lucas:4G +/Lucas_:51 +/Lucifer:6B +/Lucifer_:25 +/Lucille:2J +/Ludax:63 +/Lue:3H +/Lukah:42 +/Lukin:1C +/Lukin_:03 +/Lukin_HAL:2B +/LukrBtyan:2T +/Lulzy:0D +/Lumez:4N +/Luxmem:4G +/LvQbrKxjXuAnErzV:4G +/LwXhpMetC:4N +/Lynn:4C +/Lyphe0:42 +/Lypheo:5E +/Lznj:0C +/M-Cburton:51 +/M16:2D +/M4riu5:4N +/MAGA2020:6C +/MAGIC:2J +/MALMM:3C +/MC-SharP:09 +/MCUIRCClient:3H +/MCWEENY:0C +/MDMA-:1Z +/MDMA_:3C +/MGTOW:1Z +/MGpOH8SEl:25 +/MGree:6C +/MIKEJONEZ:6B +/MISTERCOINBLATT:51 +/MKULTRA:2B +/MK_Delta:3M +/MK_Naomi:6H +/MK_Ultra:6H +/MNKU:03 +/MNXa:03 +/MRMET:42 +/MRNFN80:4G +/MTCan__:03 +/MTcan_:5E +/MTcan__:51 +/MTcan___:4N +/MTv:0C +/M_epshee2:09 +/M_epsheep:4G +/MaL-E:6B +/MaLi:6B +/Mac101:3C +/MacYET2:63 +/Macedonia:42 +/Macrotech:3H +/MadDecent:51 +/Mad_Love_Modus:3M +/Maestral:1C +/MagicBot:3H +/MagicPencil:3A +/Magneto:6H +/Magnolia:4N +/MagnuzMaximuz:0A +/Magoggles:2J +/Mahjong:1U +/Mahjong1:2J +/Mai:3H +/MaidenAmerica:25 +/MajMajorMajorMajor:4G +/MajorRizon:6C +/ManDick:0C +/Manhattan:42 +/Manifesst:25 +/Manny:4G +/ManofHumilty:03 +/Mantis:25 +/Mantis_:25 +/Marburg-chan:1C +/MarcLepin:3C +/Marcella:2D +/MarceloCM:2B +/MarcinWieczorek:6C +/MarcinWieczorek_:0C +/Marcus_Aurelius:3M +/Marianna:63 +/MarieLoew:0C +/MartijnBraam:3A +/Martina_i:1Z +/Martine:1C +/Martini:2J +/Mary:3M +/Maser:4N +/MasterKat:6C +/MasterOfMuppets:63 +/MasterdonX:6H +/MastrKat1:63 +/MastrKate:1U +/MathMan:1Z +/Matilde:51 +/MattG:5E +/Matt_P:63 +/Matthew:2T +/MatthewG:4G +/Matty:2T +/Matumbi:25 +/Maximus:2T +/Maxwell:6B +/Maxximus:2J +/Maxximus_:2T +/Maylay:03 +/Mbar:3H +/Mbla:09 +/McKat:51 +/McMurphy:3C +/McQueen:4C +/MeaningfulNick:1Z +/MeatStick:1Z +/Medig8r:5E +/Medih8r:4C +/MediumAbner:0A +/Medusa:0C +/Medusa-chan:1C +/Meekrab:3C +/Meepshee1:09 +/Meepsheep:51 +/Mehh:6C +/Mehh_:0D +/Mehhh:2T +/Mei:2D +/Mellowchan:1Z +/Mellowlink:1C +/Mend3s:1C +/Mentok:6H +/Mestri:6A +/Mezz:2T +/Mezz_:03 +/Mezz__:6B +/MiCulo:4C +/MiDoolo:63 +/MiMelio:3H +/Mi_92:3A +/Michael:63 +/Michael^:6C +/Michael_:63 +/Michiellll:09 +/Mickey:42 +/Micoolo:6B +/MidnightRanger:3C +/MidnightRanger_:4G +/Miep:1Z +/Miggy`:2J +/MikeBlack:42 +/MikeMurdock:03 +/MikeS:42 +/Mikollo:3H +/MikooIo:3H +/Mikoolo:51 +/MilkJug:4G +/MillerBOS:6B +/MillerBOSS:3H +/Milli:1C +/Milliway:2D +/Milliways:25 +/Milliways-:2D +/Milton:6H +/Minamo:3M +/MinimE:51 +/Minnen:0D +/Minnen|:0A +/Mirc0p:63 +/Missssy:42 +/Mista:25 +/Mister_X:0A +/Mithras:0A +/MnmJ:4N +/MoRpHiNe:2T +/MoRpHiNe-:0D +/MoX:3A +/Moab:3H +/MobileRoey:09 +/Mod:6H +/ModsToHell:2D +/ModsToHell60:6H +/ModsToHell64:1C +/ModsToHell66:3A +/ModsToVahala:1C +/ModsToVahala21:3A +/ModstoVahala:2T +/MoeIcenowy:4N +/Moeph:5E +/MohammadUddin:25 +/MojoRizon:2T +/Molly:2D +/MommyJean:2D +/MommyJeans:2D +/Monalisa:3M +/MonkeySp:5E +/Monroe:6H +/Monty5:2D +/Mooing-Bun:63 +/MoonUnit:3C +/Moone:4C +/MooseGod:0A +/Mort:2J +/Mortimer:6B +/Mortir:0D +/Morty:3H +/Mosquito:4G +/MotherSuperior:09 +/Motives:63 +/Moudi:25 +/Movieguy:0D +/Mp3S3v3r:63 +/Mpshp:5E +/Mpshp_:6B +/MrC:2T +/MrCat:6C +/MrChimp:03 +/MrDetonia:09 +/MrMW:03 +/MrMiagi:1Z +/MrMisery:25 +/MrMoose:0A +/MrOats:6H +/MrRandom:25 +/MrRandom_:0D +/MrReader:51 +/Mr_Freeman:03 +/Mr_Keyser_Soze:6B +/Mr_wh1t3:0C +/Mrox:6H +/MrsLovejoy:42 +/Mr|Dave||:6C +/Mr||Dave|:1C +/MsBIOS:2D +/MuNk:3H +/MuTao:63 +/Mufasa:2T +/Mufasa_:0C +/Muffin_Man:0C +/Mule:0A +/Mule_:0D +/MummyJean:4N +/MummyJeans:3M +/MuroAmi:4G +/Muscles_of_homosexx:3C +/MusicKing:25 +/MusicKing8:2T +/MusicKing9:2T +/MyAss:4G +/MyDickInMyHand:09 +/MyMickeyInMyHands:63 +/Myrtle:42 +/Mystic-Mac:1Z +/Mystic_Mac:1C +/Mystic_Mac_:51 +/MysticalD:51 +/N:25 +/N1XX_:4N +/N3150:4C +/N3150_:42 +/N3150__:2T +/N350:3M +/N3TFL1X:03 +/NANCY:5E +/NBA2K21PC:3H +/NC1776:25 +/NES:4N +/NHS:0A +/NIN101:2J +/NLDM:6H +/NSA:2T +/NSAGov:3M +/NSAnigger:42 +/NUGu:42 +/NX4bb:6B +/NZpF:4C +/Nabilushk:6C +/Nachlader:51 +/Nadezhda:51 +/Nadyushka:4G +/NaiGhe:4C +/Naia:3H +/NakaNaka:2D +/Nakah:25 +/Nan:5E +/Nando:03 +/Nanoha:3C +/NaomiShaniquala:6B +/Naomi_Shaniquala_Al-Baghadadi:0D +/Naomi_Shaniquala_Al-Baghdadi:5E +/Nap:0A +/Nap0:09 +/Narple:42 +/Nasrani:03 +/NatGreen:1Z +/Navi21:0C +/NcXk:2T +/NeX-:51 +/Nea:1Z +/NebulaAI:42 +/NebulaCentre:63 +/Nebula_W-:2D +/Nebula_W2081d:0A +/Nebula_W2082d:3C +/Nebula_WD40:3A +/Necrodancer:6C +/Necrodancer`:6H +/NedDigger:2J +/Ned_Digge:63 +/Negra:09 +/Neijei:03 +/Neil2:1C +/Neil_:3C +/Neil_Zaza:0C +/NejjqsJyR:2J +/Nekobot:4G +/Nekobot1:25 +/Nemesys:2D +/Nemomen:0C +/NerdCore:09 +/NerdLyfe:3A +/NerdyGirl:3H +/Nesie:2D +/Netboy3:6H +/Neutrino:6H +/New:51 +/NiKaN:03 +/Nice:42 +/Nick71:4N +/NickSerc:25 +/NickServ:3H +/Nick_Gerkiller:3M +/NigerMurderer:2D +/Nigger:51 +/Nikitis:2B +/Nikola:5E +/Nikonova:2D +/Nilfirith:2T +/Nilgeist:1C +/Nilgeist_:42 +/NimFan:4G +/NiniGeo2:4C +/Ninja3047:42 +/NinjaMast:40 +/Nintenuen:4C +/Nipun:4N +/Nka:3C +/Nl3avE:1Z +/NoLivesMatter:1Z +/NoStepOn:0C +/NoXPhasma:1Z +/No_One:0A +/Noemi:4C +/Nognosis:4G +/Nol888:4N +/Nomkid:6B +/Non-ICE:6H +/Nora11:42 +/Norsemen:63 +/Norvegia:2J +/NotALawyer:0C +/NotAnna:3M +/Not_Beast:1U +/NotnotOutOfGum:42 +/Noxturnix:09 +/Nrk:3C +/Nslobz:3H +/NuSpike:1C +/Nuclear:3M +/Nugem:6H +/NukesTop5:0A +/Null_:2D +/Nuotoh:42 +/Nyx:0C +/N|GG0R:6C +/O:6B +/OCCLNkjkK:2B +/OKIU:4N +/OMg74:4N +/OMg747:3A +/ONhB:3C +/ORIENTAL:4N +/ORIENTAL16:42 +/OXaku:42 +/O_od:42 +/ObLQ:42 +/Obama:5E +/Obl1vion:51 +/Oblivion:03 +/Obunga:6C +/Ofelia:6B +/Ogre:0C +/Ohfah:2J +/Ohfai:5E +/Ohgac:1C +/Ohkaa:3C +/Oksana:25 +/Oksana_:63 +/Oksana_Baiul:2D +/OldGnom:2J +/OldSch00l:6C +/OldSchoo1:3H +/Oluc:0A +/Omelette:6B +/OmenOvKane:3H +/OmenOvKane_:3C +/Omen_Ov_Kane:2T +/OmerAti:2J +/OnLine:0D +/OnMind:09 +/OneBTS_:09 +/OneBTS__:3H +/OneBTS___:0C +/OneVision:4C +/OodieT:3H +/Oongia:2T +/OpaAdolf:5E +/OperServ:2J +/OperatorR:6H +/OpiSIS:4N +/OpiSIS_:0C +/Oprah:09 +/OrGoN3:3A +/OrcaKun:5E +/Orelob:6B +/Ori_B:51 +/OriginalAntiHustler:5E +/Orillion:1Z +/Orval:3M +/Osama:6B +/Oscar:0C +/Oshkosh:51 +/Osloane:1Z +/Osloanie:1Z +/Othermeats:3M +/OttoYukie:5E +/OutOfGum:6C +/OutOfGum_:0C +/OutOfGum__:4G +/Outlaw:3A +/Outlawed:4G +/OutlawedOutlaw:4C +/OverFiend:3M +/OverMind:2J +/Ovular:51 +/Owl:1C +/OxYCoNtiN:0D +/Oxdeadbeef:3H +/OyashiroChama:09 +/OzRat:5E +/OzRat_:6C +/P00Pstink:51 +/PATTY:0C +/PC__:0C +/PEDOMETER:42 +/PEEgwvviG:6A +/PG13:1Z +/PHPWoman:1C +/PIES_:42 +/PIba:2T +/PKFraudster:6C +/PKsimp:3C +/PLSk:3A +/PPA:51 +/PPs:0C +/PQLe:2D +/PR0PH3T:2T +/PRETEXTATO:2D +/PSyMASA:1C +/PXPYxI3:42 +/P_B:6C +/Paddy:5E +/Palaver_:2D +/PaleHorseGiddyUp:2D +/PaleHorseGiddyup:09 +/Pali:6B +/Palmon:3A +/Pamela:2J +/Pantheistic:03 +/Parf:4G +/Parf_:51 +/Parfing:25 +/Parfingto:3H +/Parfington:42 +/Parfol:3P +/Passcor:4N +/Passivit1:6B +/Passivity:5E +/Passivity2:5E +/Patch:1C +/Patch_:5E +/Patrese:51 +/Patrick:3A +/Patrick^:6H +/Paul:42 +/Paula:6B +/PbiipxD:0A +/PdTMmFv:4C +/Pe2WVOhlb:1C +/PeGaSuS:5E +/PeacefulDeath:3M +/Pear:03 +/Peebs:0A +/Peggy:0D +/Pelos:3C +/PepeLopez:1Z +/PepePains:3M +/PeptoBismark:0C +/Peregrinus_:09 +/Peregrinus__:5E +/Perineum:3A +/Perkele:3H +/Perv4chat:0D +/PervFag:6B +/Petar_:3C +/PeteyPebbles:2J +/PhahH:3H +/Phallus:42 +/Philas:25 +/Phish:3C +/PhoneOwner:6B +/Phy:3A +/PiOjitoh:3C +/Piba:42 +/PicantePaavo:6C +/Pikachu:1Z +/Pillus:03 +/Pinco:4C +/Pineapple:42 +/PingPong`:4G +/Pinguo:3H +/Pinkisjustnumber:51 +/Pinklady:6C +/Piojo:03 +/Pipel:42 +/PissWizard:3C +/Pistachio:51 +/Pixi:6B +/Pixi_:0A +/Pixi__:0C +/Pixi`:2J +/Pizza_:4N +/PlanBinc:2T +/Plas:2J +/Plas_:6B +/Platinum_:42 +/PleXus:0C +/PleaseSuckMyDick:5E +/Ploks:6H +/Ploo:1Z +/PmIS:0C +/PoPp:03 +/Poirot:3C +/Pol_Haddad:09 +/Police:09 +/Politik:2T +/Pontuzz:3C +/Pontuzz_:4N +/Ponyo:5E +/PonzoSporrigan:2J +/PooftersFroth:4C +/PoolShark:42 +/Poorchop:4C +/Poot:1Z +/Popper:2J +/Porco:3H +/PornStar:63 +/PostKode:4N +/Potardo:3A +/PrOZaC:3M +/PrOZaC-:42 +/Prendar:51 +/PriVEHTqK:1Z +/PrimalP67:1C +/PrimalP76:6B +/PrimalP92:1Z +/PrimalPuppy:1Z +/PrinceUSA:3C +/PrincessEmmaOfNorway:25 +/PrincessKitanaEliteDarkWhite:3A +/Prinsessa:51 +/ProfesionalRapist:3C +/ProfessionalRapist:4G +/ProfessionalRapistTT:25 +/ProgressiveRapist:2T +/Proklantis:2J +/Proleeh:4G +/Prometheus:4G +/PrometheusRising:42 +/Protestant:25 +/ProtoType:3A +/ProudBoy`:6H +/Provic:3C +/Przemek92_:0A +/PsYcHoPaT:4N +/Psion:3C +/PsyChoop:1C +/PsyChoopa:4N +/PsyMassa:3A +/PsyMaster:42 +/PsyMastre:63 +/Psymaster:4C +/PubesGrowGrowGrow:1C +/Publios:6N +/Pucker:0D +/PuertoRoc:6H +/PumpSlut:4N +/PumpSlut`:0D +/PuntGathrr:4N +/Punter:0A +/PureTryOut[m]:3H +/Purpl:6C +/Purple:3C +/Purpleb0w:2T +/Purplebow:2D +/PussyHater:03 +/PussyKiller:63 +/PyR3X:1U +/PyR3X_:4G +/Pzex:63 +/Q2M0xl:2J +/Q91:42 +/QANON:5E +/QAnon:1Z +/QDX45:6C +/QJoP:1Z +/QKnown:0A +/Q\ANON:03 +/Qnorsten:1Z +/Qnus:09 +/Qoggis:3C +/QuadRTX:3C +/QuadRow:42 +/Quallure:51 +/Quandall:6H +/Quanemmi:4C +/Quantum_Alpha:2D +/Queer91:25 +/QueiDa:6C +/Qui_Sum:3H +/Quindall:2T +/Quinii:6B +/Quixo:2J +/Quotes:03 +/R:09 +/R0ckSh0x:6B +/R0nnie:1Z +/R2D2:5E +/R3D3:1Z +/R4D4:63 +/R4Rfw:0D +/RABIA[45]:4G +/RAPISTofficial:51 +/RASHIDA^wolfgang:63 +/RAlex:03 +/RDyLzgdMp:4G +/RJ45:3H +/RJ45_:2J +/RMOTAO:3M +/RPG:3H +/RTB:5E +/RTB_:0C +/RTFT:0D +/RTX3090:3M +/R_Reagan:2J +/Raaku:2B +/Rabid_Masochist:6B +/Raccoon:3H +/Raccoon`:3C +/Rachael:4N +/RacistBat:0C +/RackSmurf:0D +/Radio:2T +/Rafaela:1C +/RaginCajun92:6H +/Ragone:2D +/Raina:3M +/Raina_:3A +/Ran:3M +/RanchIsla:3C +/Rando:3M +/Random:6C +/Random024:09 +/Random024A:3A +/Random1:4G +/Random420:1Z +/Random4200:25 +/Random42000:2D +/RandomPir49:3C +/Randy:1Z +/Randy-:2D +/Randy_:3H +/Randy__:4G +/Raoknar:2T +/RapStar:1C +/RapeIsaRight:25 +/RapistLifeMatters:09 +/RareDCOMC:1Z +/RaySting:4G +/Raya:0C +/RayaMew:2J +/Rayaa:6C +/Raymond:4N +/Rayvyn:03 +/ReThan:4G +/Reader:0A +/Ready:51 +/Ready_:09 +/RealJew:2J +/RealKit:4C +/RealSatoshiNakamoto:4N +/Rebecca^:4N +/Red:25 +/Red14:3A +/RedW:6C +/Reed39:1C +/Reed_Solomon:0C +/Regor:51 +/Relena:4G +/Relih_:51 +/Relis:4G +/Relis7:6C +/RemyV:09 +/Rena_Ryugu:3M +/RepairManManMan:1C +/Requit:4G +/Retalin:4G +/RhinoBeetle:1C +/RhinoCodes:2T +/Rhum-blan:2D +/Rhumblanc:0C +/Rhvs:0C +/Rhvs_:0D +/RiTaLiN:3A +/RiTaLiN-:09 +/RiTaLiN_:0A +/Ricardus:4N +/Ricardus_:0C +/Ricardus__:0D +/Richard^:63 +/RickJames009:4G +/RickyRocks:4G +/Riddrib:42 +/Riefie:3H +/RigelStar:3M +/RiggedHorror:03 +/RindFrost:2D +/Ringo-:09 +/Ritche:25 +/Rizo98469:6B +/Rjx:0A +/RoBiN:6H +/RoSe:3C +/RobBond:3C +/RobanovThomaski:3A +/Robby:0A +/Robert:4C +/Robin:51 +/RobinHood:5E +/RobotoneX:3H +/RockShox:25 +/RockinRobin:51 +/Rodney:3H +/Roedy:2D +/Roffles:51 +/Roliga:6C +/Rome:0D +/Romer:3H +/RonaldKof:03 +/RootA:51 +/RootB:2J +/Rowan:25 +/RowdyFun:03 +/Royal:5E +/Royce:3A +/Ru:0D +/Rue:4N +/Rue_:0C +/Ruemu:2J +/Ruin:4C +/Ruint:0A +/Ruint-:63 +/Rukus:3M +/Rukusz:3A +/Rum:4G +/RumpHurl:5C +/Rusalka:5E +/Russell:3C +/Russell-:4G +/Ruth:0C +/Ruthless:6C +/Rwiz:3M +/Ryan_Evans:1C +/Rytord:1C +/Ryuuguu:3H +/S2AmgpXFp:2D +/S2N2:51 +/S3N7IN3L:2T +/S3xyL1nux:63 +/SBG:0C +/SBn00b109:3H +/SBn00b156:09 +/SBn00b157:1C +/SBn00b176:51 +/SBn00b192:40 +/SBn00b200:2J +/SBn00b240:40 +/SBn00b245:0A +/SBn00b269:2J +/SBn00b29:4N +/SBn00b324:5E +/SBn00b328:09 +/SBn00b361:4C +/SBn00b376:1Z +/SBn00b377:5E +/SBn00b389:51 +/SBn00b398:6B +/SBn00b412:09 +/SBn00b420:5C +/SBn00b469:40 +/SBn00b528:03 +/SBn00b551:6N +/SBn00b579:6N +/SBn00b589:2D +/SBn00b631:2D +/SBn00b668:0C +/SBn00b671:1Z +/SBn00b678:3P +/SBn00b724:6H +/SBn00b735:40 +/SBn00b773:6A +/SBn00b823:63 +/SBn00b826:40 +/SBn00b85:3H +/SBn00b852:3M +/SBn00b86:5C +/SBn00b872:2B +/SBn00b911:2J +/SBn00b979:0C +/SBn00b987:09 +/SBn00b994:2B +/SCHAPiE:2J +/SD:3A +/SDCHN:03 +/SDr:1C +/SE:1C +/SEEN:3H +/SENebula_W2081d:1C +/SEPassivity:3H +/SERGE90:3A +/SEX:51 +/SH3RM:2J +/SHEENY:4C +/SINOHAWK:0C +/SLAAAPP_YUA`-:42 +/SLAAPP_CORP`-:4G +/SLAAP_CORP`-:6B +/SLAPP_ASS`-:1C +/SLAPP_BAN`-:1Z +/SLAPP_CEO`:03 +/SLAPP_CEO`-:3A +/SLAPP_CON`-:1Z +/SLAPP_COR:1C +/SLAPP_CORP:4C +/SLAPP_CORP`-:4N +/SLAPP_CO`:51 +/SLAPP_CO`-:2D +/SLAPP_CUM`-:2T +/SLAPP_DOCTOR`-:5E +/SLAPP_DUDE`-:09 +/SLAPP_INC`-:6B +/SLAPP_IT`:03 +/SLAPP_IT`-:42 +/SLAPP_NET:6H +/SLAPP_NET`-:4G +/SLAPP_NOW`-:51 +/SLAPP_NO`-:2D +/SLAPP_ON`-:63 +/SLAPP_PORN`-:51 +/SLAPP_U`-:63 +/SLAPP_YOU`-:0C +/SLAPP_`-:42 +/SLAP_CORP`-:0C +/SLAP_INC`-:42 +/SLAP_PRO`-:63 +/SLAP_TV`-:6H +/SLu7:2T +/SNIFF:40 +/SOMTA:1Z +/SP3:4N +/SP9002Alu:5E +/SPOON:4N +/SRBLuka:3M +/SRBLuka_:2T +/SRidc32t:0C +/SSI_bux:1C +/SS_CORP`-:51 +/STARY_FON:3C +/STUPID:3M +/SWEJ:6C +/SWL:03 +/SXL:4G +/SYF_:6C +/S_Co`-:2D +/Sagara1:25 +/Saidu:1C +/Saifxin:5E +/Saitan:42 +/Sakuyak:0C +/Salvadori:4N +/SamHyde:0C +/SamIam:2J +/Sam_:6C +/Samantha^:3M +/Samhain:51 +/Samy:4N +/Samy^ZzZz:6C +/SandFlow:6H +/SandPower:6C +/Sander:6C +/Sandflow:25 +/Sandra:0C +/SanePerson:25 +/Saneperson:4C +/Sanguine:2D +/Santiago38:09 +/Santiago38_2:4N +/Santiago38_3:03 +/Sapphirus:1C +/Sarah^:2D +/SatanX:1C +/Sathurion:5E +/SaylrMoon:2J +/Scalia:1Z +/SchwarzeLocke:2D +/Scientist578:4G +/Sciuro:6B +/ScoobsMcD:3A +/Scopes:0A +/Scotteh:1Z +/Scrappy:25 +/Scub:4C +/Sd:3A +/Se8v:4C +/Searbo:6H +/Secondary:42 +/Secondary1:1C +/SeeRob:25 +/Seepei:5E +/Seerbo:2D +/SeiZe:0A +/Seirdy:0C +/Seirdy0:3H +/Self-Love:3C +/SelfDJ:2D +/Semilevel:0D +/SendInTheFeds:1C +/SendInTheMeds:4N +/Sentient:2D +/Serah:42 +/Seran:63 +/SereneBea:63 +/SereneSwan:3C +/Seres:0D +/Seresu:0D +/Serh:3H +/Serh_:6B +/SeriousCouching:1Z +/Server-Rooted-By-CSH-Members:6C +/ServiceBot:09 +/Seshat:3M +/Seshat`:03 +/SethRCooper:4N +/SethRCooper78:2T +/SethRyanCooper:51 +/Seth__:09 +/Sexton-Hardcastle:51 +/Sexton-Hardcastle5:63 +/Seyaryuki:42 +/Sh3r1ff:6H +/Sh3rP:0C +/Sh3rP_:3H +/Sh4rP:63 +/Shadowmm:2D +/Shadowmm-:0C +/Shadowmm_:1Z +/Shahid:4G +/Shane:2J +/ShannoW:42 +/SharP-:4G +/SharP0ink:5E +/SharP99:1Z +/SharP_:25 +/SharP_X9:2J +/SharP_x3:0D +/SharP_x5:2J +/SharP`:63 +/SharkB0lz:09 +/Shark_CHX:2D +/Shark_YDQ:1Z +/Sharky:3C +/Sharon:5E +/Shawn:4C +/Sheep:4G +/Shelly:42 +/Shillos:2T +/Shine-j2me:03 +/Shinku_:4C +/ShinyRice:09 +/Shipp:25 +/Shirakawa:40 +/ShitTierSpaghettiCoder:0C +/Shm00:3M +/Shooxo:0C +/Shuqu:1C +/Siberian_Shaman:2J +/Silence:42 +/SilentAnime:3M +/SilentMES:63 +/SillyGoose:5E +/Silver4K:63 +/SilverSpoon:3A +/Silverbac:2B +/Simping:63 +/Sinusoid:3C +/Siousxie:4C +/Siouxsie:6C +/SirVerII:2D +/Sirdon:3H +/Sithlord:25 +/SixNein:3A +/Skaface82:4N +/SkinFlute:63 +/Skrillex:03 +/Sky-Wizard:3C +/SkyDad:1C +/Sky_Wizard:3C +/SlaSerX:63 +/SleepyMokou:6C +/Slimey:0A +/Slugs:6B +/Slumlord:2J +/SlyTheDog:6C +/Smagigy:0C +/Smaque:4G +/Smaque_:3P +/Smaque|2:03 +/Smax:09 +/Smax`:3H +/Smegma_Sandwich:09 +/Smoke:3C +/SmokeyZ:0A +/Smoque:4N +/SmutLord:63 +/SmutLord^:0C +/Smutlord:4C +/Snail:3A +/Snail_:1Z +/SnakeEyes:3A +/Sniper:3M +/SnowDrop:3M +/SoB:0D +/SoPasqyfW:0A +/Sobek:03 +/SocialistRapist:1C +/SockMonkey:1Z +/Sofiia:3A +/Sog:1C +/Sog51:4N +/SolarAqu-:0A +/SolarAquarion:6H +/Solbu:1Z +/Soldev:3A +/Solo:4G +/SoloEjo27:1C +/SomeB:4N +/Someblackguy:5E +/Sonder:51 +/Sonder_:1Z +/SoniCF242:25 +/SoniCFL:6B +/Sook:42 +/Sookie:09 +/Soosi:4G +/Sopel:2J +/Sophie:3H +/Soraya:0D +/SoreNina:6H +/Soreina:1C +/Soros:4G +/SoulCareer:5E +/Souseiseki:1Z +/Souseiseki_:03 +/Southern_B|tch:42 +/Southern_Gentlem:3H +/SouulCareer:4N +/SovereignNSW:03 +/Soviet_Soldier:09 +/SoyBot:6C +/SoyBot_v2:2D +/SoyLunafan:1Z +/SoyberManifest:4N +/SpaceDoG:3C +/SpamcyPnt:0A +/Spartacus:2J +/SpearRaven:2D +/Speario:3M +/Special-G:2J +/SpiderGwen:3C +/SpiredMoth:6B +/SpmcyPntz:6H +/SponeBob:7E +/Sponk:2D +/SponkH:4N +/Spooky:09 +/Spooky_:1Z +/Sprinkle:0C +/Spud17:25 +/Spydar007:1Z +/St0ner`:6B +/StCyber:51 +/StUcK2[S:51 +/Stalin:1C +/StanMarkov:2J +/Stanley:42 +/Starla:0C +/Starter:5E +/StaticX:1C +/Statton:0C +/Stealth:4N +/Stefan:1Z +/Stella:5E +/Stellar:3C +/StephenLynx:2D +/Steve:3C +/SteveM:2J +/SteveV6:3A +/Stewie:03 +/Stfuktx:3A +/StillCyco:0A +/Stillgerm:6B +/StinkySteve:25 +/Stoney:0D +/StoneyBark:1C +/Stormo32Piqued:2D +/Stormo32Piqued__:4N +/StormofBytes:3C +/Strasbourgs:2D +/StripleP:2D +/StrongBad:42 +/StrongGod:6C +/StrongSad:25 +/StrongTop:1Z +/Stuk:5E +/SuchWow:2T +/SuckBoiSlime:1C +/SuckMySmallDick:4N +/Suffer:51 +/Suffering:09 +/Sufo:4N +/Sugar_:3H +/Sugar__:0C +/Sugar___:25 +/Sugar____:40 +/SuicideHelper:42 +/SuicideMaster:0C +/SuicideSupport:3M +/Suigintou_:25 +/Sumbrero:6H +/Summer2020:51 +/Sun:5E +/Suntop:09 +/Suntop_:1C +/Suntop__:2T +/Superstar:3A +/Superzak:0C +/Superzak_:1C +/SurplusCamel:51 +/Susan:3M +/SuspiciousPizza:03 +/SvenG:0C +/SwampAss:3C +/Swayze:1Z +/Swayze_:51 +/Sweag:0C +/SwedishMeatball:42 +/SweetPoto:1Z +/Swin3:0D +/Swine:09 +/Sycophant:2J +/SyneRyder:0C +/Synth:6B +/Syzop:51 +/T-2:3A +/TAFKAMP:25 +/TAFKAMP_:0C +/TAS-2012v:3M +/TAS_2012v:3M +/TBNK420:2T +/TCZ:63 +/TDK:0C +/TGMC:1C +/THATFUCKN:1Z +/THEGAME:25 +/THERULES:03 +/THE_FORECASTER:3A +/THEjman:4N +/TJC2020:2D +/TJC2040:4N +/TJzaXOqQO:2D +/TK614:1C +/TKO:1Z +/TOMBRADY:3A +/TRANS:40 +/TRB143:4N +/TRUGOAT:6B +/TRUMP2020:1C +/TStark:1Z +/TUDOR^1985:0A +/TVfan69:42 +/T_D_H:2J +/TaWPgLnXV:5E +/TaZeR:0C +/TaZeR2:4G +/Tableset:4G +/Tacky:51 +/TackyTack:03 +/Taetarthe:3M +/Taetarthe1:1U +/Tagged:3H +/Tai:6H +/Taigabot:25 +/Takehiko101:4N +/Talia:0D +/Talia`:6B +/Tamaresu:1Z +/Tanami:1Z +/Tanoc:03 +/Tantivy:5E +/Tar:0C +/Taurus:1Z +/TechB:3P +/TechGuru:63 +/TechItch:63 +/TechSmurf:09 +/Techman:2J +/Techman-:1C +/Techman_:51 +/Ted:63 +/Teeed:3P +/Teenagecitry:5E +/Teeph:63 +/TekWizOne:6C +/Tekdude:3A +/Tekdude-:42 +/Tekdude2:2T +/TekdudeLT:0A +/TekdudeN:51 +/TekdudeN-:3A +/TeleType:4N +/TeleType_:51 +/Tempest:3M +/TempoFunktron:51 +/Temptress:2J +/TendieQueen:2T +/Tenicu:2J +/Teridax:3M +/TerminatorOfVermin:6C +/Tero:4N +/Terofoo:2T +/Terri:63 +/TestDude:09 +/Testah:4N +/Testware:25 +/TgrS:1Z +/Th3Z0h4n:2J +/Thabtos:6H +/Thacu:09 +/Thaodan:3H +/The:0C +/TheAssassin:2D +/TheDarb:2T +/TheDoctor:51 +/TheFag:6B +/TheFalcon:25 +/TheGentleman:0C +/TheGoodMa:63 +/TheHoliestRoger:4G +/TheLegitimateMod:4C +/TheLie:3C +/TheMajesticCamel:51 +/TheMod:2D +/TheNSA:1Z +/TheNigerianPrince:51 +/TheOneAnd:3A +/TheOneAndOnlyMod:6C +/TheOnlyMod:2D +/TheQuantumAlpha:2J +/TheReader:40 +/TheRealKi:42 +/TheSashm_:3M +/TheSashmo2:3H +/TheSilentLink:4C +/TheSilentLink_:0C +/The_Blosso:4N +/The_Hanging_Flesh__of_Jcaesar1:6H +/The_Hatta:42 +/The_Myth:42 +/The_Real_Nebula:0C +/Theas:0A +/Theev:6C +/ThermZ:6C +/Thidran:25 +/Thidran3:42 +/This:1Z +/Thisisbilly:3M +/ThorDK:3C +/Thor_dk:6H +/Thorne:0C +/Thorne_:0C +/Thorne__:0C +/Thorne___:09 +/Thot_Police:3A +/ThruthHam:42 +/Thule2welt:3C +/Thunder:2D +/ThunderChicken:6H +/TiLT:3H +/TiSg:3H +/Tibsi:03 +/Tiddles:0A +/Tiddles_:6B +/TideRZ:25 +/TideRZ2:6B +/Tiefling:6B +/TigerbotHesh:3C +/TimWolla:42 +/TimWolla_:0D +/Time:3C +/TimeWolf:4G +/Timorousness:0A +/Timorousness1:0A +/Timorousness2:0A +/Timorousness3:0A +/Timorousness4:0A +/Timorousness5:0A +/Timothy:2D +/TimothyT:0C +/TimothyWT:0D +/Timourousness:0A +/Timourousness1:0A +/Timourousness2:0A +/Timourousness3:0A +/Timourousness4:0A +/Timourousness5:0A +/TirMcdhol:4G +/TirMcdhol2:4G +/Tjark:3M +/TlrPrkGrl:6B +/TnwR:0A +/ToUsMiC:2T +/ToWL:2T +/Toastmaster124:6C +/TohPiD:63 +/TokyoGringo:3M +/TomHilnig:5E +/TomatoSyn:6H +/Tomma:4N +/TommyHiln:42 +/Tomoko:51 +/TonTon:63 +/TonyL:42 +/TooCool:09 +/TooCool-:6H +/TooCool_:2T +/TooMuchX:6H +/TooPi:03 +/ToofAudit:51 +/Tools:4N +/ToonLink2:6B +/Toothless:1C +/TopBanana:4G +/Toples:4N +/Torikhtil:6C +/Torikhtil_:09 +/Torrenter:3C +/Tosiaki:4C +/TotallyNotEKcryptor:0C +/Touran:3C +/Toxic:6B +/Toyota:2T +/Tracreed:3A +/Trasp:42 +/Travis:2D +/TreeServ:25 +/Trevelyan:63 +/Trichocereus:0D +/Trickster:25 +/Trieste:1Z +/TripityDudeGuy:3C +/Tripper35303:6C +/Tristan:3H +/Trixar_za:4N +/Trollol_owo:51 +/Truenos:5E +/Trump20:42 +/Trump_202:25 +/Trumper:0C +/Truth:03 +/Tsukasa-kun:4C +/Tsutsu:3M +/TubeStake:09 +/TubeSteak:6H +/Tum:63 +/Tur:3C +/Turrent:3H +/Turrent_:4G +/Tware:4G +/TwiPrime:0C +/TwinTail:4G +/TwinTail_:3C +/TwisT:25 +/TwisTg2sb:6C +/TwisTqew3:4N +/Tyrod:6C +/Tyrone:25 +/TzepesH:1C +/TzepesH_:09 +/U1S1A1:2D +/U7v8:63 +/UBykpigKL:0C +/UD98:0A +/UFC:09 +/UFC_:5E +/UIcT:4G +/UOAM:4N +/UTC:4G +/UYLZ1:4N +/UberGoof:0C +/Uberius:25 +/Uberius_:2T +/Uberking:6C +/Ubermensc:4C +/Ugur:2D +/Uiwoo:25 +/Ultra-Far-Right:3C +/Umeeg:6B +/UmpireRewire:03 +/UnaChicaYeye:42 +/Uncled1023:03 +/Uncled1023_:25 +/Undefined_Reference:1Z +/Underdose:5E +/Undermose:0C +/UniquelyGeneric:0A +/UnrealFeeds:2J +/Upaeko:63 +/UpandDown:1Z +/UpnDown:4G +/Uranium:1U +/Uranium28:1C +/Uranium58:1U +/UrbenHulk:4N +/Urine_Bubbles:1Z +/Ursa:25 +/UserNo1:3C +/UserOO7:6C +/User_:09 +/User__:4G +/Uthes:25 +/V1nL4nD:2D +/V1nL4nD_:63 +/V1p3rBytes|`:2T +/V3n3RiX:5E +/VIKU:0C +/VLetrmx:6C +/VOiceMe:63 +/VPNmob:6N +/VZfz:51 +/VaLiuM:6B +/Vaerchi:42 +/Valyrie:25 +/VampirePonyo:6C +/VanEclair:2D +/Vanessa:4C +/Vegan:0C +/Veixe:5E +/Veldsky:3H +/Venu:42 +/Veracioux:25 +/Vernon:6B +/Vertigo1:6A +/ViCi:25 +/ViCoDiN:5E +/ViCoDiN-:0A +/ViCoDiN_:4G +/ViKU:0C +/ViaGetty:09 +/ViciousVoila:3C +/VictimToEmma:3H +/VictimtoKo:2J +/Vile:1U +/Vincent:5E +/VincentXi:25 +/Vinny666:3M +/Viper:03 +/Vipera:25 +/Virgin98:1Z +/Virginox:0C +/Virginox_:1C +/Virtual:1C +/VirtualIl:2J +/Visig0th:4G +/Visigoth:6C +/Visor:25 +/VitamineD:1C +/VitaoDoidao:5E +/ViveChat_44342:1Z +/Vizitator_8509:0C +/VoZtFOeKr:3H +/Vodka:3A +/VodkaV:6B +/Vohtee:3H +/Volentis:0C +/Vomista:25 +/Vomitus:09 +/Vortex:1Z +/Vousti:03 +/W00gaWoo:6C +/W8LPJFQnZ:0C +/WANG-HANG:1C +/WAP:1Z +/WEAKmage:1C +/WESTDAMION:42 +/WIN98SE:63 +/WOPR:3H +/WORDPRESS:3P +/WOW:0C +/WQ5aj:6C +/WU_1596487322336:0D +/WU_1600224364883:03 +/WU_1600792671750:2J +/WZOp:4C +/WZRD:3H +/WackyWolf:4C +/Wallet:2J +/Warsawio:63 +/Warss:09 +/Wasim7:51 +/Waye:51 +/Wayne:0C +/WeEatnKi1:4G +/WeEatnKid:03 +/WeGotMoreGum:2J +/WeLoveCP:6B +/WeeBo:09 +/WeeBo_:03 +/Weenished:51 +/WheelZ:3H +/WhereIsMySpoon:4N +/WhiteBoy:3M +/WhiteBull:25 +/WhiteNigs:4G +/WhiteTiger:0C +/WhiteTigerRage:03 +/Whitewolf:6B +/WhizzWarlock:3A +/WiZ:2D +/Wildstorm:4C +/Wildthang2:3C +/WillePoik:25 +/William:3A +/William^:51 +/Willux:51 +/Willux-chan:3H +/WinSock:3H +/Winddd:2D +/Windigo:6C +/Wint3r:51 +/WiseOne:6H +/WishIHadACock:51 +/Wizzup:4N +/Wnlqra:3A +/Wobbly:3M +/Wolf:3M +/Wolfy87:09 +/Wompum3:5E +/Word:0A +/Wordswort:1C +/Wordswrth:5E +/Workbench:42 +/WorkingGoose:25 +/Wrongnick:3A +/WuhanFlu:0A +/Wulfe:6H +/WyAn:6H +/Wylie:2T +/Wynton:03 +/WzDarwin:3A +/X:09 +/X-Scale:0D +/X-Scale`:3A +/XSlS:03 +/XYAZvrovp:3H +/XaNaX-:1C +/XaNaX_:4C +/Xafloc:6C +/Xakurinha32:4N +/Xavi92:3C +/XbCKzvEfB:6B +/Xea:4N +/Xen0:5E +/Xhdhc:4G +/Xibalba:6B +/Xicor:1U +/XqUr:09 +/Xylitol:2T +/Xylitol^:1Z +/Xzibath-H:1C +/Y-BOTHA:4G +/YAYOfolksYAYO:51 +/YCKWMfg:2D +/YEWKQL:5E +/YIwO:3C +/YT-info:0C +/Yaedie:2D +/Yak-san:0A +/Yakui:6B +/Yakui_:2D +/Yallqueda:6A +/Yasze:1C +/Yeji:0A +/Yeji_:3M +/Yemeni:03 +/Yendred:3H +/Yito:2T +/Yito37:3M +/Yito54:03 +/Yito9:03 +/Yitomato:0A +/Yitoo:6H +/Yndrd:3H +/YodaGnom:3C +/YogSoWhat:4G +/Yossarian:09 +/Yoursself:6B +/YtxrIxsEE:3H +/Yukiiii:3H +/Yuppie:4N +/YuwuY:2T +/YuwuY_:42 +/Z4CH3:6N +/Z4CHe:51 +/ZUB:3A +/Zach2:03 +/ZaeQue:2J +/ZahVu:1Z +/Zanthas:3A +/Zarharva:03 +/Zarharvester:1U +/ZayStorm:3C +/Zayto:3A +/ZcwM:6C +/Zed:42 +/Zeeye:1Z +/Zelda:6H +/Zerg51:4N +/Zerg_:1Z +/Zero:4C +/ZeroFux:3H +/Zeth:0C +/Zig_Zoss:0C +/Ziginox:3H +/ZipStick:4N +/Zn3s:5E +/Zoe_Pace:1U +/Zoldax_II:4G +/ZoomGuy:0A +/Zordon:3M +/Zork:0C +/Zub:6C +/Zub_:42 +/Zuppone:0D +/Zx:03 +/ZyAO:3H +/Zyll:2D +/[:5E +/[-_-]:3A +/[-{}-]:4N +/[7hC]x5h4d0w:0C +/[ARS:51 +/[BigDadE]:40 +/[CFLeX]:4C +/[CIA]:6B +/[Crow]:3M +/[E:25 +/[Harlot]:1Z +/[I-R-D-1-:3A +/[IRS]:3M +/[KGB]:4C +/[Marius]:2T +/[NSA]:2T +/[NoNameAvailable]:5E +/[RMS]:03 +/[R]:03 +/[Randall]:0D +/[TriiiX]:25 +/[_^Ne[N]o^_]:2T +/[`:51 +/[`voidhlwm_:3C +/[d-_-b]:2T +/[haydenh]:7H +/[k00l]zducuck:6B +/[k]:4C +/[k]LtKWR:03 +/[k]LtKWRI:09 +/[k]WATLTL:1C +/[k]bed:3M +/[k]beerIn:2J +/[k]doogh:0D +/[k]habib:25 +/[k]inBED:1Z +/[k]inBar:3C +/[k]itbs:3A +/[k]mbp:4C +/[k]mbpINb:4G +/[k]sunbat:6B +/[k]walk:6C +/[k]work:6B +/[k]workpc:2T +/[m]:03 +/[m]_:2T +/[mezmur]:6C +/[mz]:4C +/[roar]:3H +/[roar]_:3H +/[twat]:4G +/[vae]:42 +/[vlad]:5E +/[werejag]:0D +/[x]:0C +/\:1Z +/\0:42 +/\\:6H +/\\Mr_C\\:42 +/\_:1Z +/\`\:1Z +/\g:42 +/\o:0A +/]IBF[:1C +/]R[:1C +/][_R_][:6C +/]haydenh[:7H +/^-^:6C +/^1597514^:51 +/^1597532^:1Z +/^1597546^:5E +/^1598128^:4N +/^1598151^:0D +/^1599937^:09 +/^1599966^:2J +/^1600552^:51 +/^1600570^:6H +/^1601138^:09 +/^1601146^:1C +/^1601175^:51 +/^1601204^:4C +/^1601298^:2T +/^1601756^:6H +/^1601780^:4N +/^1602971^:6C +/^1603575^:4C +/^1603577^:6H +/^1609020^:40 +/^1609034^:2D +/^1609625^:1C +/^1609639^:4G +/^Emi^^:6N +/^Emilay^:6N +/^Emily^:0A +/^Voyager:40 +/^^:6B +/^^^Emily^:4G +/^^^emi^^^:1Z +/^_Emi_^:03 +/^_^:09 +/^_^_:3M +/^__^:25 +/^___^:3H +/^______^:3A +/^_______^:4G +/^e_mily^:1C +/^emi^:4C +/^emi^^:3A +/^emi^^^:0C +/^emily^:1C +/^emma^:63 +/^i^:2J +/^neet^:4N +/^pHANTOM-:5E +/^pHANTOM^:6B +/^syn^:03 +/_:3A +/_07N1:2J +/_0N1P:1C +/_0nap:51 +/_0pan:51 +/_0x5fc3:6B +/_Biznz:51 +/_Dude_:09 +/_Leviticus_:63 +/_Parvati_:09 +/_QB:1Z +/_QB_:2T +/_Q_:1C +/_Royal:42 +/_SoniCFL:4G +/_Supersta:4G +/_Zialus_:6A +/__:3M +/___:09 +/______:42 +/__ahimsa:3C +/__minty:09 +/__poke:3M +/__sbrk:3A +/_alph4_:3A +/_benj:4G +/_blasty`:6H +/_cr4ck_b1:42 +/_d:0A +/_ghoul:4G +/_heavyarm:03 +/_insomniac:6B +/_jiggawat:2T +/_jim:63 +/_joey_:4C +/_kylef:6C +/_mak:4N +/_mak_:42 +/_minty:0A +/_ncog:3C +/_notK:2T +/_oranges_:42 +/_owo:4N +/_paranoid:2D +/_poke:40 +/_tepes:09 +/_willo_:3A +/`:3H +/`-`:5E +/`360`MM:2D +/`360`mm:5E +/`Ice:42 +/`Sprinkle:6C +/`St0ner:63 +/``:4G +/````:6B +/`````:2T +/````````````````:3C +/`nonamoos:63 +/a:0D +/a1exs:6B +/a23456789:6A +/a2m:2D +/a2m_:3A +/a3d:3H +/a7:4N +/a7_:0D +/aBiesh:3H +/aDB-[u]:0C +/aFaggot:63 +/aFaggotHunterWhosAlsoAFaggot:63 +/aFaggotHunterWhosAlsoAFaggotKi:6H +/aFaggotKiller:0C +/aGT-[e]:2T +/aGaviW:3M +/aHT-[u]:4N +/aLongNick:4N +/aLpine_:3H +/aMC-[e]:3A +/aPJ-[u]:4N +/aPV-[i]:6B +/aRV-[i]:2D +/aTD-[i]:3A +/aTurkRapingSwedes:2D +/aWC-[i]:1C +/aWT-[u]:2T +/aZM-[e]:3C +/a_:0D +/aa:3C +/aaa:3H +/aaaa:3A +/aaaaa:0C +/aaapycov:51 +/aanji:4N +/aaro:0D +/aaronmcadam:3C +/abdf9988:03 +/abe_simpson_:63 +/abeato:03 +/abecx:4N +/abecx_:6C +/aber:6C +/abigail:03 +/abq9J:0A +/abrahm:6A +/absinthe-:6H +/absinthe_:1C +/abuck05:63 +/abum:25 +/abum2:3H +/abumfone:03 +/abumpad:3A +/abumphone:51 +/abyssangel:3H +/ac1:25 +/ac1dvegas:6H +/ac2:6H +/acappell-:3M +/acappella:2D +/acbn:3A +/accuracy:1Z +/ace_kevi:03 +/acerising:51 +/acid-:2J +/acid_:51 +/acidapex:0C +/acidchik:09 +/acidified:6B +/acidjazz:4N +/acidjazz_:63 +/acidspaces:42 +/acidvegas:51 +/aclark:2J +/acrsu:25 +/activFDNY:2D +/adahn:0A +/adam:42 +/adamd:0A +/adamd_:42 +/adamr:51 +/adc:0C +/addc182:4G +/adde9708:0D +/adesas:0A +/adhn:42 +/adium:6C +/adm:0A +/admin__:63 +/admin___:2D +/adon:1Z +/adonisasu:4C +/adresas:6C +/adrien:25 +/adrien-:3A +/adrien1:6C +/adv0c4te:2J +/adventure:0C +/aeChi:51 +/aeGie:3H +/aeShe:2T +/aeZiek:03 +/aecoiG:3H +/aegis:4G +/aelien27:5E +/aempirei_:2T +/aeres:3C +/aesthetic:3H +/aesthetik:3H +/aether_:03 +/aether`:63 +/afb1:1C +/afkay:03 +/afkgoy:5E +/after8:2J +/afx:0D +/agant:6B +/aghgurqa:25 +/agmbat:1C +/agmethod_:2D +/agnahim:63 +/agsv:3M +/aguslr:0C +/ahFie:51 +/ahNgum:2D +/ahf:03 +/ahfeel:2J +/ahimsa:4C +/ahltvrlb:25 +/ahmet:0A +/ahmuT:3M +/ahplA:4C +/ahtoX:2D +/aiKuiy:5E +/aiWoKe:03 +/aidenholmes:3M +/aids:63 +/aids_:3H +/aidsbird:4N +/aidz:63 +/aims:25 +/ainoue:2T +/ainoue_:6B +/air:5E +/airconditioner:6C +/airconditioner2:42 +/aisec:51 +/aisec3:3P +/aiwahS:2D +/aj:0A +/ajace:5E +/ajax:51 +/ajcau:6H +/ajgrit_:2T +/ajguille:6C +/ajpfefj:3M +/ajpiano:3A +/ajpywlb:0A +/akaso:3M +/akejay:5E +/akejay_:2D +/akem__:2B +/akfuu:3C +/akfuu_:25 +/akitten:42 +/aku:03 +/alanna:09 +/alaskabea:3H +/alberto:6H +/albino:0C +/alchemist:4C +/alchemist0:6C +/aldKorn:51 +/aldcor:51 +/aldocr:1C +/aldroc:0A +/alex[in]chains:4G +/alexs:0D +/alexsm:63 +/alexss:1C +/alff:25 +/alfred_cockhitch:63 +/alfredo:3C +/alg0d:3A +/alhassana:6B +/alhassanaraouf:1C +/alice:2T +/alien88:63 +/alienbaby:4N +/alison:6B +/alkalinity:2D +/alkyl:09 +/all-ameri:2J +/allant4:2T +/allant40:4G +/allant401:42 +/allenp:3A +/allenwren:3A +/allfather:0C +/allison:4N +/allison_:6C +/aloeventj:3M +/alongtong:3H +/alph:42 +/alph02:6B +/alt3r3d:4N +/alt_5t5:3A +/alterego:2D +/alterego__:2J +/altomo:3H +/alts:3A +/alucardo:6C +/alucardoo:2T +/alyosha:6B +/alyosha_:0D +/alyoshaa:2D +/alz:3M +/am_an_exit:2D +/amadeus:4C +/amanda_:0A +/amar:6B +/ambrose:6B +/ambrosia:0A +/amc-:0A +/amcclure:4C +/amelian:4C +/amelian_:03 +/amez:1Z +/amino:3H +/amino-:2D +/aminoo:25 +/aminooo:5E +/aminux:42 +/aml:63 +/amlutios:1C +/ammon:2T +/amolith:3P +/amphibulu:0C +/amphibulus:3C +/amrowsell:0C +/amrowsell_:1Z +/amvoled:0D +/ana:0C +/anachron:0C +/anarchist:6C +/anarchy_1:3C +/anarchy__:4C +/anass:3C +/ancmt:03 +/andai:4G +/andai1:4N +/ando:1Z +/andonuts:03 +/andquesada:25 +/andras:63 +/andrea:4G +/andropov:3H +/andropov_:4N +/andsee:0C +/andy_:1Z +/andykof20:4G +/andyvk5:6B +/anfpilu:4C +/ang8lax:4G +/ange1:1Z +/angel_fir:03 +/angelzrkr:3H +/angieb:0C +/angular:4G +/anherop:5E +/animu:3M +/anishakar:2J +/anita_20:6H +/anjel:51 +/anjelic:0A +/anjifa:3H +/anjifa_:03 +/anlqw:5E +/annA:6C +/anna:1Z +/annaSEX:4N +/anna_:51 +/anna_\:5E +/annaa:09 +/annal:1Z +/annalena:4C +/annalisa:6H +/annamalinka:4G +/anniez:25 +/anniez-:3H +/anniez9:25 +/anniez_:4N +/annna:25 +/annnna:2D +/annon:51 +/ano^:4C +/anon:42 +/anon1:03 +/anon108:09 +/anon1312:09 +/anon2:4N +/anon4:6N +/anon623:0D +/anon9234:1C +/anon9234_:1Z +/anon987321:25 +/anon_:1C +/anon__:4G +/anonamoos:1C +/anonssssssss:4C +/anonymoos:4C +/anonymous_:1Z +/anonyxoxo:25 +/anoroc:0C +/anthis:4G +/anthis_:3C +/anthk1:09 +/anthonyg:6H +/anti-soci:51 +/antifox:4C +/antipeace:25 +/antipent:1C +/antithes_:0A +/antithesis_:3H +/antithesis__:63 +/antitype:63 +/antman:42 +/anton:4G +/anton1:2T +/anton2:6B +/antonizoon:2T +/anton|pw:0C +/anubis:09 +/anunciad:03 +/anus:42 +/anxia:1Z +/anystasia:3C +/anzzrjg:4N +/apb:0C +/apenas:4N +/apetresc:0C +/apetresc[m]:1Z +/aphrax:2D +/aphrodite:3A +/api:5E +/aporpo:42 +/apostate:3A +/apostrope:2J +/apple:6B +/apu:3C +/aqmgdxp:42 +/aqua_teh:4G +/aquinzie:2T +/aquoot_:6C +/ar:6H +/ar-:63 +/arabi:6H +/aradesh:4G +/ararouge:25 +/ararouge_:51 +/arbogt:25 +/arbogt_:3A +/archbspwm_:63 +/archwizard:0D +/arcseconds:4N +/ardoyne:2D +/ardoynne:3H +/arf20:2J +/argoss:3M +/arhoy:3A +/ariana:25 +/arianagrande:0A +/ariciu2k-:2J +/ariel:1Z +/ariel_1:51 +/arii:1U +/ario:6B +/ark:0A +/ark_:5E +/arleigh:4C +/arleigh`:25 +/armeni:42 +/armin:03 +/armin76:25 +/armoth:03 +/arnge:1Z +/aroticoz:0D +/arsekeks:0C +/arsekeks_:51 +/arsmagna:3M +/arsonal:4G +/arzael:09 +/asd123:6H +/asdadasasdqw:51 +/asdadfa:3M +/asdf__:6B +/asdfgh:6B +/asdfghjk:2T +/asdjaksdjkasdjkasdj:0C +/ash:25 +/ash9:2D +/ash_:0D +/ash___:1Z +/ashie:63 +/ashtrace:0C +/ashtrace_:09 +/ashy:6B +/ashylary:09 +/ask_anyon:09 +/askaxon:6B +/askme:3H +/asome1:40 +/ass:3A +/ass_:1C +/assboy:6B +/asscandle:3H +/assfog:2D +/assfrog:0C +/asspiringfaggot:4C +/asswhispr:0C +/asterismo:6H +/asterismo_:3M +/astr1:42 +/astra:1Z +/astra_:1C +/astro:2J +/astro_:3M +/astroid__:1C +/astron:2D +/astro|:3C +/asuka:0C +/atechad:25 +/ateppqx:51 +/ath0:4C +/atk:03 +/atlas_:42 +/atlus3:6H +/atomic:6B +/atrocityvoyeur:5E +/atunecat:09 +/aucampia:6C +/aucklan:1Z +/audemux:6H +/audioslave:1C +/aunickuser:4G +/aunickuser1:4C +/aunickuser_:6B +/aunickuser__:3H +/aurghyadip:2T +/aurghyadip0:09 +/aurghyadip3:1C +/aurghyadip4:25 +/auronite:1Z +/autism:2D +/autismnesday:51 +/autismo:3C +/autismo_:4N +/auxdemux:63 +/avalon:25 +/avast:3H +/avdb:42 +/awe:3A +/awex:25 +/awfgq3gq3:25 +/awwe:25 +/ax0l:03 +/axlwqp:0A +/axon:5E +/axu:0C +/aycanada:2B +/ayersea:25 +/ayerseas:42 +/aylamao:2J +/ayool:09 +/ayylmao:1C +/azel:09 +/azgbz:3C +/azirino:6C +/azod:3C +/azrael:4G +/azsciitec:25 +/azsclltec:0A +/azscootec:6N +/azscqqtec:09 +/azscuutec:25 +/aztec:51 +/azupoo:4N +/azurexp:09 +/azuzu:42 +/azza:3H +/b:0C +/b00bs-:2T +/b00da:5E +/b00t:4C +/b0dhi:3A +/b0dhi_:2T +/b0nk:42 +/b0redey:63 +/b0x:1C +/b0x191446253:2T +/b0za:6C +/b0za_:6H +/b17bmber:6H +/b1ackcat:2D +/b1ink:3M +/b30wulf:3H +/b333nz:03 +/b333nz_:4G +/b33nz:3H +/b3ck_2k2:03 +/b3d1n4t01:1Z +/b3d1n4t02:09 +/b3d1n4t03:2D +/b3d1n4t0r:3M +/b3enz:4N +/bBNXhE:25 +/bROG:4C +/bUTTvOMIT:1Z +/b_:2T +/babo:0D +/baby_penguin:09 +/babychaos:51 +/babyfarts:4N +/backronymman:3M +/backspace:4C +/baconshit:0A +/bacterio:0C +/badbit:3C +/badcloud_:0C +/badcmpany:2J +/bade_:63 +/badperson:4N +/bads:6C +/bads_:1Z +/badumbum:0C +/badumbum_:1C +/bafs:25 +/baguette:1Z +/baguette_:0D +/bakedpotato:0A +/bakuzan8:5E +/bakuzan87:4C +/bakuzan88:25 +/ballsweat:1C +/balters:3C +/bamdad:03 +/bamdad_:25 +/bananazur:6C +/bananstol:4C +/barby:63 +/barf:3P +/barguesto:3M +/barkl:3M +/barnie_:0C +/baruchel:2D +/based:6H +/basse:0A +/bassedul:4N +/batewolf:3C +/batman:2D +/batman-:4N +/baus:0A +/bax:5E +/bax__:6H +/baxmoke:63 +/baz_:42 +/bb:3C +/bb420:63 +/bb8:3C +/bbb:3C +/bbb1:3M +/bbbbuni:6H +/bbcereal:2D +/bbojug:1Z +/bbqnp:09 +/bbunni:6C +/bcd:6B +/bch:25 +/bchall:09 +/bcphmx:6B +/bcqgpsba:3H +/bcwcebiwb:25 +/bda:09 +/bdavey:2J +/bdna:09 +/bdotdiwd:6C +/bdown:2T +/bdz:2T +/beach:2D +/bean__curd:25 +/bean_curd:3C +/bean_curd_:2J +/bean_curl:1Z +/bear9:03 +/beard:6C +/bearmarch:4G +/beatdown-:25 +/beatdown_:25 +/beautyy:3M +/bedrolls:6H +/beeard:09 +/beebz:09 +/beeenz:51 +/beef:3P +/beefadd:51 +/beenz:1C +/beenz-:6C +/beepingwindows:6B +/beers:03 +/beez:0C +/begriffs:6N +/behold_a_great_red_dragon:2J +/behrad:0C +/bela_lago:4C +/belanthor:2T +/belcher:1Z +/belcher_:4G +/bellman:4N +/ben:3A +/ben-z_:0C +/benburwell:2J +/benburwell_:3P +/bencoh:3H +/benderRodriguez2:6C +/bendoin:5E +/benedikt:09 +/benett:51 +/beng-nl:51 +/bengt:6B +/benharri:5E +/benj:4N +/benna831:40 +/benvenuto:3H +/beoli999:03 +/bep:1Z +/bergur_:1C +/bero:25 +/bertiger:3A +/bestmusic:3H +/beta-:42 +/betaboy25uk:51 +/betatester:2T +/bex:09 +/bex-:63 +/bex_:2T +/bex__:4G +/bexiled:3C +/bexit:5C +/bextra:2D +/bexxx:6C +/bfnhyu:2J +/bfot:51 +/bg_:2T +/bg__:3H +/bhavesh:3M +/bheekie:6B +/bhkor:4C +/bhp:3H +/biePha:1C +/bigBelly:3A +/bigV:2D +/bigVplaya:2J +/big_dad_e:3M +/big_t:42 +/bigbird:1C +/bigbob:3M +/bigboss:25 +/bigboy42:51 +/bigchungus:2J +/bigdave:0C +/bigdouche:3A +/biggus:5E +/biggus_diccus:4G +/bigjohn:1Z +/bigman1337420:0D +/bigman645886:1C +/bigman789420:2J +/bigmark:0C +/bigrichie:4G +/biheoad:4C +/bikr:0C +/bilbo991:2T +/bildramer:09 +/bilegeek:6B +/bills:42 +/billyb0b:3H +/bin:03 +/binary_:51 +/binbasti:0C +/binfu:03 +/biniar:6C +/binky:3A +/binwiederhier:09 +/bionic:4N +/bionic_:1Z +/bionicpup:1Z +/birkoff:6B +/birth:0D +/birth_:3A +/biscoro:09 +/bitatem:1Z +/bitch:2J +/bitchass:2T +/bitchlor-:6C +/bitchlord:63 +/bitco:6H +/bithov:0C +/bitrot:1Z +/bitrush:5E +/bixnood:42 +/bj0rg:2B +/bj0rn:6C +/bjongo:25 +/bk:25 +/bkhl:2T +/bkjxkaxg:2D +/bkyy:6B +/bla:3C +/blaag:3H +/blaag1:2T +/blackbea-:4N +/blackbea|:5C +/blackbird:2J +/blackbit:1C +/blackdev-:4C +/blackdevl:0C +/blackest_mamba:3M +/blackest_mamba_:03 +/blackjid:0C +/blackntan:51 +/blackout:1Z +/blackpape:3A +/blackrose1:3A +/blacktie:3P +/blackwhale:2D +/blah:0C +/blakange-:4N +/blakem:2T +/blank:6C +/blass:0A +/blass_:63 +/blaxthos_:6H +/bleach:0C +/bleb:2T +/bletch:2D +/blfyah:6B +/bling:63 +/blink:3M +/blink_:5E +/blip:03 +/blippy:03 +/blitzen:3H +/blmbm:3C +/blocked:1Z +/blocko:0C +/blode:09 +/bloeree:2T +/blogbird:2T +/blogging:2B +/bloodyMurder:25 +/blowfish:3A +/blowmeok^:1C +/bludfurst:63 +/blue:25 +/blue_:3H +/blue__:3H +/bluefourier:4C +/bluerose:2D +/blumpkin:4C +/bmlnpw:63 +/bnozliee:3M +/bo-:2T +/bob:6C +/bobMarley:0C +/bobafett:3M +/bobpp_:6C +/bobsonofb:0A +/bogo_lode:3A +/bohCh:09 +/boii:4N +/bollocks:25 +/bomas:4G +/bombluje:2T +/bomct:4C +/bonfacemu:2D +/bong:6B +/bono_nob:0A +/bono_nob_:25 +/bonz060:0C +/boo:3H +/boobtube:3H +/boof:25 +/boof_:2T +/boogaloo:3C +/booger_:63 +/boopingwindows:09 +/bootleg:3M +/bootrom:1C +/bootydoom:6H +/bopadoo:2D +/borliz:3A +/bot22:1C +/bothadeez:42 +/bothofthosearethesame:42 +/botulf:3C +/boubou:4G +/bougyman:3C +/bovpxdb:1C +/box1:25 +/boxer:0C +/boxrick:6C +/boxrick_:0D +/boza:51 +/bozozcur:6B +/bozozocur:3A +/br1dg:4G +/br377:0C +/brabo:3M +/bradley:3P +/brah:40 +/braixenirl:4C +/braixenirl0:6C +/braixenirl2:1Z +/braixenirl6:4N +/branden:3A +/brandfilt:3A +/brandi_:4N +/branefawt:2T +/branon:3H +/brap:6H +/braplord:25 +/brayden:3C +/brea:03 +/bree33:2J +/brendantcc:3C +/brendantcc1:3C +/brendo:2J +/brian__:1U +/bricks:3C +/bricks_:03 +/briesss:0D +/brite:3A +/brite19:6B +/brite41:0A +/brite49:2T +/brite50:2D +/brite90:4G +/brobird:1Z +/brocashelm:0C +/brokenrecord:42 +/brolin_empey:03 +/bronzie94:2D +/brooklyn:5E +/broski:3C +/bruh:1C +/brujomemin:6C +/brule:3M +/brutex:0C +/bruv:2J +/bryce:2D +/bryno:03 +/bs719:3H +/bsd:1C +/bsteel:2J +/bteeer:2D +/buZz:3M +/bubble26111989:0D +/bubbles:4C +/buck_lanc:2J +/buckhardp:0C +/bugtester:2J +/buh:3M +/buinb:1C +/buinb_:6H +/buinb__:6C +/bulldozer:1Z +/bullet:6C +/bullet_:0C +/bullmark:3C +/bullmark-:09 +/bullmark_:3H +/bully:6B +/bumfuck:0A +/bunbun:3H +/bungo:25 +/bunkerrr:09 +/burak:1C +/burn:1U +/burn_:6H +/burnmjd:03 +/burnout:6C +/burntjew:1Z +/burntkale:03 +/bushwhack:3M +/bushwhacker:0D +/bushwhacker_:3C +/buss:5E +/bustghost:4C +/butcha:09 +/butcha-:03 +/buttercup:0A +/buttercup^:4C +/buttertoast:42 +/butth0le:2D +/butthash:3M +/butts:09 +/buttvomit:2J +/buyer__:1C +/bwkyurrl:6B +/bx:5E +/byoung:3H +/bysizngp:51 +/byte1032:63 +/bzed:6C +/bzed_:5E +/bzeld:42 +/bzjakq:2D +/bzzp:3C +/c041:51 +/c0nker:42 +/c0ntempt:1C +/c0ntempt`:4G +/c1v1l:09 +/c2cCJSRl:4N +/c5n:2D +/c64:3A +/cBQW:3A +/cDpY:2T +/cGSmNYyQw:4G +/c__bmxlkb:0C +/c_hi3:0A +/c_hi3-:4G +/cabat:42 +/cable_:4G +/cacco:4N +/cactus:1C +/caeTh:4N +/caesar:51 +/caesar-:3A +/caesar_:25 +/caesium:3M +/caffeinatedcode:6C +/cahXee:03 +/cahlosspl:4N +/caitlynn:51 +/calaf:3H +/calafRPG:2J +/callcc:4C +/callow:6B +/calma:5E +/calsonic:2T +/calsonic28:51 +/calsonic58:40 +/camSF:09 +/camus:2D +/canada420:6C +/candy:63 +/candyman:6H +/cant_chat:6H +/cantstop_:0A +/capheind:51 +/capt_zap:25 +/capt_zap_:42 +/captian_c:4N +/carciofino:3M +/carciofino68:2D +/careet:1C +/carly:63 +/carradine:0D +/cartier:03 +/cartman:0C +/casanostr:5E +/cashstir:1Z +/casimir:51 +/caskd:1Z +/caskd-dev:2J +/caskd-uir:5E +/caskd-uirc:1Z +/cassim:6B +/cassim-:42 +/cat:3M +/catacomb1:3C +/catacombs:3C +/catalase:42 +/catalase_:03 +/catatoni-:0D +/catatonic:3M +/catatoni|:1C +/catdad:3H +/catman:0C +/catman370:03 +/catpeach:51 +/cau0:25 +/caubert:2T +/caubert_afk:63 +/cave:2T +/cazpxqw:51 +/cbdoll:1C +/cbmsfdwh:25 +/cbmuser:3P +/cbtgr:4C +/ccanw:0A +/ccjqudw:25 +/cdBr:25 +/cdb:6H +/cdma:4G +/cdolan22:3C +/ceasar:0C +/ceaser:4N +/cecilb:4C +/ced117:1Z +/ceene:63 +/ceibal:4C +/ceibal_:4G +/cel:6C +/cephalus:63 +/cerulean:2D +/cews:51 +/cfongyyf:0C +/cgixyyms:42 +/ch:2D +/ch00m:4C +/ch3mist:5E +/ch4ff:03 +/chEEKie:2B +/chaff:0C +/challah:6C +/chals:4G +/champ:5E +/changO-:4N +/changeme:4C +/changoXPR:5E +/chanhold:42 +/chanhold.hlircnet.:0C +/chanhold@chanhold:0A +/chanhold@chanhold.hlircnet.:03 +/chano:42 +/chano0:5E +/chano2:6H +/chano3:2J +/chano4:2J +/chano5:4G +/chano6:0D +/chano7:2D +/chano8:3C +/chano9:5E +/chanserv:0A +/chapi:09 +/charles_bottle_popper:0D +/charles_bottle_popper_with_che:25 +/charliebrownau:3H +/chartreuse:25 +/chase_:09 +/chatStroker:0C +/chc4:6H +/cheapie:6A +/checho:63 +/cheeNe:5E +/cheeseburger:4N +/cheesemonk:6B +/cheesemonk-:6B +/cheesemonk_:1Z +/cheez_:51 +/cheiBu:25 +/cheller:09 +/chelmzy:0A +/chelmzy8:2D +/chemicalgraft:42 +/chemist:09 +/chemtrail:0C +/chendo_:25 +/cheno1115:09 +/chernobyl:25 +/chewbacca:4G +/chewy:42 +/chicane:03 +/chicane_:3C +/chicken_nugger:1C +/chik:2J +/chik_:2T +/chiklet:6C +/chiku:4C +/chill:4G +/chill_:2D +/chill__:63 +/chinaski:5E +/chinatown:1C +/chioLa:6H +/chipolux:6C +/chippah:0D +/chitao:2T +/chiyou:03 +/chiyou-:09 +/chiyou3:6H +/chiyou_:4C +/chkrr00k:6C +/chmuri:4N +/choob_:63 +/choom:63 +/choom_:5C +/chopchop1:1C +/chowder:63 +/chown-:6C +/chown_:3C +/chown__:03 +/chrippa:1C +/chris39:63 +/chris3915:3M +/chris_40:2D +/chrisfagd:1Z +/chrisgayd:25 +/chrissy:6C +/christistheway:2T +/chromis:4C +/chron:6B +/chrono:1Z +/chrono-:09 +/chrono_:1C +/chrono__:1U +/chuchu:09 +/chucky_d:25 +/chxeizpr:6H +/cidal:03 +/cidal_:3P +/cil:1C +/cilla:6H +/cipher:3M +/ciprian_:25 +/circuitbone:09 +/cismq:4G +/cities:25 +/cjg:42 +/cjglyefa:4N +/cjmtyx:6B +/cjrroevm:1C +/ck:3A +/ckat:2J +/ckejsdib:3A +/claire:63 +/clam_:4C +/clamkin:6C +/clamkin-:0C +/clamkin|:4C +/clams:3H +/clapback:3A +/clarux:5E +/classhole:5E +/clavichords:3A +/cleaningwindows:6B +/cleantwat:1C +/clitboner:6C +/clort:2D +/clotrim:3C +/clownUSA:2D +/clownboy:2T +/clownprty:63 +/cm:25 +/cmang_:6H +/cmccabe:42 +/cmos:2J +/cmx:63 +/cncfi:6H +/cnr:6C +/cobra_:40 +/cockroach:2D +/cocks:0C +/coderobe:3H +/codestr0m:6C +/codez:4G +/cody-:0C +/coffeeiazo:1C +/cogitase:0A +/cohen:0A +/colbertin:25 +/coldwheels:4G +/colombus:0C +/colonials:0A +/coltseavers:2J +/coltseavers_:0D +/commodus:6H +/commodus_:1C +/communist:3C +/comnsense:51 +/comod0:6H +/comodo:0C +/comp4:42 +/compTECH:3C +/compTECH-:3A +/computer:4C +/computers:0C +/comrade:1Z +/comrade-:09 +/comstud:6H +/conf_t:09 +/conno:4G +/connor332:4N +/conrad:63 +/constructed:4C +/contained:42 +/contrail:0A +/convict:4G +/convolution:1C +/cooey:51 +/cooey-:25 +/cooey^:63 +/cookie:6H +/coolacid:25 +/coolbeens:6C +/cooldude:3M +/coolio:09 +/coolmandude:51 +/coolmandudebro:6B +/coolmandudebroguy:4N +/coolomb:0A +/coontach:25 +/cope:0C +/copypasta:25 +/copypaste:03 +/copypasteque:0D +/corelax:25 +/coreleade:4G +/corey1:4G +/corey2:2D +/coreys:1C +/coreystephan:4G +/corn:3A +/cornfeedhobo:2J +/cornflake:4G +/coronadetona:1C +/corosiv:40 +/corr64:25 +/corvex:3C +/cosa:4N +/costin:5E +/coughsyru:42 +/covid19:2T +/covid19_:0C +/covid19__:63 +/cow0w:4N +/cow0w_:4N +/cozen:1Z +/cp_veneto:3C +/cprez:2J +/cpyne007:4G +/cpyne777:4C +/cqi:09 +/cr1p:5E +/cr4ck_b1t:6B +/crackfu:6C +/crackfu_:0A +/craig:1C +/craig1:4C +/craig2:2T +/craig3:2T +/craig4:3C +/craigt:0C +/cramey:5C +/cranium:03 +/cranky:3M +/crapple:42 +/crash:63 +/cray0n:63 +/crayonsandsisssors:6C +/crayonsyummy:0C +/crazy88:40 +/crazyfox:1C +/crazyfoxy:6C +/crazytypo:0C +/crdb055:0D +/creedmoot:51 +/creep^ltx:1C +/creider:3M +/crimisok:0C +/crip:2D +/crip_:03 +/cripplekike:2D +/cris10an:1Z +/crisu:42 +/crisu_:4N +/crns:25 +/crns_:0C +/cron:2J +/crono_:4C +/crono|:4G +/crossword:2T +/crushdmb:4G +/crwl:0A +/crwl_:5E +/crypt0kr1:63 +/crypt0kraken:2J +/cryptopanic:5E +/crzdfkr:0C +/crzlg:4N +/crzlg_:0D +/csadilek:63 +/csawedpo:42 +/cshrik3:2T +/csr:51 +/cstroie:3C +/ct6:42 +/ct8:6B +/ctcp:1Z +/ctone:3A +/ctt:25 +/cttechnician:25 +/ctxu:2T +/cubes:3M +/cuck:4C +/cuckadoodledoo:0C +/cuckoo:0A +/cuckoo1:6H +/cujkh:2D +/cukcyzd:1Z +/cull:2J +/cum:3C +/cumbayah:40 +/cunny:2D +/cunt:1Z +/cuntrox:6C +/cup:3A +/cupaiV:09 +/cupcake:25 +/curegodde:09 +/curiouscity:42 +/curmet:2J +/curveball:42 +/cushin:3C +/cutie:3C +/cutiepie:42 +/cutlass:2D +/cvx:1C +/cwgnmp:4N +/cx:63 +/cxp:42 +/cyb3r:0C +/cyber:2T +/cyberPUNK:6C +/cyberfr0g:03 +/cyberjunkie:3M +/cyberlard:6B +/cygnus:1Z +/cykaspy`:3M +/cylex:1Z +/cyr4x3:4N +/cyren:42 +/cyria:03 +/cyrus:03 +/cyzx400:1Z +/czaks:2J +/czarbomba:25 +/czer00:6N +/czolgosz:25 +/czolgosz_:25 +/d:3H +/d-_-:51 +/d-_-b:1C +/d0:4C +/d00dles:1C +/d0m3r:1C +/d0m3r0:6B +/d0mP33-:1C +/d0mP33_:1U +/d0ndit0:1C +/d0ze-phone:42 +/d1g1t:63 +/d3m0:25 +/d3m0nm4dn3ss:25 +/d4:6B +/d4nny:0A +/d4redevil:03 +/d9thought:0C +/dArK:03 +/dArK_:2J +/dAwUD__:4C +/dCwBDusJO:51 +/dEEMZ:3C +/dEEMZ187:63 +/dNk:4N +/dOm3r:03 +/d_rebel:4C +/d_rebel_:0C +/d`:6A +/dab21:3C +/dabUFC:3H +/dabdab:2T +/dabears:2T +/dabears_:25 +/dabguy:3A +/dabguy000:2J +/dabguy2:51 +/dabguy3:51 +/dabguy444:4G +/dabguy555:6B +/dabguy666:51 +/dabguy7:0C +/dabguy777:3M +/dabguy778:03 +/dabguy8:6B +/dabguy9:2D +/dabguy999:6B +/dabguy_:3P +/dabguyrul:0C +/dabman:09 +/dabmuslim:6C +/dabohm:42 +/dad:0A +/dad_:3H +/daddy:0C +/daed_:5E +/daedisgay:09 +/daggett:2J +/daglhx:6B +/dah-rat:4G +/dahrat:51 +/dailykenster:25 +/dailykoder:4C +/daim2k5:4C +/dakkar:51 +/dakuwan:3H +/dalasfpok:1C +/dalila:0D +/dalila_:1C +/damax452:0C +/dan:5E +/dan_:1Z +/dani:25 +/daniel_:0C +/danielinux:4G +/danielz:6H +/dann:3M +/dap:2T +/daphne:03 +/dark_tang:5E +/darka:42 +/darkdoomer:3M +/darkdoomer_:6B +/darkex:03 +/darkfade1:51 +/darkfader:3M +/darkmage:3H +/darkmage_:1U +/darkmagic:40 +/darkmask:09 +/darkmask`:2T +/darkneb5b:03 +/darknelc9:51 +/darkness:25 +/darkness1:09 +/darkness_:0A +/darkneyp8:2D +/darksage:3M +/darksnake:1Z +/darkspadez|lapto:09 +/darkwind:3H +/darkwise:3A +/darkydark:4N +/darn:5C +/darndush:1C +/dart:2J +/darwin:03 +/darwin-:6B +/darwin-el:0C +/datajerk:2J +/datalobe:25 +/datalobe_:4G +/dataman:25 +/dataman2:2D +/dataman4:09 +/datastrea:63 +/dave:6C +/dave4925:6B +/dave4925_:2J +/david:2T +/davis:51 +/davitt:6B +/daw:1C +/daww:0A +/dayid:3H +/db-:1C +/db-_:3P +/db420:4G +/dboard2:4G +/dburno:42 +/dcNY:2D +/dcamp:3H +/dcamp_:0A +/dcat:3A +/dcli:25 +/dcm3605:3A +/dcoPSnEi8:1C +/dctrud:6C +/dctrud_:25 +/dcx:25 +/ddarko:2D +/ddd:0D +/dddd5555:4N +/dddddd:1C +/ddelony:4N +/ddevault:4N +/ddfd:2T +/ddos_hard:1C +/ddos_me_h:6B +/ddosalert:0A +/ddosbird:63 +/deadcat:03 +/deaderz:4G +/deadguy:2D +/deadhomie:09 +/deadly:1C +/deadmeat:5E +/deadnigs:6C +/death5:4N +/death_to_NWO:6C +/deathbybandaid:2T +/deathbybandaid_:63 +/deceit:1C +/deceit_:5E +/decent:3C +/dee_:0A +/deeply:25 +/deerbutts:09 +/deez:42 +/def_not_s:3H +/default:3M +/defiler:09 +/defqon:63 +/deicer:3H +/deiol:09 +/delial:4N +/delisa:42 +/della3:1Z +/deltaepsilon23:4N +/demfloro:3A +/demo:4G +/demo_:3M +/demogorg1:6H +/demogorgo:5E +/demsh:6N +/demure:2J +/demure-test:2D +/denkenz:1Z +/denkenz_:25 +/denwa:51 +/denwa2:5E +/derk0pf:3A +/derr__:6N +/derwutmann:0A +/destro:51 +/desu:4N +/desu9x:63 +/deth_vege:09 +/deurzen:4N +/dev\null:2J +/developer:3C +/devi8d:03 +/devil:1Z +/devilfox:40 +/devilfoxy:63 +/devnewton:3M +/devrtz:0A +/dewbieZ:3H +/dewbieZ_:3A +/dex:25 +/deysu:51 +/dfgh_:4G +/dfghj:2J +/dfive:4G +/dfksjlfda:25 +/dflp:6A +/dfs:4N +/dfstorm:2T +/dfx:2D +/dh:51 +/dhPu:2T +/dh_:3A +/dhejavu:4G +/di0ad_:51 +/diChe:6B +/diE:1C +/dianora:4N +/dibi:3A +/dice:2D +/dick:4N +/dickey:1Z +/dickey_:0C +/dickey__:51 +/dicot:3A +/didheevenexist:6B +/didjital:0C +/didnotknowthatiusesuchalongnic:1Z +/didsle:4C +/dieforir1:2D +/dieforirc:3A +/digi_:3A +/digital:42 +/digital_:25 +/digitl:5E +/digitlaci:3A +/dijit:0C +/dijit-:4G +/dijit-hexchat:6C +/dilubxwv:0C +/dimples:4G +/ding0pryd:4N +/dingir:6B +/dingir_:4N +/dingir__:4G +/dingo:63 +/dingopryd:4C +/dinkee:3C +/dionysis:6C +/dioxide:4C +/dip:25 +/directhex:42 +/dirmaster:3A +/disc:3A +/disc9:0D +/disci:5E +/disconnected:0A +/disconz:0C +/discord:09 +/discussed:4N +/dislabled1:3A +/disobey:3H +/dispose:5E +/disturb:2T +/disturb_:4G +/diviny:63 +/diviny-csh:63 +/diviny1337:3A +/divve:0D +/dj-e:0A +/dj-rollex:4G +/djahandarie:2T +/djce:63 +/djcoby:4N +/djel:6B +/djeleas:6A +/djeleas__:0A +/djmoch:42 +/djneomxl:4G +/djordjecupic:4C +/djpeebles:6C +/djreflecc:09 +/djreflect:51 +/djste:25 +/dk56:25 +/dk57:6C +/dk58:1U +/dkcf:6B +/dklsdkl:3C +/dlan:09 +/dld630-2:3C +/dleu:4N +/dleux:4C +/dlippy:4N +/dlm92j:4C +/dm:0C +/dm9kriFkQ:1Z +/dma:4N +/dma_:03 +/dma`:6N +/dmage:6H +/dmask`:2J +/dmt:0D +/dns:1Z +/dnsk:03 +/dnsk_:63 +/dnull:1C +/dnwklin:09 +/doberty:6H +/doc:2D +/docteurfolamour:0C +/dog_whistle:4C +/dogg:0C +/dok:2D +/dokuja:4G +/dolarhyde:3H +/dolaver:09 +/dolbe:25 +/dolla:63 +/dolphin:1U +/dolrayge:2D +/dongfix:3C +/donkarr:09 +/donkey:03 +/doodles:3A +/doomas:0D +/doomer0:4C +/doomer8:63 +/doppler:2J +/dorf:0A +/dorkmage:42 +/dorkness:4C +/dorkvader:6H +/dornier:3P +/dos1:09 +/dosmap:3H +/dothacker:2D +/dotskin:0C +/dotsonskin:2J +/dotsonskin45:6B +/dottymcdotface:0A +/dottymcdots:25 +/dottys:3A +/dotzee:3H +/double-a:3P +/douche:51 +/douche-:6C +/doug:25 +/doviny:3M +/download:3H +/doyhen:2T +/doyhen_:0C +/dozer_:51 +/dpIi:3H +/dpgb:2B +/dptdrma:6C +/dptklei:25 +/dqfO:2J +/dqk:25 +/dr1p:6H +/drPrimate:0C +/dr_rce_:6C +/dr_rce__:1C +/drachen:4C +/dragnalus:3A +/dragon2:5E +/dramo:5E +/drastik:6B +/drastikbot:03 +/dratbaby:6H +/drbean:4N +/drbean_:0C +/dreadful:5C +/dreamer:51 +/dreamer_:6H +/dreamingwindows:0D +/drek:1Z +/drelcott:4G +/drelcott_:6H +/drestglas:1C +/drewlande:0A +/drewsh:4G +/drewski:25 +/drhamstuh:42 +/driver76:3C +/driver77:4C +/driver78:2J +/driver79:09 +/driz:42 +/drkcactus:1C +/drkhsh:3C +/drkmg:2T +/dromer:1U +/dropkick:0C +/droptone:3C +/dross_Phy:09 +/droud:4G +/drpepper:25 +/drulw:2D +/drum:51 +/drunk:63 +/drunkos:63 +/druqs:1C +/dsasd:1Z +/dsaxzaq:1C +/dsc_:0C +/dsp:2B +/dtwpeoc:3M +/du6w:25 +/dubb:4N +/dublord:5E +/duckhunt:03 +/duckhunt101:1C +/duckk:2D +/duckonomy:5E +/ducksauce:2D +/dude2:2J +/dude3:4G +/dude4:6C +/dudis:42 +/dudisss:1C +/dudley:6A +/duglbexg:4N +/duiLah:1Z +/duk0r:1C +/dumbergoy:09 +/dumbgoy:6H +/dumbgoy1:4C +/dumbgoy5:3C +/dumbgoy_:09 +/dumbgoyy:0C +/dumbgu:6C +/dumbguy:0A +/dumbguy-:3A +/dumbguy2:42 +/dumbguy22:2T +/dumbguy4:03 +/dumbguy5:3H +/dumbguy^:0D +/dumbguy_:6B +/dumbguy|:3H +/dumguy:6C +/dumguy2:2T +/dumvgut:0A +/dupa:6B +/duro:3M +/duroSK:4G +/dusker:3M +/dv:1C +/dvdmuckle:6B +/dvqgm:1C +/dwa:4G +/dwainbird:2D +/dwaineNOT:2D +/dwarfinyourwalls:42 +/dwarfinyourwalls_:2J +/dwayne:6H +/dwts:6A +/dwts39:1Z +/dxahv:63 +/dxsqa:1Z +/dylan:63 +/dzajs:42 +/dzho:3M +/dzjfm:42 +/dzl:3H +/dzyuflf:3A +/e:4G +/e0f:6B +/e0f_:0A +/e8narx:0A +/eCW-[a]:6B +/eDG-[a]:2J +/eFX-[u]:6H +/eKM-[a]:2J +/eLN-[a]:03 +/ePOg:4N +/eR0dicChat:25 +/eRB-[u]:3M +/eRT-[i]:09 +/eU696Bl:4N +/eWT-[a]:1Z +/eXS:6C +/eYV-[i]:6B +/e_:6B +/eaDae:2D +/eafahV:5E +/ealona:6C +/earlgrey:6C +/earne3:51 +/eastcoastweb:25 +/easy_switch:4N +/eatshit:0D +/eav:3C +/ebwaj:09 +/ece:25 +/ecelis:3H +/ecelis1:51 +/echapa:3M +/ecmo:3C +/ecmo0:3C +/ecmo1:2J +/ecmo2:0C +/ecmo3:4N +/ecmo4:6B +/ecmo5:03 +/ecmo6:6H +/ecmo7:0D +/ecmo8:3C +/ecmo9:2J +/ecs:2D +/ectomorph:25 +/ed:0D +/eddie:25 +/eddie-:3A +/eddie_:6B +/edgarfrie:63 +/edgelord:3A +/edicius:09 +/edin:3A +/ediot:42 +/edists3w:0D +/edtej:2J +/eduardas:09 +/edward:3P +/edward_:3A +/edward__:25 +/edxley:1Z +/eeDaB:6C +/eeGhee:63 +/eeHae:51 +/eeHiet:4G +/eeNgu:0C +/eePaes:1C +/eeShie:6C +/eeZahr:25 +/eeero:3M +/eeesy:25 +/eeesy_:3C +/eeesy__:1C +/eefer:51 +/eefer_:09 +/eegenolf:1C +/eegenolf1:09 +/efge:42 +/efil4cri:3M +/efil4cri1:3M +/efil4cri2:3M +/efil4cri3:3M +/efil4cri4:3M +/efil4cri5:3M +/efil4cri_:3A +/efircorg:51 +/efman:4G +/efman_:5E +/efnable:0C +/efnet.deic.eu:40 +/efnetbot:0C +/efnetbot0:3C +/efnetbot`:2J +/efriendly:03 +/efsenable:4N +/efsnable:03 +/efsneable:0D +/eggo:2T +/eggsalad:4C +/eggy:1C +/eggy1:3H +/eghkun:3H +/egito:03 +/egypcio:3C +/ehdee:4C +/ehejnej:2D +/ehioCh:42 +/eiGohx:6B +/eiLeiC:6B +/eiThi:5E +/eightChad:4N +/eightmegs1:40 +/eiruLu:4G +/eisen:03 +/ejgywfud:6B +/ejh:3C +/ejr:2B +/ekeinos:2B +/ekollof:25 +/el8:09 +/elena:3C +/elevator:6C +/elias:6C +/elioat:0A +/elita:2J +/elldvc:03 +/elle:2J +/ellie:1Z +/ells:6C +/elp:03 +/elph:3A +/elph_:25 +/elred_:63 +/els:4G +/elsimio:4G +/elusive:6B +/elw:4N +/elwisp:3M +/elx:3H +/em:6N +/emaliy:6C +/emay:6N +/emayyyy:40 +/emb:2B +/embri0n:25 +/emhcnmy:25 +/emiemi:51 +/emiemiemi:6C +/emiiiiii:5E +/emli:2T +/emllle:2T +/emma03:03 +/emma035:2J +/emmaa:0C +/emmaf:5E +/emmaloui:09 +/emmalouis:09 +/emmalouise:2D +/emmalouise11:4N +/emmalouise14:4G +/emmalouise27:51 +/emmalouise37:63 +/emmalouise42:1C +/emmalouise71:3A +/emmalouise84:42 +/emmalouise85:6H +/emmalui:1C +/emmaluigi:09 +/emmanuel_:1C +/emmaps:03 +/emmasfather:1C +/emmff:0C +/emo-effy:3C +/emoEFFY:4G +/emoguy:6C +/emojiirc:25 +/emp:03 +/emp_:2T +/emu:6A +/enderwigg:6H +/endofinte:3C +/engelbart_prickly:03 +/englishm:4G +/eni:0C +/enigma:2J +/enqcih:25 +/enrique:51 +/ent:3C +/entartet:3C +/enthd:25 +/enthdgree:2D +/enyc:0A +/eoUt:3A +/eojksem:4N +/epbzh:3A +/epd:6B +/ephemer0l:4G +/epl:25 +/epl692:63 +/epl6921:09 +/epl692_:25 +/epoch:0C +/equwal:6H +/eqxvwj:6B +/era:3A +/erase:03 +/eraser:1C +/eraser_:25 +/erazer:0C +/erf:09 +/erf-:0A +/erfenable:3C +/ergo:3C +/ergo_:3M +/erica__:4C +/ericdm:3H +/erika:2D +/erikb:4G +/erin:2T +/erin_:03 +/erin__:1C +/erocker:51 +/erockr:2D +/erockr_:3A +/erratic:6H +/erratic_:09 +/erratic__:0C +/error:6B +/eruantiensaga:09 +/erzr:1Z +/esk2mo:6B +/eskimo:5E +/eskimo_:3M +/eslowai:25 +/esql:42 +/esqws:3C +/esran:3H +/esrh:1C +/et:4C +/eta:51 +/etendard:0C +/etendard_:0A +/eti:0A +/etki:25 +/etki-b:3H +/euidzero:3C +/eurydice:6A +/evelynm:6B +/every0ne:5E +/everyone:3C +/evewasframed:6H +/eviMek:2D +/evilRails:6H +/evilgrin:2J +/evt:3H +/evulanjal:1C +/evy:42 +/ewerd:4N +/ex25:2D +/ex2525:1C +/exHc:42 +/exYG:4N +/exp0sure:25 +/expjx:2T +/expo:25 +/exposed:1Z +/extreem:1C +/exusser:0D +/eyehate_:4C +/eyehbdyd:4G +/eyenx:3H +/eyenx|m:6B +/eyersea:4C +/eyersea1:3H +/eyersea_:4G +/eyesage:5E +/eyowh:5E +/eyrsea:0A +/eysage:0C +/ezvmgk:0C +/f00k:5E +/f0zk:3A +/f13:1C +/f17needhelpwithmacbookairpls:6C +/f212e:1C +/f3bruary:5E +/f3bruary_:03 +/f3r0x:42 +/f4ggles:6A +/f6hn:3H +/fAzEr:1U +/fC:63 +/fEEUOqLHK:3C +/fLegmatik:6B +/f_:0A +/fabs:0C +/facebiter:6H +/factshurt:6C +/faeQuu:4N +/fag:4G +/fagasarus:0A +/fagg0t:3M +/faggator:3M +/faggetttss:2J +/faggles:2D +/faggot:5E +/faggot-:6C +/faggot--:1C +/faggotbot:3A +/faggots:3H +/faggtchan:25 +/fagsage:4C +/fagstag:51 +/fagstag-:63 +/failog:1C +/failtime:2J +/failure_:1Z +/fairee:3A +/fairlyhard:0C +/faith_:2D +/falcon_:4G +/falconx:6H +/family:4C +/fancsali:09 +/faqata:03 +/far0ut:2T +/fartbird:6H +/fartgang:0C +/fasibcs:3A +/fat_frog:0C +/fatalhalt:3C +/fatcor:0C +/fatcor2:1Z +/fatfag:0A +/fatman:63 +/fault:09 +/fault-:0C +/fauna:09 +/fauna_:63 +/faust:2T +/faust_:3H +/fausto:25 +/favicon:5E +/fbs:3A +/fc-:1Z +/fckd:0A +/fckd-:42 +/fckd^:5E +/fckd_:5E +/fckd`:4N +/fckda:42 +/fckd|:0D +/fcobz:2J +/fd0e:4N +/fd71:1C +/fd71_:0D +/fdckr:09 +/fdfd:3A +/feach:3H +/fearUSA:40 +/fear_:0C +/feczcei:63 +/fed:51 +/feddef:4G +/feelingsreal:25 +/feibg:6H +/feisod:2J +/felon:3M +/felon`:4G +/femi:1Z +/femy:4G +/ferminter:1Z +/fever:6C +/fever1:09 +/ffej:3H +/ffejj:3C +/ffl:1C +/ffl|lappy:0D +/fforfuck:4C +/ffucvw:09 +/ffuentes:5E +/ffuentes1:51 +/ffuentes_:6H +/fg:6H +/fgau:6H +/fgghjjkll:2T +/fgghjjkll2:42 +/fgts:2T +/fgts3:63 +/fhfjkhf:0A +/fhhj:63 +/fhrnjrjr:42 +/fiMui:3H +/fiQ:1C +/fiQ2:4C +/fiber0ps:0C +/fieryFU:6C +/fieryGT:51 +/fieryUSA:2J +/fifth:4G +/fiftysixer:3C +/fight:3M +/filostyktos:3H +/finex:4G +/finextodingo:3H +/fireaves:51 +/fireman:2D +/firewyre:09 +/fishbutt:4N +/fishe:3C +/fishe2:3A +/fishe_:2T +/fishebage:6H +/fission:6C +/fitcor:51 +/fittan:6B +/fitzgerald1337:03 +/five5:63 +/fjgkjkljn:0C +/fjmc8:3C +/fjyimwz:3M +/fkinEZ:2J +/fkinglag:63 +/fkinglag_:63 +/fkkzypern:25 +/fklnEZ:51 +/fkr:3P +/fkxpcw:2D +/flagondry:4G +/flameboi:5E +/flash67:5E +/flavoral:2D +/flewkey:42 +/flex14:6C +/flgr:0C +/flip:3M +/flipp:2T +/flippp:09 +/flipppp:4N +/flippy:4G +/flippyBOT:2D +/flippybot:4N +/flippyy:09 +/flippyyyyyyyyyyyyyyyyyy:2D +/flippyyyyyyyyyyyyyyyyyyyyyyyyy:25 +/flo:63 +/florens:0C +/florens_:2D +/flp:25 +/fluff:4N +/fluffy:2T +/fluffypony:4N +/flunky:0A +/flunky_:3C +/flurp:2D +/flurry:0C +/flute:51 +/fly:4N +/flysky:6H +/flytronix:3A +/fmoonII:0A +/fmoonSW:2J +/fmop:03 +/fn:4N +/fnbridge:2T +/fncy:6B +/fni:2T +/fni_:3M +/fnnmbjq:1C +/fnoodl:5E +/fnoodl_:1C +/fnzqvwz:3A +/fohCha:25 +/folesfan:3H +/foo:1Z +/foobar:25 +/fook:2T +/for_a_memory:6C +/foreverr:25 +/forkbomb:51 +/forks:1Z +/fornicato:3A +/fossegrim:0D +/fossegrim[m]:6H +/fossy:0C +/foto:3C +/foureyes:4G +/foureyes-:3H +/fow:4G +/fox:3C +/fox_:4N +/foxbutt:2T +/foxes:4G +/foxes_:40 +/foxtrash:3C +/foxyou:1Z +/foxzillah:1Z +/fp:6C +/fpb4:0C +/fpfihuh:4C +/fppe:42 +/fppe-:6C +/fpwr:4G +/fpwr_:5C +/fr0sty:09 +/fr0zn:1C +/fr33d0g:2D +/fr3en0de:7H +/frEEKie:2T +/fractal:51 +/fractal-:1U +/fran:51 +/franscan:0D +/franzer:0A +/franzer_:3C +/freakazoid0223:03 +/freckles:1Z +/fred:09 +/fred-:3C +/fred--:3M +/fred_:51 +/fredy1:0A +/free:2J +/free2:6H +/free2_:63 +/freedom:42 +/freekoala:2T +/freem:2J +/freemangordon:5E +/freex:2B +/frenK:1C +/freq:03 +/frewq:2T +/frez:03 +/frida:09 +/friend:3C +/fris_:5E +/frisjon:2T +/fritzl:25 +/frogaincia:0D +/frogface:51 +/frogface_:2T +/frogface_outside:63 +/frosty:63 +/frozen:0A +/frrobert:03 +/frrobert_:63 +/frvazab:3H +/frvbcbbh:0A +/fsckoff:09 +/fsh:51 +/fshow1:2D +/fstd:4G +/fstd_:3C +/fstd__:03 +/fstrelok:2B +/fstrelok_:5C +/fstrelok`:4N +/ftl:6B +/ftwjames:25 +/fuck:3C +/fuckJews:51 +/fuckasss:4G +/fuckdoll:51 +/fuckdoll_:2T +/fuckface:3H +/fucku:0C +/fucsadfga:4N +/fujikmoh:4N +/fujikmon:2J +/fujikom0:0D +/fujikomo:3C +/fullybent:25 +/fumblefez:0C +/functions:0C +/funintl:2J +/funkpow:6H +/funkpow1:4C +/funkpow1_:1C +/funkpowe1:6B +/funkpower:0D +/funkpwr`:03 +/funpower:03 +/furlow:03 +/fury:4G +/fusionroc:0C +/fuzpock:2J +/fuzz:3M +/fxjewlfu:6C +/fy:25 +/fyr:3M +/fyrfaras:03 +/fyxiamk:1Z +/g:1Z +/g0d_:25 +/g0dub:2J +/g0dub_:63 +/g0dub__:2D +/g0newtw:25 +/g0wce:6C +/g0wse:1C +/g22:4N +/g33:3A +/g3n713m4n:4G +/g3phi:5E +/g4570n:3M +/g7ji:1C +/gBHK:4G +/gNQf:3H +/gaetano:51 +/gaetano_:6B +/gah2:1C +/gahSh:2T +/galago:2T +/galego:09 +/gall0ws:6H +/gamakichi:4C +/gamedude:0A +/gamerdude:3H +/gamerrr:42 +/gamersdude:2T +/gammald:09 +/gandhi:3H +/gands:4N +/gangIand:3M +/gangfart:0C +/gangland:0C +/gangreen:1C +/gantry:5E +/garandil:25 +/gareppa:0D +/gargantua:0A +/gargus:1Z +/garlic:03 +/garp:6B +/garp_:2J +/garre:6H +/garret:3C +/garret88:25 +/garrett:42 +/gary:2D +/gary_oak:4N +/garyd:0A +/gascon:0C +/gascon_:5E +/gascon_lady:4N +/gascon_test_web:25 +/gasconheart:4N +/gasconheart1:6H +/gasconheart`:4C +/gast0n:0A +/gast0n_:0C +/gasull:3M +/gateway2000:3A +/gatti:4G +/gatti_:3H +/gatti`:25 +/gauss:0C +/gayrage:4N +/gayrape:4N +/gaysage:03 +/gayzee:63 +/gbmor:09 +/gbrqgme:25 +/gclau_:5C +/gcsyql:0A +/gctechs:3A +/gdkbql:4G +/gdyjifr:3C +/gebejhe:2T +/gediz0x53:25 +/gediz539:3M +/geeJee:3C +/geee:2J +/geezus:4G +/gelb:6H +/gemmi:6H +/gemmo:40 +/generalC:0D +/generalC_:6B +/genesc:3M +/genkade:6B +/genkade_:3H +/gentoodwm:6C +/geordie:3A +/geordie_:25 +/george:1Z +/georgette:3H +/gephi:2J +/geqjrxsg:3C +/gerbet:0C +/germ:42 +/germy:2J +/gerry666:6B +/getinrich:6N +/getout:6A +/gf5FaN5rx:25 +/gffmhk:1Z +/gfj:25 +/gfrds:0C +/gfsgd:4C +/gg:3C +/ggainey:6B +/ggg:63 +/ggibyza:5E +/gguopkin:42 +/gh0st:2J +/ghjgh777:4C +/ghjkl:2D +/ghost:09 +/ghost2501:3C +/ghost2501_:03 +/ghost64:6C +/ghost_:4N +/ghost__:1C +/ghosti1990:5E +/ghoul:09 +/gibigiana:5E +/gid:4G +/gigga:63 +/giggle:2T +/giggle-tan:25 +/gigio2000:2D +/gigs:3A +/gillz_:5E +/gimp:1Z +/gingerling:1Z +/ginopino:4C +/giorgos:3H +/gir:3H +/gisah:3A +/gituser:09 +/giwwvy:2D +/gizmo_:0C +/gjtgkt:63 +/gjvc:0A +/gjvc_:63 +/gk:42 +/gl00m:0D +/gl0ck:1Z +/glHC:42 +/glaciurso:51 +/gleevauomm:5E +/glenda:2T +/glhmnqfp:1Z +/glider:4C +/glinder:6H +/glitrbitz:6B +/gllit:0C +/globbot:4N +/glooby_32:1C +/gloomDev:2T +/glorfind1:42 +/glorfinde:2D +/glorious:1Z +/glorious_:4N +/glppvaa:4C +/gm:0C +/gmh:6C +/gmh-:51 +/gmh--:4C +/gmh--_:2J +/gms:2T +/gmxpllqe:03 +/gnaahoe:6H +/gnik:2D +/gnomus:42 +/gnostik:2T +/gnstaxo:0C +/gnupluslinux:42 +/gnusd:1C +/gnusd_:0C +/gob:4C +/gobbo:0C +/gobbo_:3A +/god:4N +/god_:4C +/god_is_dead:03 +/goduck777:3M +/goduck777_:2T +/gogo:3A +/gogog:25 +/goh:51 +/golakers:51 +/goldie:3A +/goldnick7:3H +/golem:3H +/goliath:6C +/gongreen:3A +/goodtimes:6B +/goody:3M +/goody2:63 +/gooey:4N +/goofypeen:4N +/goog:2J +/googal:03 +/google:1C +/gookfuzi:0C +/gophbot:09 +/gorgonzol:03 +/gorilla:2T +/goring1:2T +/gorthx:3C +/gotdosd:03 +/gotothekitchen:42 +/gowce:51 +/gowse:63 +/gowse_:6C +/gpQf:1Z +/gpaqdbpp:03 +/gppcpu:4C +/gpunjjkt:5E +/gq:0D +/gqbriele:09 +/gqllo:0C +/gr:2T +/gr-:3A +/gr0zz:2D +/gr3p:51 +/gr3y:25 +/gradew:4N +/gravestench:51 +/gravitas:0D +/gravitaz:6C +/gravyv:4G +/grawity1:2T +/grayskull:1C +/grayv:3C +/gre:3M +/greasee:0D +/greasy:3M +/greelly:5E +/greenbagels:3M +/greenone:6H +/greeter:03 +/greettest:0C +/greg:6C +/greg_:09 +/greghume:51 +/greghume_:3M +/gregory:3A +/grenade_:6H +/gretathunberg:3H +/greyc4:0A +/greywolver:5E +/greywolver_:4C +/grfzsnk:0C +/gri-:1C +/grimes:4G +/grimfosse:6C +/grip:3A +/grip-:3A +/grip^:4N +/grip_:3A +/gri|:3C +/grns3:4N +/grns4:40 +/groid:03 +/groin:5E +/groin_:0A +/groki:2D +/groove-o-:0C +/grosjean:51 +/grpar:4G +/grrf:3A +/grrfield:3M +/grrr:42 +/grrrrr:2T +/grsjfcn:03 +/gru:5E +/grufwub:3A +/grumble:1Z +/grungy:09 +/gruodf:6H +/grxyox:2D +/gry:3C +/gry_:4N +/gsserxo:63 +/gt:03 +/gt100boss:4N +/gtb:0C +/gtc:0C +/gtc1977:4N +/gtc19771:2J +/gtrhteh:63 +/gturner:6C +/guest1211:09 +/guest50320:25 +/guk:4G +/gulamakba:25 +/gumpybloo:3C +/gun:0C +/gupdg:1C +/guseboi:3A +/gusugs:4N +/guy9000:42 +/guzzo:51 +/gvzgcze:3C +/gwxsyz:2D +/gxyaem:3C +/gxykwllk:6C +/gyepfqd:42 +/gzyiyn:4G +/h0nk:4N +/h0noo:2J +/h0t1ine:25 +/h0tl1ne:0C +/h0tline:3A +/h1x:4C +/h1x_:4N +/h31:3M +/h3h3:4N +/h4ppy:0C +/h4rb1ng3rs:2T +/hHgs3s:2T +/hUpc:2D +/h_:3H +/h_hvn:7H +/haarek:25 +/hackerman:42 +/hackles:40 +/haeGh:0A +/hagen:1Z +/haiPa:6B +/haiku:42 +/hairyanus:1C +/haitch:1Z +/haleysmith:3A +/hallucinate:03 +/halmmfke:42 +/halt:3C +/hana:2J +/hangar118:6H +/hank:1C +/hank-:63 +/hank_:3H +/happy:1Z +/happy_day:6C +/happy_har:1C +/happyblue:4N +/happybox:5E +/happyhog:40 +/harilikha:2D +/harloe:3A +/harlow:6C +/harmetic:4N +/hasan:3C +/hasanAbi:3M +/hashcat:4N +/hashcat_:2D +/hashem:5E +/hashfyre:6H +/hata:4N +/hatefuckr:3M +/hatesec:6H +/have:2D +/havel:3A +/havel_:0C +/hawking_romantic:63 +/hay:0D +/haydenh:7H +/haydenh_:7H +/haydenh__:7H +/haydenh___:7H +/haydenh____:X7E +/haydenvh:2D +/haywalk:6B +/haywo:6C +/hazel:25 +/hc9:2T +/hcliph:6H +/he_has_risen:25 +/hea:4N +/heartface:2J +/heartless:0C +/heartliss:63 +/heartofrevel:6C +/heartofrevel1:2T +/heartofrevel4:09 +/heather:25 +/heatwave0:6H +/heaven_:0A +/heavy-r:6C +/heavyarms:0C +/heckle:09 +/hedge123:5E +/hedy:6H +/heftig1:4G +/heimdall:03 +/heimdall_:5E +/heimdallr:63 +/heinrich:3C +/hekyn:6H +/hellfire:0C +/hellfox:63 +/hellfoxy:2D +/hello_navi:03 +/hellofox:63 +/hellofoxy:51 +/help:6B +/henninb:51 +/henosis:3H +/henrique:3C +/heredoc:5E +/heretyk:51 +/hero:0A +/herszt:4N +/hextasy:0D +/hextasy^:3A +/heydude_:25 +/heydude`:09 +/heyron:6H +/heyron-:3M +/hfg:03 +/hfhgd:1C +/hgc:0C +/hgc_:3M +/hgdfsh:25 +/hghg:0C +/hhh:0C +/hhh`:09 +/hhhh:63 +/hhjbov:5E +/hhmmhh:2D +/hhvn:7H +/hhvn_:63 +/hhvn__:63 +/hhvnscv:2J +/hi:3C +/hiWoh:3A +/hiddmahj:03 +/hieFai:4G +/hif:2D +/hifbpz:3C +/higgs:6H +/higgsboso:6C +/hijack:09 +/hilighter:6H +/himmler:2T +/hinac:63 +/hippopotamus:51 +/hirnspiel:42 +/hiro:25 +/hisacro:1C +/hislittlelordshipFontleroy:0A +/hist0ry:3H +/hiteki:1Z +/hitl3r:09 +/hitler:2D +/hive-min1:0C +/hive-mind:42 +/hjenny:3M +/hjnzko:6C +/hkgf:6B +/hlfm:6B +/hmamj:6C +/hmh:09 +/hmm:4N +/hmmh:6B +/hnb:63 +/hobbelpaard:63 +/hobbler:2T +/hobosock:25 +/hobotier:3M +/hoek:6C +/hoho:0D +/hoho1:25 +/hollowleviathan:4N +/hollywood:6H +/hologra:6H +/holtmann:63 +/honest:40 +/honk:3H +/honk-:25 +/honken:1Z +/honk|:4C +/hook_ups:0C +/hooligani:25 +/hoosier5-:51 +/hoosier54:3C +/hooway:03 +/hooway_:6N +/hornyguy:25 +/horseshoecrab:63 +/hostserv:03 +/hotdogess:1C +/hotfart:63 +/hotline:09 +/hozed:5E +/hozed_:4G +/hpbvw:5E +/hpyc9:4N +/hrbdnjrh:4G +/hrbsjd:4C +/hrmtkrl:3H +/hrz:3H +/hschmale:6A +/hsen:1C +/html5car:63 +/htmrkl_:6B +/htmrmkml:5E +/htnrmek:0C +/htnrmkl:1Z +/htrkel:3M +/https:1C +/hub.efnet.us:3M +/hub.eu.hlircnet.:3H +/hub.us.hlircnet.:0D +/hubertf:4C +/hubutm20:63 +/hugo:4C +/huloxia:3M +/humbleMan:3M +/humility:3C +/hung0ver:5E +/hungral:2D +/hunko:51 +/hunnie:42 +/hunter_cat:6C +/hushmummy:3C +/huyens:1C +/hvhost1:2D +/hvnh:5E +/hvvn:6H +/hwidke:3H +/hyb:42 +/hybrid:5E +/hydrololi:0D +/hydrololi_:5E +/hyiltiz:09 +/hyiltiz_:51 +/hyper_object:4C +/hyperreal:1C +/hyperreal0:6B +/hyperreal3:42 +/hyperreal4:4G +/hyperreal6:0D +/hyyoyfk:3C +/hzavaesc:63 +/i:3H +/i3-lover:51 +/i87:2T +/iCjay:0C +/iKahl:3H +/iNgiew:4C +/iRapedYourFather:3C +/iRuint:5E +/iTzNavic:51 +/iTzNavic-:25 +/iZcc:4G +/i_like_THISsuperLONGnickBetter:63 +/i`:0C +/ia:6B +/ia2:6B +/ia_:51 +/ia__:1Z +/ia`:03 +/iahlbb:4N +/iai:0D +/iai_:1C +/iamerror:3H +/iamgr00t:42 +/iamkorea:1Z +/iamnotbob:42 +/iamthebug:2J +/ian:2J +/ianax:0C +/ibiza:6C +/ibnii:1Z +/icaretoomuch:6B +/ice303:1C +/icebane:0C +/iceman:25 +/icequeen81:6B +/iceweasel:3C +/icon:51 +/icy:1C +/idal-:63 +/identd-:63 +/identify:3M +/idiot:51 +/idiot_:6C +/idiot__:3H +/idleman:2T +/idleman_:03 +/ido:5E +/ie:1C +/ieBoo:3A +/ieGhi:4G +/ieHoch:1Z +/ieHooh:6C +/ieNohg:2T +/ieatcrayons:0C +/ieatcrayons66:3H +/ieatcrayons76:42 +/ieatpaste:2D +/ieatpaste21:42 +/ieatpaste37:25 +/ieatpaste76:6H +/iehueD:42 +/ieloyptj:51 +/iephoF:63 +/iga:1Z +/igel_:40 +/iggysage:6H +/ignucious:09 +/igol:03 +/igol_:1C +/igotreez:63 +/ihasdivui:63 +/ihate:6B +/ihavealongnickna:1Z +/ihower:63 +/ihtiby:51 +/ihugjews:4C +/ii:3M +/iiee:4N +/iiee2:1C +/iiee`:3H +/iiee``:3A +/iiee```:0D +/iiee````:1Z +/iije:2J +/iije`:09 +/iije``:6C +/iiwsa:2J +/iizqsvzr:3M +/ikhfxkcg:0C +/ikiboo:1C +/ikiycw:3A +/ikkkhakv:3M +/ikmaak:6C +/iko:6B +/ikr:1C +/ileHU:63 +/ill_eagle:3C +/illumin:4C +/ilovekit:3C +/iloveshortnickfuckyoumotherfuc:0D +/ilsa:3M +/ilsundal:3H +/ilumnatr:3M +/iluvkoala:42 +/imad_al-din-1970:0D +/imbbwjma:1C +/imbroken:4G +/imd0ne:1Z +/imfee:5E +/imnothere:1C +/impact:09 +/impl:4N +/impl-:0C +/impl_:25 +/impo:6B +/inVictus:03 +/incal:2T +/incel:3M +/incel46:51 +/incelupri:6H +/incluso:6B +/inco6:09 +/incog:4G +/inconsistentt:2J +/incubus:09 +/indacuhh:42 +/indulgence:5E +/indy:4C +/ine:3C +/inex:3A +/infection:0C +/infidelis:03 +/infil00p:51 +/infox:4C +/infraudsi:0C +/infraudsr:4G +/infspire:0D +/infy:0A +/inhiding:0C +/inky:63 +/innercircle:1Z +/innmntvs:3M +/innominat:4C +/inocent:0C +/ins4n3:4G +/ins4n3_:0C +/insanity:0C +/insep_:6B +/insidiou1:25 +/insidious:09 +/inssh:6C +/intebenis:4N +/intekra:0C +/intelinsidecore7:6B +/intelinsidecorei7:03 +/intercep7:4C +/intercep8:3H +/interdom:3C +/interdom-:0C +/interdom3:09 +/interdome:4G +/internut:0A +/intr0:09 +/intrin:63 +/intro:1C +/intx:03 +/invertednetron3:0A +/inz:2J +/io:4G +/iocc:09 +/iocc_:40 +/iolhkrl:03 +/ionosphre:3C +/iori_:03 +/ip22:3C +/ip_:42 +/irc:6H +/irc-eu-1.darkscience.net:03 +/irc-eu-2.darkscience.net:09 +/irc-us-east-1.darkscience.net:3H +/irc-us-east-2.darkscience.net:6C +/irc.Prison.NET:0C +/irc.area51.haydenvh.com:25 +/irc.efnet.nl:3A +/irc.haydenvh.com:3C +/irc1.unrealircd.org:09 +/irc2.unrealircd.org:3H +/ircMERC:63 +/ircchannelinfluencer:6C +/ircshark:1C +/ircuser01:6B +/ircuser10:4N +/iriHei:6B +/irick:2T +/irie:4G +/irie_:5E +/irish666:25 +/irish667:2J +/irishsoft:5C +/irl:5E +/ironmountain:3A +/ironybomb:03 +/irt^:1Z +/irwinz:1C +/is-:2J +/is-_:42 +/isaac:03 +/isahYe:2D +/ishutin:42 +/islam:3A +/islam2:4N +/ismoke:6B +/ismokechronik:2D +/it:3A +/it9exm:3M +/it_doesnt_matter_if_your_black:6H +/its_a_question:03 +/itsanaddiction:4C +/itsmylife:4G +/itspecial:51 +/itsracist:6H +/ivan:2J +/ivanfrey:25 +/iwq:51 +/ixirc1:4G +/iyeaa:3A +/iyzsong:03 +/iyzsong-:2B +/j0rdan:3M +/j0rdn:25 +/j0rdn]:2T +/j0rdn_:4G +/j0sh:42 +/j3wbird:0C +/jIMcRaMER:42 +/jWang:5E +/jabol:0C +/jaccid_:4G +/jaccid__:4N +/jack:09 +/jackiff:25 +/jaekwon:0D +/jagjoe:42 +/jah:2J +/jahPhi:6C +/jaiQu:6B +/jak:4C +/jak_:63 +/jake_:0A +/jakk:4C +/jakk_:5E +/jakks0:1Z +/jakozy85:1Z +/james:3A +/james_freewall:0C +/jameshjacks0njr:25 +/jammr:5E +/janet:09 +/japexxxx:4N +/jappxx:5E +/japxe:51 +/japxx:03 +/japxxx:4G +/jaqque:2T +/jar:2D +/jarg:25 +/jarro:6C +/jasmaz:0D +/jason14:63 +/jason7:42 +/jason_:0C +/javier37:42 +/javier38:2T +/jax0m:63 +/jay7369:6H +/jayde:6H +/jaydubbs:03 +/jayhamm-:1Z +/jaymondaddy:51 +/jayparee:2D +/jayw:3C +/jbaikge:5E +/jbals:2D +/jbird:1Z +/jblslpf:63 +/jboy:3C +/jbzabd:2D +/jcatv:25 +/jcb:03 +/jcrawford:0A +/jdavid:3C +/jdavid_:3H +/jduck:5E +/jdvfvleu:3C +/jdx:3A +/je:3H +/jebug29:03 +/jebug29_:0A +/jebug29__:3A +/jedi:4G +/jednak:09 +/jednak_:51 +/jeeLai:3A +/jeepee:63 +/jeff_stacey:3A +/jeffrey:25 +/jehru:6C +/jellyb:2T +/jellybeens:03 +/jenna:3A +/jenni_:2D +/jennie:6H +/jennie1:1C +/jepvpv:51 +/jepx:42 +/jerem:5E +/jericho:1C +/jerk:51 +/jerm:4N +/jero2:4N +/jero3:1Z +/jero4:6C +/jeru:09 +/jeru-:51 +/jerufu:0C +/jeruism:4G +/jerwin:42 +/jerwin-:51 +/jes:3C +/jess:42 +/jess-----:2T +/jessica:1Z +/jessica-:0A +/jessica-_:1Z +/jessup:1Z +/jest0:42 +/jester:0A +/jesusaur:6B +/jet_:25 +/jetcream:3C +/jetienne:3C +/jetscream:03 +/jevin:3C +/jew_b1rds:1Z +/jewbird:42 +/jewbird-:4N +/jewbird`:63 +/jewbirds:4C +/jewline:6C +/jewpax:1C +/jezbel:1Z +/jezza:63 +/jfkhibz:3A +/jh0ng:6C +/jhigh:6C +/jhigh_:0C +/jhigh__:4N +/jhill:4G +/jhonny:0C +/jhutchins:6C +/ji:09 +/ji_:6A +/jieuunwx:4G +/jig:0C +/jig_:3H +/jiggawatt:0D +/jiggawatz:0D +/jilla:1C +/jim0r:1C +/jim^:0C +/jim_:63 +/jimmy-:3M +/jims:51 +/jimz0fr:0C +/jimz0r:0A +/jimzor:6H +/jitoz:42 +/jiurjyts:6H +/jizzle_anesthesia:42 +/jizzmore:1C +/jjohnstone:0D +/jjrhekqo:6H +/jjs_tty:3M +/jkli5_:3M +/jkli5_________________________:3H +/jkrueger:3H +/jkyahgha:51 +/jlu5:03 +/jmancully:2D +/jmanfatty:4G +/jmansWifey:2D +/jmanswife:4G +/jmcgann:4C +/jmlich:4G +/jmoney:42 +/jmpzer0:51 +/jmw2020software:1C +/jnhmjyg:51 +/jns:09 +/jns_:6B +/jnsjunio1:4N +/jnsjunior:03 +/jnvhphe:6C +/joacim:6C +/joacim_:4C +/joacim__:25 +/joacim___:4G +/joaoprb:0A +/joe1701:63 +/joe1710:5E +/joeblogs:2D +/joedoe47:42 +/joelchrono12:4C +/joeleg:03 +/joeroller:42 +/joeroller_:1C +/joes:2J +/joes_:63 +/joew:5E +/jogisgaya:3A +/johan_:2D +/johansen:2D +/john-titor:3H +/john222:2D +/john_ceph:1C +/johncylee:2T +/johngalt3:51 +/johnhamelink:3H +/johnm:3M +/johnny569:09 +/join_sub1ine:1C +/join_subline:6H +/joji:4C +/jojoje:4G +/jojoli:4G +/jokk55:1U +/jokk555:4C +/jokk55_:6B +/jokles:3H +/jolia:1Z +/jolt:2T +/jonah:40 +/jonathan:0D +/jonnow:2J +/jonsger:3A +/jonsger1:1Z +/joobird:63 +/joonnnn:3C +/jooopltr:1C +/jordan_0:09 +/jordan__:0C +/jordan_o:3A +/jordan_o_:1C +/jordintosh:3A +/jordizle:6H +/jordn:0C +/jorge:2D +/josecito:6B +/joseph:09 +/josh:3A +/josi:6C +/josuah:25 +/jowbvu:2J +/jpcw:2T +/jprestwo:4C +/jpwg:3C +/jpx:3H +/jpxx:4N +/jpxxx:1Z +/jrayhawk:3M +/jrgufc:3M +/jrhorn424:3H +/jrra:0A +/jrra1:4G +/jrra3:2D +/jrra4:3C +/jrra5:1C +/jrra_:2D +/jrrabird:1Z +/jrrra:25 +/jrue:03 +/jrwr:3H +/jshoard:6C +/jshoard_:42 +/jshoard__:3C +/jsilver:2J +/jsilver_iphone:1C +/jsilvertw:42 +/jsmalls:2T +/jsmalls1:0C +/jsmalls2:6A +/jstg:0C +/jtm-lis:03 +/jtru:5E +/jts:42 +/jts_:25 +/juRs:1C +/jualgcqn:2D +/juda__:6C +/judge:51 +/julienxx:1C +/julienxx_:4G +/juliet:25 +/jungnam:6H +/junter2:4N +/jupedbir1:0C +/jupedbird:09 +/jupitor:42 +/just-testing3:03 +/justice:4C +/jvoisin:6B +/jvxxja:2J +/jwheare:51 +/jwinn:09 +/jwst:2B +/jxftlagd:51 +/jzrcvc:2D +/k:03 +/k0ga:0D +/k1r1t0:3M +/k22:4N +/k3yp:5E +/k3yp-:5E +/k4be:6C +/k82k8:3C +/k8du27d5:0C +/kB`:3M +/kB`_:4N +/k__:63 +/k___:2T +/k____:63 +/k_____:63 +/k______:3H +/k________:25 +/ka0s:42 +/kaalto:2J +/kaan:2D +/kaasen:1C +/kahn:51 +/kaiserin:09 +/kaj:2D +/kaj_:6C +/kajira:2D +/kakama:6C +/kakama_:63 +/kakamobil:09 +/kal:2D +/kal_:3C +/kalbasit:3H +/kalekale:3C +/kalekale_:3H +/kali:0C +/kalle:03 +/kalube:6C +/kamawana1:6H +/kamawanai:4G +/kamchatka:2D +/kameel:1Z +/kamel:2J +/kamel-:3H +/kamper:1Z +/kamper1:6C +/kaotisk:03 +/kaotisk_:0D +/kap:4G +/kara-:25 +/kara_:3C +/karatesan:6C +/karli:1Z +/karma:1C +/karnath:09 +/kash:25 +/kash_:3C +/kaskokaos:6H +/kathy:0D +/katkiller:6B +/kattarin-:3C +/kattarina:09 +/katzeilla:25 +/katzeilla1:3H +/kaw:0C +/kayo5:6H +/kayos:3M +/kayos_:2T +/kayzee:0C +/kb22:42 +/kbenn:3C +/kbrosnan:2J +/kbz:03 +/kbz3:4C +/kcayr:09 +/kcefjnm:42 +/kchr:3M +/kcn:6C +/kd:6B +/kd4wov:5C +/kdjdjd:4N +/kdndksj:0C +/kdy:3M +/kee:1Z +/keeZa:25 +/kee_:4N +/keentech:1Z +/kefka:3A +/keithhulu:1Z +/kek:63 +/kelp:1Z +/kelp-asusfone:1C +/kelp_:25 +/kelp____:3H +/kelpstar:6C +/ken:1C +/kendra-NU:6C +/kenn:42 +/kennedy:1C +/kenny:25 +/kenster:4C +/kerbalbass:25 +/keria:2J +/kermit:6C +/keroff:6H +/kest10:6H +/ketas:0A +/ketas-:03 +/kevin_:0D +/kevin_mit:1Z +/kevinburke:3C +/kevrocks67:2J +/keweiH:3M +/keyz:51 +/kgkfeaq:6B +/kgsuhy:25 +/khaybar:6B +/khecka_:2T +/khronos:2D +/khronos63:09 +/kiad:63 +/kichimi:3H +/kichimi2:0C +/kick-azz8:6C +/kidskilll:2D +/kierank:2D +/kiff_:5E +/kike1:6H +/kikee:2D +/kikes:3H +/kikesmasher:4N +/kill:1Z +/kill_grandma:4G +/killah2k:3A +/killarney:0A +/killer:51 +/killsushi:3C +/killwhite:25 +/killwhtes:03 +/killwites:4G +/kilroy:25 +/kilroy1:6B +/kilroy_:5E +/kilroy__:4G +/kilroy_work:2T +/kimberlite:2D +/kimjun:4G +/kindling:4N +/kinduff:1Z +/kinduff1:3H +/kinduff5:4G +/kingcobra:3H +/kingdom:6B +/kingdomz:3M +/kirch:0D +/kiririno[m]:4G +/kiryin:2J +/kissie:3M +/kit:2D +/kitTails:2T +/kitk:0A +/kitoy:51 +/kitoy_:1Z +/kitt:51 +/kittens:0A +/kiwi_27:6A +/kiwi_28:2D +/kiwi_38:51 +/kiwi_56:4G +/kiwi_57:3M +/kiwi_6:25 +/kiwi_99:1C +/kizuka:2D +/kj8am:3M +/kj8am_:51 +/kj8am_AFK:2D +/kj8am_CZ:3M +/kja:6C +/kjg:63 +/kjkomu:4N +/kk_:09 +/kkczk:42 +/kkk:0D +/kkkk:5E +/kkplqc:63 +/klaus:09 +/klaus-sleep:2T +/klaus1:2T +/klaus_:0C +/klc-:1Z +/klob:09 +/kloenk:4C +/klotski:2D +/klu:6B +/klu1:63 +/klu_:6C +/klyburn:0C +/klys:2T +/km:6B +/km_:5E +/kmbwabba:51 +/kmypw:09 +/kn1f3:09 +/kn1fe:3H +/kneegr0w:63 +/kneeldownbeforehim:2J +/knives:25 +/knqxbw:2D +/koalab:4C +/koasa:03 +/kobach:6B +/koenig:3C +/kog8:6H +/koga:09 +/koh:51 +/koi:25 +/koirishima:42 +/koisser:3H +/kojak:5E +/kokamo:2T +/kolobyte:2T +/komhxwn:4G +/konata404:51 +/kongfuzi:63 +/konox-csh:6C +/konox1337:6H +/konsentr`:3H +/konsonanz:03 +/kontaxis:3M +/koolaid:3C +/kornelio1:0C +/korneliov:3M +/koroded:42 +/koroded_:1C +/korozion:42 +/kosmorage:0C +/koss:42 +/kossy:4C +/koz:6H +/kr:51 +/kr1ss:03 +/krampus:0A +/krampus_:3M +/krell:2J +/kristal:2D +/kristian_on_linu:03 +/kristian_on_linu_:6B +/kristjans:0C +/krjst:3C +/krkd:3C +/krml:3A +/kron:5E +/kronik:2J +/kronuz:2J +/krud__:1U +/krusty:6C +/krys:63 +/ktrace:42 +/kubast2:6B +/kubes:2J +/kug:4C +/kujira:3M +/kukost:3H +/kulj:09 +/kultur:4N +/kun1z:2J +/kundumsta:40 +/kunt:0A +/kuntry:0A +/kuntz:1Z +/kupo:3H +/kuroi_dotsh:1C +/kuz:25 +/kuz2:3M +/kuz3:03 +/kuzx:4C +/kvm2k:1C +/kvothe:51 +/kwamaking:4G +/kwrs:4N +/kwvqnvad:25 +/kyle:2T +/kyle-:63 +/kyle2f:42 +/kylef:2T +/kylef_:0A +/kylefhitempest:3C +/kyloren:5E +/kyonko:3H +/kyonko_:25 +/kyonko___:40 +/kyonko|2:4G +/kyoon_:1C +/kyoon__:6B +/kyshoc:51 +/kyuzo:1Z +/kyzer:1Z +/kzxbcd:09 +/l0bster:4C +/l0bster_:1C +/l0de:0C +/l0de_:1C +/l0de__:03 +/l0decuck:3H +/l0dehater:3M +/l0demas:03 +/l0demas_:6A +/l0deradio:3M +/l0dey:3M +/l0dey_:1C +/l0deyear:2J +/l0draydio:09 +/l0ganWh1t:51 +/l0gic:1C +/l0gic__:6C +/l0l:5E +/l0l6:25 +/l0ra:4N +/l1tup:63 +/l1tup_:6H +/l200bps:5E +/l200bps_:09 +/l200bps__:1C +/l23456:4C +/l23456`:4G +/l4g:6H +/lFu9d52Ne:0A +/lIPMACaPHY:6B +/lJCg:1Z +/lRma:51 +/l^l:09 +/l_bratch:42 +/labanu:0C +/laboum:2J +/laboum-:03 +/laburd:5E +/laceless:6H +/lacni:5E +/ladew__:09 +/ladewerk:1C +/ladyG:4G +/lady_caro:63 +/ladyg:4N +/laePe:4C +/lagzilla:09 +/lain:3A +/lal:2J +/lal_:4N +/lameshit:3A +/lan:3A +/lane:1C +/largetni:3A +/lari:03 +/lari1:4N +/larpingwindows:42 +/larsan:2J +/lasers:3P +/last:63 +/last_:0C +/laters:1C +/latez_:2J +/lawjbug:4G +/lawnchair:25 +/lazr:42 +/lazyhazy:6C +/lb:4N +/ld100:63 +/ldrancer:2T +/leachim6:2T +/lead_pip3:4N +/lead_pipe:2D +/lead_pipe23:3C +/lean:1C +/lebbe1:1C +/lebbe2:4C +/lecci:09 +/lecter:0C +/legendary:3C +/legended:4G +/legended_:09 +/leighton:25 +/leisrech1:1C +/leisrich:2T +/lek:4N +/leku:0A +/lel:3A +/lel_:09 +/lelo:25 +/lemmings:4C +/lemon:6C +/lemon_meringue:3C +/lemond:42 +/lemongra1s:51 +/lemongrass:0C +/lemur:1C +/len:3C +/len_rose:4N +/lenin:51 +/lenin_:3P +/lenk:1C +/lennox:3A +/lennx:0D +/lenny:2D +/lenny_:0C +/leodisk:1Z +/leodisk_:6B +/leotare:4N +/lesderid:6B +/lesderid_:3M +/lesmo:09 +/lesmo1:6C +/lesmo3:6H +/lesmo7:6B +/lesmo8:2D +/less:42 +/lessbCd:0A +/leveal:4N +/levon444:2T +/lfozhyad:6H +/lhoqvso:1C +/lhtrsua:2D +/liber:42 +/liber2:4G +/lich:0D +/lickingwindows:4C +/lictalotofpuss:3C +/liePah:63 +/lienus:2J +/lift:25 +/lightup:2T +/likesboc:03 +/likwid:25 +/lil0ne-:03 +/lil0ne-_:1Z +/lil0ne-_-:3A +/lileh__:2T +/lilfagpoo:3A +/lillith:2D +/lillybett:1C +/lily_:1C +/limie:2T +/lin:6H +/lindalap:4G +/lindso:6B +/lindso_:09 +/lindso__:4N +/linear:0C +/linear-:6B +/linear_:2B +/linear__:6N +/linkinpar:4G +/linmob:4G +/linuxunix:03 +/linuxyo:1Z +/linuxyo3:63 +/linuxyo3_:4G +/linuxyo_:2B +/linx:03 +/lionkilla:1C +/liothen:4C +/liquidpc:4G +/liquidpc_:3C +/liqwud:2B +/liron:1Z +/liron_:1C +/liron__:1C +/lisq:0C +/litenull:5E +/literati:0A +/littleEVA:25 +/litup:2D +/litup_:25 +/liujhuw:2D +/live4irc:0C +/liveanna:2T +/livepan:09 +/livespan:6N +/ljrLBlx:6C +/ljypk:3A +/lklowdq:4G +/lkpsp:51 +/lkpsp__:63 +/lloyd15:4N +/llpmfq:25 +/lneely:2B +/loadlin:1C +/localhost:63 +/lochnas:1C +/lodis:51 +/lodis_:2D +/loganwhit:63 +/logic:3H +/loja:0A +/lokenorth:09 +/loki:0C +/lol:4G +/lol0gram:42 +/loliba:2J +/loller:2T +/loller_:42 +/lolmac:5E +/lolman:3C +/lologram:2J +/lolwhut:2J +/lolz0r:5E +/lolzenik:4C +/longer:40 +/longnickboi:5E +/loob:0C +/looney:6B +/looool:4G +/loophole_:6H +/loplz:6C +/lord-znc:2T +/lordbobso:4N +/lordfoxes:2T +/lordfoxle:25 +/lordkarf:4G +/lordsea:42 +/loser:09 +/loserwastaken:3C +/lossevaril:25 +/lost`:3H +/lostd:09 +/lostd_:6B +/losto__:4G +/losuler:09 +/loul:0A +/lovbe:09 +/love:4G +/love-:42 +/lovesage:51 +/lowkey:5E +/loyal:6B +/loyalis:51 +/loyalist:3P +/loyalty:6B +/loyqlist:0C +/lpgtwysr:1Z +/lphnus:3H +/lrvx:3C +/lt:1Z +/ltCd-:51 +/ltooru:63 +/ltup:1Z +/ltup_:0C +/lu1ldangs:1C +/luajvt:1C +/lucy_:6H +/luis:1Z +/lukaso666:2D +/luldangs:4G +/lulu:03 +/lulzee:03 +/lulzy:1Z +/lulzyyyyy:4C +/lumi:2J +/lumpy:63 +/luna_is_here:6B +/luna_is_here_:2J +/lunario:1C +/lurk:4C +/lus:2B +/luth:3M +/luvbunny_:0A +/luxneet:6C +/lvmbdv:42 +/lvwW:3C +/lvzffm:5E +/lwop:63 +/lxmrft:3C +/lynxis:3M +/lyrical:09 +/m0ds_halp:0D +/m0ngk:1U +/m0ngk_:6H +/m0nk:3P +/m0nt3:63 +/m0p4r:09 +/m0rgan:1Z +/m0rgan_:4C +/m0rgan__:6B +/m0rt1m0r:2J +/m1k[3y]:6H +/m1sdirection:2J +/m1sdirection_:6H +/m242:2J +/m33:0A +/m34r:1C +/m34r_:3H +/m3sk:5E +/m4d3lf:1C +/mAyui46:4C +/mEDIH8R:3A +/mIRC:51 +/mOrO^:42 +/mRl:0C +/mRmiSta:03 +/mWkO:63 +/ma0u:0C +/mac:1Z +/machiavel:42 +/machicol:09 +/machicola:3M +/macho:3A +/macho_man:4G +/machoduck:6B +/mackstann:4N +/macpie:0A +/madH4tter:1Z +/madHatter:3C +/madd:1C +/maddo:1Z +/madhatt_:6H +/madmouse:4N +/madmouse_:42 +/madog:51 +/madonna:6H +/madsage-:2B +/madsage-_:6A +/maga1488:5E +/magevet:5E +/maggie:3A +/magic:3M +/magicfx:3C +/magictest:6B +/magpie_:3C +/magus:0A +/mahoogan:2T +/majic_:1Z +/mak:6C +/mak13:1Z +/maki_:51 +/maki__:5E +/makudonarudo:3M +/malar:5E +/malice:1C +/maligno:3H +/mamabird:09 +/mamadou:3H +/man:03 +/manat:3C +/manat-:03 +/manat_:4C +/mandiblegrip:42 +/mandico:63 +/manedwolf:4N +/manhattan:4C +/maniac:42 +/manjaro-user-:3C +/manjaroi3_:0A +/manjaroxfcelol:1C +/manjaroxfcelol_:3H +/manoloeld:09 +/mantas322:09 +/mantra:3H +/manweuhk:25 +/mao:5E +/maph3r1us:2D +/maph3r1us-csh:5E +/maph3r1us1337:6C +/maph3r1us_csh:1C +/mapherius:3H +/mapherius_:5E +/mapperr:6H +/mar77i:0A +/marco_:63 +/marcthe12:2J +/mardril:6B +/mardril_:3P +/marfles:4N +/marg:6C +/marguesto:4G +/marienz:51 +/marihone:0D +/marilou:4G +/marissa:4C +/mark_:0C +/mark__:6B +/markm:4G +/marley:2D +/maroon:2D +/martin:09 +/martiu:4N +/martti:0C +/marvin:51 +/marvvin:2T +/marxthebat:2D +/marxthebat_:0A +/marxthebat__:0C +/mas4u20000:2T +/mason:4G +/masonburt:6C +/masoncb:4G +/masterdonx2:6H +/mastry0da:6H +/matcha:4G +/materiyolo:1Z +/mathepauker:4G +/mathsman:25 +/matiasP:6H +/matiasP_:3C +/matiasP__:51 +/matlio:4N +/matr1x:09 +/matrix:1C +/matrixrel:6H +/matryoshka:03 +/mattf:3C +/mattf1:2J +/matthew_:1Z +/matthewcu:3A +/matthewga:6C +/matthewth:6B +/mattisgay:3A +/matty:51 +/matuka:2D +/matus_120:63 +/mauRai:0C +/max10char:0C +/max_:2D +/max_stir-:0C +/max_stirner:09 +/maxh:0A +/maxster:63 +/maxwell:1Z +/maxxe:42 +/maxxe_:6B +/maya:03 +/mayui:6H +/maze:2J +/mazet:3A +/mbezyyat:4N +/mbp:51 +/mcburton:2J +/mcburton_:3M +/mcornick:6B +/mcornick_:3C +/mcp:0C +/mdashx:6C +/mdgsqbu:2T +/mdn:6B +/me-u:2D +/me`:1Z +/meadre:0A +/meaningfulNick:09 +/meat:3M +/meatthug:4C +/mech:3H +/mech_:0C +/mecosito:4N +/media:4N +/meemo:0C +/meenk_:2D +/meetnana:1Z +/meganrat:42 +/meh:09 +/meh`:2D +/mehcositi:0D +/mehh:3C +/mekyb:6H +/mel:09 +/mel_:2D +/melans:51 +/mella:5E +/mella-:03 +/mella|:6C +/mels:0A +/mels_:25 +/meltdown:5E +/meltheadorable:51 +/mem0ut:2J +/membranou:40 +/memingwindows:25 +/menfie:25 +/mengel3:6H +/mengu:63 +/meowmeow:03 +/meowy_:3C +/merav:0C +/merav-:5E +/meridion:2T +/merlin_1991:3C +/mermi:3A +/merpkz:3C +/mert:6H +/merzbow:42 +/messiah:2D +/metalchic:3A +/metalrock:2J +/metaphaze:1C +/metaphz:2T +/metaqwe:6A +/metestbug:42 +/mexicunt:3M +/mez:2J +/mfebxg:3C +/mffrice:6B +/mg55:2J +/mgsyfmw:63 +/mhitmikey:42 +/mhj:3M +/mhuqjq:6H +/mib_14puyt:51 +/mib_77vq3i:6B +/mib_8ygx9x:09 +/mib_geowgq:42 +/mib_jktqft:3C +/mib_m0go3k:2D +/mib_nor4ml:03 +/mib_s6lvls:0D +/mib_tujkas:6C +/mib_zj6ij1:6B +/mibggt:25 +/micha:6C +/michael_:6B +/michaelfm1211:5E +/michaelrules:6C +/michaelrules2:5E +/michaelrules_:03 +/michele:09 +/michele_:6C +/michi:51 +/michi_:0C +/michill:6A +/miconda:25 +/micrex22:0A +/microwire:42 +/midgardlol:42 +/midphase:09 +/mieJah:6H +/migbatix:1C +/miggy-chan:3C +/mighty17[m]:1C +/migranha:6H +/mihoX:25 +/mike_:5E +/mikealgor:3M +/mikejonez:4N +/mikemike:3H +/mikepence:1C +/mikeshea:4N +/milenia:0C +/militant-:3C +/milkii:3M +/milkness:0C +/milkness_:0C +/milktoast:2D +/millet:3H +/milquetoasti:3A +/mime:1U +/mimilaUra:4N +/mindcrime:5E +/mindlesstux:25 +/minicom:1C +/minicom7:3A +/minix92:3P +/mink:5E +/minorov:42 +/mintice:3M +/minty:6H +/minus:3C +/minusMplz:3C +/mion__:42 +/mircus:1Z +/mirhorse:3H +/mirhorse_:1C +/mirik:40 +/mirika:51 +/misfit:51 +/misfit_:3C +/misslavey:2T +/missx:63 +/misterjester:1C +/mithras_:1Z +/mits`:25 +/mixter:5E +/miyamoto:6N +/miyu:6C +/mjankovi`:2T +/mjankovic:1C +/mjo:2D +/mk-nn:5E +/mkfpq:63 +/mkk:2J +/mkke:03 +/mkkee:3H +/mkky:2T +/mkultra:3H +/mlaine:1Z +/mlavr:51 +/mlm:5C +/mm:6B +/mm29942:4C +/mmalecki:4C +/mmango:3C +/mmm:51 +/mmmh:6B +/mnemonix:4C +/mnmn:03 +/mnu:0C +/mnwafletx978:1C +/mnx:25 +/mnx_:09 +/mny:51 +/moane:03 +/mob_w:0A +/mobirails:1Z +/mod:42 +/modsToValhalla:5E +/moej:51 +/mofo-x:3A +/mofo-z:1C +/mohnish:0D +/mohnish_:25 +/mom:51 +/mona:1U +/monad:3A +/money40:1C +/moneytree:6H +/mongrel:2D +/moni12:3H +/monich:5E +/monique:63 +/monkey:09 +/monkeybal:0A +/mono:0D +/mono2:03 +/monokrom1:3H +/monokrome:6H +/monoxane:3A +/monoxane6:42 +/monoxyde:0C +/monte:6B +/monte-:0D +/monx:2J +/moon_:09 +/moondanc1:1Z +/moondance:3H +/moony:09 +/moony1:4N +/moony_:1C +/moot:03 +/mopi:4N +/mork:6B +/morse_naughty:63 +/mort:5E +/morthrane:3A +/mortisha:1C +/mosh:6A +/mostcows:3C +/mosterdt:3C +/moth3r:6N +/motte:5E +/motte_:6C +/moucly:6C +/mousepad:4G +/mouser:5E +/moutai__:3C +/mover:4G +/moxie:4N +/moxie`:5E +/mozillasandvich:63 +/mpt:6C +/mpwvyjdk:1C +/mpx:09 +/mr_hhvn:7H +/mr_moobs:4N +/mr_pants:0D +/mrafiee:6C +/mrbentarikau:4C +/mrbitterness:6A +/mrdubz:0C +/mre:42 +/mredgarfr:03 +/mrfreeze:3C +/mrhanky:2J +/mrinfinity:25 +/mrjones:6B +/mrkajetanp[m]:09 +/mrm:1C +/mrmehtada:6A +/mrnicke:1Z +/mrpfilser:42 +/mrraj:3A +/mrs__novak:51 +/mrs_hhvn:3P +/mrsfatty:0C +/mrskunk:4G +/mrtux_:03 +/mruno:4N +/ms_d:03 +/mshadle:5E +/mtqonv:6H +/muba:6H +/muba2:42 +/mugen:0C +/mugen_afk:4N +/mulberi:2J +/mulpjo:51 +/mumtaz_mahal95:3C +/mumtaz_mahal_:25 +/muneytree:3A +/munki_:4C +/muppeth:0C +/murmur_:4G +/musashi:5C +/muse:4C +/mushu:3H +/musicmake:3C +/muskrat:0C +/muslim:42 +/muslim_:0C +/mutarts:4N +/mutiny:09 +/mvDs:3H +/mwb:3M +/mwczwl:4N +/mwdkfx:6H +/mxl:0D +/mxthang:6C +/my5:4G +/myax:63 +/mychal:0A +/mydeardiary:4C +/mykah:2J +/myla:4G +/myr:4C +/mys:4C +/mys149:42 +/mys_:4C +/myscor:2T +/mysltex:1C +/mystery:0D +/mysticum:3M +/mystos:03 +/mzal:2T +/mzal_:25 +/mzgvpgpg:6B +/mzm:63 +/mzmzm:2T +/mzydjc:51 +/n00b:6C +/n00b100:4C +/n00b549:4N +/n00b620:4C +/n00b684:5E +/n00b849:2T +/n00b984:09 +/n00b__:3M +/n00ber:3A +/n00ber_:63 +/n07m3:2T +/n07m3-:2J +/n0_m0re:0A +/n0a110w:0C +/n0haxt:4N +/n0ne:2J +/n0ne`:6B +/n0nsense:2D +/n0rv:0C +/n0t0w:63 +/n0txx:2D +/n30nhybr1:1C +/n3mt4b:0A +/n473r5:0A +/n6tadam:0C +/nCore:6B +/nEverpk:4G +/nHlu:0A +/nIYO:4G +/nJRv:2T +/nOgAnOo:3A +/nUN3F47:4C +/na2met:2J +/naari:3H +/nabla:3A +/naeXi:6B +/nagdr:2D +/nagisa:3H +/nagual:25 +/nagual_:4G +/nahkhpjs:09 +/nahtjona:3M +/naitootat:42 +/naka:4G +/nala:0C +/name1:0A +/namibj:2J +/nan:63 +/nan0:6C +/nance:1C +/nancee:3C +/nanceeeee:3H +/nancy:4N +/nang:63 +/nani:2D +/nanii:3M +/nannerjammer:63 +/nano:03 +/nano-:2T +/nano_:4N +/nano_8086:51 +/nanoniem:51 +/nanoniem\:6A +/narada:2J +/narkos:09 +/nasteacat:3H +/nat:25 +/nate1:6C +/natsuya:2J +/nature:6A +/nax:1C +/nax_:4C +/nbozyoh:63 +/nc_:1Z +/ncqgjq:6H +/ndsddaeb:2T +/ndyeaj:25 +/ne:51 +/neaeto:63 +/neato:51 +/nebtakesthingsto:42 +/nebula027:25 +/nebula495:1Z +/neeasade:2J +/need:25 +/neelam69:3C +/negroe:6C +/negrokiller:4N +/negrox:3A +/neilalexander:0D +/neko_:4G +/nekobot:5E +/nekochen:03 +/nekomune:4C +/nem:3M +/nemdiggers:2T +/nemesisx:3M +/nemo:09 +/neonCoinZ:6C +/neonSimp:4C +/neonfreon:3H +/neongold:42 +/neonjesus:6B +/neonsata1:0A +/neonsatan:03 +/nerdk0re_:03 +/nero:3M +/nervous:0C +/neshpion:2J +/nesipice:63 +/nesipice_:2T +/nesoi:6C +/nesoi1:51 +/nesoin:42 +/nesta:2J +/nestacat:3H +/netblaz3:09 +/netblaze:6B +/netblaze-:0A +/netlan:2D +/netsec:4G +/netyaroze:6B +/netz:6C +/netz_:3M +/neuro:1C +/new:0D +/newbie:1C +/newnigger:51 +/newt:6H +/newt456:03 +/nexis_:2J +/nf:5E +/nga:63 +/nga0x539:09 +/nhahzwz:3C +/nharris:3H +/nhmmjtjc:6B +/ni291187:6H +/ni638629:4G +/ni886105:25 +/nib9888:0C +/nib9888_:6B +/nicenice:03 +/niceplace:3C +/nicesage:25 +/nicesage_:2D +/nicetry:42 +/nicetry-:4C +/nick1234:1C +/nick2:2J +/nickel:09 +/nickel_:3A +/nickl008:6C +/nickname:03 +/nickname0:3M +/nickotheus:03 +/nickserv:1Z +/nickyxxxl:6C +/nico1:51 +/nicolagi:03 +/nicolas:2J +/nicotime:6C +/nicteamn:6C +/nig_:2D +/niget:1C +/nigg3r:03 +/nigga:4C +/nigger:6B +/niggerman:3C +/niggerple:09 +/niggers:3A +/niggs:0A +/nightmares:3M +/nignog:4G +/nigsaw:4C +/nik:63 +/niles:3A +/nilnull:25 +/nin:4C +/nine:3A +/nine11:1C +/ninewise:51 +/ninex:2T +/ninex-:1Z +/ninex-_:4N +/ninex_:4C +/ninjabuffet:51 +/niqqqer:25 +/nirojan:4C +/nirvan4:5E +/nirvana:4N +/nisse:3H +/nitoplayer:42 +/nitrogen:6B +/nitroxis:09 +/nix:3C +/nixfloyd:3C +/niyish:2D +/nj:42 +/njaM:3C +/njha:3A +/njsg:51 +/njsg_:2J +/nk9k:3C +/nka:6B +/nkbkie:4N +/nkuld4:42 +/nm0i:6C +/nmQW:09 +/nmeum:4G +/nmmm:09 +/nmnm:4C +/nmvpf:2D +/nn:2J +/nnbt:4C +/nnnn:6C +/nnns:0C +/nnrre:4G +/no:5E +/nobo:4C +/nobo_:4N +/nobo__:0A +/nobody:4N +/nocarrie1:3C +/nocarrier:6H +/nocbz:6H +/nocountryforoldboy:0C +/nocturnal:2J +/nocturne:3A +/node:2T +/nodebit:1Z +/nodebit0:0C +/nodewire:0D +/nodfhfgf:6C +/noface:0C +/nofc:3C +/nohaq:2D +/nohesnot:1Z +/nohit:2J +/noice:5E +/nola_f_15:3M +/nolan:25 +/nolentils:1Z +/nolte:4N +/nom_:0D +/nom__:6H +/nomad:2T +/nomam:6H +/nomans:1Z +/nomic:1C +/nomic2:6B +/noname:4G +/noname_:3A +/noname__:63 +/nonickame:1C +/nonicknam:4C +/nonickname:3H +/nonlinear:0C +/nonlinear1:3A +/nonlinear2:63 +/noob_noob:2D +/noodlesx:2J +/nookname:2D +/nop:4N +/nope:03 +/nor:2J +/norex:42 +/normale:03 +/norvegia:42 +/norwaygrl:4N +/nosilica:1C +/nosilica_:03 +/nospam:63 +/nospinzy:42 +/nospinzyz:3H +/nostradms:40 +/not-rich:2J +/notB:09 +/notI:25 +/notK:3M +/notOutOfGum:6H +/not_b:42 +/not_seird:2J +/notagain:3M +/notatall:4N +/notb:3H +/notblaag:3M +/notbrewster:09 +/notdumb:6B +/notgamedude:6C +/nothuman:2T +/notimp:3H +/notkoro:3M +/notkoro_:03 +/notlenny:51 +/notnaka:2J +/notnoobr:0C +/notpk:25 +/notptr:1C +/notvash:1Z +/novidroog:2D +/novpnsigu:09 +/npchuv:2D +/nqafqtaq:1C +/nrgeqp:25 +/nsee:6B +/nt0__:3C +/ntr:03 +/ntvvyc:0A +/nubbles:4N +/nubbs:03 +/nubiee:2T +/nucor:42 +/nudist^AF:03 +/nufsed:25 +/nugget:3M +/nugrape:1C +/nujabes:0A +/nujabes-:6B +/null:3H +/null_:2T +/null__:3M +/null_ex:2J +/nulligan:09 +/nullptr:1C +/nullptr_:1C +/nully:1C +/nully2:3A +/number3:63 +/numbnuts:1C +/nutz0:6C +/nvnuq:1Z +/nvrhome:6B +/nxTMeksmG:4C +/nxnja:3H +/nxocd:6C +/ny:2J +/nyan:03 +/nyctea:4G +/nyctroll:6A +/nydel:09 +/nyku:3A +/nym:3A +/nymph:25 +/nyt:3C +/nyt_:51 +/nyyGOfLvb:2B +/o0:03 +/o9aa:63 +/oChoo:3A +/oGOMLsCMG:25 +/oMo:2D +/oTeeHi:2D +/o_0:0C +/o_C:3M +/o__o:25 +/oarion7:2T +/obake:4N +/obiZu:09 +/obon:2J +/obungie:4N +/obviyus:3H +/ocin:09 +/oclet:6C +/oct0:2T +/oct0pus:25 +/octest:51 +/octo:0C +/octopus:3A +/octopus-:6C +/octopus8:25 +/octopus`:6C +/od6n:3C +/odd13:4G +/odd13_:0D +/oddity:3C +/oddluck:0D +/oddluck7:0D +/odie:2T +/odp:0A +/oeXar:1C +/oelna5:25 +/oem:4G +/oepsie:4C +/oerjan:6H +/oevl:03 +/ofafynqw:09 +/offended:42 +/offendo:0C +/offic:4C +/offic_:6B +/offic__:6B +/ofiqjm:6C +/ogdeuwo:5E +/oh:0C +/ohJai:6C +/ohNgi:2J +/ohThoo:5E +/ohceiX:2T +/ohfmsmbh:4G +/ohgeetee:1C +/ohgeetee`:1Z +/ohn0s0hard:03 +/ohshi:3M +/ohyeahhh:3C +/ohyed:4G +/oicxvkzo:4G +/ojsdtxt:3A +/ok_____:0C +/okaber:51 +/okami:4N +/okay:6B +/okboss:3A +/okc0mputer:3M +/oketoch:63 +/okgovz:2D +/oksvk8989:6B +/olderkind:25 +/oldgeek:1Z +/olie-bol:63 +/oliebol:51 +/ollieparanoid[m]:51 +/ols:3A +/olsas:09 +/olus:03 +/olusx:0C +/omhwg:4N +/omlet:5E +/omlet_:4C +/oms:2D +/omse:0C +/onOw:51 +/one:6C +/one_almond:1U +/oned4:51 +/oneeightf:3A +/oneeightfourstco:51 +/oniijin:0A +/onmfd:2T +/onodera:6B +/ooGeeH:1C +/ooNge:4C +/ooNgoh:2J +/ooQuah:3M +/ooXav:3C +/oogaa:0A +/oohMemory:6C +/ooo:6H +/oopgcwv:51 +/oops_i_did_it_again:1C +/oosh:0A +/opal:51 +/opal-:63 +/opal_:6B +/openface:5E +/openface_:0A +/openfly:03 +/operbot:1Z +/ophie:03 +/opkes:51 +/opkes_:63 +/oppgqd:6H +/oppnhj:03 +/opposition:09 +/opticnerve:3H +/orahPi:4C +/orangefox:3A +/orangutan:3C +/orb:6C +/orbital:3C +/orblivion:09 +/ordinon:63 +/ordy:2T +/ordy1:25 +/ordy18:25 +/oregano:3M +/oreo:6B +/orgamses:2J +/ori:3H +/orko57:09 +/orlly:2D +/orlly11:1Z +/orlly2:63 +/orlly3:4C +/oroboroso:5E +/orthros:5E +/orthros77:0C +/osaoL:3M +/oscar:42 +/oshaH:3A +/osiris:1Z +/osprey:4C +/ossii:4N +/ot5436:2J +/ot54361:42 +/otfms:03 +/otorp:3A +/outsider_f:3C +/outt13:4N +/outtie:3M +/outwardjourney:2J +/ovan:3H +/over_loa-:09 +/over_load:4C +/overdose:09 +/ovsbgsem:3A +/ow:6B +/owenambro:63 +/owlpatrol:3A +/owo:1Z +/owo_:6C +/owo_owner_trollolol:25 +/ox8d:25 +/oxblood_r:5E +/oxidation:2J +/oxide:4G +/oxihe:1C +/ozamiz:09 +/oziiiz:2D +/p-ng:5E +/p0rpoise:4C +/p0rps:1C +/p0tat0es:3A +/p0tus:42 +/p1gl33t:3P +/p2pefnet:09 +/p4r4n0id0ne:3H +/p4xz:0A +/p80info:51 +/p80info`:3M +/pFUd:0C +/pHeS:1Z +/pJPQ:0A +/pRDB:1Z +/p`:6H +/p``f:5E +/p`f:0A +/paajeit:09 +/pagbndfv:6B +/pahreese:03 +/paige:1C +/paige1:2J +/pajeet:63 +/pajeet-:2J +/palisade:2D +/palooka:3C +/palyboy:3M +/pam_unix:0C +/panda1:6H +/pando:0D +/panicstr:2T +/panicstr_:4N +/panini:1U +/panini_:3M +/panini`:3A +/panitaliemom:1Z +/pankkake:2T +/panorain:3H +/panthar:4G +/panthar-:25 +/panzeroceania:3A +/papa:51 +/papawoofs:51 +/paper:6B +/parallels:5E +/paranoid:6B +/parazyd:3H +/parloir:3H +/parnini:51 +/parodie:0A +/partall:2J +/pask:42 +/pask2:6C +/passerby:3A +/password123:5E +/pastorkoa:0C +/pat:0C +/patkgnp:2D +/patpat4567:3H +/patpat4568:3A +/patpat4569:6C +/patryk:25 +/paul43:6B +/paulk-collins:1C +/pauum:3H +/paven:2J +/paven`:2T +/paxed:3C +/pay4irc:42 +/payforirc:51 +/payge:6B +/paysage:2J +/pb:1C +/pbb:4G +/pbb_:6B +/pbot:4G +/pbrxoifu:5E +/pbui:0C +/pbx5000:3H +/pbxou:2D +/pc:3P +/pc_:4G +/pcap:3A +/pcgjm:4C +/pcmike:1Z +/pea:51 +/peacecheese:0A +/peaches:25 +/peazz:42 +/peckr:09 +/pedo`:25 +/pedofile:6C +/pedophile:3C +/pedro[46]:4C +/peepee:1Z +/peetah:6C +/pekka:3A +/pemi:51 +/pencewins:51 +/pene:4G +/penedicavallo:1Z +/penis:1C +/penisbot:1Z +/penistits:6B +/penkster:2D +/penny:3M +/penski:1C +/penski_:0A +/penta:1Z +/penus:4G +/peppeag:3M +/perc:09 +/pere:3M +/pere_:1Z +/perlfan:4G +/perohig:3C +/peron:6B +/peron_:1C +/perp1exa:25 +/perplexa:2J +/perrierjo:0D +/pesky:3C +/pesky_:4G +/pespin:1C +/pespin_:4N +/peterhil:42 +/peterpomade:3C +/peters:2D +/pezmonkey:0C +/pf:1C +/pgreptom:0C +/pgrptm:6B +/ph0cis:3C +/ph0cus:25 +/phaggit:4C +/phanaeus:09 +/phantomb:63 +/phargle:6B +/phargul:0C +/phc:1Z +/pheni:0A +/phieP:6C +/phil:2T +/phillbush:3M +/phillipe5221:3H +/philmacfly:42 +/philzimmermann:3C +/phish:1Z +/phlud:4N +/phobos:2J +/phobos-:6A +/phocus:2J +/phocus`:4G +/phocus`_:3M +/phoenixcanary:4N +/phonekait:4N +/phonic:0A +/phooey:4G +/phooey_:4G +/photocyte:3M +/phr33d0m:03 +/phreak:1Z +/phrgl:3A +/phrost:4C +/phylum:3H +/pi:1C +/pi_:6B +/pi__:2D +/pickfire:1Z +/pickfire_:1C +/pico:3M +/pie:5E +/pierre:1C +/piesage:42 +/pig:6C +/pigeons:42 +/pinchy:3C +/pine127:09 +/ping:3H +/pingagn:42 +/pinkky:09 +/pinsessa:0C +/pinsessa14:2D +/piotrcap:0C +/pip:6N +/piratefox:25 +/piskapo-:25 +/pissbottl:0A +/pisslord:5E +/pitbull:2J +/pitbull_:4C +/pitz:6H +/pitz-:03 +/pixel_:25 +/pixelated:0C +/piyop:4G +/pizptein:4G +/pizzapal:4G +/pjgtre:6B +/pk:3A +/pk_is_fat:3H +/pkap:4G +/plab:03 +/plab_:42 +/plab__:25 +/plarceny:2T +/plastic:42 +/plasticca:5E +/plasticcat23434:3H +/plasticcat4030432:63 +/plasticcat420:4G +/player6969:4G +/pleemrkrl:03 +/plexa:1C +/ploks:03 +/plow:25 +/plskm:63 +/plsno:51 +/plsunban:3A +/plusMe:0C +/plus_m:2D +/plus_v-_p:1C +/plusme:3H +/plusvee:4G +/plusvplz:25 +/plzunban:4N +/pm-:5E +/pmi:0C +/pmis:3A +/pmis2:42 +/pmise:25 +/pnazzm:1C +/pnotic:6H +/poccri:09 +/poche:3M +/pocketpr0:1C +/pocketpro:25 +/pocky:51 +/podesta:3M +/podesta_:5E +/podesta__:63 +/poggri:51 +/pohBu:2J +/pok:2T +/poka:0A +/polanco:6B +/politburo:51 +/politicallycorrect:2D +/polka:63 +/pollini:2D +/pollpoc:42 +/poloanjel:25 +/polyglot:3M +/polyhrut:51 +/polyhurt:1U +/polyprop:1Z +/pomegra:3A +/pomf:4G +/pomff:1Z +/pomfret:4G +/pomfyyy:63 +/pomggf:6B +/pong:1C +/ponziSchemer:6B +/poontang:1U +/poop:0C +/poopbaby:1Z +/popcorn:4N +/popey:1C +/poppy:63 +/poptart:09 +/poqznx:6C +/porksandwich:5E +/pornini:03 +/porno:0A +/port:3C +/portee:3C +/potgirl:4C +/potien203:0C +/potien356:51 +/potsmoka:3A +/potus:6C +/poutine:3C +/powerfulmind:51 +/powiw:2D +/ppcpunk:4N +/ppp1:03 +/ppx:3C +/ppydsny:3M +/pr0pri3taryn0de:3C +/prank:2T +/prawnsalad:2J +/praxage:2B +/praxsage:4N +/prc194:0C +/prcdn:03 +/precipic1:6B +/precipic2:5E +/precipice:0C +/pregoia:3H +/prepuk:4N +/presonic:1Z +/presonic_:3C +/pretma:03 +/prez:6C +/prg:03 +/princeski:5E +/princesskitana:6B +/princesskitana-csh:0A +/princesskitana1337:6H +/prinsessa:25 +/prinsesse:3A +/priti:51 +/privbot:4N +/privy:6C +/prizzly:6B +/prizzly_:2T +/prjrbhru:5E +/prnflks:5E +/pro:3C +/profedward:4G +/profetik777:4N +/progrel:3C +/project:2J +/projectak:51 +/prometheus:2D +/proof:3H +/prophet:0A +/proto:6C +/proto-:0A +/protocol:3M +/protocol-:6C +/prym:2D +/psauqro:2T +/psg:2J +/psych094:63 +/psychedel:1C +/psycho:3M +/psychobee:3H +/psymasta:3H +/psymaste1:3H +/psynigger:2D +/psyop:4N +/psyvenrix:1Z +/pt300:03 +/ptadv:2T +/ptol3my:2J +/publicNME:4N +/puccimane:5E +/pudtrt:4G +/puke:03 +/puke2020:5E +/pulsar12:3C +/puly:5E +/pumpbull:3A +/pumpkins:1Z +/punished_mayu:0C +/puoSa:51 +/pupper:3P +/puppy:3C +/puppy-:4G +/purgemaster:3A +/purist:4G +/purp_:40 +/purpel:1C +/pussy:1Z +/pwkwht:0A +/pxgjlozt:42 +/pymassa:09 +/pyn:25 +/pyrate:2J +/pyrate_:03 +/pyratebeard:09 +/pyre:4C +/pyrex:42 +/pzUhgzI2s:42 +/q-u-a-n:42 +/q-u-a-n1:51 +/q-u-a-n2:1C +/q-u-a-n3:1C +/qD:1Z +/qapla_org:6B +/qarhmkrl:51 +/qbit:4G +/qcbiboy:0D +/qdflUe:51 +/qgkreg:4C +/qhfrmkv:3C +/qi:4G +/qizbdpct:6C +/qjajrkel:09 +/qk:4G +/qksmekl:51 +/qkvmuxb:6H +/qmiwea:63 +/qmjtlr:0C +/qnorsten|away:0A +/qpt:25 +/qpvud:2J +/qq2222222222222222222222222222:42 +/qqq:51 +/qryfhob:51 +/qrzn:1Z +/qscju:6B +/qsgpd:5E +/qssqxxu:0A +/qsvgu:09 +/qto:3C +/qto^:4N +/qtpie:0D +/qtpie_:3H +/quadDamage:4N +/quan:4N +/quan_:0D +/quantax:6B +/quantax_:0C +/quantico:0C +/quarex:2J +/quarex_:4G +/qubix_:6C +/queenofkings:6H +/queiD:25 +/quertzuiop:4G +/quiXuj:4N +/quinq:2J +/quisling:0C +/qw:42 +/qwe123454:2D +/qwebirc12:1Z +/qwebirc71:63 +/qwerty:3A +/qwertzuiop:51 +/qwertzuiop_:4G +/qwop:09 +/qy:03 +/qy_:1C +/r00t_Gh0sT:03 +/r00tobo:09 +/r00xz:2D +/r0bby:3H +/r0bobox:2J +/r0ndit0:6H +/r1mu:3H +/r1oWHt:0C +/r2d2:6C +/r3ader:6B +/r3d:03 +/r3d-:3C +/r3d_:4N +/r3d__:0D +/r3hab:3C +/r3mk:2D +/r6ZD:6H +/rEspiD:6H +/rMobWYX:1C +/ra-ra:03 +/ra-ra_:6H +/ra1n:63 +/ra7s:6H +/ra8s:6B +/raT:1Z +/raab:03 +/rabbipires:03 +/rabbitear:3M +/raboof:63 +/racehorse:2T +/racist-:2B +/radchad:40 +/radie:1C +/rafael2k:3A +/rage-:6H +/ragga64:3C +/raghavgururajan:3A +/ragnarok_:6B +/rails:4N +/rain`:2T +/rain`_:0C +/rainbowjo:40 +/rainy:0A +/raisin:4C +/raj:0C +/raj_:09 +/rak:0C +/rakemeS:6H +/rakiru:6C +/rakshasa:4C +/ramenz:1Z +/rami:0A +/rami_:3M +/ramiferou:09 +/rampage-:0C +/ramsay:25 +/ramsay_:4N +/ramses:4G +/ramses_:5E +/rand:3H +/randnet3:3C +/rando_99:2J +/random:0A +/randomO24:0C +/random_yanek:3C +/randomnickname:2J +/ranix:6B +/rapemerdr:3H +/rapemurdr:2T +/raperape:2D +/raph_ael:0A +/raphidae:03 +/raphidae-:0C +/raphidae`:6B +/rapunzel:25 +/rasengan:1Z +/rask0ln1k0v:1C +/raskolni-:0A +/raskolni|:2T +/raspcherry:6H +/raspcherry_:3A +/raspcherry__:4C +/rastabomb:4N +/rat:42 +/ratbert:09 +/ratfactor:51 +/rattle:1Z +/ratxue:03 +/ravagrrl:3C +/raven_:4N +/rawr:6H +/raxa:4C +/razy:4N +/rbk:0C +/rbots:51 +/rbrdv:0C +/rbrezzmh:5E +/rcdgpxe:63 +/rcdjssqd:25 +/rcf:42 +/rcf1:09 +/rda:40 +/rdr:2J +/rdr_:3H +/rds:1C +/rdtbjvoq:6C +/reading:5E +/reagen_:6C +/realDonaldTrump:3C +/realcone:2D +/reallll:42 +/reallylongnick:1C +/reaxt:3C +/rebel:6C +/rebel_:3P +/rebirf_:3M +/rebirth:6B +/rebs:25 +/receptive:2J +/rechos:6B +/redLotus:6B +/redangel:3M +/redbear:3M +/reden:2J +/redlegion:0C +/redneonglow:3C +/redragon:6H +/redsand:25 +/redsquare:6B +/redubious:03 +/redukt:51 +/redx113:51 +/redxer:2D +/reebot:03 +/reeee:03 +/reeeeeeeeee:2J +/refusist:2D +/regeneron:09 +/regulate:2D +/rehab:63 +/reiamani:3C +/reillyeon:6C +/reinnosuki:25 +/reisub:25 +/rejeeC:2J +/rejon:63 +/rekir:3C +/relaxo:51 +/relic:4N +/remogt:4N +/removepk:0C +/ren00b:0A +/rengaf:3C +/rennie:3A +/replicant:0C +/reppard:4N +/resemc:03 +/reshma:3H +/resident-:3H +/respect_:6C +/resting:4C +/restless:0D +/retards:4C +/retsetbug:4G +/retsetgub:3A +/retwt:0C +/reuntal:4G +/revilon:0C +/revolution:03 +/rewq:6B +/rfeany:25 +/rfmctm:0C +/rfx:40 +/rgcpcTqva:2D +/rgdgnfnfgh:51 +/rgsbkq:1Z +/rgu:1C +/rhauch:25 +/rhysm:63 +/ricardus:0C +/ricardus_mini9:0C +/richard:0A +/richiez:25 +/rickhayes:51 +/ricksanch:2D +/rievies:1Z +/right:1C +/riker:0A +/rill1:4N +/rimas:3C +/riznqfd:0A +/rjc:3M +/rjhurt:51 +/rjt_znc:6B +/rjyzlbt:5E +/rkk:3H +/rkl__:0C +/rklorax:4G +/rkl|:3C +/rlam1:4C +/rlszoc:51 +/rm:0C +/rm-:6C +/rmb:1Z +/rmb0:03 +/rmb1:63 +/rmmm:0C +/rmmm_:2J +/roaar:4C +/roach:42 +/roar:6C +/roar_:25 +/rob0:6H +/robbiet480:25 +/robbos:5E +/robboss:25 +/robertm:51 +/robi:3A +/robits:0D +/robmusial:03 +/robo_:6H +/roboirc:6C +/roboirc-:1C +/robot:0C +/robotic:51 +/roboticr:25 +/robotnik:4G +/robotnik_:2J +/robrand:3C +/robrand_:3C +/robwerks:03 +/rocepj:2T +/rocia:51 +/rock1:3M +/rockets:0C +/rocketsnail:4G +/rockey:1Z +/rockho:25 +/rodolphoeck:63 +/rodpod:3P +/rodpodimu:2D +/roen:2D +/roen1:4N +/rofl:2B +/roflwaffl:63 +/romare:3M +/romarefai:0C +/ron:2J +/rondeeto:51 +/rondito:6B +/ronery:2D +/roniez:4N +/ronnic:6H +/ronvoit:51 +/rooky:6C +/root:09 +/root1:25 +/root2:0C +/root3:3H +/roroboin-:0D +/roroboing:1Z +/roror:0C +/rorx:03 +/rosemary:0D +/rosemary1:6C +/rosfr:0A +/rosseaux:2T +/rossjones:63 +/rottenbi1s:3A +/rottenbits:4G +/route:3M +/roygbiv:2D +/rozay:3M +/rpP6QW5Q:09 +/rpifan:51 +/rptr:25 +/rpwwij:42 +/rqifio:2D +/rrats:4C +/rrats_:3M +/rrfx:25 +/rrn:5E +/rrn_:0C +/rrn__:4N +/rrn___:4G +/rrrts:4G +/rsaa:6C +/rsakeys:3P +/rsal:2T +/rsdmovw:1Z +/rshakin:3A +/rsoemn:4N +/rtalk101:4C +/rthrthstr:6C +/rubii:3A +/ruciu:4C +/rude:63 +/ruedeguy:2T +/ruedeguy1:3H +/rugan:2D +/rum-:3C +/rumblepez:3H +/rumbler:4G +/rumblerez:1C +/runswithcrayons:3A +/runswithsissors:3H +/runswithsissors7:03 +/runswithsissors8:25 +/rush:4G +/russanna2020---SnapChatName:2D +/russian:4N +/ruthless:40 +/ruthlesss:2T +/rvbres:2J +/rwDK:51 +/rwZL:2D +/rx:0D +/rx5100:1C +/rx999:03 +/ryan:0C +/ryanbw:42 +/ryanm:42 +/ryans:4N +/rydyi:09 +/rymeten:3M +/ryst:1Z +/ryxxed:25 +/rznegva:5E +/rznwclpu:2J +/s010:63 +/s0berag:3A +/s0berage:51 +/s0k1t:3H +/s0k1t_:3C +/s1l3nced:03 +/s1lent:25 +/s31:4G +/s3xyl1nux__:42 +/s628940:4N +/s7ntax:0D +/sBjc:6H +/sD:4G +/sF3Y:2D +/sHIa:0C +/sHIa2489:09 +/sKitt:25 +/sKyK:6H +/sLuL:0C +/sOkefenok:3M +/sSsSSs:09 +/sSssSs:4G +/sTranGer:0D +/sUbMuNdO:42 +/sUbMuNdO_:03 +/sVez:0C +/sZKuKutk:6C +/s\ash:42 +/saba:4G +/sabazios:51 +/sabazios_:3H +/sabotage:6C +/sabre:51 +/sacon:1C +/sact:2T +/sactown:5C +/sadasaulna:51 +/sadblue:6C +/safe:3P +/sagashi:1Z +/saika11:3C +/saintpie:3C +/sakura:3C +/sakurazuk:2D +/sal_:42 +/sal__:6H +/salerace:25 +/salimfadh:2T +/sally_v:4N +/saltbird:25 +/saltyspittoon:3A +/salvador:63 +/sam:0C +/samdems:3C +/sameo:4C +/sameo_:63 +/sammuel86:4N +/sammyette:2J +/samueldr:4G +/sand:6A +/sandflow:25 +/sandman:0C +/santiago39-uy:25 +/santiago39uy:51 +/santiago__:2J +/sara:2D +/sarkazm:5E +/sashimi:51 +/satan:63 +/saty:0C +/saty_:3C +/sauce1:6B +/sav:25 +/say10:5E +/sayjay:5C +/sbeve:0D +/sbffrtevz:2D +/sbhg:3C +/sbk:0C +/sboke:0A +/scar`face:6A +/scarecrow:09 +/scared:6C +/scarface:51 +/scd:0D +/scd_:0A +/schmillin:2B +/scholar:3A +/schwuk:3H +/sci3nc3:51 +/scifi:25 +/scifi_:63 +/sckuz:3A +/scones:6B +/scrapped:3A +/screamscreamSCREAM:3M +/screamscreamSCREAM_:2J +/screwgohan:3A +/scrim:0A +/scrotal_b:1Z +/scrub_:3M +/scruffles:1Z +/sctqha:4C +/scuttle:3C +/scuzwoot:2T +/sdas:4N +/sdfawdfas:3M +/sdfs:0D +/sdk:1Z +/sdldjsk:3M +/sdlfsd:3C +/sdrawkca1:5E +/sdrawkcab:1Z +/sdsadewf:6C +/se200718:1Z +/se7en:6B +/sea:3H +/sea_:63 +/seanh:3M +/seans:40 +/seasons:6H +/sebbu:2T +/sebbu2:2D +/sebyrock:3M +/secef:3H +/secretmyth:51 +/secure:1Z +/secure-:42 +/sedbot:4C +/sedjuani:3H +/seeNg:4C +/sefnintr:4G +/sehaydenh:X7E +/sehnsucht:4N +/seijvert:2J +/seisatsu:4G +/sektie:4G +/semendemon:25 +/sentinL:09 +/sepples:25 +/seriesofnumbers:25 +/serious:1Z +/seroquel:25 +/seroquel_:51 +/serrabqr:25 +/serviteur:5E +/set:2D +/seth:2T +/seuzt:0C +/severbot:3M +/sex:3M +/sex_slave:3H +/sexsex:2J +/sexslave:51 +/sfd8:3C +/sfowler:3A +/sg111:42 +/sgkfvgc:5E +/sgo:0C +/sh4:09 +/shadowfox:6H +/shaed:6C +/shah^:0A +/shamoanjac:2J +/shamus:09 +/shardy:0C +/sharky2:4G +/sharp:0A +/shawn:1Z +/shawn_:63 +/shaye:1Z +/shaye3:2T +/shekk:0C +/shelpe:0D +/shelpe_:3H +/sheraldo2:3P +/sherlock:25 +/sherop:2D +/shii:3M +/shiitake:4N +/shin_getter:63 +/shine:1C +/shine_:1C +/shine__:1C +/shinedown:4G +/shit:3C +/shitlord:1C +/shlomostein:5E +/shmoo:2J +/shockwave:1C +/showyrslf:2D +/shr00m:0A +/shrooms:2J +/sht:3M +/shusky:2T +/shusky_:4C +/shutuploser:3H +/shutuploser_:09 +/shzzx:4G +/sicelo:09 +/sickofag:6H +/sideffect:3H +/sife:6C +/sigkill:2J +/signop:03 +/sigrun:4N +/silhuette:03 +/sili:2J +/simbaLion:1C +/simboona:4C +/simp:4C +/simplewom:2T +/sin:42 +/singasbr:51 +/siniStar:4N +/sins:2J +/sitths:51 +/six8:03 +/sixone:42 +/sixwells:3M +/sjc:5E +/sjrvf:63 +/sk8erchic:4C +/skOlast:6B +/skalar10-:6H +/skankhunt:3C +/skapeg0aa:2T +/skepo:0A +/skg:6A +/skg_xyz:6H +/skill:1C +/skindots:5E +/skinzz87:3C +/skirl:1C +/skjoldr:4C +/sknkhnt42:3A +/skrike:6C +/skroni:09 +/skronind:4N +/skrzyp:4C +/skud_:3M +/skvidal:4G +/skydog:4N +/skydrome:2J +/skyghosts:09 +/skymaster:0C +/skywalk0:0C +/slackfam:1Z +/slackfam1:6B +/slapnuts:0A +/slaqer:63 +/slavegirl:25 +/slawz:2D +/slaypage:42 +/slee:5E +/sleeping:2J +/sleepy:51 +/sleepy_:4N +/slegna:0C +/slewis:42 +/sliceOirc:40 +/slime:5E +/slimeball:0A +/slopey:51 +/sloth`:3A +/slovenia:42 +/slowbot:4N +/sluagh:3A +/sly:3M +/sly_:4C +/slyshot:4G +/sm00:2J +/smPPtoDf:42 +/smartguy:4N +/smash-:0C +/smashgra_:2D +/smashgrab:5E +/smashjew:63 +/smashjew2:0A +/smbopax:6B +/smegmab0y:2J +/smithnesson:25 +/smlckz:42 +/smoke-z:42 +/smolder:5E +/smptnx:25 +/sn00p:4C +/sn00p_:51 +/sn00p___:51 +/sn1ff:0A +/sn1ff_:3H +/sn2ff:51 +/snEak:6B +/snEk:5E +/sn_:3A +/sn_ff:25 +/snadge:3M +/snazo:03 +/sneak:6A +/sneek:25 +/snek:1C +/snek_snab:3C +/snibeti:4N +/sniff:42 +/sniff-:1C +/sniff_:25 +/snip:25 +/snitches:3A +/snitchku:0C +/snk:03 +/snoozens:5E +/snorf:5E +/snow_:1Z +/snowdy:3H +/snuf:0C +/snuffy:3C +/snufkin:0C +/snufkinson:0C +/snugglo:6B +/snwwro:6B +/soTWYKFwt:25 +/society:6B +/sockmister:25 +/socks_:3H +/sockspls:51 +/socraticDev:0D +/soda4fries:6B +/sodium:03 +/softashell:25 +/soho:4G +/sohoichai2:2T +/sol:1Z +/sol37829:09 +/sol748923:6B +/solanjay:42 +/solene:03 +/solidus:1C +/solo:6B +/somatic:63 +/somedude:03 +/someguy:0C +/someguy__:6B +/someone:3A +/sonic-:1C +/soolo:6B +/sorengard:2D +/sorinello:6C +/sorinello1:4N +/soso:1Z +/soul_:4G +/souph3r:6H +/souph3r-csh:6H +/souph3r_:6H +/soupher-csh:63 +/soupnazi:25 +/soupspin:4G +/southey:3C +/southie:03 +/soxfan:3H +/soybean:42 +/sp:3H +/sp5ke:6H +/sp5ke_:3C +/sp8ke:4G +/sp8ke_:6C +/spGke:3H +/spQke:6H +/spQke_:42 +/spVke:25 +/spVke_:1C +/spWke:03 +/sp^ke:25 +/sp_:4N +/sp_ke:6H +/sp_ke_:3C +/space_rou:4G +/spacecat:5E +/spacecore:0D +/spags:1Z +/spags2:51 +/spake:51 +/spamus:1Z +/spamus_:2J +/spamus__:03 +/spamux:3M +/spark1313:3C +/sparklee:3M +/sparrow:0D +/spartan:6A +/spathi-wa:0A +/spawn-:6H +/spear:4G +/spear-:6B +/spear-_:4N +/spear^:51 +/spear_:2J +/spear|:3H +/spectre:3C +/sped:03 +/speedy:6C +/speedy_:4C +/speedy__:3M +/speko:4C +/spetzes:6C +/sphx:6C +/sphx_:6C +/sphx__:6C +/spice_:42 +/spidy:3H +/spidy_:2D +/spike:0C +/spill:6H +/spindizy:3H +/spinsane:2J +/spirit:6H +/spitroast:09 +/spk:6B +/splat:3C +/splatter:09 +/spoek:1U +/spoke:09 +/spoon:42 +/spoonm:4C +/spricht:2D +/sprinkle:2D +/spuddy:3C +/spuddy-:25 +/spunkworm:1Z +/spxke:4C +/spxke_:4N +/spy_:4N +/spynxic:3M +/spzke:25 +/sq:6H +/sq_:0A +/squiggle:1Z +/squirt:2D +/squirts:2B +/srh:3A +/srm:6C +/srmf:6C +/srsrh:6H +/srvdown:0A +/ssd:0A +/sslbea:2T +/sslr_:3H +/sss:25 +/sstd:2D +/ssxlfm:1C +/st0vepipe:0C +/stEvo:4N +/stabbie:4G +/stacker:2J +/stackiller:51 +/stansmith:2T +/starbomba:6C +/starboy:2T +/stardome:0D +/stark:4G +/starman85:4C +/starmobba:3C +/starrcade:0A +/starseed:0A +/stateles1:2D +/stateless:09 +/staticfox:3A +/staymad:1C +/stcyber:4N +/stcyber_:4N +/stdio:5E +/stdio_:3H +/ste90:4C +/ste[:1C +/steamgirl:42 +/steampot:0A +/stedly:3A +/stedly_:42 +/stedly__:6B +/steeby:2J +/steev:0A +/stegotti:03 +/sterile:2D +/steve:4C +/stevenix:2T +/stevenm:2T +/stevepipe:1Z +/steveskyp:4G +/stevoo:51 +/sth:3M +/sth-2:42 +/sthors:1Z +/stian:0C +/stick:6C +/stickfigure:03 +/stid3r:42 +/stigger:0D +/stigma:1C +/stigma2:2D +/stilbruch:6N +/stinker:3M +/stirlitz:2J +/stkhomi:1Z +/stoic:6H +/stoked:0A +/stomper:0D +/stompykins:0C +/ston3r:2D +/stone:0A +/stonecold:4N +/stonedcold:0A +/stonedcold_:3M +/stormd:4N +/stormium:2J +/stormsz:03 +/stormsz3:51 +/stormsz4:3C +/stormsz6:25 +/stormsz9:3C +/stormsz92:0C +/stormsz98:6H +/stovep1p3:2D +/stovep1pe:5E +/stovepip3:25 +/stovepipe:6B +/stovepooo:09 +/stovep|pe:1C +/stowa:1Z +/stowaway1:1C +/stranger:2D +/straton:2D +/stratum:03 +/stratum_:4N +/stratum__:5E +/stratum`:42 +/stratum`_:6C +/stratumm:25 +/straw-hat:2D +/strike:2J +/strikersh:6C +/strixy:1C +/strontium:42 +/stroopwafel:25 +/strtok:5E +/stu_meat:5E +/stupidguy:4C +/stuttgart:6B +/stygian:1Z +/styledash:4N +/styledash3:25 +/styledash7:3M +/styles:3M +/stylez:3C +/styopah:2D +/sub0hm:0D +/sub0hm-:42 +/sub0hm|:3M +/subXhm:4C +/subcon:3C +/subway:42 +/suckbot:51 +/suckmuh:63 +/suckmywan:3M +/sud0:3A +/sueuse:3C +/sufizzle:3H +/sugar:4N +/sugoi:51 +/sulke:1C +/sully:4C +/sultanofping:51 +/sum:51 +/sumbrero:1Z +/sumbrero_:5C +/sun-light:3C +/sun-lightt:51 +/sundie__:0A +/sundie___:6C +/sunrise:51 +/sunrise_:3P +/sunshavi:4C +/sunshy:1C +/sunzer0:25 +/suparel:0A +/suparel\aw:42 +/super-ultra_extreme_far_right:6B +/super_duper_uber_far_right:4G +/super_duper_uber_ultra_extreme:63 +/super_duper_uber_ultra_far_rig:03 +/superalpine:5E +/superalpine_:3M +/supercilious:4N +/superflu9:2J +/superfly:2T +/superher0:6A +/superjack:6N +/superpj:4C +/suplani:25 +/supradyn:3A +/surfdiver:3M +/surplussi:0A +/surreal:3H +/surreal_:0C +/sushibut:4G +/susse:3H +/sussumu:09 +/suswrd:3C +/suwa:42 +/svere:0C +/swab:6H +/swaps:4N +/swaps_:09 +/swaps__:4C +/swapss:63 +/swarthyPerson:1Z +/swiffles:2D +/swift:4G +/swift110:09 +/swift110_:4G +/swinder:51 +/swiss1:1C +/swrangsar:4G +/swudth:3A +/sxyvitami:3M +/sy:3C +/sy11ab3ar:1C +/syamimerinin:1C +/sycopa:6B +/syf:6C +/syf_:2T +/sykoeye:09 +/sylar:5E +/symtecs:3C +/syn:3A +/syn3yrb:25 +/syn\:2D +/syn^:6B +/syn`_:6C +/syn`__:4G +/synbiose:2T +/syneevj:5E +/synm7n3:3H +/synnlf3:25 +/synowvu:4G +/synqf4f:3C +/synszre:2T +/syntax:2T +/synth:25 +/synthk:09 +/synxqgf:6C +/synyof1:2D +/syrianrue:2D +/syrius:51 +/syrius_:3M +/sys:4G +/sysadmins:6B +/sysfz:2D +/sysop:4G +/system:6H +/systwi:5E +/systwi_:0A +/sz3kl3r:6H +/szass:6C +/szass_:09 +/szsdvfi:2D +/szssitdt:2D +/szzymzt:1Z +/t--manyt-c-unt:3C +/t--manyt-t-unt:2J +/t0fu:3M +/t0fu_:63 +/t2:2D +/t3chn01r:4C +/t3hyoshi:4C +/t3xtm0de:6H +/t420:6C +/t420_:0A +/t4l:09 +/t4n:4G +/t4nk949:2T +/t9Z4n:3A +/tGumbie:09 +/tXeX:4N +/tXmD:1C +/tXul:3M +/taaLu:25 +/tabb:6B +/tachikoma:5C +/tacocat:1C +/tacosage:3C +/tadam:40 +/taehuH:25 +/tafari:4G +/tag-:63 +/tag_:6H +/tahCha:4C +/tailpush:63 +/taimur:2J +/taimur_:6B +/tait1491:1Z +/takoyaki:63 +/tald:4N +/talia`:51 +/talia``:0A +/tallship:3M +/tallship_:5C +/tallship__:4N +/tammy:1C +/tanami:6H +/tangier:1C +/tankfox:3C +/tankfox_:63 +/tao:3H +/tardbaby:6B +/tater:0A +/tater_:0C +/tau:4N +/tawny:4N +/taxman:0D +/tay:4C +/tay_:0C +/taylor85345:25 +/tbwfv:1C +/tcghhj:4G +/tcm:3C +/td:6C +/td`:4G +/tdk:6B +/te:3H +/teGhi:3C +/teaman:0C +/teaman_:4G +/teaman__:25 +/teamux:42 +/technically:42 +/technically_:1C +/techniggger2:4C +/teddy66:2T +/tedead:6H +/teechay:6H +/tef:51 +/tegxxw:3A +/teiwaX:3A +/tekk:2T +/teksimia1:6C +/teksimian:4C +/telephone:6B +/television:51 +/teller:6B +/tem:4G +/tem_:6B +/tempette:3M +/tenecks:3C +/tenecks-:4N +/tepes:63 +/tepssct:25 +/tera_:1C +/teragram:03 +/teranaut:51 +/teratoma:51 +/teratoma_:3A +/termer:1Z +/termer_:1Z +/termina:3A +/terps:0C +/terpy:3C +/terra:3M +/terra-x:03 +/terri`schiavos`lover:09 +/terror:2D +/tertl3:5E +/test:1C +/test2:25 +/testabbb:3H +/testbot:4G +/testbot1:0C +/tester:3C +/tester_:6H +/testing:1Z +/testing123:42 +/testing123456:03 +/testing_:0C +/testman:2J +/testman9:6C +/testtest:1C +/tet3020:4G +/tetrasage:6C +/tetsing:4C +/teu-:1C +/teu-_:1Z +/tevzsbffr:3C +/textmate:4G +/tfpfzel:51 +/tgzgiy:3H +/th0rn:6A +/th1nkp4d:0C +/th3m4dm4n:4G +/th3r4p1st:40 +/thanat0s:4N +/thanatos:6B +/thanatos_:6C +/thatsme:4G +/thatsraci:2D +/thatty:4N +/that|Guy:1U +/the-fool:1Z +/theGrg:2D +/the_ark:1C +/the_d:03 +/the_hwite_race:3A +/thebaconfromhell:6B +/thecrp:6H +/thefoxes:5C +/thegiant:4N +/thelounge35:1Z +/thelounge92:5E +/them:2D +/them_:1Z +/themaSk:3H +/themadman:3C +/themask:03 +/thenewdesu:4N +/therealemma:4G +/therestrainingorder:25 +/theruleofodds:3C +/thetasock:25 +/thief:4N +/thinking:2D +/thinkp_:6C +/thinkpad:0C +/thirstyho:3C +/thirty:09 +/thomas:1C +/thonao:6H +/thonao_:42 +/thooGi:3A +/thopas:5E +/thot:1Z +/thot_:5E +/threv:6B +/thrillho:03 +/thruways:0C +/thufir:0A +/thwack:4N +/tiberius:4C +/tickles:4G +/tidux:6B +/tidux|webchat:25 +/tigg3r:6C +/tigger:25 +/tiggers:0D +/tim1:09 +/timecrystal:4G +/timm:0C +/timmah:3C +/tin_:4C +/tire:6C +/tires:2T +/tis:40 +/tiwEllien:3C +/tiwesdaeg:03 +/tiwesdaeg1:0D +/tiwgy:4N +/tj:1C +/tj_:2T +/tj__:0D +/tj___:0C +/tjuda:42 +/tjw:09 +/tkane:6C +/tkjmlb:4C +/tkk:63 +/tkk__:4C +/tlac:03 +/tlyu:0A +/tm512:3C +/tmberg:0C +/tmlind:6B +/tmux:25 +/tmuxedo:51 +/tndez:3A +/to0n:25 +/toast__:25 +/tobias:3H +/tobo:4N +/tobo2:09 +/toddler:1Z +/todlyncz:3A +/tofu:3H +/tofu_:1C +/tokyogringo:2J +/tokyogringo`:5E +/tomchanks:51 +/tomhanks:6B +/tomhanks-:6C +/tomhanx:1Z +/tomma`:0A +/tomo:1Z +/tomo_:5E +/tony:0C +/tony-:63 +/tooFarry:2T +/toocool_:42 +/tooka:3A +/tool1:2T +/tool2:25 +/tool4:6C +/toor_:25 +/tootle:4C +/tor.hlircnet.:1C +/torax:1Z +/torbot:3C +/torbox:6B +/torgal:3C +/torvalds_jovial:42 +/tosiaki1:0C +/tosiaki2:5E +/totally_not_OutOfGum:5E +/tough:1C +/tourettes:4C +/tourmaline:42 +/toxait174115422819548835257138:51 +/toxik:0D +/tprime:6B +/tprophet:4G +/tqcdw:3M +/tqndkruj:0C +/tr3:1Z +/trafficcone:03 +/tranny4u:42 +/trans:25 +/trans-git:2J +/trans-old:3M +/trans2:0A +/transact:42 +/transacte:3M +/transtest:5E +/trapgawd:3M +/traph:3C +/trapstze:3A +/traxex:25 +/trdaisuke:6C +/trebbn:4C +/tredfghyu:03 +/tree^_^:5C +/treehugga:1Z +/treeman2:4G +/treeman5:0C +/treeman6:51 +/treeman7:3H +/treeview:3M +/treeview2:0C +/treeview3:25 +/tref:6B +/trench:4C +/trev:63 +/trev1:4N +/trey:42 +/trigex:3C +/trigex_:03 +/trilobyte:0C +/trip:0C +/trip_:09 +/tripledonkey:09 +/tripped:3C +/triques:51 +/triques4:63 +/triques6:51 +/triques9:0C +/trishi:25 +/trivalleur23:1C +/trixis:1C +/trixisowned:4G +/trn:03 +/trnv2:3M +/trn|c:09 +/trollUSA:09 +/trollfag:3P +/tron:3A +/tronic:4C +/trper:3A +/true-asset:3A +/trummo:4N +/trump2020:0A +/truthhurtssome:6C +/truthr:5E +/truthrx:3H +/truthvalue:25 +/trypanoss:25 +/tsal:5E +/tsarb:2D +/tsarbobma:51 +/tsarbomb-:3H +/tsarbomb_:3A +/tsarbomba:1Z +/tsarmabob:3A +/tsiegel:0A +/tsk_:1C +/tsong:51 +/tt:09 +/tt1:09 +/ttill:2T +/tubes__:63 +/tubman_:42 +/tubman__:6C +/tuinhekje:5E +/tulpa:25 +/tulpa_:09 +/tumble:1Z +/tumble_:51 +/tumbleweed:1Z +/tuna:6H +/turd:2J +/turdboy:6H +/turin:3M +/turkrapingswedes:1C +/turtle:3M +/tuy360:3A +/tuy360_:42 +/tvall:1Z +/tw0:3H +/tweak:1C +/twinkcrea:4C +/twinkiecr:51 +/twinkream:2J +/twitch069:03 +/twixisowned:25 +/twoshay:03 +/twpvhyaw:63 +/txgl3mos:3C +/tyil:4N +/tynkle:2T +/type:6B +/type0:5E +/tystratum:63 +/tytratum:3C +/tyui:09 +/tzanger:2D +/tzanger_:4N +/tzngr:4C +/u:1Z +/u0_a117:4G +/u0_a157:3H +/u0_a165:0A +/u0_a165_:3A +/u0_a202:1C +/u0_a256:6B +/u0_a313:2D +/u0_a633:3C +/u1ktMQhOW:25 +/u2NmP2:42 +/u3046:1C +/u4ea:3C +/u4ea_:2D +/u4t:5E +/uBaig:6H +/uMaike:1C +/uNeebe:3C +/uReeve:0C +/uXLGKVgqI:3M +/uXyZ9V:0C +/ub`:5E +/ubergeek:2T +/uberius:42 +/uchi:4G +/udjygrpx:3H +/uejgk:4N +/uflwrm:1C +/ufo:2B +/ugjokndk:51 +/uhTrFrXXd:09 +/uhekki:1C +/uhg:1C +/uhhhh:3P +/ui89o:40 +/uid:63 +/ujcMaMSFZ:6H +/ukkces:3H +/ukulelele:6H +/ulcerpain:25 +/ulijtzvo:3M +/ultimate-:6C +/ultimate11:2J +/ultimate11_:6H +/ultra_extreme_far_right:5E +/ultraanon:0A +/ultraanon2:6H +/ulua:1C +/umaruchan:6C +/unacked:2T +/unbanMe:4G +/uncool:1C +/undefinde7:09 +/underAnt:5C +/underd0g:1Z +/underd0g_:2J +/underdoge:6B +/underline:2D +/undream:25 +/undream_:3M +/undulum:6C +/unfo-:0C +/unickusr:3C +/unicorn:1Z +/univrsal:1C +/unixbsd:0C +/unkn00n:0C +/unkn0w7n:3C +/unkster:6A +/unkw0oN:51 +/unlqrau:09 +/unrAAlvgJ:4N +/unreal23:2B +/unrooted:09 +/unrznbl[m]:3H +/unsane:6C +/unsmoked:51 +/unstone:6C +/unwrappin:1C +/uoam:03 +/uoya:25 +/uoya_:3A +/upfuck:5E +/upgrade:3M +/upyhpeh:4C +/uqbyuhnj:25 +/uqxhx:4G +/urhfre:03 +/urlinfo:4C +/urlinfo`:4N +/urodna:0C +/urodna_:3C +/ursa_vox:6H +/ursula:25 +/urthmover:2J +/usKt:63 +/usaezc:63 +/usedbird:6H +/user:2T +/user99200:4N +/user_:3C +/user__:0D +/user___:4N +/usernick:6C +/usr1987:25 +/usr481320:2T +/usxWieIrI:2T +/utanapischti:42 +/uther:3H +/utrvmfth:4N +/uuPB:1C +/uuVee:2J +/uvos:3H +/uw0tm8:3A +/uwvqgpgd:3M +/uxtfm:2D +/uzasof:1Z +/v:03 +/v4th0r:0A +/vFQF:3M +/vLK:3M +/vacuum:4N +/vae:0C +/vae1cpf:2D +/vae1tqp:6C +/vae1xte:0C +/vae2zs1:51 +/vae38d0:1Z +/vae3w06:4C +/vae483d:4N +/vae8705:03 +/vae8hwl:2D +/vae92rx:1Z +/vae99y9:6H +/vae_:0C +/vaeab91:2T +/vaebo5y:4N +/vaeccag:63 +/vaecx23:4G +/vaecyqw:3C +/vaed0ug:6C +/vaed8wa:25 +/vaedgub:1C +/vaedmoi:42 +/vaefj7u:5E +/vaegob7:51 +/vaei75x:3A +/vaej89o:0C +/vaejrk0:0C +/vaekc8h:6C +/vaekmov:1Z +/vaem7fg:1C +/vaemf63:4N +/vaemfbx:09 +/vaemztr:6C +/vaeoh2m:3M +/vaeolnr:63 +/vaeoped:09 +/vaeos67:09 +/vaeosj7:3H +/vaeqqkp:63 +/vaeqsii:3M +/vaesima:63 +/vaeuvrl:3M +/vaevboc:3C +/vaevjby:6H +/vaey480:2D +/vaeyqbi:3C +/vagisil:6C +/valiant:4C +/valuables:2D +/vamp1337:6B +/vamprella:03 +/vandmend:51 +/vanir:3C +/vanity:3M +/vanity-:2J +/vantawyte:0A +/vap0r_:1C +/var-g:42 +/var-g_:51 +/variableLabel:0D +/varju:63 +/vasalquaf:3M +/vash:3M +/vash-:63 +/vash_:6B +/vauvroe:6H +/vb:3C +/vbskapg:1Z +/vc:6H +/vectis:5E +/veeVoh:63 +/veiRu:0C +/vencx:63 +/vencx_:3M +/venial:3M +/venodka:3A +/ventures:2T +/venus_:6C +/venx:03 +/ver1z0n:2D +/ver1z0nn:3P +/verifier:1C +/verm1n:25 +/vert:6H +/vert2:3C +/veryvery:1C +/vet:2D +/vexorg:3M +/vexuC:42 +/vfC:2B +/vfrmedia:0D +/vicentius:0C +/videl:2D +/vigilant:42 +/vigilant`:3A +/vigilante:2D +/vigilan|:1Z +/vigole:0C +/viic:42 +/vikara_das:1C +/vikodin:4G +/vikodin_:4G +/vim:6C +/vim_user:03 +/vincenzo7:2T +/vino:6H +/vintagero:6B +/viper-:2J +/viper__:4N +/vir:25 +/virago:3M +/virginAnalyst:2D +/vish:09 +/visitoor:2J +/vita:6H +/vitimiti:6B +/viutk:1Z +/viwxcr:3C +/vix:40 +/vixen`_:1C +/vlad:1C +/vlad-:3A +/vmz:40 +/vnc-:09 +/vodka:4N +/vodka_:4N +/voet:42 +/vohHo:0A +/voice4u:4C +/voice_of_reason:4N +/voicemepl:1C +/voicepls:3M +/voiceplx:25 +/voidP0inter:3A +/voiddwm_:63 +/voidhlwm:42 +/voidhlwm_:4N +/volusto:4C +/vortex:4C +/vp:2D +/vpnbase:2T +/vprowl:3C +/vprowless:6B +/vpw:4G +/vr0n:6B +/vr0n1:6B +/vr0n2:6B +/vr0nmas:6B +/vr0nmas2:6B +/vr0nmas3:6B +/vraphim:5E +/vraphim_:0D +/vrelchott:25 +/vrl:2T +/vroomfondel:0C +/vrshfp:2J +/vscefj:4N +/vtgoneh:3H +/vueafk:25 +/vujxt:6C +/vvjkk:3A +/vvv_:6B +/vwehpreq:3H +/vx:25 +/w:42 +/w0bos:3A +/w0nder:63 +/w0rd:2J +/w0rd_:3H +/w0red:2D +/w0rhed:2T +/w0rm:0C +/w10x12:1C +/w10x121:42 +/w3stside:6B +/wDZY:6H +/wGumbie:0C +/wJVeZoc:6N +/waax:2T +/wagonbird:51 +/wakaranai:1C +/waleed:51 +/walrus:6B +/wang:51 +/wangs:6B +/wangx:09 +/wankEboi:25 +/warmbrake:42 +/warsawiol:3M +/warsoul:09 +/wasd55:6B +/wasd55_:25 +/wattlings:1Z +/waveclaw:0D +/waveclaw_:3A +/waveframe:2J +/waw:2J +/waylon531:3A +/wayne:51 +/wayne_:6H +/wb9814:0A +/wbwj:6B +/wdna:09 +/wdz:09 +/we_____:4C +/wear:25 +/weather:42 +/webslayer:2D +/wednesday:3A +/wednesday_:3C +/weds:63 +/weds_:3M +/weeHiz:0A +/weeds:0C +/weekend:2T +/weekend-away:6C +/weekoro:3M +/weems:2D +/weird:2J +/wer1:3M +/wer2:3M +/wer3:3M +/wer4:3M +/wer5:3M +/werejag:2J +/werewolf:3C +/werrejag:2T +/wervenyt:4N +/west:6C +/westerns:03 +/westor:25 +/westor{off}:3M +/wfUauWQ:0A +/wfnincor:0D +/wfnintor:1Z +/wfnintr:3M +/wfnintr_:3M +/wfnintr___:3M +/whatwut:0C +/wheat:3C +/wheresmyv:2D +/whiplash:09 +/whirlygig:42 +/whispers:4N +/whitecaps:0C +/whitetras:0A +/whitey:5E +/whjuwb:09 +/whoami:1Z +/whodini:6B +/whoef:09 +/whoflungpoop:3A +/whoops:03 +/whore:4N +/whtes:3M +/whuntley:51 +/whyiseveryonecha:6C +/wiavb:0C +/wikkid:0C +/wil:2J +/wil_:2T +/wildting:4G +/wildting2:03 +/wildting4:42 +/wildtingTwo:6B +/wilkie:0C +/william:3A +/wilsonk|2:6C +/wilt3d:0C +/wilt3d_:4N +/win:6H +/win95:6B +/win98:6B +/windsok:2B +/wink:2D +/winny:6B +/wirss:1C +/wise:1Z +/wise_:6C +/wise__:6B +/wisefool:3C +/wiseguy:3M +/wiseone:42 +/wishbone:25 +/wizard:4N +/wizarddude:0C +/wizrd:2D +/wizrd_:3H +/wjmnmeuq:42 +/wk:1C +/wkr4k4r:09 +/wkuwxk:4N +/wleslie:51 +/wleslie_:4G +/wlsn:2J +/wlsseksv:4G +/wmllximz:3H +/wnqubdx:4C +/wo0GieWoO:3C +/wof:4N +/wof_:4N +/wof__:4G +/wojo:3H +/wombat:3C +/wombat_:25 +/womble2:03 +/wompum:3C +/wonder:6H +/woofwoof:1Z +/wook:0D +/wook_____:3C +/wooky:1C +/wooky__:3A +/wordpress:63 +/workdays:6B +/worst_alternative:03 +/worstwish:0D +/wowaname:03 +/woyzz:1C +/wpsoonkh:6H +/wqphasi:3H +/wrapper:0C +/wredny:2D +/wreo:42 +/wrex:03 +/wrjeod:25 +/wrqhw:1C +/wsco:2D +/wsgkx:63 +/wslahr:51 +/wsmith:2D +/wsnnPVBoA:63 +/wtfanon:2J +/wtweek:3C +/wurrier:2D +/wut:3A +/wuvjfq:3H +/wuwei:6H +/www:3C +/wyaei:2T +/wyldmagyc:09 +/wylel:0D +/wymillerlinux:1Z +/wyn:3A +/wynton_boomer:6H +/wyrm:6B +/wytau:63 +/x:3C +/x-amy-x:4C +/x-fag:3H +/x-girl:1C +/x0:0A +/x11r72:0C +/x1bncwn:1C +/x1bncwn_:5C +/x1bncwn__:6N +/x3mboy:6H +/x3pom:3P +/x507:0C +/x7z:6C +/x90:6C +/xAsh:42 +/xDemonessx:3H +/xGps:4G +/xGumbie:25 +/xKqK:4N +/xLara:6B +/xLink:0D +/xSubZer0x:0C +/xVgZdftRO:3A +/xYaA:0C +/x_:6B +/x_x:1Z +/xa0s:2J +/xadammr:2J +/xade:42 +/xaePhu:5E +/xanban:0C +/xanban6:2J +/xaphod:0C +/xaphod1:4N +/xargs1:3A +/xart:4C +/xartet:42 +/xartet-:2D +/xartet--:3H +/xartet_:4C +/xartet__:3M +/xavier:2T +/xaviercm63:63 +/xb0ner:2D +/xbbitfm:3A +/xbeastx:1Z +/xbfuxp:6C +/xbhjxk:51 +/xbmhy:0A +/xboner:4C +/xbpyyx:0A +/xc:42 +/xczzcas:3A +/xc|:0D +/xdaff:42 +/xdragon:4C +/xecut:25 +/xeeder:1C +/xelpapus:5E +/xeni:42 +/xeno:2J +/xeno_:4G +/xero:0C +/xerrox:0C +/xerrox_:3A +/xes_:5E +/xes__:4N +/xfskoo:3C +/xhigb:6H +/xiXai:3C +/xikkub:2D +/xiktc:6B +/xinnie:1Z +/xioGh:63 +/xjcyq:4C +/xkwgre:6C +/xld:3H +/xlei:6C +/xmage:6C +/xmn:3A +/xmyicyu:6H +/xnaas:0D +/xnaas2:42 +/xnaas7:4N +/xokfealn:25 +/xolhbj:3H +/xorhash:4N +/xoutxin:1Z +/xqndpk:6B +/xqxvjr:0C +/xrmjlwcz:4C +/xs:3M +/xspfgoqt:1Z +/xtc:25 +/xtc-:1Z +/xtfcpdm:6H +/xtor:42 +/xtraterra:3H +/xuu:3C +/xvcusv:42 +/xxaY:3H +/xxld:0C +/xxx32:3H +/xxxxx:51 +/xyte:09 +/xz:6B +/y0m5CQtGb:2J +/y91y91y91:2T +/yDFw:0C +/yGYK1Vg:3H +/yQOX:6H +/yUpKx:09 +/yWbc:0C +/yakamo:3H +/yakuza:3C +/yall:63 +/yang:3M +/yanski:4C +/yanski_:63 +/yanu:6H +/yasoR:42 +/yaungcor:4G +/yawkvlhp:0A +/yayjman:09 +/yayoman:0C +/yayomanpatty:0C +/yayomanshatty:4N +/yaypixxo:1Z +/ybbuq:3H +/ybwfneiv:09 +/ydtotm:03 +/ydvvzqyh:4C +/ydxccjxa:3H +/yeagel:4G +/yeahok:63 +/yeeQu:4G +/yeee:3H +/yeee`:2J +/yelmxn:51 +/yenrod:1C +/yerseas:51 +/yeti:1Z +/yeti1:3H +/yeye:51 +/yeynruru:2J +/yhoxHCaj:51 +/yhsiang:09 +/yito:2J +/yjgbn:25 +/yjxbxmc:3H +/ykjsony:2T +/ylJPQu6Z:25 +/ymtdmkz:51 +/yngwizard:4N +/ynizyjq:6B +/yoduh:1C +/yoonix:0A +/yoonix-:1C +/yoonix0:3H +/yoshi15:1C +/yoss:2D +/youdontknowme:42 +/youfuckin:1C +/yourbothere:1C +/yourname:42 +/yowhbvq:3C +/yoyomiho:0A +/ypfkqig:3M +/ysyck:4G +/ytcracker:2D +/ytf0rd:2T +/ytilimuh:6B +/ytlyv97:1Z +/ytoucs:2D +/yumas:3A +/yur3i:5C +/yxhjsh:5E +/yxutqvz:63 +/yxxqpb:3H +/yyy:4G +/yzUBAy:0C +/z:03 +/z0z0:6B +/z3bra:09 +/z3n:2D +/z3ntu_:0A +/z3r0:2J +/z3uS:3A +/zFgXdqQKQ:3H +/zabxg:6C +/zacts:3M +/zahyxqxd:1C +/zakku:3C +/zakku90:09 +/zakku900:1C +/zakkus:09 +/zambia:42 +/zanetti:3H +/zapatasec:25 +/zaqtjwv:09 +/zb_:42 +/zcPq:42 +/zcrayfish:5E +/zcrbqs:6C +/zdfop:0C +/zduchac:4N +/zeamp:5E +/zeb:03 +/zebra:25 +/zedfreak:51 +/zeeshi:1C +/zeezoo:6B +/zeezoo_:6C +/zelest:3A +/zen:0C +/zen-:6C +/zeng0d:1C +/zenga:4C +/zenik:51 +/zenik-:4C +/zenik^:51 +/zenik_:3A +/zenik|:6C +/zenostar:4G +/zensor:6B +/zen|:0A +/zeougm:3H +/zephros:4G +/zeptar:3A +/zer0rest:0D +/zero:51 +/zeroNot:4G +/zerocool:4G +/zerocool0:2D +/zerodaysfordays:2J +/zerodub:3H +/zerosouls:0D +/zerous:3C +/zerous1:3A +/zeta:51 +/zethius:4N +/zfs:0D +/zfvxv:4G +/zfvxv-:0D +/zgngzzya:6H +/zgrep:3M +/zhhawgql:5E +/zhig:4N +/zi:1C +/zid:3C +/zigg:09 +/ziggys:25 +/zigzag:0C +/zinestro:51 +/zinestro_:6B +/zip:3M +/zipper:2J +/zippity:6H +/ziqlqwu:2J +/zllkemev:6H +/zlspetek:1C +/zmm:63 +/zmugee:1Z +/znEk:6C +/zneak:1C +/znedw:3H +/zneeb:0A +/zodi4c:25 +/zof:42 +/zooey:4C +/zorg:1Z +/zorg1:4G +/zoroaster:3C +/zouz:42 +/zouz_:4N +/zozo:42 +/zp:2D +/zphinx:6H +/zpkbz:3A +/zpmafkuf:1C +/zpwMjXYrF:40 +/zqjfk:2T +/zrrn:3A +/zsjrsre:03 +/ztmihhl:3A +/zuHiHu:63 +/zuexys:2D +/zujnavyi:2T +/zune:6B +/zup:4C +/zwansch:2T +/zx:3C +/zyfuob:3A +/zyklon:63 +/zylone:25 +/zylone_:6H +/zylone__:4N +/zyme:3A +/zyxx0r:2D +/zyxxor:6C +/zzenik:1C +/zzmm`:2T +/zzzzzzzzzzzzzzz:2D +/{0_o}:03 +/{nick}:5E +/{zenik}:3C +/|:51 +/|-{}-|:2D +/|00|:3P +/|23|:2T +/|3[]T:2D +/|GIG:6B +/|GIG-1:0A +/|GIG2:4N +/|V||K[][]|_[]:09 +/|WEREJAG|:6C +/|X-File|:3A +/|][][]:63 +/|beatdown:6C +/|darkwind:3C +/|dev|:2D +/|haydenh|:7H +/|iCE|:0A +/|san|:03 +/|san|-:1Z +/|silicon:3C +/|werejag:2J +/|werejag|:0A +/|werejeg|:0C +/|||||||||:0C +/}{-XP-}{:3C +/beenz/beenz:1C +/davis/davis:2J +/fixingshithopefully/fixingshithopefully:25 +/happy/happy:1Z +/hyperreal/hyperreal:1C +/ia/ia:6B +Rizon/#/g/technology/hyperreal:4N +Rizon/#8chan/Benett:4G +Rizon/#8chan/Wildstorm:0C +Rizon/#8chan/viic:03 +Rizon/#uk/Benett:03 +Rizon/#uk/Wildstorm:4C +Rizon/#uk/viic:42 +efnet/#IRC30/beenz:2J +efnet/#asciiart/haydenh:5E +efnet/#efnet/haydenh:5E +hlircnet/#hlircnet/davis:3M +hlircnet/#hlircnet/fixingshithopefully:03 +sdf/#sdf/haydenh:09 + +[set] +/NickServ:3H +/Sopel:2J +/card.freenode.net:5C +/efnet.port80.se:6N +/freenode-connect:40 +/hhvn:7H +/irc.haydenvh.com:3C +/irc.nebulacentre.net:09 +/irc.sdf.org:2D +/legended:4G +/thufir:0A +/unix.chat:03 diff --git a/.config/irssi/scripts/README b/.config/irssi/scripts/README @@ -1,21 +0,0 @@ - -ascii.pl: - /ASCII [-c1234] [-f <fontname>] [-p <prefix>] [-l|-s|-m <where>] <text> - /COLSAY [-1234] [-m <where>] <text> - /COLME [-1234] <text> - /COLTOPIC [-1234] <text> - /COLKICK [-1234] [nick(,nick_1,...,nick_n)] <reason> - /COLQUIT [-1234] <reason> - /SET ascii_figlet_path [path] - -auto_whois: - all is handled by itself - -nickcolor.pl: - all is handled by itself - -url_hilight.pl: - all is handled by itself - -usercount.pl: - all is handled by itself diff --git a/.config/irssi/scripts/adv_windowlist.pl b/.config/irssi/scripts/adv_windowlist.pl @@ -1,2954 +0,0 @@ -use strict; -use warnings; - -our $VERSION = '1.9'; # 32a6d4807a45e71 -our %IRSSI = ( - authors => 'Nei', - contact => 'Nei @ anti@conference.jabber.teamidiot.de', - url => "http://anti.teamidiot.de/", - name => 'adv_windowlist', - description => 'Adds a permanent advanced window list on the right or in a status bar.', - sbitems => 'awl_shared', - license => 'GNU GPLv2 or later', - ); - -# UPGRADE NOTE -# ============ -# for users of 0.7 or earlier series, please note that appearance -# settings have moved to /format, i.e. inside your theme! -# the fifo (screen) has been replaced by an external viewer script - -# Usage -# ===== -# copy the script to ~/.irssi/scripts/ -# -# In irssi: -# -# /run adv_windowlist -# -# In your shell (for example a tmux split): -# -# perl ~/.irssi/scripts/adv_windowlist.pl -# -# To use sbar mode instead: -# -# /toggle awl_viewer -# -# Hint: to get rid of the old [Act:] display -# /statusbar window remove act -# -# to get it back: -# /statusbar window add -after lag -priority 10 act - -# Options -# ======= -# formats can be cleared with /format -delete -# -# /format awl_display_(no)key(_active|_visible) <string> -# * string : Format String for one window. The following $'s are expanded: -# $C : Name -# $N : Number of the Window -# $Q : meta-Keymap -# $H : Start hilighting -# $S : Stop hilighting -# /+++++++++++++++++++++++++++++++++, -# | **** I M P O R T A N T : **** | -# | | -# | don't forget to use $S if you | -# | used $H before! | -# | | -# '+++++++++++++++++++++++++++++++++/ -# key : a key binding that goes to this window could be detected in /bind -# nokey : no such key binding was detected -# active : window would receive the input you are currently typing -# visible : window is also visible on screen but not active (a split window) -# -# /format awl_name_display <string> -# * string : Format String for window names -# $0 : name as formatted by the settings -# -# /format awl_display_header <string> -# * string : Format String for this header line. The following $'s are expanded: -# $C : network tag -# -# /format awl_separator(2) <string> -# * string : Character to use between the channel entries -# variant 2 can be used for alternating separators (only in status bar -# without block display) -# -# /format awl_abbrev_chars <string> -# * string : Character to use when shortening long names. The second character -# will be used if two blocks need to be filled. -# -# /format awl_title <string> -# * string : Text to display in the title string or title bar -# -# /format awl_viewer_item_bg <string> -# * string : Format String specifying the viewer's item background colour -# -# /set awl_prefer_name <ON|OFF> -# * this setting decides whether awl will use the active_name (OFF) or the -# window name as the name/caption in awl_display_*. -# That way you can rename windows using /window name myownname. -# -# /set awl_hide_empty <num> -# * if visible windows without items should be hidden from the window list -# set it to 0 to show all windows -# 1 to hide visible windows without items (negative exempt -# active window) -# -# /set awl_detach <list> -# * list of windows that should be hidden from the window list. you -# can also use /awl detach and /awl attach to manage this -# setting. an optional data_level can be specified with ",num" -# -# /set awl_detach_data <num> -# * num : hide the detached window if its data_level is below num -# -# /set awl_detach_aht <ON|OFF> -# * if enabled, also detach all windows listed in the -# activity_hide_targets setting -# -# /set awl_hide_data <num> -# * num : hide the window if its data_level is below num -# set it to 0 to basically disable this feature, -# 1 if you don't want windows without activity to be shown -# 2 to show only those windows with channel text or hilight -# 3 to show only windows with hilight (negative exempt active window) -# -# /set awl_hide_name_data <num> -# * num : hide the name of the window if its data_level is below num -# (only works in status bar without block display) -# you will want to change your formats to add $H...$S around $Q or $N -# if you plan to use this -# -# /set awl_maxlines <num> -# * num : number of lines to use for the window list (0 to disable, negative -# lock) -# -# /set awl_maxcolumns <num> -# * num : number of columns to use for the window list when using the -# tmux integration (0 to disable) -# -# /set awl_block <num> -# * num : width of a column in viewer mode (negative values = block -# display in status bar mode) -# /+++++++++++++++++++++++++++++++++, -# | ****** W A R N I N G ! ****** | -# | | -# | If your block display looks | -# | DISTORTED, you need to add the | -# | following line to your .theme | -# | file under | -# | abstracts = { : | -# | | -# | sb_act_none = "%K$*"; | -# | | -# '+++++++++++++++++++++++++++++++++/ -# -# /set awl_sbar_maxlength <ON|OFF> -# * if you enable the maxlength setting, the block width will be used as a -# maximum length for the non-block status bar mode too. -# -# /set awl_height_adjust <num> -# * num : how many lines to leave empty in viewer mode -# -# /set awl_sort <-data_level|-last_line|refnum> -# * you can change the window sort order with this variable -# -data_level : sort windows with hilight first -# -last_line : sort windows in order of activity -# refnum : sort windows by window number -# active/server/tag : sort by server name -# lru : sort windows with the last recently used last -# "-" reverses the sort order -# typechecks are supported via ::, e.g. active::Query or active::Irc::Query -# undefinedness can be checked with ~, e.g. ~active -# string comparison can be done with =, e.g. name=(status) -# to make sort case insensitive, use #i, e.g. name#i -# any key in the window hash can be tested, e.g. active/chat_type=XMPP -# multiple criteria can be separated with , or +, e.g. -data_level+-last_line -# -# /set awl_placement <top|bottom> -# /set awl_position <num> -# * these settings correspond to /statusbar because awl will create -# status bars for you -# (see /help statusbar to learn more) -# -# /set awl_all_disable <ON|OFF> -# * if you set awl_all_disable to ON, awl will also remove the -# last status bar it created if it is empty. -# As you might guess, this only makes sense with awl_hide_data > 0 ;) -# -# /set awl_viewer <ON|OFF> -# * enable the external viewer script -# -# /set awl_viewer_launch <ON|OFF> -# * try to auto-launch the viewer under tmux or with a shell command -# /awl restart is required all auto-launch related settings to take -# effect -# -# /set awl_viewer_tmux_position <left|top|right|bottom|custom> -# * try to split in this direction when using tmux for the viewer -# custom : use custom_command setting -# -# /set awl_viewer_xwin_command <shell command> -# * custom command to run in order to start the viewer when irssi is -# running under X -# %A - gets replaced by the command to run the viewer -# %qA - additionally quote the command -# -# /set awl_viewer_custom_command <shell command> -# * custom command to run in order to start the viewer -# -# /set awl_viewer_launch_env <string> -# * specific environment settings for use on viewer auto-launch, -# without the AWL_ prefix -# -# /set awl_shared_sbar <left<right|OFF> -# * share a status bar for the first awl item, you will need to manually -# /statusbar window add -after lag -priority 10 awl_shared -# left : space in cells occupied on the left of status bar -# right : space occupied on the right -# Note: you need to replace "left" AND "right" with the appropriate numbers! -# -# /set awl_path <path> -# * path to the file which the viewer script reads -# -# /set fancy_abbrev <no|head|strict|fancy> -# * how to shorten too long names -# no : shorten in the middle -# head : always cut off the ends -# strict : shorten repeating substrings -# fancy : combination of no+strict -# -# /set awl_custom_xform <perl code> -# * specify a custom routine to transform window names -# example: s/^#// remove the #-mark of IRC channels -# the special flags $CHANNEL / $TAG / $QUERY / $NAME can be -# tested in conditionals -# -# /set awl_last_line_shade <timeout> -# * set timeout to shade activity base colours, to enable -# you also need to add +-last_line to awl_sort -# (requires 256 colour support) -# -# /set awl_no_mode_hint <ON|OFF> -# * whether to show the hint of running the viewer script in the -# status bar -# -# /set awl_mouse <ON|OFF> -# * enable the terminal mouse in irssi -# (use the awl-patched mouse.pl for gestures and commands if you need -# them and disable mouse_escape) -# -# /set awl_mouse_offset <num> -# * specifies where on the screen is the awl status bar -# (0 = on top/bottom, 1 = one additional line in between, -# e.g. prompt) -# you MUST set this correctly otherwise the mouse coordinates will -# be off -# -# /set mouse_scroll <num> -# * how many lines the mouse wheel scrolls -# -# /set mouse_escape <num> -# * seconds to disable the mouse, when not clicked on the windowlist -# - -# Commands -# ======== -# /awl detach <num> -# * hide the current window from the window list. num specifies the -# data_level (optional) -# -# /awl attach -# * unhide the current window from the window list -# -# /awl ack -# * change to the next window with activity, ignoring detached windows -# -# /awl redraw -# * redraws the windowlist. There may be occasions where the -# windowlist can get destroyed so you can use this command to -# force a redraw. -# -# /awl restart -# * restart the connection to the viewer script. - -# Viewer script -# ============= -# When run from the command line, adv_windowlist acts as the viewer -# script to be used together with the irssi script to display the -# window list in a sidebar/terminal of its own. -# -# One optional parameter is accepted, the awl_path -# -# The viewer can be configured by three environment variables: -# -# AWL_HI9=1 -# * interpret %9 as high-intensity toggle instead of bold. This had -# been the default prior to version 0.9b8 -# -# AWL_AUTOFOCUS=0 -# * disable auto-focus behaviour when activating a window -# -# AWL_NOTITLE=1 -# * disable the title bar - -# Nei =^.^= ( anti@conference.jabber.teamidiot.de ) - -no warnings 'redefine'; -use constant IN_IRSSI => __PACKAGE__ ne 'main' || $ENV{IRSSI_MOCK}; -use constant SCRIPT_FILE => __FILE__; -no if !IN_IRSSI, strict => (qw(subs refs)); -use if IN_IRSSI, Irssi => (); -use if IN_IRSSI, 'Irssi::TextUI' => (); -use v5.10; -use Encode; -use Storable (); -use IO::Socket::UNIX; -use List::Util qw(min max reduce); -use Hash::Util qw(lock_keys); -use Text::ParseWords qw(shellwords); - -BEGIN { - if ($] < 5.012) { - *CORE::GLOBAL::length = *CORE::GLOBAL::length = sub (_) { - defined $_[0] ? CORE::length($_[0]) : undef - }; - } - *Irssi::active_win = {}; # hide incorrect warning -} - -unless (IN_IRSSI) { - local *_ = \@ARGV; - &AwlViewer::main; - exit; -} - - -use constant GLOB_QUEUE_TIMER => 100; - -our $BLOCK_ALL; # localized blocker -my @actString; # status bar texts -my @win_items; -my $currentLines = 0; -my %awins; -my $globTime; # timer to limit remake calls - -my %CHANGED; -my $VIEWER_MODE; -my $MOUSE_ON; -my %mouse_coords; -my %statusbars; -my %S; # settings -my $settings_str = '1'; -my $window_sort_func; -my $custom_xform; -my ($sb_base_width, $sb_base_width_pre, $sb_base_width_post); -my $print_text_activity; -my $shade_line_timer; -my ($screenHeight, $screenWidth); -my %viewer; - -my (%keymap, %nummap, %wnmap, %specialmap, %wnmap_exp, %custom_key_map); -my %banned_channels; -my %detach_map; -my %abbrev_cache; - -use constant setc => 'awl'; - -sub set ($) { - setc . '_' . $_[0] -} - -sub add_statusbar { - for (@_) { - # add subs - my $l = set $_; - { - my $close = $_; - no strict 'refs'; - *{$l} = sub { awl($close, @_) }; - } - Irssi::command("^statusbar $l reset"); - Irssi::command("statusbar $l enable"); - if (lc $S{placement} eq 'top') { - Irssi::command("statusbar $l placement top"); - } - if (my $x = $S{position}) { - Irssi::command("statusbar $l position $x"); - } - Irssi::command("statusbar $l add -priority 100 -alignment left barstart"); - Irssi::command("statusbar $l add $l"); - Irssi::command("statusbar $l add -priority 100 -alignment right barend"); - Irssi::command("statusbar $l disable"); - Irssi::statusbar_item_register($l, '$0', $l); - $statusbars{$_} = 1; - Irssi::command("statusbar $l enable"); - } -} - -sub remove_statusbar { - for (@_) { - my $l = set $_; - Irssi::command("statusbar $l disable"); - Irssi::command("statusbar $l reset"); - Irssi::statusbar_item_unregister($l); - { - no strict 'refs'; - undef &{$l}; - } - delete $statusbars{$_}; - } -} - -my $awl_shared_empty = sub { - return if $BLOCK_ALL; - my ($item, $get_size_only) = @_; - $item->default_handler($get_size_only, '', '', 0); -}; - -sub syncLines { - my $maxLines = $S{maxlines}; - my $newLines = ($maxLines > 0 and @actString > $maxLines) ? - $maxLines : - ($maxLines < 0) ? - -$maxLines : - @actString; - $currentLines = 1 if !$currentLines && $S{shared_sbar}; - if ($S{shared_sbar} && !$statusbars{shared}) { - my $l = set 'shared'; - { - no strict 'refs'; - *{$l} = sub { - return if $BLOCK_ALL; - my ($item, $get_size_only) = @_; - - my $text = $actString[0]; - my $title = _get_format(set 'title'); - if (length $title) { - $title =~ s{\\(.)|(.)}{ - defined $2 ? quotemeta $2 - : $1 eq 'V' ? '\u' - : $1 eq ':' ? quotemeta ':%n' - : $1 =~ /^[uUFQE]$/ ? "\\$1" - : quotemeta "\\$1" - }sge; - $title = eval qq{"$title"}; - $title .= ' '; - } - my $pat = defined $text ? "{sb_awl $title\$*}" : '{sb_awl }'; - $text //= ''; - $item->default_handler($get_size_only, $pat, $text, 0); - }; - } - $statusbars{shared} = 1; - remove_statusbar (0) if $statusbars{0}; - } - elsif ($statusbars{shared} && !$S{shared_sbar}) { - add_statusbar (0) if $currentLines && $newLines; - delete $statusbars{shared}; - my $l = set 'shared'; - { - no strict 'refs'; - *{$l} = $awl_shared_empty; - } - } - if ($currentLines == $newLines) { return; } - elsif ($newLines > $currentLines) { - add_statusbar ($currentLines .. ($newLines - 1)); - } - else { - remove_statusbar (reverse ($newLines .. ($currentLines - 1))); - } - $currentLines = $newLines; -} - -sub awl { - return if $BLOCK_ALL; - my ($line, $item, $get_size_only) = @_; - - my $text = $actString[$line]; - my $pat = defined $text ? '{sb_awl $*}' : '{sb_awl }'; - $text //= ''; - $item->default_handler($get_size_only, $pat, $text, 0); -} - -# remove old statusbars -{ my %killBar; - sub get_old_status { - my ($textDest, $cont, $cont_stripped) = @_; - if ($textDest->{level} == 524288 and $textDest->{target} eq '' and !defined $textDest->{server}) { - my $name = quotemeta(set ''); - if ($cont_stripped =~ m/^$name(\d+)\s/) { $killBar{$1} = 1; } - Irssi::signal_stop; - } - } - sub killOldStatus { - %killBar = (); - Irssi::signal_add_first('print text' => 'get_old_status'); - Irssi::command('statusbar'); - Irssi::signal_remove('print text' => 'get_old_status'); - remove_statusbar(keys %killBar); - } -} - -sub _add_map { - my ($type, $target, $map) = @_; - ($type->{$target}) = sort { length $a <=> length $b || $a cmp $b } - $map, exists $type->{$target} ? $type->{$target} : (); -} - -sub get_keymap { - my ($textDest, undef, $cont_stripped) = @_; - if ($textDest->{level} == 524288 and $textDest->{target} eq '' and !defined $textDest->{server}) { - my $one_meta_or_ctrl_key = qr/((?:meta-)*?)(?:(meta-|\^)(\S)|(\w+))/; - $cont_stripped = as_uni($cont_stripped); - if ($cont_stripped =~ m/((?:$one_meta_or_ctrl_key-)*$one_meta_or_ctrl_key)\s+(.*)$/) { - my ($combo, $command) = ($1, $10); - my $map = ''; - while ($combo =~ s/(?:-|^)$one_meta_or_ctrl_key$//) { - my ($level, $ctl, $key, $nkey) = ($1, $2, $3, $4); - my $numlevel = ($level =~ y/-//); - $ctl = '' if !$ctl || $ctl ne '^'; - $map = ('-' x ($numlevel%2)) . ('+' x ($numlevel/2)) . - $ctl . (defined $key ? $key : "\01$nkey\01") . $map; - } - for ($command) { - last unless length $map; - if (/^change_window (\d+)/i) { - _add_map(\%nummap, $1, $map); - } - elsif (/^(?:command window goto|change_window) (\S+)/i) { - my $window = $1; - if ($window !~ /\D/) { - _add_map(\%nummap, $window, $map); - } - elsif (lc $window eq 'active') { - _add_map(\%specialmap, '_active', $map); - } - else { - _add_map(\%wnmap, $window, $map); - } - } - elsif (/^(?:active_window|command ((awl )?ack))/i) { - _add_map(\%specialmap, '_active', $map); - $viewer{use_ack} = $1; - } - elsif (/^command window last/i) { - _add_map(\%specialmap, '_last', $map); - } - elsif (/^(?:upper_window|command window up)/i) { - _add_map(\%specialmap, '_up', $map); - } - elsif (/^(?:lower_window|command window down)/i) { - _add_map(\%specialmap, '_down', $map); - } - elsif (/^key\s+(\w+)/i) { - $custom_key_map{$1} = $map; - } - } - } - Irssi::signal_stop; - } -} - -sub update_keymap { - %nummap = %wnmap = %specialmap = %custom_key_map = (); - Irssi::signal_remove('command bind' => 'watch_keymap'); - Irssi::signal_add_first('print text' => 'get_keymap'); - Irssi::command('bind'); - Irssi::signal_remove('print text' => 'get_keymap'); - for (keys %custom_key_map) { - if (exists $custom_key_map{$_} && - $custom_key_map{$_} =~ s/\01(\w+)\01/exists $custom_key_map{$1} ? $custom_key_map{$1} : "\02"/ge) { - if ($custom_key_map{$_} =~ /\02/) { - delete $custom_key_map{$_}; - } - else { - redo; - } - } - } - for my $keymap (\(%specialmap, %wnmap, %nummap)) { - for (keys %$keymap) { - if ($keymap->{$_} =~ s/\01(\w+)\01/exists $custom_key_map{$1} ? $custom_key_map{$1} : "\02"/ge) { - if ($keymap->{$_} =~ /\02/) { - delete $keymap->{$_}; - } - } - } - } - Irssi::signal_add('command bind' => 'watch_keymap'); - delete $viewer{client_keymap}; - &wl_changed; -} - -# watch keymap changes -sub watch_keymap { - Irssi::timeout_add_once(1000, 'update_keymap', undef); -} - -{ my %strip_table = ( - # fe-common::core::formats.c:format_expand_styles - # delete format_backs format_fores bold_fores other stuff - (map { $_ => '' } (split //, '04261537' . 'kbgcrmyw' . 'KBGCRMYW' . 'U9_8I:|FnN>#[' . 'pP')), - # escape - (map { $_ => $_ } (split //, '{}%')), - ); - sub ir_strip_codes { # strip %codes - my $o = shift; - $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; - $o - } -} -## ir_parse_special -- wrapper around parse_special -## $i - input format -## $args - array ref of arguments to format -## $win - different target window (default current window) -## $flags - different kind of escape flags (default 4|8) -## returns formatted str -sub ir_parse_special { - my $o; - my $i = shift; - my $args = shift // []; - y/ /\177/ for @$args; # hack to escape spaces - my $win = shift || Irssi::active_win; - my $flags = shift // 0x4|0x8; - my @cmd_args = ($i, (join ' ', @$args), $flags); - my $server = Irssi::active_server(); - if (ref $win and ref $win->{active}) { - $o = $win->{active}->parse_special(@cmd_args); - } - elsif (ref $win and ref $win->{active_server}) { - $o = $win->{active_server}->parse_special(@cmd_args); - } - elsif (ref $server) { - $o = $server->parse_special(@cmd_args); - } - else { - $o = &Irssi::parse_special(@cmd_args); - } - $o =~ y/\177/ /; - $o -} - -sub sb_format_expand { # Irssi::current_theme->format_expand wrapper - Irssi::current_theme->format_expand( - $_[0], - ( - Irssi::EXPAND_FLAG_IGNORE_REPLACES - | - ($_[1] ? 0 : Irssi::EXPAND_FLAG_IGNORE_EMPTY) - ) - ) -} - -{ my $term_type = Irssi::version > 20040819 ? 'term_charset' : 'term_type'; - if (Irssi->can('string_width')) { - *screen_length = sub { Irssi::string_width($_[0]) }; - } - else { - local $@; - eval { require Text::CharWidth; }; - unless ($@) { - *screen_length = sub { Text::CharWidth::mbswidth($_[0]) }; - } - else { - my $err = $@; chomp $err; $err =~ s/\sat .* line \d+\.$//; - #Irssi::print("%_$IRSSI{name}: warning:%_ Text::CharWidth module failed to load. Length calculation may be off! Error was:"); - print "%_$IRSSI{name}:%_ $err"; - *screen_length = sub { - my $temp = shift; - if (lc Irssi::settings_get_str($term_type) eq 'utf-8') { - Encode::_utf8_on($temp); - } - length($temp) - }; - } - } - sub as_uni { - no warnings 'utf8'; - Encode::decode(Irssi::settings_get_str($term_type), $_[0], 0) - } - sub as_tc { - Encode::encode(Irssi::settings_get_str($term_type), $_[0], 0) - } -} - -sub sb_length { - screen_length(ir_strip_codes($_[0])) -} - -sub run_custom_xform { - local $@; - eval { - $custom_xform->() - }; - if ($@) { - $@ =~ /^(.*)/; - print '%_'.(set 'custom_xform').'%_ died (disabling): '.$1; - $custom_xform = undef; - } -} - -sub remove_uniform { - my $o = shift; - $o =~ s/^xmpp:(.*?[%@]).+\.[^.]+$/$1/ or - $o =~ s#^psyc://.+\.[^.]+/([@~].*)$#$1#; - if ($custom_xform) { - run_custom_xform() for $o; - } - $o -} - -sub remove_uniform_vars { - my $win = shift; - my $name = __PACKAGE__ . '::custom_xform::' . $win->{active}{type} - if ref $win->{active} && $win->{active}{type}; - no strict 'refs'; - local ${$name} = 1 if $name; - remove_uniform(+shift); -} - -sub lc1459 { - my $x = shift; - $x =~ y/][\\^/}{|~/; - lc $x -} - -sub window_list { - my $i = 0; - map { $_->[1] } sort $window_sort_func map { [ $i++, $_ ] } Irssi::windows; -} - -sub _calculate_abbrev { - my ($wins, $abbrevList) = @_; - if ($S{fancy_abbrev} !~ /^(no|off|head)/i) { - my @nameList = map { ref $_ ? remove_uniform_vars($_, as_uni($_->get_active_name) // '') : '' } @$wins; - for (my $i = 0; $i < @nameList - 1; ++$i) { - my ($x, $y) = ($nameList[$i], $nameList[$i + 1]); - s/^[+#!=]// for $x, $y; - my $res = exists $abbrev_cache{$x}{$y} ? $abbrev_cache{$x}{$y} - : $abbrev_cache{$x}{$y} = string_LCSS($x, $y); - if (defined $res) { - for ($nameList[$i], $nameList[$i + 1]) { - $abbrevList->{$_} //= int((index $_, $res) + (length $res) / 2); - } - } - } - } -} - -my %act_last_line_shades = ( - r => [qw[ 50 40 30 20 ]], - g => [qw[ 1O 1I 1C 16 ]], - y => [qw[ 5O 4I 3C 26 ]], - b => [qw[ 15 14 13 12 ]], - m => [qw[ 54 43 32 21 ]], - c => [qw[ 1S 1L 1E 17 ]], - w => [qw[ 7W 7T 7Q 3E ]], - K => [qw[ 7M 7K 27 7H ]], - R => [qw[ 60 50 40 30 ]], - G => [qw[ 1U 1O 1I 1C ]], - Y => [qw[ 6U 5O 4I 3C ]], - B => [qw[ 2B 2A 29 28 ]], - M => [qw[ 65 54 43 32 ]], - C => [qw[ 1Z 1S 1L 1E ]], - W => [qw[ 6Z 5S 7R 7O ]], - ); - -sub _format_display { - my (undef, $format, $cformat, $hilight, $name, $number, $key, $win) = @_; - if ($print_text_activity && $S{line_shade}) { - my @hilight_code = split /\177/, sb_format_expand("{$hilight \177}"), 2; - my $max_time = max(1, log($S{line_shade}) - log(1000)); - my $time_delta = min(3, min($max_time, log(max(1, time - $win->{last_line}))) / $max_time * 3); - if ($hilight_code[0] =~ /%(.)/ && exists $act_last_line_shades{$1}) { - $hilight = 'sb_act_hilight_color %X'.$act_last_line_shades{$1}[$time_delta]; - } - } - $cformat = '$0' unless length $cformat; - my %map = ('$C' => $cformat, '$N' => '$1', '$Q' => '$2'); - $format =~ s<(\$.)><$map{$1}//$1>ge; - $format =~ s<\$H((?:\$.|[^\$])*?)\$S><{$hilight $1%n}>g; - my @ret = ir_parse_special(sb_format_expand($format), [$name, $number, $key], $win); - @ret -} - -sub _get_format { - Irssi::current_theme->get_format(__PACKAGE__, @_) -} - -sub _is_detached { - my ($win, $active_number) = @_; - my $level = $win->{data_level} // 0; - my $number = $win->{refnum}; - my $name = lc1459( as_uni($win->{name}) ); - my $active = lc1459( as_uni($win->get_active_name) // '' ); - my $tag = $win->{active} && $win->{active}{server} ? lc1459( as_uni($win->{active}{server}{tag}) // '' ) : ''; - my @cond = ($number); - push @cond, "$name" if length $name; - push @cond, "$tag/$active" if length $tag && length $active; - push @cond, "$active" if length $active; - push @cond, "$tag/*", "$tag/::all" if length $tag; - push @cond, "*", "::all"; - for my $cond (@cond) { - if (exists $detach_map{ $cond }) { - my $dd = $detach_map{ $cond } // $S{detach_data}; - return $win->{data_level} < abs $dd - && ($number != $active_number || 0 <= $dd); - } - } - return; -} - -sub _calculate_items { - my ($wins, $abbrevList) = @_; - - my $display_header = _get_format(set 'display_header'); - my $name_format = _get_format(set 'name_display'); - my $abbrev_chars = as_uni(_get_format(set 'abbrev_chars')); - - my %displays; - - my $active = Irssi::active_win; - @win_items = (); - %keymap = (%nummap, %wnmap_exp); - - my ($numPad, $keyPad) = (0, 0); - if ($VIEWER_MODE or $S{block} < 0) { - $numPad = length((sort { length $b <=> length $a } keys %keymap)[0]) // 0; - $keyPad = length((sort { length $b <=> length $a } values %keymap)[0]) // 0; - } - my $last_net; - my ($abbrev1, $abbrev2) = $abbrev_chars =~ /(\X)(.*)/; - my @abbrev_chars = ('~', "\x{301c}"); - unless (defined $abbrev1 && screen_length(as_tc($abbrev1)) == 1) { $abbrev1 = $abbrev_chars[0] } - unless (length $abbrev2) { - $abbrev2 = $abbrev1; - if ($abbrev1 eq $abbrev_chars[0]) { - $abbrev2 = $abbrev_chars[1]; - } - else { - $abbrev2 = $abbrev1; - } - } - if (screen_length(as_tc($abbrev2)) == 1) { - $abbrev2 x= 2; - } - while (screen_length(as_tc($abbrev2)) > 2) { - chop $abbrev2; - } - unless (screen_length(as_tc($abbrev2)) == 2) { - $abbrev2 = $abbrev_chars[1]; - } - for my $win (@$wins) { - my $global_tag_header_mode; - - next unless ref $win; - - my $backup_win = Storable::dclone($win); - delete $backup_win->{active} unless ref $backup_win->{active}; - - $global_tag_header_mode = - $display_header && ($last_net // '') ne ($backup_win->{active}{server}{tag} // ''); - - if ($win->{data_level} < abs $S{hide_data} - && ($win->{refnum} != $active->{refnum} || 0 <= $S{hide_data})) { - next; } - elsif (exists $awins{$win->{refnum}} && $S{hide_empty} && !$win->items - && ($win->{refnum} != $active->{refnum} || 0 <= $S{hide_empty})) { - next; } - elsif (_is_detached($win, $active->{refnum})) { - next; } - - my $colour = $win->{hilight_color} // ''; - my $hilight = do { - if ($win->{data_level} == 0) { 'sb_act_none'; } - elsif ($win->{data_level} == 1) { 'sb_act_text'; } - elsif ($win->{data_level} == 2) { 'sb_act_msg'; } - elsif ($colour ne '') { "sb_act_hilight_color $colour"; } - elsif ($win->{data_level} == 3) { 'sb_act_hilight'; } - else { 'sb_act_special'; } - }; - my $number = $win->{refnum}; - - my ($name, $display, $cdisplay); - if ($global_tag_header_mode) { - $display = $display_header; - $name = as_uni($backup_win->{active}{server}{tag}) // ''; - if ($custom_xform) { - no strict 'refs'; - local ${ __PACKAGE__ . '::custom_xform::TAG' } = 1; - run_custom_xform() for $name; - } - } - else { - my @display = ('display_nokey'); - if (defined $keymap{$number} and $keymap{$number} ne '') { - unshift @display, map { (my $cpy = $_) =~ s/_no/_/; $cpy } @display; - } - if (exists $awins{$number}) { - unshift @display, map { my $cpy = $_; $cpy .= '_visible'; $cpy } @display; - } - if ($active->{refnum} == $number) { - unshift @display, map { my $cpy = $_; $cpy .= '_active'; $cpy } - grep { !/_visible$/ } @display; - } - $display = (grep { length $_ } - map { $displays{$_} //= _get_format(set $_) } - @display)[0]; - $cdisplay = $name_format; - $name = as_uni($win->get_active_name) // ''; - $name = '*' if $S{banned_on} and exists $banned_channels{lc1459($name)}; - $name = remove_uniform_vars($win, $name) if $name ne '*'; - if ($name ne '*' and $win->{name} ne '' and $S{prefer_name}) { - $name = as_uni($win->{name}); - if ($custom_xform) { - no strict 'refs'; - local ${ __PACKAGE__ . '::custom_xform::NAME' } = 1; - run_custom_xform() for $name; - } - } - - if (!$VIEWER_MODE && $S{block} >= 0 && $S{hide_name} - && $win->{data_level} < abs $S{hide_name} - && ($win->{refnum} != $active->{refnum} || 0 <= $S{hide_name})) { - $name = ''; - $cdisplay = ''; - } - } - - $display = "$display%n"; - my $num_ent = (' 'x max(0,$numPad - length $number)) . $number; - my $key_ent = exists $keymap{$number} ? ((' 'x max(0,$keyPad - length $keymap{$number})) . $keymap{$number}) : ' 'x$keyPad; - if ($VIEWER_MODE or $S{sbar_maxlen} or $S{block} < 0) { - my $baseLength = sb_length(_format_display( - '', $display, $cdisplay, $hilight, - 'x', # placeholder - $num_ent, - $key_ent, - $win)) - 1; - my $diff = (abs $S{block}) - (screen_length(as_tc($name)) + $baseLength); - if ($diff < 0) { # too long - my $screen_length = screen_length(as_tc($name)); - if ((abs $diff) >= $screen_length) { $name = '' } # forget it - elsif ((abs $diff) + screen_length(as_tc(substr($name, 0, 1))) >= $screen_length) { $name = substr($name, 0, 1); } - else { - my $ulen = length $name; - my $middle2 = exists $abbrevList->{$name} ? - ($S{fancy_strict}) ? - 2* $abbrevList->{$name} : - (2*($abbrevList->{$name} + $ulen) / 3) : - ($S{fancy_head}) ? - 2*$ulen : - $ulen; - my $first = 1; - while (length $name > 1) { - my $cp = $middle2 >= 0 ? $middle2/2 : -1; # clearing position - my $rm = 2; - # if character at end is wider than 1 cell -> replace it with ~ - if (screen_length(as_tc(substr $name, $cp, 1)) > 1) { - if ($first || $cp < 0) { - $rm = 1; - $first = undef; - } - } - elsif ($cp < 0) { # elsif at end -> replace last 2 characters - --$cp; - } - (substr $name, $cp, $rm) = $abbrev1; - if ($cp > -1 && $rm > 1) { - --$middle2; - } - my $sl = screen_length(as_tc($name)); - if ($sl + $baseLength < abs $S{block}) { - (substr $name, ($middle2+1)/2, 1) = $abbrev2; - last; - } - elsif ($sl + $baseLength == abs $S{block}) { - last; - } - } - } - } - elsif ($VIEWER_MODE or $S{block} < 0) { - $name .= (' ' x $diff); - } - } - - push @win_items, _format_display( - '', $display, $cdisplay, $hilight, - as_tc($name), - $num_ent, - as_tc($key_ent), - $win); - - if ($global_tag_header_mode) { - $last_net = $backup_win->{active}{server}{tag}; - redo; - } - - $mouse_coords{refnum}{$#win_items} = $number; - } -} - -sub _spread_items { - my $width = $screenWidth - $sb_base_width - 1; - my @separator = _get_format(set 'separator'); - if ($S{block} >= 0) { - my $sep2 = _get_format(set 'separator2'); - push @separator, $sep2 if length $sep2 && $sep2 ne $separator[0]; - } - $separator[0] .= '%n'; - my @sepLen = map { sb_length($_) } @separator; - - @actString = (); - my $curLine; - my $curLen = 0; - if ($S{shared_sbar}) { - $curLen += $S{shared_sbar}[0] + 2; - $width -= $S{shared_sbar}[2]; - } - my $mouse_header_check = 0; - for my $it (@win_items) { - my $itemLen = sb_length($it); - if ($curLen) { - if ($curLen + $itemLen + $sepLen[$mouse_header_check % @sepLen] > $width) { - $width += $S{shared_sbar}[2] - if !@actString && $S{shared_sbar}; - push @actString, $curLine; - $curLine = undef; - $curLen = 0; - } - elsif (defined $curLine) { - $curLine .= $separator[$mouse_header_check % @separator]; - $curLen += $sepLen[$mouse_header_check % @sepLen]; - } - } - $curLine .= $it; - if (exists $mouse_coords{refnum}{$mouse_header_check}) { - $mouse_coords{scalar @actString}{ $_ } = $mouse_coords{refnum}{$mouse_header_check} - for $curLen .. $curLen + $itemLen - 1; - } - $curLen += $itemLen; - } - continue { - ++$mouse_header_check; - } - $curLen -= $S{shared_sbar}[0] - if !@actString && $S{shared_sbar}; - push @actString, $curLine if $curLen; -} - -sub remake { - my %abbrevList; - my @wins = window_list(); - if ($VIEWER_MODE or $S{sbar_maxlen} or $S{block} < 0) { - _calculate_abbrev(\@wins, \%abbrevList); - } - - %mouse_coords = ( refnum => +{} ); - _calculate_items(\@wins, \%abbrevList); - - unless ($VIEWER_MODE) { - _spread_items(); - - push @actString, undef unless @actString || $S{all_disable}; - } -} - -sub update_wl { - return if $BLOCK_ALL; - remake(); - - Irssi::statusbar_items_redraw(set $_) for keys %statusbars; - - unless ($VIEWER_MODE) { - Irssi::timeout_add_once(100, 'syncLines', undef); - } - else { - syncViewer(); - } -} - -sub screenFullRedraw { - my ($window) = @_; - if (!ref $window or $window->{refnum} == Irssi::active_win->{refnum}) { - $viewer{fullRedraw} = 1 if $viewer{client}; - $settings_str = ''; - &setup_changed; - } -} - -sub restartViewerServer { - if ($VIEWER_MODE) { - stop_viewer(); - start_viewer(); - } -} - -sub _simple_quote { - my @r = map { - my $x = $_; - $x =~ s/'/'"'"'/g; - $x = "'$x'"; - } @_; - wantarray ? @r : shift @r -} - -sub _viewer_command_replace_format { - my ($ecmd, @args) = @_; - my $file = _simple_quote(SCRIPT_FILE()); - my $path = _simple_quote($viewer{path}); - my @env; - for my $env (shellwords($S{viewer_launch_env})) { - if ($env =~ /^(\w+)(?:=(.*))$/) { - push @env, "AWL_$1=$2" - } - } - my $cmd = join ' ', - (@env ? ('env', _simple_quote(@env)) : ()), - 'perl', $file, '-1', _simple_quote(@args), $path; - $ecmd =~ s{%(%|\w+)}{ - my $sub = $1; - if ($sub eq '%') { - '%' - } - elsif ($sub =~ /^(q*)A(.*)/) { - my $ret = $cmd; - for (1..length $1) { - $ret = _simple_quote($ret); - } - "$ret$2" - } - else { - "%$sub" - } - }gex; - $ecmd -} - -sub start_viewer { - unlink $viewer{path} if -S $viewer{path} || -p _; - - $viewer{server} = IO::Socket::UNIX->new( - Type => SOCK_STREAM, - Local => $viewer{path}, - Listen => 1 - ); - unless ($viewer{server}) { - $viewer{msg} = "Viewer: $!"; - $viewer{retry} = Irssi::timeout_add_once(5000, 'retry_viewer', 1); - return; - } - $viewer{server}->blocking(0); - set_viewer_mode_hint(); - $viewer{server_tag} = Irssi::input_add($viewer{server}->fileno, INPUT_READ, 'vi_connected', undef); - - if ($S{viewer_launch}) { - if (length $ENV{TMUX_PANE} && length $ENV{TMUX} && lc $S{viewer_tmux_position} ne 'custom') { - my $cmd = _viewer_command_replace_format('%qA', '-p', lc $S{viewer_tmux_position}); - Irssi::command("exec - tmux neww -d $cmd 2>&1 &"); - } - elsif (length $ENV{WINDOWID} && length $ENV{DISPLAY} && length $S{viewer_xwin_command} && $S{viewer_xwin_command} =~ /\S/) { - my $cmd = _viewer_command_replace_format($S{viewer_xwin_command}); - Irssi::command("exec - $cmd 2>&1 &"); - } - elsif (length $S{viewer_custom_command} && $S{viewer_custom_command} =~ /\S/) { - my $cmd = _viewer_command_replace_format($S{viewer_custom_command}); - Irssi::command("exec - $cmd 2>&1 &"); - } - } -} - -sub set_viewer_mode_hint { - return unless $viewer{server}; - if ($S{no_mode_hint}) { - $viewer{msg} = undef; - } - else { - my ($name) = __PACKAGE__ =~ /::([^:]+)$/; - $viewer{msg} = "Run $name from the shell or switch to sbar mode"; - } -} - -sub retry_viewer { - start_viewer(); -} - -sub vi_close_client { - Irssi::input_remove(delete $viewer{client_tag}) if exists $viewer{client_tag}; - $viewer{client}->close if $viewer{client}; - delete $viewer{client}; - delete $viewer{client_keymap}; - delete $viewer{client_settings}; - delete $viewer{client_env}; - delete $viewer{fullRedraw}; -} - -sub vi_connected { - vi_close_client(); - $viewer{client} = $viewer{server}->accept or return; - $viewer{client}->blocking(0); - $viewer{client_tag} = Irssi::input_add($viewer{client}->fileno, INPUT_READ, 'vi_clientinput', undef); - syncViewer(); -} - -use constant VIEWER_BLOCK_SIZE => 1024; -sub vi_clientinput { - if ($viewer{client}->read(my $buf, VIEWER_BLOCK_SIZE)) { - $viewer{rcvbuf} .= $buf; - if ($viewer{rcvbuf} =~ s/^(?:(active|\d+)|(last|up|down))\n//igm) { - if (defined $2) { - Irssi::command("window $2"); - } - elsif (lc $1 eq 'active' && $viewer{use_ack}) { - Irssi::command($viewer{use_ack}); - } - else { - Irssi::command("window goto $1"); - } - } - } - else { - vi_close_client(); - Irssi::timeout_add_once(100, 'syncViewer', undef); - } -} - -sub stop_viewer { - Irssi::timeout_remove(delete $viewer{retry}) if exists $viewer{retry}; - vi_close_client(); - Irssi::input_remove(delete $viewer{server_tag}) if exists $viewer{server_tag}; - return unless $viewer{server}; - $viewer{server}->close; - delete $viewer{server}; -} -sub _encode_var { - my $str; - while (@_) { - my ($name, $var) = splice @_, 0, 2; - my $type = ref $var ? $var =~ /HASH/ ? 'map' : $var =~ /ARRAY/ ? 'list' : '' : ''; - $str .= "\n\U$name$type\_begin\n"; - if ($type eq 'map') { - no warnings 'numeric'; - $str .= " $_\n ${$var}{$_}\n" for sort { $a <=> $b || $a cmp $b } keys %$var; - } - elsif ($type eq 'list') { - $str .= " $_\n" for @$var; - } - else { - $str .= " $var\n"; - } - $str .= "\U$name$type\_end\n"; - } - $str -} -sub syncViewer { - if ($viewer{client}) { - @actString = (); - if ($currentLines) { - killOldStatus(); - $currentLines = 0; - } - my $str; - unless ($viewer{client_keymap}) { - $str .= _encode_var('key', +{ %nummap, %specialmap }); - $viewer{client_keymap} = 1; - } - unless ($viewer{client_settings}) { - $str .= _encode_var( - block => $S{block}, - ha => $S{height_adjust}, - mc => $S{maxcolumns}, - ml => $S{maxlines}, - tc => $S{true_colour}, - ); - $viewer{client_settings} = 1; - } - unless ($viewer{client_env}) { - $str .= _encode_var(irssienv => +{ - length $ENV{TMUX_PANE} && length $ENV{TMUX} ? - (tmux_pane => $ENV{TMUX_PANE}, - tmux_srv => $ENV{TMUX}) : (), - length $ENV{WINDOWID} ? - (xwinid => $ENV{WINDOWID}) : (), - }); - $viewer{client_env} = 1; - } - my $separator = _get_format(set 'separator'); - my $sepLen = sb_length($separator); - my $item_bg = _get_format(set 'viewer_item_bg'); - my $title = _get_format(set 'title'); - if (length $title) { - $title =~ s{\\(.)|(.)}{ - defined $2 ? quotemeta $2 - : $1 eq 'V' ? '\U' - : $1 eq ':' ? quotemeta '%N' - : $1 =~ /^[uUFQE]$/ ? "\\$1" - : quotemeta "\\$1" - }sge; - $title = eval qq{"$title"}; - } - $str .= _encode_var(redraw => 1) if delete $viewer{fullRedraw}; - $str .= _encode_var(separator => $separator, - seplen => $sepLen, - itembg => $item_bg, - title => $title, - mouse => $mouse_coords{refnum}, - key2 => \%wnmap_exp, - win => \@win_items); - - my $was = $viewer{client}->blocking(1); - $viewer{client}->print($str); - $viewer{client}->blocking($was); - } - elsif ($viewer{server}) { - if (defined $viewer{msg}) { - @actString = ((uc setc()).": $viewer{msg}"); - } - else { - @actString = (); - } - } - elsif (defined $viewer{msg}) { - @actString = ((uc setc()).": $viewer{msg}"); - } - if (@actString) { - Irssi::timeout_add_once(100, 'syncLines', undef); - } - elsif ($currentLines) { - killOldStatus(); - $currentLines = 0; - } -} - -sub reset_awl { - Irssi::timeout_remove($shade_line_timer) if $shade_line_timer; $shade_line_timer = undef; - my $was_sort = $S{sort} // ''; - my $was_xform = $S{xform} // ''; - my $was_shared = $S{shared_sbar}; - my $was_no_hint = $S{no_mode_hint}; - %S = ( - sort => Irssi::settings_get_str( set 'sort'), - fancy_abbrev => Irssi::settings_get_str('fancy_abbrev'), - xform => Irssi::settings_get_str( set 'custom_xform'), - block => Irssi::settings_get_int( set 'block'), - banned_on => Irssi::settings_get_bool('banned_channels_on'), - prefer_name => Irssi::settings_get_bool(set 'prefer_name'), - hide_data => Irssi::settings_get_int( set 'hide_data'), - hide_name => Irssi::settings_get_int( set 'hide_name_data'), - hide_empty => Irssi::settings_get_int( set 'hide_empty'), - detach => Irssi::settings_get_str( set 'detach'), - detach_data => Irssi::settings_get_int( set 'detach_data'), - detach_aht => Irssi::settings_get_bool(set 'detach_aht'), - sbar_maxlen => Irssi::settings_get_bool(set 'sbar_maxlength'), - placement => Irssi::settings_get_str( set 'placement'), - position => Irssi::settings_get_int( set 'position'), - maxlines => Irssi::settings_get_int( set 'maxlines'), - maxcolumns => Irssi::settings_get_int( set 'maxcolumns'), - all_disable => Irssi::settings_get_bool(set 'all_disable'), - height_adjust => Irssi::settings_get_int( set 'height_adjust'), - mouse_offset => Irssi::settings_get_int( set 'mouse_offset'), - mouse_scroll => Irssi::settings_get_int( 'mouse_scroll'), - mouse_escape => Irssi::settings_get_int( 'mouse_escape'), - line_shade => Irssi::settings_get_time(set 'last_line_shade'), - no_mode_hint => Irssi::settings_get_bool(set 'no_mode_hint'), - true_colour => Irssi::parse_special('$colors_ansi_24bit'), - viewer_launch => Irssi::settings_get_bool(set 'viewer_launch'), - viewer_launch_env => Irssi::settings_get_str(set 'viewer_launch_env'), - viewer_xwin_command => Irssi::settings_get_str(set 'viewer_xwin_command'), - viewer_custom_command => Irssi::settings_get_str(set 'viewer_custom_command'), - viewer_tmux_position => Irssi::settings_get_str(set 'viewer_tmux_position'), - ); - $S{fancy_strict} = $S{fancy_abbrev} =~ /^strict/i; - $S{fancy_head} = $S{fancy_abbrev} =~ /^head/i; - my $shared = Irssi::settings_get_str(set 'shared_sbar'); - if ($shared =~ /^(\d+)([<])(\d+)$/) { - $S{shared_sbar} = [$1, $2, $3]; - } - else { - Irssi::settings_set_str(set 'shared_sbar', 'OFF'); - $S{shared_sbar} = undef; - } - lock_keys(%S); - if ($was_sort ne $S{sort}) { - $print_text_activity = undef; - my @sort_order = grep { @$_ > 4 } map { - s/^\s*//; - my $reverse = s/^\W*\K[-!]//; - my $undef_check = s/^\W*\K~// ? 1 : undef; - my $equal_check = s/=(.*)\s?$// ? $1 : undef; - s/\s*$//; - my $ignore_case = s/#i$// ? 1 : undef; - - $print_text_activity = 1 if $_ eq 'last_line'; - - my @path = split '/'; - my $class_check = @path && $path[-1] =~ s/(::.*)$// ? $1 : undef; - my $lru = "@path" eq 'lru'; - - [ $reverse ? -1 : 1, $undef_check, $equal_check, $class_check, $ignore_case, $lru, @path ] - } "$S{sort}," =~ /([^+,]*|[^+,]*=[^,]*?\s(?=\+)|[^+,]*=[^,]*)[+,]/g; - $window_sort_func = sub { - no warnings qw(numeric uninitialized); - for my $so (@sort_order) { - my @x = map { - my $ret = 0; - $_ = lc1459($_) if defined $_ && !ref $_ && $so->[4]; - $ret = $_ eq ($so->[4] ? lc1459($so->[2]) : $so->[2]) ? 1 : -1 if defined $so->[2]; - $ret = defined $_ ? ($ret || -3) : 3 if $so->[1]; - $ret = ref $_ && $_->isa('Irssi'.$so->[3]) ? 2 : ($ret || -2) if $so->[3]; - -$ret || $_ - } - map { - $so->[5] ? $_->[0] : reduce { return unless ref $a; $a->{$b} } $_->[1], @{$so}[6..$#$so] - } $a, $b; - return ((($x[0] <=> $x[1] || $x[0] cmp $x[1]) * $so->[0]) || next); - } - return ($a->[1]{refnum} <=> $b->[1]{refnum}); - }; - } - if ($was_xform ne $S{xform}) { - if ($S{xform} !~ /\S/) { - $custom_xform = undef; - } - else { - my $script_pkg = __PACKAGE__ . '::custom_xform'; - local $@; - $custom_xform = eval qq{ -package $script_pkg; -use strict; -no warnings; -our (\$QUERY, \$CHANNEL, \$TAG, \$NAME); -return sub { -# line 1 @{[ set 'custom_xform' ]}\n$S{xform}\n}}; - if ($@) { - $@ =~ /^(.*)/; - print '%_'.(set 'custom_xform').'%_ did not compile: '.$1; - } - } - } - - my $new_settings = join "\n", $VIEWER_MODE - ? ("\\", $S{block}, $S{height_adjust}, $S{maxlines}, $S{maxcolumns}, $S{true_colour}) - : ("!", $S{placement}, $S{position}); - - my $first_viewer = $settings_str eq '1'; - if ($settings_str ne $new_settings) { - @actString = (); - %abbrev_cache = (); - $currentLines = 0; - killOldStatus(); - delete $viewer{client_settings}; - $settings_str = $new_settings; - } - - my $was_mouse_mode = $MOUSE_ON; - if ($MOUSE_ON = Irssi::settings_get_bool(set 'mouse') and !$was_mouse_mode) { - install_mouse(); - } - elsif ($was_mouse_mode and !$MOUSE_ON) { - uninstall_mouse(); - } - - unless ($first_viewer) { - my $path = Irssi::settings_get_str(set 'path'); - my $was_viewer_mode = $VIEWER_MODE; - if ($was_viewer_mode && - defined $viewer{path} && $viewer{path} ne $path) { - stop_viewer(); - $was_viewer_mode = 0; - } - elsif ($was_viewer_mode && $S{no_mode_hint} != $was_no_hint + 0) { - set_viewer_mode_hint(); - } - $viewer{path} = $path; - if ($VIEWER_MODE = Irssi::settings_get_bool(set 'viewer') and !$was_viewer_mode) { - start_viewer(); - } - elsif ($was_viewer_mode and !$VIEWER_MODE) { - stop_viewer(); - } - } - - %banned_channels = map { lc1459(as_uni($_)) => undef } - split ' ', Irssi::settings_get_str('banned_channels'); - - %detach_map = ($S{detach_aht} - ? (map { ( lc1459(as_uni($_)) => undef ) } - split ' ', Irssi::settings_get_str('activity_hide_targets')) : (), - (map { my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; - ( lc1459(as_uni($k)) => $v ) } - split ' ', $S{detach})); - - my @sb_base = split /\177/, sb_format_expand("{sbstart}{sb_awl \177}{sbend}"), 2; - $sb_base_width_pre = sb_length($sb_base[0]); - $sb_base_width_post = max 0, sb_length($sb_base[1])-1; - $sb_base_width = $sb_base_width_pre + $sb_base_width_post; - - if ($print_text_activity && $S{line_shade}) { - $shade_line_timer = Irssi::timeout_add(max(10 * GLOB_QUEUE_TIMER, 100*$S{line_shade}**(1/3)), 'wl_changed', undef); - } - - $CHANGED{AWINS} = 1; -} - -sub hide_window { - my ($data) = @_; - my $ent; - - $data =~ s/\s*$//; - my $win = Irssi::active_win; - my $number = $win->{refnum}; - my $name = as_uni($win->{name}); - my $active = as_uni($win->get_active_name) // ''; - my $tag = $win->{active} && $win->{active}{server} ? as_uni($win->{active}{server}{tag}) // '' : ''; - if (length $name) { - $ent = "$name"; - } - elsif (length $tag && length $active) { - $ent = "$tag/$active"; - } - else { - $ent = "$number"; - } - - my $found = 0; - my @setting; - for my $s (split ' ', $S{detach}) { - my ($k, $v) = (split /(?:,(-?\d+))$/, $s)[0, 1]; - if (lc1459(as_uni($k)) eq lc1459($ent)) { - unless ($found) { - if ($data =~ /^(-?\d+)$/) { - $ent .= ",$1"; - } - if (defined $v && 0 == abs $v) { - $win->print("Hiding window $ent"); - } - push @setting, as_tc($ent); - $found = 1; - } - } - else { - push @setting, defined $v ? "$k,$v" : $k; - } - } - unless ($found) { - $win->print("Hiding window $ent"); - if ($data =~ /^(-?\d+)$/) { - $ent .= ",$1"; - } - push @setting, as_tc($ent); - } - - if (@setting) { - Irssi::command("^set ".(set 'detach')." @setting"); - } else { - Irssi::command("^set -clear ".(set 'detach')); - } -} - -sub unhide_window { - my ($data, $server, $witem) = @_; - my $win = Irssi::active_win; - my $number = $win->{refnum}; - my $name = as_uni($win->{name}); - my $active = as_uni($win->get_active_name) // ''; - my $tag = $win->{active} && $win->{active}{server} ? as_uni($win->{active}{server}{tag}) // '' : ''; - - my %detach_aht; - if ($S{detach_aht}) { - %detach_aht = (map { ( lc1459(as_uni($_)) => undef ) } - split ' ', Irssi::settings_get_str('activity_hide_targets')); - } - my @setting; - my @kills = (length $name ? $name : undef, - length $tag && length $active ? "$tag/$active" : undef, - length $active ? $active : undef, - $number); - my @was_unhidden = (0) x @kills; - for my $s (split ' ', $S{detach}) { - my ($k, $v) = (split /(?:,(-?\d+))$/, $s)[0, 1]; - my $k2 = lc1459(as_uni($k)); - my $kill; - for my $ki (0..$#kills) { - if (defined $kills[$ki] && $k2 eq lc1459($kills[$ki])) { - $kill = $ki; - } - } - - if (defined $kill) { - if (defined $v && 0 == abs $v) { - $was_unhidden[$kill] = 1; - push @setting, defined $v ? "$k,$v" : $k; - } else { - $win->print("Unhiding window $kills[$kill]"); - } - } - else { - push @setting, defined $v ? "$k,$v" : $k; - } - } - my @is_hidden = (defined $kills[0] && (exists $detach_map{"*"} || exists $detach_map{"::all"}), - defined $kills[1] && (exists $detach_map{lc1459("$tag/*")} || exists $detach_map{lc1459("$tag/::all")} - || exists $detach_map{"*"} || exists $detach_map{"::all"}), - defined $kills[2] && (exists $detach_map{"*"} || exists $detach_map{"::all"}), - (exists $detach_map{"*"} || exists $detach_map{"::all"}) - ); - for my $ki (1, 2, 0, 3) { - if ($is_hidden[$ki]) { - unless ($was_unhidden[$ki]) { - $win->print("Unhiding window $kills[$ki]"); - push @setting, "$kills[$ki],0"; - $was_unhidden[$ki] = 1; - } - last; - } - } - my @is_hidden_aht = (defined $kills[0] && (exists $detach_aht{lc1459($name)} - || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), - defined $kills[1] && (exists $detach_aht{lc1459("$tag/$active")} - || exists $detach_aht{lc1459($active)} - || exists $detach_aht{lc1459("$tag/*")} || exists $detach_aht{lc1459("$tag/::all")} - || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), - defined $kills[2] && (exists $detach_aht{lc1459($active)} - || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), - (exists $detach_aht{$number} || exists $detach_aht{"*"} || exists $detach_aht{"::all"}) - ); - for my $ki (1, 2, 0, 3) { - if ($is_hidden_aht[$ki]) { - unless ($was_unhidden[$ki]) { - $win->print("Unhiding window $kills[$ki], it is hidden because ".(set 'detach_aht')." is ON"); - push @setting, "$kills[$ki],0"; - $was_unhidden[$ki] = 1; - } - last; - } - } - - if (@setting) { - Irssi::command("^set ".(set 'detach')." @setting"); - } else { - Irssi::command("^set -clear ".(set 'detach')); - } -} - -sub ack_window { - my ($data, $server, $witem) = @_; - my $win = Irssi::active_win; - my $number = $win->{refnum}; - if (grep { $_->{cmd} eq 'ack' } Irssi::commands) { - my $Orig_Irssi_windows = \&Irssi::windows; - local *Irssi::windows = sub () { grep { !_is_detached($_, $number) } $Orig_Irssi_windows->() }; - Irssi::command("ack" . (length $data ? " $data" : "")); - } else { - my $ignore_refnum = Irssi::settings_get_bool('active_window_ignore_refnum'); - my $max_win; - my $max_act = 0; - my $max_ref = 0; - for my $rec (Irssi::windows) { - next if _is_detached($rec, $number); - - # ignore refnum - if ($ignore_refnum && - $rec->{data_level} > 0 && $max_act < $rec->{data_level}) { - $max_act = $rec->{data_level}; - $max_win = $rec; - } - - # windows with lower refnums break ties - elsif (!$ignore_refnum && - $rec->{data_level} > 0 && - ($rec->{data_level} > $max_act || - ($rec->{data_level} == $max_act && $rec->{refnum} < $max_ref))) { - $max_act = $rec->{data_level}; - $max_win = $rec; - $max_ref = $rec->{refnum}; - } - } - $max_win->set_active if defined $max_win; - } -} - -sub refnum_changed { - my ($win, $old_refnum) = @_; - my @old_setting = split ' ', $S{detach}; - my @setting = map { - my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; - if ($k eq $old_refnum) { - $win->{refnum} . (defined $v ? ",$v" : "") - } - else { - $_ - } - } @old_setting; - if ("@old_setting" ne "@setting") { - $S{detach} = "@setting"; - Irssi::settings_set_str(set 'detach', "@setting"); - &setup_changed; - } - else { - &wl_changed; - } -} - -sub window_destroyed { - my ($win) = @_; - my @old_setting = split ' ', $S{detach}; - my @setting = grep { - my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; - if ($k eq $win->{refnum}) { - 0; - } - else { - 1; - } - } @old_setting; - if ("@old_setting" ne "@setting") { - $S{detach} = "@setting"; - Irssi::settings_set_str(set 'detach', "@setting"); - &setup_changed; - } - else { - &awins_changed; - } -} - -sub stop_mouse_tracking { - print STDERR "\e[?1005l\e[?1000l"; -} -sub start_mouse_tracking { - print STDERR "\e[?1000h\e[?1005h"; -} -sub install_mouse { - Irssi::command_bind('mouse_xterm' => 'mouse_xterm'); - Irssi::command('^bind meta-[M command mouse_xterm'); - Irssi::signal_add_first('gui key pressed' => 'mouse_key_hook'); - start_mouse_tracking(); -} -sub uninstall_mouse { - stop_mouse_tracking(); - Irssi::signal_remove('gui key pressed' => 'mouse_key_hook'); - Irssi::command('^bind -delete meta-[M'); - Irssi::command_unbind('mouse_xterm' => 'mouse_xterm'); -} - -sub awl_mouse_event { - return if $VIEWER_MODE; - if ((($_[0] == 3 and $_[3] == 0) - || $_[0] == 64 || $_[0] == 65) and - $_[1] == $_[4] and $_[2] == $_[5]) { - my $top = lc $S{placement} eq 'top'; - my ($pos, $line) = @_[1 .. 2]; - unless ($top) { - $line -= $screenHeight; - $line += $currentLines; - $line += $S{mouse_offset}; - } - else { - $line -= $S{mouse_offset}; - } - $pos -= $sb_base_width_pre; - return if $line < 0 || $line >= $currentLines; - if ($_[0] == 64) { - Irssi::command('window up'); - } - elsif ($_[0] == 65) { - Irssi::command('window down'); - } - elsif (exists $mouse_coords{$line}{$pos}) { - my $win = $mouse_coords{$line}{$pos}; - Irssi::command('window ' . $win); - } - Irssi::signal_stop; - } -} - -sub mouse_scroll_event { - return unless $S{mouse_scroll}; - if (($_[3] == 64 or $_[3] == 65) and - $_[0] == $_[3] and $_[1] == $_[4] and $_[2] == $_[5]) { - my $cmd = 'scrollback goto ' . ($_[3] == 64 ? '-' : '+') . $S{mouse_scroll}; - Irssi::active_win->command($cmd); - Irssi::signal_stop; - } - elsif ($_[0] == 64 or $_[0] == 65) { - Irssi::signal_stop; - } -} - -sub mouse_escape { - return unless $S{mouse_escape} > 0; - if ($_[0] == 3) { - my $tm = $S{mouse_escape}; - $tm *= 1000 if $tm < 1000; - stop_mouse_tracking(); - Irssi::timeout_add_once($tm, 'start_mouse_tracking', undef); - Irssi::signal_stop; - } -} - -sub UNLOAD { - @actString = (); - killOldStatus(); - stop_viewer() if $VIEWER_MODE; - uninstall_mouse() if $MOUSE_ON; -} - -sub addPrintTextHook { # update on print text - return unless defined $^S; - return if $BLOCK_ALL; - return unless $print_text_activity; - return if $_[0]->{level} == 262144 and $_[0]->{target} eq '' - and !defined($_[0]->{server}); - &wl_changed; -} - -sub block_event_window_change { - Irssi::signal_stop; -} - -sub update_awins { - my @wins = Irssi::windows; - local $BLOCK_ALL = 1; - Irssi::signal_add_first('window changed' => 'block_event_window_change'); - my $bwin = - my $awin = Irssi::active_win; - my $lwin; - my $defer_irssi_broken_last; - unless ($wins[0]{refnum} == $awin->{refnum}) { - # special case: more than 1 last win, so /win last; - # /win last doesn't come back to the current window. eg. after - # connect & autojoin; we can't handle this situation, bail out - $defer_irssi_broken_last = 1; - } - else { - $awin->command('window last'); - $lwin = Irssi::active_win; - $lwin->command('window last'); - $defer_irssi_broken_last = $lwin->{refnum} == $bwin->{refnum}; - } - my $awin_counter = 0; - Irssi::signal_remove('window changed' => 'block_event_window_change'); - unless ($defer_irssi_broken_last) { - # we need to keep the fe-windows code running here - Irssi::signal_add_priority('window changed' => 'block_event_window_change', -99); - %awins = %wnmap_exp = (); - do { - Irssi::active_win->command('window up'); - $awin = Irssi::active_win; - $awins{$awin->{refnum}} = undef; - ++$awin_counter; - } until ($awin->{refnum} == $bwin->{refnum} || $awin_counter >= @wins); - Irssi::signal_remove('window changed' => 'block_event_window_change'); - - Irssi::signal_add_first('window changed' => 'block_event_window_change'); - for my $key (keys %wnmap) { - next unless Irssi::window_find_name($key) || Irssi::window_find_item($key); - $awin->command("window goto $key"); - my $cwin = Irssi::active_win; - $wnmap_exp{ $cwin->{refnum} } = $wnmap{$key}; - $cwin->command('window last') - if $cwin->{refnum} != $awin->{refnum}; - } - for my $win (reverse @wins) { # restore original window order - Irssi::active_win->command('window '.$win->{refnum}); - } - $awin->command('window '.$lwin->{refnum}); # restore last win - Irssi::active_win->command('window last'); - Irssi::signal_remove('window changed' => 'block_event_window_change'); - } - $CHANGED{WL} = 1; -} - -sub resizeTerm { - if (defined (my $r = `stty size 2>/dev/null`)) { - ($screenHeight, $screenWidth) = split ' ', $r; - $CHANGED{SETUP} = 1; - } - else { - $CHANGED{SIZE} = 1; - } -} - -sub awl_refresh { - $globTime = undef; - resizeTerm() if delete $CHANGED{SIZE}; - reset_awl() if delete $CHANGED{SETUP}; - update_awins() if delete $CHANGED{AWINS}; - update_wl() if delete $CHANGED{WL}; -} - -sub termsize_changed { $CHANGED{SIZE} = 1; &queue_refresh; } -sub setup_changed { $CHANGED{SETUP} = 1; &queue_refresh; } -sub awins_changed { $CHANGED{AWINS} = 1; &queue_refresh; } -sub wl_changed { $CHANGED{WL} = 1; &queue_refresh; } - -sub window_changed { - &awins_changed if $_[1]; -} - -sub queue_refresh { - return if $BLOCK_ALL; - Irssi::timeout_remove($globTime) - if defined $globTime; # delay the update further - $globTime = Irssi::timeout_add_once(GLOB_QUEUE_TIMER, 'awl_refresh', undef); -} - -sub awl_init { - termsize_changed(); - setup_changed(); - update_keymap(); - Irssi::timeout_remove($globTime) - if defined $globTime; - awl_refresh(); - termsize_changed(); -} - -sub runsub { - my $cmd = shift; - sub { - my ($data, $server, $item) = @_; - Irssi::command_runsub($cmd, $data, $server, $item); - }; -} - -Irssi::signal_register({ - 'gui mouse' => [qw/int int int int int int/], - }); -{ my $broken_expandos = (Irssi::version >= 20081128 && Irssi::version < 20110210) - ? sub { my $x = shift; $x =~ s/\$\{cumode_space\}/ /; $x } : undef; - Irssi::theme_register([ - map { $broken_expandos ? $broken_expandos->($_) : $_ } - set 'display_nokey' => '$N${cumode_space}$H$C$S', - set 'display_key' => '$Q${cumode_space}$H$C$S', - set 'display_nokey_visible' => '%2$N${cumode_space}$H$C$S', - set 'display_key_visible' => '%2$Q${cumode_space}$H$C$S', - set 'display_nokey_active' => '%1$N${cumode_space}$H$C$S', - set 'display_key_active' => '%1$Q${cumode_space}$H$C$S', - set 'display_header' => '%8$C|${N}', - set 'name_display' => '$0', - set 'separator' => ' ', - set 'separator2' => '', - set 'abbrev_chars' => "~\x{301c}", - set 'viewer_item_bg' => sb_format_expand('{sb_background}'), - set 'title' => '\V'.setc().'\:', - ]); -} -Irssi::settings_add_bool(setc, set 'prefer_name', 0); # -Irssi::settings_add_int( setc, set 'hide_empty', 0); # -Irssi::settings_add_int( setc, set 'hide_data', 0); # -Irssi::settings_add_str( setc, set 'detach', ''); # -Irssi::settings_add_int( setc, set 'detach_data', -3); # -Irssi::settings_add_bool(setc, set 'detach_aht', 0); # -Irssi::settings_add_int( setc, set 'hide_name_data', 0); # -Irssi::settings_add_int( setc, set 'maxlines', 9); # -Irssi::settings_add_int( setc, set 'maxcolumns', 4); # -Irssi::settings_add_int( setc, set 'block', 15); # -Irssi::settings_add_bool(setc, set 'sbar_maxlength', 1); # -Irssi::settings_add_int( setc, set 'height_adjust', 2); # -Irssi::settings_add_str( setc, set 'sort', 'refnum'); # -Irssi::settings_add_str( setc, set 'placement', 'bottom'); # -Irssi::settings_add_int( setc, set 'position', 0); # -Irssi::settings_add_bool(setc, set 'all_disable', 1); # -Irssi::settings_add_bool(setc, set 'viewer', 1); # -Irssi::settings_add_str( setc, set 'shared_sbar', 'OFF'); # -Irssi::settings_add_bool(setc, set 'mouse', 0); # -Irssi::settings_add_str( setc, set 'path', Irssi::get_irssi_dir . '/_windowlist'); # -Irssi::settings_add_str( setc, set 'custom_xform', ''); # -Irssi::settings_add_time(setc, set 'last_line_shade', '0'); # -Irssi::settings_add_int( setc, set 'mouse_offset', 1); # -Irssi::settings_add_int( setc, 'mouse_scroll', 3); # -Irssi::settings_add_int( setc, 'mouse_escape', 1); # -Irssi::settings_add_str( setc, 'banned_channels', ''); -Irssi::settings_add_bool(setc, 'banned_channels_on', 1); -Irssi::settings_add_str( setc, 'fancy_abbrev', 'fancy'); # -Irssi::settings_add_bool(setc, set 'no_mode_hint', 0); # -Irssi::settings_add_bool(setc, set 'viewer_launch', 1); # -Irssi::settings_add_str( setc, set 'viewer_launch_env', ''); # -Irssi::settings_add_str( setc, set 'viewer_tmux_position', 'left'); # -Irssi::settings_add_str( setc, set 'viewer_xwin_command', 'xterm +sb -e %A'); # -Irssi::settings_add_str( setc, set 'viewer_custom_command', ''); # - -Irssi::signal_add_last({ - 'setup changed' => 'setup_changed', - 'print text' => 'addPrintTextHook', - 'terminal resized' => 'termsize_changed', - 'setup reread' => 'screenFullRedraw', - 'window hilight' => 'wl_changed', - 'command format' => 'wl_changed', -}); -Irssi::signal_add({ - 'window changed' => 'window_changed', - 'window item changed' => 'wl_changed', - 'window changed automatic' => 'window_changed', - 'window created' => 'awins_changed', - 'window destroyed' => 'window_destroyed', - 'window name changed' => 'wl_changed', - 'window refnum changed' => 'refnum_changed', -}); -Irssi::signal_add_last('gui mouse' => 'mouse_escape'); -Irssi::signal_add_last('gui mouse' => 'mouse_scroll_event'); -Irssi::signal_add_last('gui mouse' => 'awl_mouse_event'); -Irssi::command_bind( setc() => runsub(setc()) ); -Irssi::command_bind( setc() . ' redraw' => 'screenFullRedraw' ); -Irssi::command_bind( setc() . ' restart' => 'restartViewerServer' ); -Irssi::command_bind( setc() . ' attach' => 'unhide_window' ); -Irssi::command_bind( setc() . ' detach' => 'hide_window' ); -Irssi::command_bind( setc() . ' ack' => 'ack_window' ); - -{ - my $l = set 'shared'; - { - no strict 'refs'; - *{$l} = $awl_shared_empty; - } - Irssi::statusbar_item_register($l, '$0', $l); -} - -awl_init(); - -# Mouse script based on irssi mouse patch by mirage -{ my $mouse_status = -1; # -1:off 0,1,2:filling mouse_combo - my @mouse_combo; # 0:button 1:x 2:y - my @mouse_previous; # previous contents of mouse_combo - - sub mouse_xterm_off { - $mouse_status = -1; - } - sub mouse_xterm { - $mouse_status = 0; - Irssi::timeout_add_once(10, 'mouse_xterm_off', undef); - } - - sub mouse_key_hook { - my ($key) = @_; - if ($mouse_status != -1) { - if ($mouse_status == 0) { - @mouse_previous = @mouse_combo; - #if @mouse_combo && $mouse_combo[0] < 64; - } - $mouse_combo[$mouse_status] = $key - 32; - $mouse_status++; - if ($mouse_status == 3) { - $mouse_status = -1; - # match screen coordinates - $mouse_combo[1]--; - $mouse_combo[2]--; - Irssi::signal_emit('gui mouse', @mouse_combo[0 .. 2], @mouse_previous[0 .. 2]); - } - Irssi::signal_stop; - } - } -} - -sub string_LCSS { - my $str = join "\0", @_; - (sort { length $b <=> length $a } $str =~ /(?=(.+).*\0.*\1)/g)[0] -} - -# workaround for issue #271 -{ package Irssi::Nick } - -# workaround for issue #572 -@Irssi::UI::Exec::ISA = 'Irssi::Windowitem' - if Irssi::version >= 20140822 && Irssi::version <= 20161101 && !@Irssi::UI::Exec::ISA; - -UNITCHECK -{ package AwlViewer; - use strict; - use warnings; - no warnings 'redefine'; - use Encode; - use IO::Socket::UNIX; - use IO::Select; - use List::Util qw(max); - use constant BLOCK_SIZE => 1024; - use constant RECONNECT_TIME => 5; - - my $sockpath; - - our $VERSION = '0.8'; - - our ($got_int, $resized, $timeout); - - my %vars; - my (%c2w, @seqlist); - my %mouse_coords; - my (@mouse, @last_mouse); - my ($err, $sock, $loop); - my ($keybuf, $rcvbuf); - my @screen; - my ($screenHeight, $screenWidth); - my ($disp_update, $fs_open, $one_shot_integration, $one_shot_resize); - my $integration_position; - my $show_title_bar; - - sub connect_it { - $sock = IO::Socket::UNIX->new( - Type => SOCK_STREAM, - Peer => $sockpath, - ); - unless ($sock) { - $err = $!; - return; - } - $sock->blocking(0); - $loop->add($sock); - } - - sub remove_conn { - my $fh = shift; - $loop->remove($fh); - $fh->close; - $sock = undef; - %vars = (); - @screen = (); - } - - { package Terminfo; # xterm - sub civis { "\e[?25l" } - sub sc { "\e7" } - sub cup { "\e[" . ($_[0] + 1) . ';' . ($_[1] + 1) . 'H' } - sub el { "\e[K" } - sub rc { "\e8" } - sub cnorm { "\e[?25h" } - sub setab { "\e[4" . $_[0] . 'm' } - sub setaf { "\e[3" . $_[0] . 'm' } - sub setaf16 { "\e[9" . $_[0] . 'm' } - sub setab16 { "\e[10" . $_[0] . 'm' } - sub setaf256 { "\e[38;5;" . $_[0] . 'm' } - sub setab256 { "\e[48;5;" . $_[0] . 'm' } - sub setafrgb { "\e[38;2;" . $_[0] . ';' . $_[1] . ';' . $_[2] . 'm' } - sub setabrgb { "\e[48;2;" . $_[0] . ';' . $_[1] . ';' . $_[2] . 'm' } - sub sgr0 { "\e[0m" } - sub bold { "\e[1m" } - sub it { "\e[3m" } - sub ul { "\e[4m" } - sub blink { "\e[5m" } - sub rev { "\e[7m" } - sub op { "\e[39;49m" } - sub exit_bold { "\e[22m" } - sub exit_it { "\e[23m" } - sub exit_ul { "\e[24m" } - sub exit_blink { "\e[25m" } - sub exit_rev { "\e[27m" } - sub smcup { "\e[?1049h" } - sub rmcup { "\e[?1049l" } - sub smmouse { "\e[?1000h\e[?1005h" } - sub rmmouse { "\e[?1005l\e[?1000l" } - } - - sub init { - $sockpath = shift // "$ENV{HOME}/.irssi/_windowlist"; - STDOUT->autoflush(1); - printf "\r%swaiting for %s...", Terminfo::sc, $::IRSSI{name}; - - `stty -icanon -echo`; - - $loop = IO::Select->new; - STDIN->blocking(0); - $loop->add(\*STDIN); - - $SIG{INT} = sub { - $got_int = 1 - }; - $SIG{WINCH} = sub { - $resized = 1 - }; - - $resized = 3; - - $disp_update = 2; - - $show_title_bar = 1; - } - - sub enter_fs { - return if $fs_open; - safe_print(Terminfo::rc, Terminfo::smcup, Terminfo::civis, Terminfo::smmouse); - $fs_open = 1; - } - - sub leave_fs { - return unless $fs_open; - safe_print(Terminfo::rmmouse, Terminfo::cnorm, Terminfo::rmcup); - safe_print(sprintf "\r%swaiting for %s...", Terminfo::sc, $::IRSSI{name}) if $_[0]; - - $fs_open = 0; - } - - sub end_prog { - leave_fs(); - STDIN->blocking(1); - `stty sane`; - printf "\r%s%sthanks for using %s\n", Terminfo::rc, Terminfo::el, $::IRSSI{name}; - } - - sub safe_print { - my $st = STDIN->blocking(1); - print @_; - STDIN->blocking($st); - } - - sub safe_qx { - my $st = STDIN->blocking(1); - my $ret = `$_[0]`; - STDIN->blocking($st); - $ret - } - - sub safe_print_sock { - return unless $sock; - my $was = $sock->blocking(1); - $sock->print(@_); - $sock->blocking($was); - } - - sub process_recv { - my $need = 0; - while ($rcvbuf =~ s/\n(.+)_BEGIN\n((?: .*\n)*)\1_END\n//) { - my $var = lc $1; - my $data = $2; - my @data = split "\n ", "\n$data ", -1; - shift @data; pop @data; - my $itembg = $vars{itembg}; - if ($var =~ s/list$//) { - $vars{$var} = \@data; - } - elsif ($var =~ s/map$//) { - $vars{$var} = +{ @data }; - } - else { - $vars{$var} = join "\n", @data; - } - $need = 1 if $var eq 'win'; - $need = 1 if $var eq 'redraw' && $vars{$var}; - if (($itembg//'') ne ($vars{itembg}//'')) { - $need = $vars{redraw} = 1; - } - _build_keymap() if $var eq 'key2'; - } - $need - } - - { my %ansi_table; - my ($i, $j, $k) = (0, 0, 0); - my %term_state; - sub reset_term_state { my %old_term = %term_state; %term_state = (); %old_term } - sub set_term_state { my %old_term = %term_state; %term_state = @_; %old_term } - %ansi_table = ( - # fe-common::core::formats.c:format_expand_styles - (map { my $t = $i++; ($_ => sub { my $n = $term_state{hicolor} ? \&Terminfo::setab16 : \&Terminfo::setab; - $n->($t) }) } (split //, '01234567' )), - (map { my $t = $j++; ($_ => sub { my $n = $term_state{hicolor} ? \&Terminfo::setaf16 : \&Terminfo::setaf; - $n->($t) }) } (split //, 'krgybmcw' )), - (map { my $t = $k++; ($_ => sub { my $n = $term_state{hicolor} ? \&Terminfo::setaf : \&Terminfo::setaf16; - $n->($t) }) } (split //, 'KRGYBMCW')), - # reset - n => sub { $term_state{hicolor} = 0; my $r = Terminfo::op; - for (qw(blink rev bold)) { - $r .= Terminfo->can("exit_$_")->() if delete $term_state{$_}; - } - { - local $ansi_table{n} = $ansi_table{N}; - $r .= formats_to_ansi_basic($vars{itembg}); - } - $r - }, - N => sub { reset_term_state(); Terminfo::sgr0 }, - # flash/bright - F => sub { my $n = 'blink'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # reverse - 8 => sub { my $n = 'rev'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # bold - "_" => sub { my $n = 'bold'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # underline - U => sub { my $n = 'ul'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # italic - I => sub { my $n = 'it'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # bold, used as colour modifier if AWL_HI9 is set - 9 => $ENV{AWL_HI9} ? sub { $term_state{hicolor} ^= 1; '' } - : sub { my $n = 'bold'; my $e = ($term_state{$n} ^= 1) ? $n : "exit_$n"; Terminfo->can($e)->() }, - # delete other stuff - (map { $_ => sub { '' } } (split //, ':|>#[')), - # escape - (map { my $close = $_; $_ => sub { $close } } (split //, '{}%')), - ); - for my $base (0 .. 15) { - my $close = $base; - my $idx = ($close&8) | ($close&4)>>2 | ($close&2) | ($close&1)<<2; - $ansi_table{ (sprintf "x0%x", $close) } = - $ansi_table{ (sprintf "x0%X", $close) } = - sub { Terminfo::setab256($idx) }; - $ansi_table{ (sprintf "X0%x", $close) } = - $ansi_table{ (sprintf "X0%X", $close) } = - sub { Terminfo::setaf256($idx) }; - } - for my $plane (1 .. 6) { - for my $coord (0 .. 35) { - my $close = 16 + ($plane-1) * 36 + $coord; - my $ch = $coord < 10 ? $coord : chr( $coord - 10 + ord 'a' ); - $ansi_table{ "x$plane$ch" } = - $ansi_table{ "x$plane\U$ch" } = - sub { Terminfo::setab256($close) }; - $ansi_table{ "X$plane$ch" } = - $ansi_table{ "X$plane\U$ch" } = - sub { Terminfo::setaf256($close) }; - } - } - for my $gray (0 .. 23) { - my $close = 232 + $gray; - my $ch = chr( $gray + ord 'a' ); - $ansi_table{ "x7$ch" } = - $ansi_table{ "x7\U$ch" } = - sub { Terminfo::setab256($close) }; - $ansi_table{ "X7$ch" } = - $ansi_table{ "X7\U$ch" } = - sub { Terminfo::setaf256($close) }; - } - # fe-windows.c:color_24bit_256 - my $cc = sub { - use integer; - - my $cstep_size = 40; - my $cstep_start = 0x5f; - - my $gstep_size = 10; - my $gstep_start = 0x08; - - my @dist = (0) x 3; - my @r; my @gr; - - for (my $i = 0; $i < 3; ++$i) { - my $n = $_[$i]; - $gr[$i] = -1; - if ($n < $cstep_start /2) { - $r[$i] = 0; - $dist[$i] = -$cstep_size/2; - } - else { - $r[$i] = 1+(($n-$cstep_start + $cstep_size /2)/$cstep_size); - $dist[$i] = (($n-$cstep_start + $cstep_size /2)% $cstep_size - $cstep_size/2); - } - if ($n < $gstep_start /2) { - $gr[$i] = -1; - } - else { - $gr[$i] = (($n-$gstep_start + $gstep_size /2)/$gstep_size); - } - } - if ($r[0] == $r[1] && $r[1] == $r[2] && - 4*abs($dist[0]) < $gstep_size && 4*abs($dist[1]) < $gstep_size && 4*abs($dist[2]) < $gstep_size) { - # skip gray detection - } - else { - my $j = $r[1] == $r[2] ? 0 : 1; - if (($r[0] == $r[1] || $r[$j] == $r[2]) && abs($r[$j]-$r[($j+1)% 3]) <= 1) { - my $k = $gr[1] == $gr[2] ? 0 : 1; - if (($gr[0] == $gr[1] || $gr[$k] == $gr[2]) && abs($gr[$k]-$gr[($k+1)% 3]) <= 2) { - if ($gr[$k] < 0) { - $r[0] = $r[1] = $r[2] = 0; - } - elsif ($gr[$k] > 23) { - $r[0] = $r[1] = $r[2] = 5; - } - else { - $r[0] = 6; - $r[1] = ($gr[$k] / 6); - $r[2] = $gr[$k]% 6; - } - } - } - } - return 16 + $r[0]*36 + $r[1] * 6 + $r[2]; - }; - $ansi_table{z} = sub { - my ($r, $g, $b) = map { hex } unpack '(A2)*', $_[0]; - $vars{tc} eq 'ON' ? Terminfo::setabrgb($r, $g, $b) : Terminfo::setab256($cc->($r, $g, $b)); - }; - $ansi_table{Z} = sub { - my ($r, $g, $b) = map { hex } unpack '(A2)*', $_[0]; - $vars{tc} eq 'ON' ? Terminfo::setafrgb($r, $g, $b) : Terminfo::setaf256($cc->($r, $g, $b)); - }; - sub formats_to_ansi_basic { - my $o = shift; - $o =~ s{(%((Z|z)(......)|X..|x..|.))}{ - if ($ansi_table{$2}) { $ansi_table{$2}->() } - elsif ($ansi_table{$3}) { $ansi_table{$3}->($4) } - else { $1 } - }gex; - $o - } - } - - sub _header { - my $str = $vars{title} // uc ::setc(); - my $ccs = qr/%(?:Z(?:[0-9A-F]{6})|X(?:[1-6][0-9A-Z]|7[A-X])|[0-9BCFGIKMNRUWY_])/i; - (my $stripstr = $str) =~ s/($ccs)//g; - my $space = int( ((abs $vars{block}) - length $stripstr) / (1 + length $stripstr)); - if ($space > 0) { - my $ss = ' ' x $space; - my @x = $str =~ /((?:$ccs)*\X(?:(?:$ccs)*$)?)/g; - $str = join $ss, '', @x, ''; - } - ($stripstr = $str) =~ s/($ccs)//g; - my $pad = max 0, (abs $vars{block}) - length $stripstr; - $str = ' ' x ($pad/2) . $str . ' ' x ($pad/2 + $pad%2); - $str - } - - sub _add_item { - my ($i, $j, $c, $wi, $screen, $mouse) = @_; - $screen->[$i][$j] = "%N%n$wi"; - if (exists $vars{mouse}{$c - 1}) { - $mouse->[$i][$j] = $vars{mouse}{$c - 1}; - } - } - sub update_screen { - $disp_update = 0; - unless ($sock && exists $vars{seplen} && exists $vars{block}) { - leave_fs(1); - return; - } - enter_fs(); - @screen = () if delete $vars{redraw}; - %mouse_coords = (); - my $ncols = ($vars{seplen} + abs $vars{block}) ? - int( ($screenWidth + $vars{seplen}) / ($vars{seplen} + abs $vars{block}) ) : 0; - my $xenl = ($vars{seplen} + abs $vars{block}) - && $ncols > int( ($screenWidth + $vars{seplen} - 1) / ($vars{seplen} + abs $vars{block}) ); - my $nrows = $screenHeight - $vars{ha}; - my @wi = @{$vars{win}//[]}; - my $max_items = $ncols * $nrows; - my $c = $show_title_bar ? 1 : 0; - my $items = @wi + $c; - my $titems = $items > $max_items ? $max_items : $items; - my $i = 0; - my $j = 0; - my @new_screen; - my @new_mouse; - $new_screen[0][0] = _header() #. ' ' x $vars{seplen} - if $show_title_bar; - unless ($nrows > $ncols) { # line layout - ++$j if $show_title_bar; - for my $wi (@wi) { - if ($j >= $ncols) { - $j = 0; - ++$i; - } - last if $i >= $nrows; - _add_item($i, $j, $show_title_bar ? $c : $c + 1, - $wi, \@new_screen, \@new_mouse); - if ($c + 1 < $titems && $j + 1 < $ncols) { - $new_screen[$i][$j] .= $vars{separator}; - } - ++$j; - ++$c; - } - } - else { # column layout - ++$i if $show_title_bar; - for my $wi (@wi) { - if ($i >= $nrows) { - $i = 0; - ++$j; - } - last if $j >= $ncols; - _add_item($i, $j, $show_title_bar ? $c : $c + 1, - $wi, \@new_screen, \@new_mouse); - if ($c + $nrows < $titems) { - $new_screen[$i][$j] .= $vars{separator}; - } - ++$i; - ++$c; - } - } - my $step = $vars{seplen} + abs $vars{block}; - $i = 0; - my $str = Terminfo::sc . Terminfo::sgr0; - for (my $i = 0; $i < @new_screen; ++$i) { - for (my $j = 0; $j < @{$new_screen[$i]}; ++$j) { - if (defined $new_mouse[$i] && defined $new_mouse[$i][$j]) { - my $from = $j * $step; - $mouse_coords{$i}{$_} = $new_mouse[$i][$j] - for $from .. $from + abs $vars{block}; - } - next if defined $screen[$i] && defined $screen[$i][$j] - && $screen[$i][$j] eq $new_screen[$i][$j]; - $str .= Terminfo::cup($i, $j * $step) - . formats_to_ansi_basic($new_screen[$i][$j]) - . Terminfo::sgr0; - $str .= Terminfo::el if $j == $#{$new_screen[$i]} && (!$xenl || $j + 1 != $ncols); - } - } - for (@new_screen .. $screenHeight - 1) { - if (!@screen || defined $screen[$_]) { - $str .= Terminfo::cup($_, 0) . Terminfo::sgr0 . Terminfo::el; - } - } - $str .= Terminfo::rc; - safe_print $str; - @screen = @new_screen; - } - - sub handle_resize { - if (defined (my $r = safe_qx('stty size'))) { - ($screenHeight, $screenWidth) = split ' ', $r; - $resized = 0; - @screen = (); - $disp_update = 1; - if ($one_shot_integration == 2) { - $one_shot_resize--; - } - } - else { - } - } - - sub _build_keymap { - %c2w = reverse( %{$vars{key}}, %{$vars{key2}} ); - if (!grep { /^[+-]./ } keys %c2w) { - %c2w = (%c2w, map { ("-$_" => $c2w{$_}) } grep { !/^\^./ } keys %c2w); - } - %c2w = map { - my $key = $_; - s{^(-)?(\+)?(\^)?(.)}{ - join '', ( - ($1 ? "\e" : ''), - ($2 ? "\e\e" : ''), - ($3 ? "$4"^"@" : $4) - ) - }e; - $_ => $c2w{$key} - } keys %c2w; - @seqlist = sort { length $b <=> length $a } keys %c2w; - } - - sub _match_tmux { - length $ENV{TMUX} && exists $vars{irssienv}{tmux_srv} && length $vars{irssienv}{tmux_pane} - && $ENV{TMUX} eq $vars{irssienv}{tmux_srv} - } - - sub process_keys { - Encode::_utf8_on($keybuf); - my $win; - my $use_mouse; - my $maybe; - KEY: while (length $keybuf && !$maybe) { - $maybe = 0; - if ($keybuf =~ s/^\e\[M(.)(.)(.)//) { - @last_mouse = @mouse;# if @mouse && $mouse[0] < 64; - @mouse = map { -32 + ord } ($1, $2, $3); - $use_mouse = 1; - next KEY; - } - for my $s (@seqlist) { - if ($keybuf =~ s/^\Q$s//) { - $win = $c2w{$s}; - $use_mouse = 0; - next KEY; - } - elsif (length $keybuf < length $s && $s =~ /^\Q$keybuf/) { - $maybe = 1; - } - } - unless ($maybe) { - substr $keybuf, 0, 1, ''; - } - } - if ($use_mouse && @mouse && @last_mouse && - $mouse[2] == $last_mouse[2] && - $mouse[1] == $last_mouse[1] && - ($mouse[0] == 3 || $mouse[0] == 64 || $mouse[0] == 65)) { - if ($mouse[0] == 64) { - $win = 'up'; - } - elsif ($mouse[0] == 65) { - $win = 'down'; - } - elsif (exists $mouse_coords{$mouse[2] - 1}{$mouse[1] - 1}) { - $win = $mouse_coords{$mouse[2] - 1}{$mouse[1] - 1}; - } - elsif ($mouse[2] == 1 && $mouse[1] <= abs $vars{block}) { - $win = $last_mouse[0] != 0 ? 'last' : 'active'; - } - else { - } - } - if (defined $win) { - $win =~ s/^_//; - safe_print_sock("$win\n"); - if (!exists $ENV{AWL_AUTOFOCUS} || $ENV{AWL_AUTOFOCUS}) { - if (_match_tmux()) { - safe_qx("tmux selectp -t $vars{irssienv}{tmux_pane} 2>&1"); - } - elsif (exists $vars{irssienv}{xwinid}) { - safe_qx("wmctrl -ia $vars{irssienv}{xwinid} 2>/dev/null"); - } - } - } - Encode::_utf8_off($keybuf); - } - - sub check_integration { - return unless $vars{irssienv}; - return unless $sock && exists $vars{seplen} && exists $vars{block}; - if ($one_shot_integration == 1) { - my $nrows = $screenHeight - $vars{ha}; - my $ncols = ($vars{seplen} + abs $vars{block}) ? int( ($screenWidth + $vars{seplen}) / ($vars{seplen} + abs $vars{block}) ) : 0; - my $items = ($show_title_bar ? 1 : 0) + @{$vars{win}//[]}; - my $dcols_required = $nrows ? int($items/$nrows) + !!($items%$nrows) : 0; - my $rows_required = $ncols ? int($items/$ncols) + !!($items%$ncols) : 0; - $rows_required = abs $vars{ml} - if ($vars{ml} < 0 || ($vars{ml} > 0 && $rows_required > $vars{ml})); - $dcols_required = abs $vars{mc} - if ($vars{mc} < 0 || ($vars{mc} > 0 && $dcols_required > $vars{mc})); - my $rows = $rows_required + $vars{ha}; - my $cols = ($dcols_required * ($vars{seplen} + abs $vars{block})) - $vars{seplen}; - if (_match_tmux()) { - # int( ($screenWidth + $vars{seplen}) / ($vars{seplen} + abs $vars{block}) ); - my ($pos_flag, $before); - if ($integration_position eq 'left') { - $pos_flag = 'h'; - $before = 1; - } - elsif ($integration_position eq 'top') { - $pos_flag = 'v'; - $before = 1; - } - elsif ($integration_position eq 'right') { - $pos_flag = 'h'; - } - else { - $pos_flag = 'v'; - } - my @cmd = "joinp -d$pos_flag -s $ENV{TMUX_PANE} -t $vars{irssienv}{tmux_pane}"; - push @cmd, "swapp -d -t $ENV{TMUX_PANE} -s $vars{irssienv}{tmux_pane}" - if $before; - $cols = max($cols, 2); - $rows = max($rows, 2); - - safe_qx("tmux " . (join " \\\; ", @cmd) . " 2>&1"); - } - else { - $resized = 1; - #safe_qx("resize -s $screenHeight $cols 2>&1") - # if $cols > 0; - } - $one_shot_integration++; - if ($resized == 1) { - handle_resize(); - resize_integration(); - } - } - elsif ($one_shot_integration == 2) { - resize_integration(1); - } - } - - sub resize_integration { - return unless $one_shot_integration; - return unless ($one_shot_resize//0) < 0 || shift; - return if ($one_shot_resize//0) > 0; - - my $nrows = $screenHeight - $vars{ha}; - my $ncols = ($vars{seplen} + abs $vars{block}) ? int( ($screenWidth + $vars{seplen}) / ($vars{seplen} + abs $vars{block}) ) : 0; - my $items = ($show_title_bar ? 1 : 0) + @{$vars{win}//[]}; - my $dcols_required = $nrows ? (int($items/$nrows) + !!($items%$nrows)) : 0; - my $rows_required = $ncols ? int($items/$ncols) + !!($items%$ncols) : 0; - $rows_required = abs $vars{ml} - if ($vars{ml} < 0 || ($vars{ml} > 0 && $rows_required > $vars{ml})); - $dcols_required = abs $vars{mc} - if ($vars{mc} < 0 || ($vars{mc} > 0 && $dcols_required > $vars{mc})); - my $rows = $rows_required + $vars{ha}; - my $cols = ($dcols_required * ($vars{seplen} + abs $vars{block})) - $vars{seplen}; - if (_match_tmux()) { - my $pos_flag; - my $before = 0; - if ($integration_position eq 'left') { - $pos_flag = 'h'; - $before = 1; - } - elsif ($integration_position eq 'top') { - $pos_flag = 'v'; - $before = 1; - } - elsif ($integration_position eq 'right') { - $pos_flag = 'h'; - } - else { - $pos_flag = 'v'; - } - my @cmd; - # hard tmux limits - $cols = max($cols, 2); - $rows = max($rows, 2); - if ($pos_flag eq 'h' && $cols != $screenWidth) { - my $change = $screenWidth - $cols; - my $dir = ($before ^ ($change<0)) ? 'L' : 'R'; - push @cmd, "resizep -$dir -t $ENV{TMUX_PANE} @{[abs $change]}"; - #push @cmd, "resizep -x $cols -t $ENV{TMUX_PANE}"; - $one_shot_resize = 1; - } - if ($pos_flag eq 'v' && $rows != $screenHeight) { - #push @cmd, "resizep -y $rows -t $ENV{TMUX_PANE}"; - my $change = $screenHeight - $rows; - my $dir = ($before ^ ($change<0)) ? 'U' : 'D'; - push @cmd, "resizep -$dir -t $ENV{TMUX_PANE} @{[abs $change]}"; - $one_shot_resize = 1; - } - - safe_qx("tmux " . (join " \\\; ", @cmd) . " 2>&1") - if @cmd; - } - else { - $cols = max($cols, 1); - $rows = max($rows, 1); - unless ($nrows > $ncols) { # line layout - if ($rows != $screenHeight) { - safe_qx("resize -s $rows $screenWidth 2>&1"); - $one_shot_resize = 1; - } - } - else { - if ($cols != $screenWidth) { - safe_qx("resize -s $screenHeight $cols 2>&1"); - $one_shot_resize = 1; - } - } - } - if ($resized == 1) { - handle_resize(); - } - } - - sub init_integration { - return unless $one_shot_integration; - if (_match_tmux()) { - } - else { - } - safe_print("\e]2;".(uc ::setc())."\e\\"); - } - - sub main { - require Getopt::Std; - my %opts; - Getopt::Std::getopts('1p:', \%opts); - my $one_shot = $opts{1}; - $integration_position = $opts{p}; - $one_shot_integration = 0+!!$one_shot; - #shift if @_ && $_[0] eq '--'; - &init; - $show_title_bar = 0; - init_integration(); - until ($got_int) { - $timeout = undef; - if ($resized) { - if ($resized == 1) { - $timeout = 1; - $resized++; - } - else { - handle_resize(); - resize_integration(); - } - } - unless ($sock || $timeout) { - connect_it(); - } - $timeout ||= RECONNECT_TIME unless $sock; - update_screen() if $disp_update; - SELECT: while (my @read = $loop->can_read($timeout)) { - for my $fh (@read) { - if ($fh == \*STDIN) { - if (read STDIN, my $buf, BLOCK_SIZE) { - do { - $keybuf .= $buf; - } while read STDIN, $buf, BLOCK_SIZE; - } - else { - $got_int = 1; - last SELECT; - } - } - else { - if ($fh->read(my $buf, BLOCK_SIZE)) { - do { - $rcvbuf .= $buf; - } while $fh->read($buf, BLOCK_SIZE); - } - else { - $disp_update = 1; - remove_conn($fh); - if ($one_shot) { - $got_int = 1; - last SELECT; - } - $timeout ||= RECONNECT_TIME; - } - } - } - $disp_update |= process_recv() if length $rcvbuf; - process_keys() if length $keybuf; - check_integration() if $one_shot; - update_screen() if $disp_update; - } - continue { - } - } - end_prog(); - } -} - -1; - -# Changelog -# ========= -# 1.9 -# - add %Z support to viewer -# -# 1.8 -# - use string_width in Irssi 1.2.0 -# -# 1.7 -# - fix crash on invalid /set awl_sort, introduced in 1.6, reported by -# tpetazzoni -# - delay viewer initialisation -# - improve race condition on tmux resize integration -# -# 1.6 -# - add detach setting to hide windows -# - fix race condition when loading the script, reported by madduck -# - improve compatibility with irssi 1.2 -# - add special value lru to awl_sort to sort windows by usage -# -# 1.5 -# - improve compat. with sideways splits -# -# 1.4 -# - fix line wrapping in some themes, reported by justanotherbody -# - fix named window key detection, reported by madduck -# - make title (in viewer and shared_sbar) configurable -# -# 1.3 -# - workaround for irssi issue #572 -# -# 1.2 -# - new format to choose abbreviation character -# -# 1.1 -# - infinite loop on shortening certain window names reported by Kalan -# -# 1.0 -# - new awl_viewer_launch setting and an array of related settings -# - fixed regression bug /exec -interactive -# - fixed some warnings in perl 5.10 reported by kl3 -# - workaround for crash due to infinite recursion in irssi's Perl -# error handling -# -# 0.9 -# - fix endless loop in awin detection code! -# - correct colour swap in awl_viewer -# - fix passing of alternate socket path to the viewer -# - potential undefinedness in mouse refnum hinted at by Canopus -# - fixed regression bug /exec -interactive -# - add case-insensitive modifier to awl_sort -# - run custom_xform on awl_prefer_name also -# - avoid inconsistent active window state after awin detection -# reported by ss -# - revert %9-hack in the viewer prompted by discussion with pierrot -# - fix new warning in perl 5.22 -# -# 0.8 -# - replace fifo mode with external viewer script -# - remove bundled cpan modules -# - work around bogus irssi warning -# - improve mouse support -# - workaround for broken cumode in irssi 0.8.15 -# - fix handling of non-meta windows (uninitialized warning) -# - add 256 colour support, strip true colour codes -# - fix totally bogus $N padding reported by Ed S. -# - make /window goto #name mappings work but ignore non-existant ones -# - improve incomplete reads reported by bcode -# - fix single % in awl_viewer reported by bcode -# - add support for key bindings by nike and ferret -# - coerce utf8 key binds -# - add settings: custom_xform, last_line_shade, hide_name_data -# - abbreviations were broken in some cases -# - fix some misuse of / as cmdchar in mouse script reported by bcode -# - add shared status bar mode -# - ${type} variables for custom_xform setting -# - crash if custom_xform had runtime error -# - update sorting documentation -# - fix odd case in size calculation noted by lasers -# - add missing font styles to the viewer reported by ishanyx -# - add italic -# -# 0.7g -# - remove screen support and replace it with fifo support -# - add double-width support to the shortener -# - correct documentation regarding $T vs. display_header -# - add missing refresh for window item changed (thanks vague) -# - add visible windows -# - add exemptions for active window -# - workaround for hiding the window changes from trackbar -# - hack to force 16colours in screen mode -# - remember last window (reported by earthnative) -# - wrong window focus on new queries (reported by emsid) -# - dataloss bug on trying to remember last window -# -# 0.6d+ -# - add support for network headers -# - fixed regression bug /exec -interactive -# -# 0.6ca+ -# - add screen support (from nicklist.pl) -# - names can now have a max length and window names can be used -# - fixed a bug with block display in screen mode and status bar mode -# - added space handling to ir_fe and removed it again -# - now handling formats on my own -# - started to work on $tag display -# - added warning about missing sb_act_none abstract leading to -# - display*active settings -# - added warning about the bug in awl_display_(no)key_active settings -# - mouse hack -# -# 0.5d -# - add setting to also hide the last status bar if empty (awl_all_disable) -# - reverted to old utf8 code to also calculate broken utf8 length correctly -# - simplified dealing with status bars in wlreset -# - added a little tweak for the renamed term_type somewhere after Irssi 0.8.9 -# - fixed bug in handling channel #$$ -# - reset background colour at the beginning of an entry -# -# 0.4d -# - fixed order of disabling status bars -# - several attempts at special chars, without any real success -# and much more weird new bugs caused by this -# - setting to specify sort order -# - reduced timeout values -# - added awl_hide_data -# - make it so the dynamic sub is actually deleted -# - fix a bug with removing of the last separator -# - take into consideration parse_special -# -# 0.3b -# - automatically kill old status bars -# - reset on /reload -# - position/placement settings -# -# 0.2 -# - automated retrieval of key bindings (thanks grep.pl authors) -# - improved removing of status bars -# - got rid of status chop -# -# 0.1 -# - Based on chanact.pl which was apparently based on lightbar.c and -# nicklist.pl with various other ideas from random scripts. diff --git a/.config/irssi/scripts/ascii.pl b/.config/irssi/scripts/ascii.pl @@ -1,405 +0,0 @@ -# -# Commands: /ASCII, /COLSAY, /COLME, /COLTOPIC, /COLKICK, /COLQUIT -# Usage: -# /ASCII [-c1234] [-f <fontname>] [-p <prefix>] [-l|-s|-m <where>] <text> -# /COLSAY [-1234] [-m <where>] <text> -# /COLME [-1234] <text> -# /COLTOPIC [-1234] <text> -# /COLKICK [-1234] [nick(,nick_1,...,nick_n)] <reason> -# /COLQUIT [-1234] <reason> -# Settings: -# /SET ascii_figlet_path [path] -# /SET ascii_default_font [fontname] -# /SET ascii_default_colormode [1-4] -# /SET ascii_default_prefix [prefix] -# /SET ascii_default_kickreason [reason] -# /SET ascii_default_quitreason [reason] -# -# Script is bassed on figlet. -# - -use strict; -use Irssi; -use Irssi::Irc; - -use vars qw($VERSION %IRSSI); - -$VERSION = "1.6.3"; -%IRSSI = ( - "authors" => "Marcin Rozycki", - "contact" => "derwan\@irssi.pl", - "name" => "ascii-art", - "description" => "Ascii-art bassed on figlet. Available commands: /ASCII, /COLSAY, /COLME, /COLTOPIC, /COLKICK, /COLQUIT.", - "url" => "http://derwan.irssi.pl", - "license" => "GNU GPL v2", - "changed" => "Fri Jun 21 17:17:53 CEST 2002" -); - -use IPC::Open3; - -# defaults -my $ascii_default_font = "small.flf"; -my $ascii_default_kickreason = "Irssi BaBy!"; -my $ascii_default_quitreason = "I Quit!"; -my $ascii_last_color = undef; -my @ascii_colors = (12, 12, 12, 9, 5, 4, 13, 8, 7, 3, 11, 10, 2, 6, 6, 6, 6, 10, 8, 7, 4, 3, 9, 11, 2, 12, 13, 5); - -# registering themes -Irssi::theme_register([ - 'ascii_not_connected', '%_$0:%_ You\'re not connected to server', - 'ascii_not_window', '%_$0:%_ Not joined to any channel or query window', - 'ascii_not_chanwindow', '%_$0:%_ Not joined to any channel', - 'ascii_not_chanop', '%_$0:%_ You\'re not channel operator in {hilight $1}', - 'ascii_figlet_notfound', '%_Ascii:%_ Cannot execute {hilight $0} - file not found or bad permissions', - 'ascii_figlet_notset', '%_Ascii:%_ Cannot find external program %_figlet%_, usign /SET ascii_figlet_path [path], to set it', - 'ascii_cmd_syntax', '%_$0:%_ $1, usage: $2', - 'ascii_figlet_error', '%_Ascii: Figlet returns error:%_ $0-', - 'ascii_fontlist', '%_Ascii:%_ Available fonts [in $0]: $1 ($2)', - 'ascii_empty_fontlist', '%_Ascii:%_ Cannot find figlet fonts in $0', - 'ascii_unknown_fontdir', '%_Ascii:%_ Cannot find figlet fontdir', - 'ascii_show_line', '$0-' - -]); - -# str find_figlet_path() -sub find_figlet_path { - foreach my $dir (split(/\:/, $ENV{'PATH'})) - { - return "$dir/figlet" if ($dir and -x "$dir/figlet"); - } -} - -# int randcolor() -sub randcolor { - return $ascii_colors[int(rand(12)+18)]; -} - -# str colorline($colormode, $text) -sub colorline { - my ($colormode, $text) = @_; - my $colortext = undef; - my $last = ($ascii_last_color) ? $ascii_last_color : randcolor(); - my $indx = $last; - - if ($colormode =~ /3/) { - $ascii_last_color = randcolor(); - }elsif ($colormode =~ /4/) { - $ascii_last_color = $ascii_colors[$last]; - }elsif ($colormode !~ /2/) { - $ascii_last_color = $ascii_colors[14+$last]; - } - - while ($text =~ /./g) - { - my $char = "$&"; - - if ($colormode =~ /3/) { - while ($indx == $last) { $indx = randcolor(); }; - $last = $indx; - }elsif ($colormode =~ /4/) { - $indx = $ascii_colors[$indx]; - }elsif ($last) { - $indx = $ascii_colors[$last]; - undef $last; - } else { - $indx = $ascii_colors[$indx]; - $last = $indx + 14; - }; - - $colortext .= $char, next if ($char eq " "); - $colortext .= "\003" . sprintf("%02d", $indx) . $char; - $colortext .= $char if ($char eq ","); - }; - - return $colortext; -}; - -# int colormode() -sub colormode { - my $mode = Irssi::settings_get_int("ascii_default_colormode"); - $mode =~ s/-//g; - return (!$mode or $mode > 4) ? 1 : $mode; -}; - -# bool ascii_test($command, $flags, $server, $window) -sub ascii_test { - my ($cmd, $test, $server, $window) = @_; - - if ($test =~ /s/ and !$server || !$server->{connected}) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_connected", $cmd); - return 0; - }; - if ($test =~ /W/ and !$window || $window->{type} !~ /(channel|query)/i) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_window", $cmd); - return 0; - }; - if ($test =~ /(w|o)/ and !$window || $window->{type} !~ /channel/i) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_chanwindow", $cmd); - return 0; - }; - if ($test =~ /o/ and !$window->{chanop}) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_not_chanop", $cmd, Irssi::active_win()->get_active_name()); - return 0; - }; - - return 1; -} - -# void cmd_ascii() -# handles /ascii -sub cmd_ascii -{ - my $usage = "/ASCII [-c1234] [-f <fontname>] [-p <prefix>] [-l|-s|-m <where>] <text>"; - my $font = Irssi::settings_get_str("ascii_default_font"); - my $prefix = Irssi::settings_get_str("ascii_default_prefix"); - my ($arguments, $server, $witem) = @_; - my ($text, $cmd, $mode); - - $font = $ascii_default_font unless ($font); - $ascii_last_color = randcolor(); - - my $figlet = Irssi::settings_get_str("ascii_figlet_path"); - if (!$figlet or !(-x $figlet)) { - my $theme = ($figlet) ? "ascii_figlet_notfound" : "ascii_figlet_notset"; - Irssi::printformat(MSGLEVEL_CRAP, $theme, $figlet); - return; - }; - - my @foo = split(/ +/, $arguments); - while ($_ = shift(@foo)) - { - /^-l$/ and show_figlet_fonts($figlet), return; - /^-c$/ and $mode = colormode(), next; - /^-(1|2|3|4)$/ and s/-//g, $mode = $_, next; - /^-f$/ and $font = shift(@foo), next; - /^-p$/ and $prefix = shift(@foo), next; - /^-m$/ and $cmd = shift(@foo), next; - /^-s$/ and $cmd = 0, next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Ascii", "Unknown argument: $_", $usage), return; - $text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo); - last; - } - - unless (length($text)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Ascii", "Missing arguments", $usage); - return; - }; - - if ($cmd eq "") { - return unless (ascii_test("Ascii", "sW", $server, $witem)); - $cmd = Irssi::active_win()->get_active_name(); - } elsif ($cmd ne "0" and !ascii_test("Ascii", "s", $server, $witem)) { - return; - } - - my $pid = open3(*FIGIN, *FIGOUT, *FIGERR, $figlet, qw(-k -f), $font, $text); - - while (<FIGOUT>) - { - chomp; - next unless (/[^ ]/); - $_ = colorline($mode, $_) if ($mode); - Irssi::printformat(MSGLEVEL_CLIENTCRAP, "ascii_show_line", $prefix.$_), next if ($cmd eq "0"); - $server->command("msg $cmd $prefix$_"); - } - - while (<FIGERR>) - { - chomp; - Irssi::printformat(MSGLEVEL_CRAP, "ascii_figlet_error", $_); - }; - - close FIGIN; - close FIGOUT; - close FIGERR; - - waitpid $pid, 0; -} - -# void show_figlet_fonts(figlet path) -sub show_figlet_fonts { - my @fontlist; - if (my $fontdir = `"$_[0]" -I 2 2>/dev/null`) { - chomp $fontdir; - foreach my $font (glob $fontdir."/*.flf") - { - $font =~ s/^$fontdir\///; - $font =~ s/\.flf$//; - push @fontlist, $font; - } - if ($#fontlist < 0) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_fontlist_empty", $fontdir); - } else { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_fontlist", $fontdir, join(", ", @fontlist), scalar(@fontlist)); - } - } else { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_unknown_fontdir"); - } -} - -# void cmd_colsay() -# handles /colsay -sub cmd_colsay { - my $usage = "/COLSAY [-1234] [-m <where>] <text>"; - my ($arguments, $server, $witem) = @_; - my ($cmd, $text); - my $mode = colormode(); - - $ascii_last_color = randcolor(); - - my @foo = split(/ /, $arguments); - while ($_ = shift(@foo)) - { - /^-(1|2|3|4)$/ and $mode = $_, next; - /^-m$/i and $cmd = shift(@foo), next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colsay", "Unknown argument: $_", $usage), return; - $text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo); - last; - }; - - unless (length($text)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colsay", "Missing arguments", $usage); - return; - }; - - if ($cmd) { - return unless (ascii_test("Colsay", "s", $server, $witem)); - } else { - return unless (ascii_test("Colsay", "sW", $server, $witem)); - $cmd = Irssi::active_win()->get_active_name(); - }; - - $server->command("msg $cmd ".colorline($mode, $text)); -} - - -sub cmd_colme { - my $usage = "/COLME [-1234] <text>"; - my ($arguments, $server, $witem) = @_; - my $mode = colormode(); - my $text; - - $ascii_last_color = randcolor(); - - my @foo = split(/ /, $arguments); - while ($_ = shift(@foo)) - { - /^-(1|2|3|4)$/ and $mode = $_, next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colme", "Unknown argument: $_", $usage), return; - $text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo); - last; - }; - - unless (length($text)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colme", "Missing arguments", $usage); - return; - }; - - return unless (ascii_test("Colme", "sW", $server, $witem)); - $witem->command("me ".colorline($mode, $text)); -} - -# void cmd_coltopic() -# handles /coltopic -sub cmd_coltopic { - my $usage = "/COLTOPIC [-1234] <text>"; - my ($arguments, $server, $witem) = @_; - my $mode = colormode(); - my $text; - - $ascii_last_color = randcolor(); - - my @foo = split(/ /, $arguments); - while ($_ = shift(@foo)) - { - /^-(1|2|3|4)$/ and $mode = $_, next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Coltopic", "Unknown argument: $_", $usage), return; - $text = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo); - last; - }; - - unless (length($text)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Coltopic", "Missing arguments", $usage); - return; - }; - - return unless (ascii_test("Coltopic", "sw", $server, $witem)); - - $server->command("topic " . Irssi::active_win()->get_active_name() . " " . colorline($mode, $text)); -}; - -# void cmd_colkick() -# handles /colkick -sub cmd_colkick { - my $usage = "/COLKICK [-1234] [nick(,nick_1,...,nick_n)] <reason>"; - my ($arguments, $server, $witem) = @_; - my $kickreason = Irssi::settings_get_str("ascii_default_kickreason"); - my $mode = colormode(); - my $who = undef; - - $ascii_last_color = randcolor(); - $kickreason = $ascii_default_kickreason unless ($kickreason); - - my @foo = split(/ /, $arguments); - while ($_ = shift(@foo)) - { - /^-(1|2|3|4)$/ and $mode = $_, next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colkick", "Unknown argument: $_", $usage), return; - $kickreason = join(" ", @foo) if ($#foo >= 0); - $who = $_; - last; - }; - - if (!$who or !length($kickreason)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colkick", "Missing arguments", $usage); - return; - }; - - return unless (ascii_test("Colkick", "swo", $server, $witem)); - $witem->command("kick $who ".colorline($mode, $kickreason)); -}; - -# void cmd_colquit() -# handles /colquit -sub cmd_colquit { - my $usage = "/COLQUIT [-1234] <reason>"; - my ($arguments, $server, $witem) = @_; - my $quitreason = Irssi::settings_get_str("ascii_default_quitreason"); - my $mode = colormode(); - - $ascii_last_color = randcolor(); - $quitreason = $ascii_default_quitreason unless ($quitreason); - - my @foo = split(/ /, $arguments); - while ($_ = shift(@foo)) - { - /^-(1|2|3|4)$/ and $mode = $_, next; - /^-/ and Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colquit", "Unknown argument: $_", $usage), return; - $quitreason = ($#foo < 0) ? $_ : $_ . " " . join(" ", @foo); - last; - }; - - unless (length($quitreason)) { - Irssi::printformat(MSGLEVEL_CRAP, "ascii_cmd_syntax", "Colquit", "Missing arguments", $usage); - return; - }; - - return unless (ascii_test("Colquit", "s", $server, $witem)); - $server->command("quit " . colorline($mode, $quitreason)); -} - -# registering settings -Irssi::settings_add_str("misc", "ascii_default_font", $ascii_default_font); -Irssi::settings_add_str("misc", "ascii_default_kickreason", $ascii_default_kickreason); -Irssi::settings_add_str("misc", "ascii_default_quitreason", $ascii_default_quitreason); -Irssi::settings_add_str("misc", "ascii_default_prefix", ""); -Irssi::settings_add_int("misc", "ascii_default_colormode", 1); -Irssi::settings_add_str("misc", "ascii_figlet_path", find_figlet_path); - -# binding commands -Irssi::command_bind("ascii", "cmd_ascii"); -Irssi::command_bind("colsay", "cmd_colsay"); -Irssi::command_bind("colme", "cmd_colme"); -Irssi::command_bind("coltopic", "cmd_coltopic"); -Irssi::command_bind("colkick", "cmd_colkick"); -Irssi::command_bind("colquit", "cmd_colquit"); diff --git a/.config/irssi/scripts/autonickprefix.pl b/.config/irssi/scripts/autonickprefix.pl @@ -1,39 +0,0 @@ -use strict; - -our $VERSION = '1.00'; -our %IRSSI = ( - authors => 'Juerd', - contact => '#####@juerd.nl', - name => 'autonickprefix', - description => "Change 'nick: ' prefix if the nick is changed while you're still editing.", - license => 'Any OSI', -); - -use Irssi::TextUI; -use Irssi qw( - signal_add active_win settings_get_str parse_special - gui_input_get_pos gui_input_set gui_input_set_pos -); - -signal_add 'nicklist changed' => sub { - my ($chan, $newnick, $oldnick) = @_; - $newnick = $newnick->{nick}; - - # Ignore other channels than current - my $viewing = active_win->{active} or return; - $viewing->{_irssi} == $chan->{_irssi} or return; - - my $char = settings_get_str 'completion_char'; - my $pos = gui_input_get_pos; - - # Incomplete nick could be something else. - $pos >= length("$oldnick$char") or return; - - my $delta = length($newnick) - length($oldnick); - - my $input = parse_special '$L'; - $input =~ s/^\Q$oldnick$char/$newnick$char/ or return; - - gui_input_set $input; - gui_input_set_pos $pos + $delta; -}; diff --git a/.config/irssi/scripts/autorun/adv_windowlist.pl b/.config/irssi/scripts/autorun/adv_windowlist.pl @@ -870,7 +870,7 @@ sub _calculate_items { if ($win->{data_level} == 0) { 'sb_act_none'; } elsif ($win->{data_level} == 1) { 'sb_act_text'; } elsif ($win->{data_level} == 2) { 'sb_act_msg'; } - elsif ($colour ne '') { "sb_act_hilight_color $colour"; } + elsif ($colour ne '') { 'sb_act_hilight'; } elsif ($win->{data_level} == 3) { 'sb_act_hilight'; } else { 'sb_act_special'; } }; diff --git a/.config/irssi/scripts/autorun/nickcolor.pl b/.config/irssi/scripts/autorun/nickcolor.pl @@ -450,6 +450,11 @@ sub topic2mlt { msg_line_tag($srv, $chan, $nick, $addr); } +sub notice2mlt { + my ($srv, $msg, $nick, $addr, $chan) = @_; + msg_line_tag($srv, $chan, $nick, $addr); +} + sub msg_line_tag_xmppaction { clear_ref(), return unless @_; my ($srv, $msg, $nick, $targ) = @_; @@ -1039,18 +1044,13 @@ Irssi::expando_create('nickcolor', \&expando_neatcolour, { 'message nick' => 'none', 'message invite' => 'none', 'message invite_other' => 'none', + 'message irc notice' => 'none', 'message topic' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), }); Irssi::expando_create('inickcolor', \&expando_neatcolour_inv, { 'message public' => 'none', 'message own_public' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), }); Irssi::signal_add({ @@ -1065,11 +1065,8 @@ Irssi::signal_add({ 'message nick' => 'nick2mlt', 'message invite' => 'invite2mlt', 'message invite_other' => 'inviteo2mlt', - 'message topic' => 'topic2mlt', + 'message irc notice' => 'notice2mlt', 'message irc mode' => 'msg_line_clear', - (map { ("message $_ action" => 'msg_line_tag', - "message $_ own_action" => 'msg_line_clear') - } qw(irc silc)), "message xmpp action" => 'msg_line_tag_xmppaction', "message xmpp own_action" => 'msg_line_clear', 'print text' => 'prnt_clear_public', diff --git a/.config/irssi/scripts/autorun/nm2.pl b/.config/irssi/scripts/autorun/nm2.pl @@ -181,27 +181,18 @@ Irssi::expando_create('nickalign', \&expando_nickalign, { 'message own_public' => 'none', 'message private' => 'none', 'message own_private' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), }); Irssi::expando_create('nicktrunc', \&expando_nicktrunc, { 'message public' => 'none', 'message own_public' => 'none', 'message private' => 'none', 'message own_private' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), }); Irssi::expando_create('nickcumode', \&expando_nickcumode, { 'message public' => 'none', 'message own_public' => 'none', 'message private' => 'none', 'message own_private' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), }); sub init_hist { @@ -222,9 +213,6 @@ my %em = ( ); my %formats = ( - own_action => [5, '{action_core {ownnick ', '$0','}}','$1' ], - action_public => [4, '{action_core {pubnick ', '$0','}}','$1' ], - own_msg => [1, '{ownmsgnick ' ,'%G$2', ' {ownnick ' ,'$0','}','' ,'}','$1' ], own_msg_channel => [1, '{ownmsgnick ' ,'%G$3', ' {ownnick ' ,'$0','}','{msgchannel $1}','}','$2' ], pubmsg_me => [0, '{pubmsgmenick ' ,'%G$2', ' {pubnick ' ,'$0','}','' ,'}','$1' ], @@ -298,29 +286,30 @@ sub update_nm { } my $longest; - if ($S{dynamic}) { - my $hist = $histories{"$tg/$target"} ||= init_hist($server, $target); - my $last = $histories{"$tg/$target/last"} || 1; - unshift @$hist, length $nick; - if (@$hist > 2*$S{history}) { - splice @$hist, $S{history}; - } - my @add; - unless ($S{shrink}) { - push @add, $last; - } - if ($S{staircase}) { - push @add, $last - 1 - } - $longest = $histories{"$tg/$target/last"} = max(@$hist, @add); - - if ($S{max} && ($S{max} < $longest || !$S{shrink})) { - $longest = $S{max}; - } - } - else { - $longest = $S{max}; - } + # if ($S{dynamic}) { + # my $hist = $histories{"$tg/$target"} ||= init_hist($server, $target); + # my $last = $histories{"$tg/$target/last"} || 1; + # unshift @$hist, length $nick; + # if (@$hist > 2*$S{history}) { + # splice @$hist, $S{history}; + # } + # my @add; + # unless ($S{shrink}) { + # push @add, $last; + # } + # if ($S{staircase}) { + # push @add, $last - 1 + # } + # $longest = $histories{"$tg/$target/last"} = max(@$hist, @add); + + # if ($S{max} && ($S{max} < $longest || !$S{shrink})) { + # $longest = $S{max}; + # } + # } + # else { + # $longest = $S{max}; + $longest = 10; + # } my $size = $mode < 4 ? $longest : max(0, $longest - $S{melength}); my $t_add = update_expando($mode, $server, $target, $nick, $size); @@ -490,15 +479,6 @@ Irssi::signal_add_first({ my ($server, $msg, $nick, $address) = @_; update_nm(2, $server, $nick, $nick); }, - (map { ("message $_ action" => sub { - my ($server, $msg, $nick, $address, $target) = @_; - update_nm(4, $server, $target, $nick); - }) } qw(irc silc)), - 'message xmpp action' => sub { - return unless @_; - my ($server, $msg, $nick, $target) = @_; - update_nm(4, $server, $target, $nick); - }, }); sub channel_nick { @@ -515,15 +495,6 @@ Irssi::signal_add_first({ my ($server, $msg, $target) = @_; update_nm(3, $server, $target, $server->{nick}); }, - (map { ("message $_ own_action" => sub { - my ($server, $msg, $target) = @_; - update_nm(5, $server, $target, $server->{nick}); - }) } qw(irc silc)), - 'message xmpp own_action' => sub { - return unless @_; - my ($server, $msg, $target) = @_; - update_nm(5, $server, $target, channel_nick($server, $target)); - }, 'message join' => sub { my ($server, $target, $nick) = @_; update_nm(2, $server, $target, $server->{nick}); diff --git a/.config/irssi/scripts/cmdind.pl b/.config/irssi/scripts/cmdind.pl @@ -1,61 +0,0 @@ -use strict; -use warnings; - -our $VERSION = '1.1'; # 67ffc4766319fe4 -our %IRSSI = ( - authors => 'Nei', - contact => 'Nei @ anti@conference.jabber.teamidiot.de', - url => "http://anti.teamidiot.de/", - name => 'cmdind', - description => 'Indicator for input prompt if you are inputting a command or text', - license => 'GNU GPLv2 or later', - ); - -# Usage -# ===== -# This script requires the -# -# uberprompt -# -# script to work. If you don't have it yet, /script install uberprompt - -# Options -# ======= -# /set cmdind_text <string> -# * string : Text to show in prompt when typing a command -# -# /set cmdind_warn_text <string> -# * string : Text to show in prompt when typing a command with spaces in front - -use Irssi; - -my $cmd_state = 0; -my $cmdchars; -my @text; - -sub check_input { - my $inputline = Irssi::parse_special('$L'); - my $c1 = length $inputline > 0 ? substr $inputline, 0, 1 : ''; - my $c2 = length $inputline > 1 ? substr $inputline, 1, 1 : ''; - my $old_state = $cmd_state; - my $x_state = length $c2 && (-1 != index $cmdchars, $c1) && $c2 ne ' '; - my $warn_state = - ($inputline =~ /^\s+(\S)/ && (-1 != index $cmdchars, $1)) - || ($x_state && $inputline =~ /^(.)\1?+\S*[\Q$cmdchars\E]/); - $cmd_state = $warn_state ? 2 : $x_state ? 1 : 3; - if ($cmd_state ne $old_state) { - Irssi::signal_emit('change prompt', $text[ $cmd_state ], 'UP_POST'); - } -} -sub setup_changed { - $cmdchars = Irssi::settings_get_str('cmdchars'); - @text = ('', - Irssi::settings_get_str('cmdind_text'), - Irssi::settings_get_str('cmdind_warn_text'), - ''); -} -Irssi::settings_add_str('cmdind', 'cmdind_text', '%gCmd:'); -Irssi::settings_add_str('cmdind', 'cmdind_warn_text', '%RMsg?'); -setup_changed(); -Irssi::signal_add_last('gui key pressed', 'check_input'); -Irssi::signal_add('setup changed', 'setup_changed'); diff --git a/.config/irssi/scripts/ctcpspoof.pl b/.config/irssi/scripts/ctcpspoof.pl @@ -1,277 +0,0 @@ -#!/usr/bin/perl -w - -## Bugreports and Licence disclaimer. -# -# For bugreports and other improvements contact Geert Hauwaerts <geert@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 script; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -## - -use strict; -use Irssi; -use vars qw($VERSION %IRSSI); - -$VERSION = "1.04"; - -%IRSSI = ( - authors => 'Geert Hauwaerts', - contact => 'geert@irssi.org', - name => 'fakectcp.pl', - description => 'This script sends fake ctcp replies to a client using a fake ctcp list.', - license => 'GNU General Public License', - url => 'http://irssi.hauwaerts.be/default.pl', - changed => '2018-09-17', -); - -my @fakectcp = (); -my $fakectcp_file = "fctcplist"; -my $irssidir = Irssi::get_irssi_dir(); - -my $help = <<EOF; - -Usage: (all on one line) -/FCTCP [-add||-replace <ctcp-item> <ctcp-reply>] [-del <ctcp-item>] [-list] [-help] - --add: Add a new fake ctcp-reply to the list. --del: Delete a fake ctcp-reply from the list. --list: Display the contents of the fake ctcp-reply list. --help: Display this useful little helpfile. --replace: Replace an existing fake reply with a new one. If the old one doesn't exist, the new one will be added by default. - -Examples: (all on one line) -/FCTCP -add CHRISTEL We all love christel, don't we! :) -/FCTCP -add LOCATION I'm at home, reading some helpfiles. - -/FCTCP -del CHRISTEL -/FCTCP -del LOCATION - -Note: The caps are not obligated. The default parameter is -list. -EOF - -Irssi::theme_register([ - 'fctcp_info', ' # ctcpitem ctcpreply', - 'fctcp_empty', '%R>>%n %_FCTCP:%_ Your fake ctcp list is empty.', - 'fctcp_added', '%R>>%n %_FCTCP:%_ Added %_$0%_ ($1) to the fake ctcp list.', - 'fctcp_replaced', '%R>>%n %_FCTCP:%_ Replaced the old fake reply %_$0%_ with the new one ($1)', - 'fctcp_delled', '%R>>%n %_FCTCP:%_ Deleted %_$0%_ from the fake ctcp list.', - 'fctcp_nfound', '%R>>%n %_FCTCP:%_ Can\'t find $0 in the fake ctcp list.', - 'fctcp_delusage', '%R>>%n %_FCTCP:%_ Usage: /FCTCP -del <ctcp-item>', - 'fctcp_usage', '%R>>%n %_FCTCP:%_ Usage: /FCTCP -add <ctcp-item> <ctcp-reply>', - 'fctcp_repusage', '%R>>%n %_FCTCP:%_ Usage: /FCTCP -replace <ctcp-item> <ctcp-reply>', - 'fctcp_nload', '%R>>%n %_FCTCP:%_ Could not load the fake ctcp list.', - 'fctcp_request', '%R>>%n %_FCTCP:%_ Used the fake reply %_$1%_ on %_$0%_', - 'fctcp_loaded', '%R>>%n %_FCTCP:%_ The fake reply %_$0%_ already exists, use %_/FCTCP -del $0%_ to remove it from the list.', - 'fctcp_print', '$[!-2]0 $[20]1 $2', - 'fctcp_help', '$0', - 'loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.' -]); - -sub ctcpreply { - - my ($server, $data, $nick, $address, $target) = @_; - my ($findex); - - $data = lc($data); - - return unless (lc($server->{nick}) eq lc($target)); - - if (!already_loaded($data)) { - $findex = check_loaded($data); - $server->command("^NCTCP $nick $data $fakectcp[$findex]->{reply}"); - Irssi::printformat(MSGLEVEL_CTCPS, 'fctcp_request', $nick, $data); - Irssi::signal_stop(); - } -} - -sub new_fctcp { - - my $fctcp = {}; - - $fctcp->{item} = shift; - $fctcp->{reply} = shift; - - return $fctcp; -} - -sub already_loaded { - - my ($item) = @_; - my $loaded = check_loaded($item); - - if ($loaded > -1) { - return 0; - } - - return 1; -} - -sub check_loaded { - - my ($item) = @_; - - $item = lc($item); - - for (my $loaded = 0; $loaded < @fakectcp; ++$loaded) { - return $loaded if (lc($fakectcp[$loaded]->{item}) eq $item); - } - - return -1; -} - -sub load_fakectcplist { - - my ($file) = @_; - - @fakectcp = (); - - if (-e $file) { - local *F; - open(F, "<", $file); - local $/ = "\n"; - - while (<F>) { - chop; - my $new_fctcp = new_fctcp(split("\t")); - - if (($new_fctcp->{item} ne "") && ($new_fctcp->{reply} ne "")) { - push(@fakectcp, $new_fctcp); - } - } - - close(F); - } else { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_nload'); - } -} - -sub save_fakectcplist { - - my ($file) = @_; - - local *F; - open(F, ">", $file) or die "Could not load the fake ctcpreply list for writing"; - - for (my $n = 0; $n < @fakectcp; ++$n) { - print(F join("\t", $fakectcp[$n]->{item}, $fakectcp[$n]->{reply}) . "\n"); - } - - close(F); -} - -sub addfakectcp { - - my ($ctcpitem, $ctcpreply) = split (" ", $_[0], 2); - - if (($ctcpitem eq "") || ($ctcpreply eq "")) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_usage'); - return; - } elsif (!already_loaded($ctcpitem)) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_loaded', $ctcpitem); - return; - } - - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_added', $ctcpitem, $ctcpreply); - push(@fakectcp, new_fctcp($ctcpitem, $ctcpreply)); - save_fakectcplist("$irssidir/$fakectcp_file"); -} - -sub delfakectcp { - - my ($fdata) = @_; - my ($fdataindex); - - if ($fdata eq "") { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_delusage'); - return; - } - - for (my $index = 0; $index < @fakectcp; ++$index) { - if (lc($fakectcp[$index]->{item}) eq $fdata) { - $fdataindex = splice(@fakectcp, $index, 1); - } - } - - if ($fdataindex) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_delled', $fdata); - save_fakectcplist("$irssidir/$fakectcp_file"); - } else { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_nfound', $fdata); - } -} - -sub replacefakectcp { - - my ($ctcpitem, $ctcpreply) = split (" ", $_[0], 2); - my ($fdataindex); - - if (($ctcpitem eq "") || ($ctcpreply eq "")) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_repusage'); - return; - } - - if (!already_loaded($ctcpitem)) { - for (my $index = 0; $index < @fakectcp; ++$index) { - if (lc($fakectcp[$index]->{item}) eq $ctcpitem) { - $fdataindex = splice(@fakectcp, $index, 1); - } elsif ($fdataindex) { - save_fakectcplist("$irssidir/$fakectcp_file"); - } - } - } - - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_replaced', $ctcpitem, $ctcpreply); - push(@fakectcp, new_fctcp($ctcpitem, $ctcpreply)); - save_fakectcplist("$irssidir/$fakectcp_file"); -} - -sub fakectcp { - - my ($cmdoption, $ctcpitem, $ctcpreply) = split (" ", $_[0], 3); - - $ctcpitem = lc($ctcpitem); - $cmdoption = lc($cmdoption); - - if ($cmdoption eq "-add") { - addfakectcp("$ctcpitem $ctcpreply"); - return; - } elsif ($cmdoption eq "-del") { - delfakectcp("$ctcpitem"); - return; - } elsif ($cmdoption eq "-help") { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_help', $help); - return; - } elsif ($cmdoption eq "-replace") { - replacefakectcp("$ctcpitem $ctcpreply"); - return; - } - - if (@fakectcp == 0) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_empty'); - } else { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_info'); - - for (my $n = 0; $n < @fakectcp ; ++$n) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'fctcp_print', $n, $fakectcp[$n]->{item}, $fakectcp[$n]->{reply}); - } - } -} - -load_fakectcplist("$irssidir/$fakectcp_file"); - -Irssi::signal_add('ctcp msg', 'ctcpreply'); -Irssi::command_bind('fctcp', 'fakectcp'); -Irssi::command_set_options('fctcp','add del list help replace'); -Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'loaded', $IRSSI{name}, $VERSION, $IRSSI{authors}); diff --git a/.config/irssi/scripts/dim_nicks.pl b/.config/irssi/scripts/dim_nicks.pl @@ -1,431 +0,0 @@ -use strict; -use warnings; - -our $VERSION = '0.4.9'; -our %IRSSI = ( - authors => 'Nei', - contact => 'Nei @ anti@conference.jabber.teamidiot.de', - url => "http://anti.teamidiot.de/", - name => 'dim_nicks', - description => 'Dims nicks that are not in channel anymore.', - license => 'GNU GPLv2 or later', - ); - -# Usage -# ===== -# Once loaded, this script will record the nicks of each new -# message. If the user leaves the room, the messages will be rewritten -# with the nick in another colour/style. -# -# Depending on your theme, tweaking the forms settings may be -# necessary. With the default irssi theme, this script should just -# work. - -# Options -# ======= -# /set dim_nicks_color <colour> -# * the colour code to use for dimming the nick, or a string of format -# codes with the special token $* in place of the nick (e.g. %I$*%I -# for italic) -# -# /set dim_nicks_history_lines <num> -# * only this many lines of messages are remembered/rewritten (per -# window) -# -# /set dim_nicks_ignore_hilights <ON|OFF> -# * ignore lines with hilight when dimming -# -# /set dim_nicks_forms_skip <num> -# /set dim_nicks_forms_search_max <num> -# * these two settings limit the range where to search for the -# nick. -# It sets how many forms (blocks of irssi format codes or -# non-letters) to skip at the beginning of line before starting to -# search for the nick, and from then on how many forms to search -# before stopping. -# You should set this to the appropriate values to avoid (a) dimming -# your timestamp (b) dimming message content instead of the nick. -# To check your settings, you can use the command -# /script exec Irssi::Script::dim_nicks::debug_forms - - -no warnings 'redefine'; -use constant IN_IRSSI => __PACKAGE__ ne 'main' || $ENV{IRSSI_MOCK}; -use Irssi 20140701; -use Irssi::TextUI; -use Encode; - - -sub setc () { - $IRSSI{name} -} - -sub set ($) { - setc . '_' . $_[0] -} - -my $history_lines = 100; -my $skip_forms = 1; -my $search_forms_max = 5; -my $ignore_hilights = 1; -my $color_letter = 'K'; -my @color_code = ("\cD8/"); # update this when you change $color_letter - -# nick object cache, chan object cache, line id cache, line id -> window map, -> channel, -> nick, -> nickname, channel -> line ids, channel->nickname->departure time, channel->nickname->{parts of line} -my (%nick_reg, %chan_reg, %history_w, %history_c, %history_n, %history_nn, %history_st, %lost_nicks, %lost_nicks_fs, %lost_nicks_fc, %lost_nicks_bc, %lost_nicks_bs); - -our ($dest, $chanref, $nickref); - - -sub msg_line_tag { - my ($srv, $msg, $nick, $addr, $targ) = @_; - local $chanref = $srv->channel_find($targ); - local $nickref = ref $chanref ? $chanref->nick_find($nick) : undef; - &Irssi::signal_continue; -} - -sub color_to_code { - my $win = Irssi::active_win; - my $view = $win->view; - my $cl = $color_letter; - if (-1 == index $cl, '$*') { - $cl = "%$cl\$*"; - } - $win->print_after(undef, MSGLEVEL_NEVER, "$cl "); - my $lp = $win->last_line_insert; - my $color_code = $lp->get_text(1); - $color_code =~ s/ $//; - $view->remove_line($lp); - @color_code = split /\$\*/, $color_code, 2; -} - -sub setup_changed { - $history_lines = Irssi::settings_get_int( set 'history_lines' ); - $skip_forms = Irssi::settings_get_int( set 'forms_skip' ); - $search_forms_max = Irssi::settings_get_int( set 'forms_search_max' ); - $ignore_hilights = Irssi::settings_get_bool( set 'ignore_hilights' ); - my $new_color = Irssi::settings_get_str( set 'color' ); - if ($new_color ne $color_letter) { - $color_letter = $new_color; - color_to_code(); - } -} - -sub init_dim_nicks { - setup_changed(); -} - -sub prt_text_issue { - my ($ld) = @_; - local $dest = $ld; - &Irssi::signal_continue; -} - -sub expire_hist { - for my $ch (keys %history_st) { - if (@{$history_st{$ch}} > 2 * $history_lines) { - my @del = splice @{$history_st{$ch}}, 0, $history_lines; - delete @history_w{ @del }; - delete @history_c{ @del }; - delete @history_n{ @del }; - delete @history_nn{ @del }; - } - } -} - -sub prt_text_ref { - return unless $nickref; - return unless $dest && defined $dest->{target}; - return unless $dest->{level} & MSGLEVEL_PUBLIC; - return if $ignore_hilights && $dest->{level} & MSGLEVEL_HILIGHT; - - my ($win) = @_; - my $view = $win->view; - my $line_id = $view->{buffer}{_irssi} .','. $view->{buffer}{cur_line}{_irssi}; - $chan_reg{ $chanref->{_irssi} } = $chanref; - $nick_reg{ $nickref->{_irssi} } = $nickref; - if (exists $history_w{ $line_id }) { - } - $history_w{ $line_id } = $win->{_irssi}; - $history_c{ $line_id } = $chanref->{_irssi}; - $history_n{ $line_id } = $nickref->{_irssi}; - $history_nn{ $line_id } = $nickref->{nick}; - push @{$history_st{ $chanref->{_irssi} }}, $line_id; - expire_hist(); - my @lost_forever = grep { $view->{buffer}{first_line}{info}{time} > $lost_nicks{ $chanref->{_irssi} }{ $_ } } - keys %{$lost_nicks{ $chanref->{_irssi} }}; - delete @{$lost_nicks{ $chanref->{_irssi} }}{ @lost_forever }; - delete @{$lost_nicks_fs{ $chanref->{_irssi} }}{ @lost_forever }; - delete @{$lost_nicks_fc{ $chanref->{_irssi} }}{ @lost_forever }; - delete @{$lost_nicks_bc{ $chanref->{_irssi} }}{ @lost_forever }; - delete @{$lost_nicks_bs{ $chanref->{_irssi} }}{ @lost_forever }; - return; -} - -sub win_del { - my ($win) = @_; - for my $ch (keys %history_st) { - @{$history_st{$ch}} = grep { exists $history_w{ $_ } && - $history_w{ $_ } != $win->{_irssi} } @{$history_st{$ch}}; - } - my @del = grep { $history_w{ $_ } == $win->{_irssi} } keys %history_w; - delete @history_w{ @del }; - delete @history_c{ @del }; - delete @history_n{ @del }; - delete @history_nn{ @del }; - return; -} - -sub _alter_lines { - my ($chan, $check_lr, $ad) = @_; - my $win = $chan->window; - return unless ref $win; - my $view = $win->view; - my $count = $history_lines; - my $buffer_id = $view->{buffer}{_irssi} .','; - my $lp = $view->{buffer}{cur_line}; - my %check_lr = map { $_ => undef } @$check_lr; - my $redraw; - my $bottom = $view->{bottom}; - while ($lp && $count) { - my $line_id = $buffer_id . $lp->{_irssi}; - if (exists $check_lr{ $line_id }) { - $lp = _alter_line($buffer_id, $line_id, $win, $view, $lp, $chan->{_irssi}, $ad); - unless ($lp) { - last; - } - $redraw = 1; - } - } continue { - --$count; - $lp = $lp->prev; - } - if ($redraw) { - $win->command('^scrollback end') if $bottom && !$win->view->{bottom}; - $view->redraw; - } -} - -my $irssi_mumbo = qr/\cD[`-i]|\cD[&-@\xff]./; -my $irssi_mumbo_no_partial = qr/(?<!\cD)(?<!\cD[&-@\xff])/; -my $irssi_skip_form_re = qr/((?:$irssi_mumbo|[.,*@%+&!#$()=~'";:?\/><]+(?=$irssi_mumbo|\s))+|\s+)/; - -sub debug_forms { - my $win = Irssi::active_win; - my $view = $win->view; - my $lp = $view->{buffer}{cur_line}; - my $count = $history_lines; - my $buffer_id = $view->{buffer}{_irssi} .','; - while ($lp && $count) { - my $line_id = $buffer_id . $lp->{_irssi}; - if (exists $history_w{ $line_id }) { - my $line_nick = $history_nn{ $line_id }; - my $text = $lp->get_text(1); - pos $text = 0; - my $from = 0; - for (my $i = 0; $i < $skip_forms; ++$i) { - last unless - scalar $text =~ /$irssi_skip_form_re/g; - $from = pos $text; - } - my $to = $from; - for (my $i = 0; $i < $search_forms_max; ++$i) { - last unless - scalar $text =~ /$irssi_skip_form_re/g; - $to = pos $text; - } - my $pre = substr $text, 0, $from; - my $search = substr $text, $from, $to-$from; - my $post = substr $text, $to; - unless ($to > $from) { - } else { - my @nick_reg; - unshift @nick_reg, quotemeta substr $line_nick, 0, $_ for 1 .. length $line_nick; - no warnings 'uninitialized'; - for my $nick_reg (@nick_reg) { - last if $search - =~ s/(\Q$color_code[0]\E\s*)?((?:$irssi_mumbo)+)?$irssi_mumbo_no_partial($nick_reg)((?:$irssi_mumbo)+)?(\s*\Q$color_code[0]\E)?/<match>$1$2<nick>$3<\/nick>$4$5<\/match>/; - last if $search - =~ s/(?:\Q$color_code[0]\E)?(?:(?:$irssi_mumbo)+?)?$irssi_mumbo_no_partial($nick_reg)(?:(?:$irssi_mumbo)+?)?(?:\Q$color_code[1]\E)?/<nick>$1<\/nick>/; - } - } - my $msg = "$pre<search>$search</search>$post"; - #$msg =~ s/([^[:print:]])/sprintf '\\x%02x', ord $1/ge; - $msg =~ s/\cDe/%|/g; $msg =~ s/%/%%/g; - $win->print(setc." form debug: [$msg]", MSGLEVEL_CLIENTCRAP); - return; - } - } continue { - --$count; - $lp = $lp->prev; - } - $win->print(setc." form debug: no usable line found", MSGLEVEL_CLIENTCRAP); -} - -sub _alter_line { - my ($buffer_id, $lrp, $win, $view, $lp, $cid, $ad) = @_; - my $line_nick = $history_nn{ $lrp }; - my $text = $lp->get_text(1); - pos $text = 0; - my $from = 0; - for (my $i = 0; $i < $skip_forms; ++$i) { - last unless - scalar $text =~ /$irssi_skip_form_re/g; - $from = pos $text; - } - my $to = $from; - for (my $i = 0; $i < $search_forms_max; ++$i) { - last unless - scalar $text =~ /$irssi_skip_form_re/g; - $to = pos $text; - } - return $lp unless $to > $from; - my @nick_reg; - unshift @nick_reg, quotemeta substr $line_nick, 0, $_ for 1 .. length $line_nick; - { no warnings 'uninitialized'; - if ($ad) { - if (exists $lost_nicks_fs{ $cid }{ $line_nick }) { - my ($fs, $fc, $bc, $bs) = ($lost_nicks_fs{ $cid }{ $line_nick }, $lost_nicks_fc{ $cid }{ $line_nick }, $lost_nicks_bc{ $cid }{ $line_nick }, $lost_nicks_bs{ $cid }{ $line_nick }); - my $sen = length $bs ? $color_code[0] : ''; - for my $nick_reg (@nick_reg) { - last if - (substr $text, $from, $to-$from) - =~ s/(?:\Q$color_code[0]\E)?(?:(?:$irssi_mumbo)+?)?$irssi_mumbo_no_partial($nick_reg)(?:(?:$irssi_mumbo)+?)?(?:\Q$color_code[1]\E)?/$fc$1$bc$sen/; - } - } - } - else { - for my $nick_reg (@nick_reg) { - if ( - (substr $text, $from, $to-$from) - =~ s/(\Q$color_code[0]\E\s*)?((?:$irssi_mumbo)+)?$irssi_mumbo_no_partial($nick_reg)((?:$irssi_mumbo)+)?(\s*\Q$color_code[0]\E)?/$1$2$color_code[0]$3$color_code[1]$4$5/) { - $lost_nicks_fs{ $cid }{ $line_nick } = $1; - $lost_nicks_fc{ $cid }{ $line_nick } = $2; - $lost_nicks_bc{ $cid }{ $line_nick } = $4; - $lost_nicks_bs{ $cid }{ $line_nick } = $5; - last; - } - } - } } - $win->gui_printtext_after($lp->prev, $lp->{info}{level} | MSGLEVEL_NEVER, "$text\n", $lp->{info}{time}); - my $ll = $win->last_line_insert; - my $line_id = $buffer_id . $ll->{_irssi}; - if (exists $history_w{ $line_id }) { - } - grep { $_ eq $lrp and $_ = $line_id } @{$history_st{ $cid }}; - $history_w{ $line_id } = delete $history_w{ $lrp }; - $history_c{ $line_id } = delete $history_c{ $lrp }; - $history_n{ $line_id } = delete $history_n{ $lrp }; - $history_nn{ $line_id } = delete $history_nn{ $lrp }; - $view->remove_line($lp); - $ll; -} - -sub nick_add { - my ($chan, $nick) = @_; - if (delete $lost_nicks{ $chan->{_irssi} }{ $nick->{nick} }) { - my @check_lr = grep { $history_c{ $_ } == $chan->{_irssi} && - $history_n{ $_ } eq $nick->{nick} } keys %history_w; - if (@check_lr) { - $nick_reg{ $nick->{_irssi} } = $nick; - for my $li (@check_lr) { - $history_n{ $li } = $nick->{_irssi}; - } - _alter_lines($chan, \@check_lr, 1); - } - } - delete $lost_nicks_fs{ $chan->{_irssi} }{ $nick->{nick} }; - delete $lost_nicks_fc{ $chan->{_irssi} }{ $nick->{nick} }; - delete $lost_nicks_bc{ $chan->{_irssi} }{ $nick->{nick} }; - delete $lost_nicks_bs{ $chan->{_irssi} }{ $nick->{nick} }; - return; -} - -sub nick_del { - my ($chan, $nick) = @_; - my @check_lr = grep { $history_n{ $_ } eq $nick->{_irssi} } keys %history_w; - for my $li (@check_lr) { - $history_n{ $li } = $nick->{nick}; - } - if (@check_lr) { - $lost_nicks{ $chan->{_irssi} }{ $nick->{nick} } = time; - _alter_lines($chan, \@check_lr, 0); - } - delete $nick_reg{ $nick->{_irssi} }; - return; -} - -sub nick_change { - my ($chan, $nick, $oldnick) = @_; - nick_add($chan, $nick); -} - -sub chan_del { - my ($chan) = @_; - if (my $del = delete $history_st{ $chan->{_irssi} }) { - delete @history_w{ @$del }; - delete @history_c{ @$del }; - delete @history_n{ @$del }; - delete @history_nn{ @$del }; - } - delete $chan_reg{ $chan->{_irssi} }; - delete $lost_nicks{$chan->{_irssi}}; - delete $lost_nicks_fs{$chan->{_irssi}}; - delete $lost_nicks_fc{$chan->{_irssi}}; - delete $lost_nicks_bc{$chan->{_irssi}}; - delete $lost_nicks_bs{$chan->{_irssi}}; - return; -} - -Irssi::settings_add_int( setc, set 'history_lines', $history_lines); -Irssi::settings_add_bool( setc, set 'ignore_hilights', $ignore_hilights); -Irssi::signal_add_last({ - 'setup changed' => 'setup_changed', -}); -Irssi::signal_add({ - 'print text' => 'prt_text_issue', - 'gui print text finished' => 'prt_text_ref', - 'nicklist new' => 'nick_add', - 'nicklist changed' => 'nick_change', - 'nicklist remove' => 'nick_del', - 'window destroyed' => 'win_del', - 'message public' => 'msg_line_tag', - 'channel destroyed' => 'chan_del', -}); - -sub dumphist { - my $win = Irssi::active_win; - my $view = $win->view; - my $buffer_id = $view->{buffer}{_irssi} .','; - for (my $lp = $view->{buffer}{first_line}; $lp; $lp = $lp->next) { - my $line_id = $buffer_id . $lp->{_irssi}; - if (exists $history_w{ $line_id }) { - my $k = $history_c{ $line_id }; - my $kn = $history_n{ $line_id }; - if (exists $chan_reg{ $k }) { - } - if (exists $nick_reg{ $kn }) { - } - if (exists $lost_nicks{ $k } && exists $lost_nicks{ $k }{ $kn }) { - } - } - } -} -Irssi::settings_add_str( setc, set 'color', $color_letter); -Irssi::settings_add_int( setc, set 'forms_skip', $skip_forms); -Irssi::settings_add_int( setc, set 'forms_search_max', $search_forms_max); - -init_dim_nicks(); - -{ package Irssi::Nick } - -# Changelog -# ========= -# 0.4.9 -# - fix default setting not working -# 0.4.8 -# - optionally ignore hilighted lines -# 0.4.7 -# - fix useless re-reading of settings colour -# 0.4.6 -# - fix crash on some lines reported by pierrot diff --git a/.config/irssi/scripts/ls.pl b/.config/irssi/scripts/ls.pl @@ -1,51 +0,0 @@ -use strict; -use vars qw($VERSION %IRSSI); -use Irssi 20020120; -$VERSION = "0.03"; -%IRSSI = ( - authors => "c0ffee", - contact => "c0ffee\@penguin-breeder.org", - name => "List nicks in channel", - description => "Use /ls <regex> to show all nicks (including ident\@host) matching regex in the current channel", - license => "Public Domain", - url => "http://www.penguin-breeder.org/irssi/", - changed => "Sun Sep 17 06:31 CEST 2017", -); - - -sub cmd_ls { - my ($data, $server, $channel) = @_; - - if ($channel->{type} ne "CHANNEL") { - Irssi::print("You are not on a channel"); - - return; - } - - $channel->print("--- Search results:"); - - my @nicks = $channel->nicks(); - - my $re = eval { qr/$data/i }; - if (not $re) { - chomp $@; - $channel->print("Invalid regex pattern:\n$@"); - return; - } - - my $found; - foreach my $nick (@nicks) { - my $n = $nick->{nick} . "!" . $nick->{host}; - - if ($n =~ $re) { - $channel->print($n); - $found = 1; - } - } - - if (not $found) { - $channel->print("No matches"); - } -} - -Irssi::command_bind('ls','cmd_ls'); diff --git a/.config/irssi/scripts/nickcolor.pl b/.config/irssi/scripts/nickcolor.pl @@ -1,1123 +0,0 @@ -use strict; -use warnings; - -our $VERSION = '0.4.0'; # c274f630aff9967 -our %IRSSI = ( - authors => 'Nei', - name => 'nickcolor_expando', - description => 'colourise nicks', - license => 'GPL v2', - ); - -# inspired by bc-bd's nm.pl and mrwright's nickcolor.pl - -# Usage -# ===== -# after loading the script, add the colour expando to the format -# (themes' abstracts are not supported) -# -# /format pubmsg {pubmsgnick $2 {pubnick $nickcolor$0}}$1 -# -# alternatively, use it together with nm2 script - -# Options -# ======= -# /set neat_colors <list of colours> -# * the list of colours for automatic colouring (you can edit it more -# conveniently with /neatcolor colors) -# -# /set neat_ignorechars <regex> -# * regular expression of characters to remove from nick before -# calculating the hash function -# -# /set neat_color_reassign_time <time> -# * if the user has not spoken for so long, the assigned colour is -# forgotten and another colour may be picked next time the user -# speaks -# -# /set neat_global_colors <ON|OFF> -# * more strongly prefer one global colour per nickname regardless of -# channel - -# Commands -# ======== -# /neatcolor -# * show the current colour distribution of nicks -# -# /neatcolor set [<network>/<#channel>] <nick> <colour> -# * set a fixed colour for nick -# -# /neatcolor reset [<network>/<#channel>] <nick> -# * remove a set colour of nick -# -# /neatcolor get [<network>/<#channel>] <nick> -# * query the current or set colour of nick -# -# /neatcolor re [<network>/<#channel>] <nick> -# * force change the colour of nick to a random other colour (to -# manually resolve clashes) -# -# /neatcolor save -# * save the colours to ~/.irssi/saved_nick_colors -# -# /neatcolor reset --all -# * re-set all colours -# -# /neatcolor colors -# * show currently configured colours, in colour -# -# /neatcolor colors add <list of colours> -# /neatcolor colors remove <list of colours> -# * add or remove these colours from the neat_colors setting - - -sub cmd_help_neatcolor { - print CLIENTCRAP <<HELP -%9Syntax:%9 - -NEATCOLOR -NEATCOLOR SET [<network>/<#channel>] <nick> <colour> -NEATCOLOR RESET [<network>/<#channel>] <nick> -NEATCOLOR GET [<network>/<#channel>] <nick> -NEATCOLOR RE [<network>/<#channel>] <nick> -NEATCOLOR SAVE -NEATCOLOR RESET --all -NEATCOLOR COLORS -NEATCOLOR COLORS ADD <list of colours> -NEATCOLOR COLORS REMOVE <list of colours> - -%9Parameters:%9 - - SET: set a fixed colour for nick - RESET: remove a set colour of nick - GET: query the current or set colour of nick - RE: force change the colour of nick to a random other - colour (to manually resolve clashes) - SAVE: save the colours to ~/.irssi/saved_nick_colors - RESET --all: re-set all colours - COLORS: show currently configured colours, in colour - COLORS ADD/REMOVE: add or remove these colours from the - neat_colors setting - - If no parameters are given, the current colour distribution of - nicks is shown. - -%9Description:%9 - - Manages nick based colouring - -HELP -} - -use Hash::Util qw(lock_keys); -use Irssi; - - -{ package Irssi::Nick } - -my @action_protos = qw(irc silc xmpp); -my (%set_colour, %avoid_colour, %has_colour, %last_time, %netchan_hist); -my ($expando, $iexpando, $ignore_re, $ignore_setting, $global_colours, $retain_colour_time, @colours, $exited, $session_load_time); -($expando, $iexpando) = ('', ''); # Initialise to empty - -# the numbers for the scoring system, highest colour value will be chosen -my %scores = ( - set => 200, - keep => 5, - global => 4, - hash => 3, - - avoid => -20, - hist => -10, - used => -2, - ); -lock_keys(%scores); - -my $history_lines = 40; -my $global_mode = 1; # start out with global nick colour - -my @colour_bags = ( - [qw[20 30 40 50 04 66 0C 61 60 67 6L]], # RED - [qw[37 3D 36 4C 46 5C 56 6C 6J 47 5D 6K 6D 57 6E 5E 4E 4K 4J 5J 4D 5K 6R]], # ORANGE - [qw[3C 4I 5I 6O 6I 06 4O 5O 3U 0E 5U 6U 6V 6P 6Q 6W 5P 4P 4V 4W 5W 4Q 5Q 5R 6Y 6X]], # YELLOW - [qw[26 2D 2C 3I 3O 4U 5V 2J 3V 3P 3J 5X]], # YELLOW-GREEN - [qw[16 1C 2I 2U 2O 1I 1O 1V 1P 02 0A 1U 2V 4X]], # GREEN - [qw[1D 1J 1Q 1W 1X 2Y 2S 2R 3Y 3Z 3S 3R 2K 3K 4S 5Z 5Y 4R 3Q 2Q 2X 2W 3X 3W 2P 4Y]], # GREEN-TURQUOIS - [qw[17 1E 1L 1K 1R 1S 03 1M 1N 1T 0B 1Y 1Z 2Z 4Z]], # TURQUOIS - [qw[28 2E 18 1F 19 1G 1A 1B 1H 2N 2H 09 3H 3N 2T 3T 2M 2G 2A 2F 2L 3L 3F 4M 3M 3G 29 4T 5T]], # LIGHT-BLUE - [qw[11 12 23 25 24 13 14 01 15 2B 4N]], # DARK-BLUE - [qw[22 33 44 0D 45 5B 6A 5A 5H 3B 4H 3A 4G 39 4F 6S 6T 5L 5N]], # VIOLET - [qw[21 32 42 53 63 52 43 34 35 55 65 6B 4B 4A 48 5G 6H 5M 6M 6N]], # PINK - [qw[38 31 05 64 54 41 51 62 69 68 59 5F 6F 58 49 6G]], # ROSE - [qw[7A 00 10 7B 7C 7D 7E 7G 7F]], # DARK-GRAY - [qw[7H 7I 27 7K 7J 08 7L 3E 7O 7Q 7N 7M 7P]], # GRAY - [qw[7S 7T 7R 4L 7W 7U 7V 5S 07 7X 6Z 0F]], # LIGHT-GRAY - ); -my %colour_bags; -{ my $idx = 0; - for my $bag (@colour_bags) { - @colour_bags{ @$bag } = ($idx)x@$bag; - } - continue { - ++$idx; - } -} -my @colour_list = map { @$_ } @colour_bags; -my @bases = split //, 'kbgcrmywKBGCRMYW04261537'; -my %base_map = map { $bases[$_] => sprintf '%02X', ($_ % 0x10) } 0..$#bases; -my %ext_to_base_map = map { (sprintf '%02X', $_) => $bases[$_] } 0..15; - -sub expando_neatcolour { - return $expando; -} - -sub expando_neatcolour_inv { - return $iexpando; -} - -# one-at-a-time hash -sub simple_hash { - use integer; - my $hash = 0x5065526c + length $_[0]; - for my $ord (unpack 'U*', $_[0]) { - $hash += $ord; - $hash += $hash << 10; - $hash &= 0xffffffff; - $hash ^= $hash >> 6; - } - $hash += $hash << 3; - $hash &= 0xffffffff; - $hash ^= $hash >> 11; - $hash = $hash + ($hash << 15); - $hash &= 0xffffffff; -} - -{ my %lut1; - my @z = (0 .. 9, 'A' .. 'Z'); - for my $x (16..255) { - my $idx = $x - 16; - my $col = 1+int($idx / @z); - $lut1{ $col . @z[(($col > 6 ? 10 : 0) + $idx) % @z] } = $x; - } - for my $idx (0..15) { - $lut1{ (sprintf "%02X", $idx) } = ($idx&8) | ($idx&4)>>2 | ($idx&2) | ($idx&1)<<2; - } - - sub debug_ansicolour { - my ($col, $bg) = @_; - return '' unless defined $col && exists $lut1{$col}; - $bg = $bg ? 48 : 38; - "\e[$bg;5;$lut1{$col}m" - } -} -sub debug_colour { - my ($col, $bg) = @_; - defined $col ? (debug_ansicolour($col, $bg) . $col . "\e[0m") : '(none)' -} -sub debug_score { - my ($score) = @_; - if ($score == 0) { - return $score - } - my @scale = $score > 0 ? (qw(16 1C 1I 1U 2V 4X)) : (qw(20 30 40 60 67 6L));; - my $v = (log 1+ abs $score)*(log 20); - debug_ansicolour($scale[$v >= $#scale ? -1 : $v], 1) . $score . "\e[0m" -} -sub debug_reused { - my ($netchan, $nick, $col) = @_; - my $chc = simple_hash($netchan); - my $hashcolour = @colours ? $colours[ $chc % @colours ] : 0; -} -sub debug_scores { - my ($netchan, $nick, $col, $prios, $colours) = @_; - my $inprogress; - unless (ref $prios) { - $inprogress = $prios; - $prios = [ sort { $colours->{$b} <=> $colours->{$a} } grep { exists $colours->{$_} } @colour_list ]; - } - my $chc = simple_hash($netchan); - my $hashcolour = @colours ? $colours[ $chc % @colours ] : 0; - unless ($inprogress) { - } - else { - } - for my $i (0..$#$prios) { - } -} - -sub colourise_nt { - my ($netchan, $nick, $weak) = @_; - my $time = time; - - my $g_or_n = $global_colours ? '' : $netchan; - - my $old_colour = $has_colour{$g_or_n}{$nick} // $has_colour{$netchan}{$nick}; - my $last_time = $last_time{$g_or_n}{$nick} // $last_time{$netchan}{$nick}; - - my $keep_score = $weak ? $scores{keep} + $scores{set} : $scores{keep}; - - unless ($weak) { - $last_time{$netchan}{$nick} - = $last_time{''}{$nick} = $time; - } - else { - $last_time{$netchan}{$nick} ||= 0; - } - - my $colour; - if (defined $old_colour && ($weak || (defined $last_time - && ($last_time + $retain_colour_time > $time - || ($last_time > 0 && grep { $_->[0] eq $nick } @{ $netchan_hist{$netchan} // [] }))))) { - $colour = $old_colour; - } - else { - # search for a suitable colour - my %colours = map { $_ => 0 } @colours; - my $hashnick = $nick; - $hashnick =~ s/$ignore_re//g if (defined $ignore_re && length $ignore_re); - my $hash = simple_hash($global_mode ? "/$hashnick" : "$netchan/$hashnick"); - - if (exists $set_colour{$netchan} && exists $set_colour{$netchan}{$nick}) { - $colours{ $set_colour{$netchan}{$nick} } += $scores{set}; - } - elsif (exists $set_colour{$netchan} && exists $set_colour{$netchan}{$hashnick}) { - $colours{ $set_colour{$netchan}{$hashnick} } += $scores{set}; - } - elsif (exists $set_colour{''} && exists $set_colour{''}{$nick}) { - $colours{ $set_colour{''}{$nick} } += $scores{set}; - } - elsif (exists $set_colour{''} && exists $set_colour{''}{$hashnick}) { - $colours{ $set_colour{''}{$hashnick} } += $scores{set}; - } - - if (exists $avoid_colour{$netchan} && exists $avoid_colour{$netchan}{$nick}) { - for (@{ $avoid_colour{$netchan}{$nick} }) { - $colours{ $_ } += $scores{avoid} if exists $colours{ $_ }; - } - } - elsif (exists $avoid_colour{$g_or_n} && exists $avoid_colour{$g_or_n}{$nick}) { - for (@{ $avoid_colour{$g_or_n}{$nick} }) { - $colours{ $_ } += $scores{avoid} if exists $colours{ $_ }; - } - } - - if (defined $old_colour) { - $colours{$old_colour} += $keep_score - if exists $colours{$old_colour}; - } - elsif (exists $has_colour{''}{$nick}) { - $colours{ $has_colour{''}{$nick} } += $scores{global} - if exists $colours{ $has_colour{''}{$nick} }; - } - - if (@colours) { - my $hashcolour = $colours[ $hash % @colours ]; - if (!defined $old_colour || $hashcolour ne $old_colour) { - $colours{ $hashcolour } += $scores{hash}; - } - } - - { my @netchans = $global_mode ? keys %has_colour : $netchan; - my $total; - my %colour_pens; - for my $gnc (@netchans) { - for my $onick (keys %{ $has_colour{$gnc} }) { - next if $gnc ne $netchan && exists $has_colour{$netchan}{$onick}; - next unless exists $last_time{$gnc}{$onick}; - if ($last_time{$gnc}{$onick} + $retain_colour_time > $time # XXX - || ($last_time{$gnc}{$onick} == 0 && $session_load_time + $retain_colour_time > $time)) { - if (exists $colours{ $has_colour{$gnc}{$onick} }) { - $colour_pens{ $has_colour{$gnc}{$onick} } += $scores{used}; - ++$total; - } - } - } - } - for (keys %colour_pens) { - $colours{ $_ } += $colour_pens{ $_ } / $total * @colours - if @colours; - } - } - - { my $fac = 1; - for my $gnetchan ($netchan, '') { - my $idx = exp(-log($history_lines)/$scores{hist}); - for my $hent (reverse @{ $netchan_hist{$gnetchan} // [] }) { - next unless defined $hent->[1]; - if ($hent->[0] ne $nick) { - my $pen = 1; - $pen *= 3 if length $nick == length $hent->[0]; - $pen *= 2 if (substr $nick, 0, 1) eq (substr $hent->[0], 0, 1) - || 1 == abs +(length $nick) - (length $hent->[0]); - $colours{ $hent->[1] } -= log($pen*$history_lines)/log($idx) / $fac - if exists $colours{ $hent->[1] }; - } - ++$idx; - last if $idx > $history_lines; - } - ++$fac; - } - } - - { my %bag_pens; - for my $co (keys %colours) { - $bag_pens{ $colour_bags{$co} } -= $colours{$co}/2 if $colours{$co} < 0; - } - for my $bag (keys %bag_pens) { - for my $co (@{ $colour_bags[$bag] }) { - $colours{$co} -= $bag_pens{$bag} / @colours - if @colours && exists $colours{$co}; - } - } - } - - my @prio_colours = sort { $colours{$b} <=> $colours{$a} } grep { exists $colours{$_} } @colour_list; - my $stop_at = 0; - while ($stop_at < $#prio_colours - && $colours{ $prio_colours[$stop_at] } <= $colours{ $prio_colours[$stop_at + 1] }) { - ++$stop_at; - } - $colour = $prio_colours[ $hash % ($stop_at + 1) ] - if @prio_colours; - - } - - unless ($weak) { - expire_hist($netchan, ''); - - my $ent = [$nick, $colour]; - push @{ $netchan_hist{$netchan} }, $ent; - push @{ $netchan_hist{''} }, $ent; - } - - defined $colour ? ($has_colour{$g_or_n}{$nick} = $has_colour{$netchan}{$nick} = $colour) : $colour -} - -sub expire_hist { - for my $ch (@_) { - if ($netchan_hist{$ch} - && @{$netchan_hist{$ch}} > 2 * $history_lines) { - splice @{$netchan_hist{$ch}}, 0, $history_lines; - } - } -} - -sub msg_line_tag { - my ($srv, $msg, $nick, $addr, $targ) = @_; - my $colour = colourise_nt('/'.$nick, $nick); - $expando = $colour ? format_expand('%X'.$colour) : ''; - $iexpando = $colour ? format_expand('%x'.$colour) : ''; -} - -# messy stuff below, hacked together by a non-perler (haydenh) -sub join2mlt { - my ($srv, $channel, $nick, $addr, $acc, $real) = @_; - msg_line_tag($srv, $acc, $nick, $acc); -} - -sub part2mlt { - my ($srv, $channel, $nick, $addr, $reason) = @_; - msg_line_tag($srv, $addr, $nick, $reason); -} - -sub quit2mlt { - my ($srv, $nick, $addr, $reason) = @_; - msg_line_tag($srv, $addr, $nick, $reason); -} - -sub kick2mlt { - my ($srv, $channel, $nick, $kicker, $address, $reason) = @_; - msg_line_tag($srv, $nick, $kicker, $reason); -} - -sub nick2mlt { - my ($srv, $nnick, $onick, $addr) = @_; - msg_line_tag($srv, $addr, $onick, $addr); -} - -sub invite2mlt { - my ($srv, $chan, $nick, $addr) = @_; - msg_line_tag($srv, $chan, $nick, $addr); -} - -sub inviteo2mlt { - my ($srv, $chan, $inv, $nick, $addr) = @_; - msg_line_tag($srv, $chan, $inv, $addr); -} - -sub topic2mlt { - my ($srv, $chan, $topic, $nick, $addr) = @_; - msg_line_tag($srv, $chan, $nick, $addr); -} - -sub msg_line_tag_xmppaction { - clear_ref(), return unless @_; - my ($srv, $msg, $nick, $targ) = @_; - msg_line_tag($srv, $msg, $nick, undef, $targ); -} - -sub msg_line_clear { - clear_ref(); -} - -sub prnt_clear_public { - my ($dest) = @_; - clear_ref() if $dest->{level} & MSGLEVEL_PUBLIC; -} - -sub clear_ref { - $expando = ''; - $iexpando = ''; -} - -sub nicklist_changed { - my ($chanobj, $nickobj, $old_nick) = @_; - - my $netchan = $chanobj->{server}{tag}.'/'.$chanobj->{name}; - my $nickstr = $nickobj->{nick}; - - if (!exists $has_colour{''}{$nickstr} && exists $has_colour{''}{$old_nick}) { - $has_colour{''}{$nickstr} = delete $has_colour{''}{$old_nick}; - } - if (exists $has_colour{$netchan}{$old_nick}) { - $has_colour{$netchan}{$nickstr} = delete $has_colour{$netchan}{$old_nick}; - } - - $last_time{$netchan}{$nickstr} - = $last_time{''}{$nickstr} = time; - - for my $old_ent (@{ $netchan_hist{$netchan} }) { - $old_ent->[0] = $nickstr if $old_ent->[0] eq $old_nick; - } - -} - -{ - my %format2control = ( - 'F' => "\cDa", '_' => "\cDc", '|' => "\cDe", '#' => "\cDi", "n" => "\cDg", "N" => "\cDg", - 'U' => "\c_", '8' => "\cV", 'I' => "\cDf", - ); - my %bg_base = ( - '0' => '0', '4' => '1', '2' => '2', '6' => '3', '1' => '4', '5' => '5', '3' => '6', '7' => '7', - 'x08' => '8', 'x09' => '9', 'x0a' => ':', 'x0b' => ';', 'x0c' => '<', 'x0d' => '=', 'x0e' => '>', 'x0f' => '?', - ); - my %fg_base = ( - 'k' => '0', 'b' => '1', 'g' => '2', 'c' => '3', 'r' => '4', 'm' => '5', 'p' => '5', 'y' => '6', 'w' => '7', - 'K' => '8', 'B' => '9', 'G' => ':', 'C' => ';', 'R' => '<', 'M' => '=', 'P' => '=', 'Y' => '>', 'W' => '?', - ); - my @ext_colour_off = ( - '.', '-', ',', - '+', "'", '&', - ); - sub format_expand { - my $copy = $_[0]; - $copy =~ s{%(Z.{6}|z.{6}|X..|x..|.)}{ - my $c = $1; - if (exists $format2control{$c}) { - $format2control{$c} - } - elsif (exists $bg_base{$c}) { - "\cD/$bg_base{$c}" - } - elsif (exists $fg_base{$c}) { - "\cD$fg_base{$c}/" - } - elsif ($c =~ /^[{}%]$/) { - $c - } - elsif ($c =~ /^(z|Z)([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})$/) { - my $bg = $1 eq 'z'; - my (@rgb) = map { hex $_ } $2, $3, $4; - my $x = $bg ? 0x1 : 0; - my $out = "\cD" . (chr -13 + ord '0'); - for (my $i = 0; $i < 3; ++$i) { - if ($rgb[$i] > 0x20) { - $out .= chr $rgb[$i]; - } - else { - $x |= 0x10 << $i; $out .= chr 0x20 + $rgb[$i]; - } - } - $out .= chr 0x20 + $x; - $out - } - elsif ($c =~ /^(x)(?:0([[:xdigit:]])|([1-6])(?:([0-9])|([a-z]))|7([a-x]))$/i) { - my $bg = $1 eq 'x'; - my $col = defined $2 ? hex $2 - : defined $6 ? 232 + (ord lc $6) - (ord 'a') - : 16 + 36 * ($3 - 1) + (defined $4 ? $4 : 10 + (ord lc $5) - (ord 'a')); - if ($col < 0x10) { - my $chr = chr $col + ord '0'; - "\cD" . ($bg ? "/$chr" : "$chr/") - } - else { - "\cD" . $ext_colour_off[($col - 0x10) / 0x50 + $bg * 3] . chr (($col - 0x10) % 0x50 - 1 + ord '0') - } - } - else { - "%$c" - } - }ge; - $copy - } -} - -sub save_colours { - open my $fid, '>', Irssi::get_irssi_dir() . '/saved_nick_colors' - or do { - Irssi::print("Error saving nick colours: $!", MSGLEVEL_CLIENTERROR) - unless $exited; - return; - }; - - local $\ = "\n"; - if (%set_colour) { - print $fid '[set]'; - for my $netch (sort keys %set_colour) { - for my $nick (sort keys %{ $set_colour{$netch} }) { - print $fid "$netch/$nick:".$set_colour{$netch}{$nick}; - } - } - print $fid ''; - } - my $time = time; - print $fid '[set]'; - my %session_colour; - for my $netch (sort keys %last_time) { - for my $nick (sort keys %{ $last_time{$netch} }) { - if (exists $has_colour{$netch} && exists $has_colour{$netch}{$nick} - && ($last_time{$netch}{$nick} + $retain_colour_time > $time - || ($last_time{$netch}{$nick} == 0 && $session_load_time + $retain_colour_time > $time) - || grep { $_->[0] eq $nick } @{ $netchan_hist{$netch} // [] })) { - $session_colour{$netch}{$nick} = $has_colour{$netch}{$nick}; - if (exists $session_colour{''}{$nick}) { - if (defined $session_colour{''}{$nick} - && $session_colour{''}{$nick} ne $session_colour{$netch}{$nick}) { - $session_colour{''}{$nick} = undef; - } - } - else { - $session_colour{''}{$nick} = $session_colour{$netch}{$nick}; - } - } - } - } - for my $nick (sort keys %{ $session_colour{''} }) { - if (defined $session_colour{''}{$nick}) { - print $fid "/$nick:".$session_colour{''}{$nick}; - } - else { - for my $netch (sort keys %session_colour) { - print $fid "$netch/$nick:".$session_colour{$netch}{$nick} - if exists $session_colour{$netch}{$nick} && defined $session_colour{$netch}{$nick}; - } - } - } - - close $fid; -} - -sub load_colours { - $session_load_time = time; - - open my $fid, '<', Irssi::get_irssi_dir() . '/saved_nick_colors' - or return; - my $mode; - while (my $line = <$fid>) { - chomp $line; - if ($line =~ /^\[(.*)\]$/) { - $mode = $1; - next; - } - - my $colon = rindex $line, ':'; - next if $colon < 0; - my $slash = rindex $line, '/', $colon; - next if $slash < 0; - my $col = substr $line, $colon +1; - next unless length $col; - my $netch = substr $line, 0, $slash; - my $nick = substr $line, $slash +1, $colon-$slash -1; - if ($mode eq 'set') { - $set_colour{$netch}{$nick} = $col; - } - elsif ($mode eq 'session') { - $has_colour{$netch}{$nick} = $col; - $last_time{$netch}{$nick} = 0; - } - } - close $fid; -} - -sub UNLOAD { - return if $exited; - exit_save(); -} - -sub exit_save { - $exited = 1; - save_colours() if Irssi::settings_get_bool('settings_autosave'); -} - -sub get_nick_color2 { - my ($tag, $chan, $nick, $format) = @_; - my $col = colourise_nt('/'.$nick, $nick); - $col ? $format ? format_expand('%X'.$col) : $col : '' -} - -sub _cmd_colours_check { - my ($add, $data) = @_; - my @to_check = grep { defined && length } map { - length == 1 ? $base_map{$_} - : length == 3 ? substr $_, 1 - : $_ } map { /(?|x(..)|([0-7].)|(.))/gi } - split ' ', $data; - my @valid; - my %scolours = map { $_ => undef } @colours; - for my $c (@to_check) { - if ((grep { $_ eq $c } @colour_list)) { - if ($add) { next if exists $scolours{$c} } - else { next if !exists $scolours{$c} } - push @valid, $c; - if ($add) { $scolours{$c} = undef; } - else { delete $scolours{$c}; } - } - } - (\@valid, \%scolours) -} - -sub _cmd_colours_set { - my $scolours = shift; - Irssi::settings_set_str('neat_colors', join '', map { $ext_to_base_map{$_} // "X$_" } grep { exists $scolours->{$_} } @colour_list); -} - -sub _cmd_colours_list { - map { "%X$_".($ext_to_base_map{$_} // "X$_").'%n' } @{+shift} -} - -sub cmd_neatcolor_colors_add { - my ($data, $server, $witem) = @_; - my ($added, $scolours) = _cmd_colours_check(1, $data); - if (@$added) { - _cmd_colours_set($scolours); - Irssi::print("%_nce2%_: added @{[ _cmd_colours_list($added) ]} to neat_colors", MSGLEVEL_CLIENTCRAP); - setup_changed(); - } - else { - Irssi::print("%_nce2%_: nothing added", MSGLEVEL_CLIENTCRAP); - } -} -sub cmd_neatcolor_colors_remove { - my ($data, $server, $witem) = @_; - my ($removed, $scolours) = _cmd_colours_check(0, $data); - if (@$removed) { - _cmd_colours_set($scolours); - Irssi::print("%_nce2%_: removed @{[ _cmd_colours_list($removed) ]} from neat_colors", MSGLEVEL_CLIENTCRAP); - setup_changed(); - } - else { - Irssi::print("%_nce2%_: nothing removed", MSGLEVEL_CLIENTCRAP); - } -} - -sub cmd_neatcolor_colors { - my ($data, $server, $witem) = @_; - $data =~ s/\s+$//; - unless (length $data) { - Irssi::print("%_nce2%_: current colours: @{[ @colours ? _cmd_colours_list(\@colours) : '(none)' ]}"); - } - Irssi::command_runsub('neatcolor colors', $data, $server, $witem); -} - -sub cmd_neatcolor { - my ($data, $server, $witem) = @_; - $data =~ s/\s+$//; - unless (length $data) { - $witem ||= Irssi::active_win; - my $time = time; - my %distribution = map { $_ => 0 } @colours; - for my $netch (keys %has_colour) { - next unless length $netch; - for my $nick (keys %{ $has_colour{$netch} }) { - if (exists $last_time{$netch}{$nick} - && ($last_time{$netch}{$nick} + $retain_colour_time > $time - || grep { $_->[0] eq $nick } @{ $netchan_hist{$netch} // [] })) { - $distribution{ $has_colour{$netch}{$nick} }++ - } - } - } - $witem->print('%_nce2%_ Colour distribution: '. - (join ', ', - map { "%X$_$_:$distribution{$_}" } - sort { $distribution{$b} <=> $distribution{$a} } - grep { exists $distribution{$_} } @colour_list), MSGLEVEL_CLIENTCRAP); - } - Irssi::command_runsub('neatcolor', $data, $server, $witem); -} - -sub _cmd_check_netchan_arg { - my ($cmd, $netchan, $nick) = @_; - my %global = map { $_ => undef } qw(set get reset); - unless (length $netchan) { - Irssi::print('%_nce2%_: no network/channel argument given for neatcolor '.$cmd - .(exists $global{$cmd} ? ', use / to '.$cmd.' global colours' : ''), - MSGLEVEL_CLIENTERROR); - return; - } - elsif (-1 == index $netchan, '/') { - Irssi::print('%_nce2%_: missing network/ in argument given for neatcolor '.$cmd, MSGLEVEL_CLIENTERROR); - return; - } - elsif ($netchan =~ m\^[^/]+/$\) { - Irssi::print('%_nce2%_: missing /channel in argument given for neatcolor '.$cmd, MSGLEVEL_CLIENTERROR); - return; - } - - unless (length $nick) { - Irssi::print('%_nce2%_: no nick argument given for neatcolor '.$cmd, MSGLEVEL_CLIENTERROR); - return; - } - elsif (-1 != index $nick, '/') { - Irssi::print('%_nce2%_: / not supported in nicks in argument given for neatcolor '.$cmd, MSGLEVEL_CLIENTERROR); - return; - } - - return 1; -} - -sub _cmd_check_colour { - my ($cmd, $colour) = @_; - $colour = substr $colour, 1 if length $colour == 3; - $colour = $base_map{$colour} if length $colour == 1; - unless (length $colour && grep { $_ eq $colour } @colour_list) { - Irssi::print('%_nce2%_: no colour or invalid colour argument given for neatcolor '.$cmd, MSGLEVEL_CLIENTERROR); - return; - } - return $colour; -} - -sub cmd_neatcolor_set { - my ($data, $server, $witem) = @_; - my @args = split ' ', $data; - if (@args < 2) { - Irssi::print('%_nce2%_: not enough arguments for neatcolor set', MSGLEVEL_CLIENTERROR); - return; - } - my $netchan; - if (ref $witem) { - $netchan = $witem->{server}{tag}.'/'.$witem->{name}; - } - my $nick; - my $colour; - if (@args < 3) { - ($nick, $colour) = @args; - } - else { - ($netchan, $nick, $colour) = @args; - } - - return unless _cmd_check_netchan_arg('set', $netchan, $nick); - return unless defined ($colour = _cmd_check_colour('set', $colour)); - - $set_colour{$netchan eq '/' ? '' : $netchan}{$nick} = $colour; - for my $netch ($netchan eq '/' ? keys %has_colour - : $global_colours ? ('', $netchan) - : $netchan) { - delete $has_colour{$netch}{$nick} unless - exists $has_colour{$netch}{$nick} && $has_colour{$netch}{$nick} eq $colour; - } - Irssi::print("%_nce2%_: %X$colour$nick%n colour set to: %X$colour$colour%n ".($netchan eq '/' ? 'globally' : "in $netchan"), MSGLEVEL_CLIENTCRAP); -} -sub cmd_neatcolor_get { - my ($data, $server, $witem) = @_; - my @args = split ' ', $data; - if (@args < 1) { - Irssi::print('%_nce2%_: not enough arguments for neatcolor get', MSGLEVEL_CLIENTERROR); - return; - } - my $netchan; - if (ref $witem) { - $netchan = $witem->{server}{tag}.'/'.$witem->{name}; - } - my $nick; - if (@args < 2) { - $nick = $args[0]; - } - else { - ($netchan, $nick) = @args; - } - - return unless _cmd_check_netchan_arg('get', $netchan, $nick); - - if ($netchan ne '/') { - unless (exists $has_colour{$netchan} && exists $has_colour{$netchan}{$nick}) { - Irssi::print("%_nce2%_: $nick is not coloured (yet) in $netchan", MSGLEVEL_CLIENTCRAP); - } - else { - my $colour = $has_colour{$netchan}{$nick}; - Irssi::print("%_nce2%_: %X$colour$nick%n has colour: %X$colour$colour%n in $netchan", MSGLEVEL_CLIENTCRAP); - } - } - my $hashnick = $nick; - $hashnick =~ s/$ignore_re//g if (defined $ignore_re && length $ignore_re); - if (exists $set_colour{$netchan} && exists $set_colour{$netchan}{$nick}) { - my $colour = $set_colour{$netchan}{$nick}; - Irssi::print("%_nce2%_: set colour for %X$colour$nick%n in $netchan: %X$colour$colour%n ", MSGLEVEL_CLIENTCRAP); - } - elsif (exists $set_colour{$netchan} && exists $set_colour{$netchan}{$hashnick}) { - my $colour = $set_colour{$netchan}{$hashnick}; - Irssi::print("%_nce2%_: set colour for %X$colour$hashnick%n in $netchan: %X$colour$colour%n ", MSGLEVEL_CLIENTCRAP); - } - elsif (exists $set_colour{''} && exists $set_colour{''}{$nick}) { - my $colour = $set_colour{''}{$nick}; - Irssi::print("%_nce2%_: set colour for %X$colour$nick%n (global): %X$colour$colour%n ", MSGLEVEL_CLIENTCRAP); - } - elsif (exists $set_colour{''} && exists $set_colour{''}{$hashnick}) { - my $colour = $set_colour{''}{$hashnick}; - Irssi::print("%_nce2%_: set colour for %X$colour$hashnick%n (global): %X$colour$colour%n ", MSGLEVEL_CLIENTCRAP); - } - elsif ($netchan eq '/') { - Irssi::print("%_nce2%_: no global colour set for $nick", MSGLEVEL_CLIENTCRAP); - } -} -sub cmd_neatcolor_reset { - my ($data, $server, $witem) = @_; - my @args = split ' ', $data; - if (@args < 1) { - Irssi::print('%_nce2%_: not enough arguments for neatcolor reset', MSGLEVEL_CLIENTERROR); - return; - } - my $netchan; - if (ref $witem) { - $netchan = $witem->{server}{tag}.'/'.$witem->{name}; - } - my $nick; - if (@args == 1 && $args[0] eq '--all') { - %set_colour = %avoid_colour = %has_colour = (); - Irssi::print("%_nce2%_: re-set all colouring"); - return; - } - if (@args < 2) { - $nick = $args[0]; - } - else { - ($netchan, $nick) = @args; - } - - return unless _cmd_check_netchan_arg('reset', $netchan, $nick); - - $netchan = '' if $netchan eq '/'; - unless (exists $set_colour{$netchan} && exists $set_colour{$netchan}{$nick}) { - Irssi::print("%_nce2%_: $nick has no colour set ". (length $netchan ? "in $netchan" : "globally"), MSGLEVEL_CLIENTERROR); - return; - } - my $colour = delete $set_colour{$netchan}{$nick}; - for my $netch ($netchan eq '' ? keys %has_colour - : $global_colours ? ('', $netchan) - : $netchan) { - delete $has_colour{$netch}{$nick} if exists $has_colour{$netch} && exists $has_colour{$netch}{$nick} - && $has_colour{$netch}{$nick} eq $colour; - } - Irssi::print("%_nce2%_: ".($netchan eq '' ? 'global ' : '')."colouring re-set for $nick".($netchan eq '' ? '' : " in $netchan"), MSGLEVEL_CLIENTERROR); -} -sub cmd_neatcolor_re { - my ($data, $server, $witem) = @_; - my @args = split ' ', $data; - if (@args < 1) { - Irssi::print('%_nce2%_: not enough arguments for neatcolor re', MSGLEVEL_CLIENTERROR); - return; - } - my $netchan; - if (ref $witem) { - $netchan = $witem->{server}{tag}.'/'.$witem->{name}; - } - my $nick; - if (@args < 2) { - $nick = $args[0]; - } - else { - ($netchan, $nick) = @args; - } - - return unless _cmd_check_netchan_arg('re', $netchan, $nick); - - unless (exists $has_colour{$netchan} && exists $has_colour{$netchan}{$nick}) { - Irssi::print("%_nce2%_: could not find $nick in $netchan", MSGLEVEL_CLIENTERROR); - return; - } - my $colour = delete $has_colour{$netchan}{$nick}; - if (grep { $colour eq $_ } @{ $avoid_colour{$netchan}{$nick} || [] }) { - $avoid_colour{$netchan}{$nick} = [ $colour ] - } - else { - push @{ $avoid_colour{$netchan}{$nick} }, $colour; - } - if ($global_colours) { - delete $has_colour{''}{$nick} if defined $colour; - - if (grep { $colour eq $_ } @{ $avoid_colour{''}{$nick} || [] }) { - $avoid_colour{''}{$nick} = [ $colour ] - } - else { - push @{ $avoid_colour{''}{$nick} }, $colour; - } - } - Irssi::print("%_nce2%_: re-colouring $nick in $netchan", MSGLEVEL_CLIENTERROR); -} -sub cmd_neatcolor_save { - Irssi::print("%_nce2%_: saving colours to file", MSGLEVEL_CLIENTCRAP); - save_colours(); -} - -sub setup_changed { - $global_colours = Irssi::settings_get_bool('neat_global_colors'); - $retain_colour_time = int( abs( Irssi::settings_get_time('neat_color_reassign_time') ) / 1000 ); - my $old_ignore = $ignore_setting // ''; - $ignore_setting = Irssi::settings_get_str('neat_ignorechars'); - if ($old_ignore ne $ignore_setting) { - local $@; - eval { $ignore_re = qr/$ignore_setting/ }; - if ($@) { - $@ =~ /^(.*)/; - print '%_neat_ignorechars%_ did not compile: '.$1; - } - } - my $old_colours = "@colours"; - my %scolours = map { ($base_map{$_} // $_) => undef } Irssi::settings_get_str('neat_colors') =~ /(?|x(..)|(.))/ig; - @colours = grep { exists $scolours{$_} } @colour_list; - - if ($old_colours ne "@colours") { - my $time = time; - for my $netch (sort keys %last_time) { - for my $nick (sort keys %{ $last_time{$netch} }) { - if (exists $has_colour{$netch} && exists $has_colour{$netch}{$nick}) { - if ($last_time{$netch}{$nick} + $retain_colour_time > $time - || ($last_time{$netch}{$nick} == 0 && $session_load_time + $retain_colour_time > $time)) { - $last_time{$netch}{$nick} = 0; - } - else { - delete $last_time{$netch}{$nick}; - } - } - } - $session_load_time = $time; - } - } -} - -sub internals { - +{ - set => \%set_colour, - avoid => \%avoid_colour, - has => \%has_colour, - time => \%last_time, - hist => \%netchan_hist, - colours => \@colours - } -} - -sub init_nickcolour { - setup_changed(); - load_colours(); -} - -Irssi::settings_add_str('misc', 'neat_colors', 'rRgGybBmMcCX42X3AX5EX4NX3HX3CX32'); -Irssi::settings_add_str('misc', 'neat_ignorechars', ''); -Irssi::settings_add_time('misc', 'neat_color_reassign_time', '30min'); -Irssi::settings_add_bool('misc', 'neat_global_colors', 0); -init_nickcolour(); - -Irssi::expando_create('nickcolor', \&expando_neatcolour, { - 'message public' => 'none', - 'message own_public' => 'none', - 'message private' => 'none', - 'message own_private'=> 'none', - 'message join' => 'none', - 'message part' => 'none', - 'message quit' => 'none', - 'message kick' => 'none', - 'message nick' => 'none', - 'message invite' => 'none', - 'message invite_other' => 'none', - 'message topic' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), - }); - -Irssi::expando_create('inickcolor', \&expando_neatcolour_inv, { - 'message public' => 'none', - 'message own_public' => 'none', - (map { ("message $_ action" => 'none', - "message $_ own_action" => 'none') - } @action_protos), - }); - -Irssi::signal_add({ - 'message public' => 'msg_line_tag', - 'message own_public' => 'msg_line_clear', - 'message private' => 'msg_line_tag', - 'message own_private'=> 'msg_line_tag', - 'message join' => 'join2mlt', - 'message part' => 'part2mlt', - 'message quit' => 'quit2mlt', - 'message kick' => 'kick2mlt', - 'message nick' => 'nick2mlt', - 'message invite' => 'invite2mlt', - 'message invite_other' => 'inviteo2mlt', - 'message topic' => 'topic2mlt', - 'message irc mode' => 'msg_line_clear', - (map { ("message $_ action" => 'msg_line_tag', - "message $_ own_action" => 'msg_line_clear') - } qw(irc silc)), - "message xmpp action" => 'msg_line_tag_xmppaction', - "message xmpp own_action" => 'msg_line_clear', - 'print text' => 'prnt_clear_public', - 'nicklist changed' => 'nicklist_changed', - 'gui exit' => 'exit_save', -}); -Irssi::command_bind({ - 'help' => sub { &cmd_help_neatcolor if $_[0] =~ /^neatcolor\s*$/i;}, - 'neatcolor' => 'cmd_neatcolor', - 'neatcolor save' => 'cmd_neatcolor_save', - 'neatcolor set' => 'cmd_neatcolor_set', - 'neatcolor get' => 'cmd_neatcolor_get', - 'neatcolor reset' => 'cmd_neatcolor_reset', - 'neatcolor re' => 'cmd_neatcolor_re', - 'neatcolor colors' => 'cmd_neatcolor_colors', - 'neatcolor colors add' => 'cmd_neatcolor_colors_add', - 'neatcolor colors remove' => 'cmd_neatcolor_colors_remove', - }); - -Irssi::signal_add_last('setup changed' => 'setup_changed'); - - -# Changelog -# ========= -# 0.4.0 -# - Allow usage of the colour as a background (using $inickcolor) -# 0.3.7 -# - fix crash if xmpp action signal is not registered (just ignore it) -# 0.3.6 -# - also look up ignorechars in set colours -# 0.3.5 -# - bug fix release -# 0.3.4 -# - re/set/reset-colouring was affected by the global colour -# - set colour score too weak -# 0.3.3 -# - fix error with get / reported by Meicceli -# - now possible to reset global colour -# - check for invalid colours -# 0.3.2 -# - add global colour option -# - respect save settings setting -# - add action handling -# 0.3.1 -# - regression: reset colours after removing colour -# 0.3.0 -# - save some more colours -# 0.2.9 -# - fix incorrect calculation of used colours -# - add some sanity checks to set/get command -# - avoid random colour changes diff --git a/.config/irssi/scripts/nojointext.pl b/.config/irssi/scripts/nojointext.pl @@ -1,35 +0,0 @@ -# vim:ft=perl:et:sw=2:ts=2: -use strict; -use Irssi; - -our $VERSION = '0.02'; -our %IRSSI = ( - authors => q{Magnus Woldrich}, - contact => q{m@japh.se}, - name => q{ignore_join_blob}, - description => q{Ignore the blob of text displayed when (re)joining a channel}, - license => q{MIT}, -); - -## ignores this: -# > Topic for #ubuntu: hi -# > Topic set by DalekSec -# > Home page for #ubuntu: https://www.ubuntu.com -# > Channel #ubuntu created Sun Nov 26 07:42:41 2006 -# -# These lines have the CRAP MSGLEVEL (because they are crap) but they don't -# respond to an /ignore * CRAP: -# https://github.com/irssi/irssi/issues/992 -# https://github.com/trapd00r/irssi/commit/87f38a20beda81e409a72efd323f5db45d824927 - -sub sig_print_text { - my ($dest, $string, $stripped) = @_; - - if($dest->{level} & MSGLEVEL_CRAP) { - if($stripped =~ m/Topic (for|set)|Channel [#]\S+ created|Home page for [#]\S+/) { - Irssi::signal_stop(); - } - } -} - -Irssi::signal_add_first('print text', \&sig_print_text); diff --git a/.config/irssi/scripts/tmux-nicklist-portable.pl b/.config/irssi/scripts/tmux-nicklist-portable.pl @@ -1,432 +0,0 @@ -# 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'); - 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[92m\@$colour".$_real->($nick)."\e[39m"); - } elsif ($nick->{'halfop'}) { - print($fifo "\e[92m%$colour".$_real->($nick)."\e[39m"); - } elsif ($nick->{'voice'}) { - print($fifo "\e[92m+$colour".$_real->($nick)."\e[39m"); - } elsif ($nick->{'other'}>32) { - print($fifo "\e[92m".(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; - -} diff --git a/.config/irssi/scripts/tmux_away.pl b/.config/irssi/scripts/tmux_away.pl @@ -1,202 +0,0 @@ -use Irssi; -use strict; -use FileHandle; - -use vars qw($VERSION %IRSSI); - -$VERSION = "2.1"; # e8934ed1ce04461 -%IRSSI = ( - authors => 'cdidier', - name => 'tmux_away', - description => 'set (un)away if tmux session is attached/detached', - license => 'GPL v2', - url => 'http://cybione.org', -); - -# tmux_away irssi module -# -# Written by Colin Didier <cdidier@cybione.org> and heavily based on -# screen_away irssi module version 0.9.7.1 written by Andreas 'ads' Scherbaum -# <ads@ufp.de>. -# -# Updated by John C. Vernaleo <john@netpurgatory.com> to handle tmux with -# named sessions and other code cleanup and forked as version 2.0. -# -# usage: -# -# put this script into your autorun directory and/or load it with -# /SCRIPT LOAD <name> -# -# there are 5 settings available: -# -# /set tmux_away_active ON/OFF/TOGGLE -# /set tmux_away_repeat <integer> -# /set tmux_away_grace <integer> -# /set tmux_away_message <string> -# /set tmux_away_window <string> -# /set tmux_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 -# tmux session status again, default is 5 seconds -# grace is the number of seconds, to wait additionally, before -# setting you away, default is disabled (0) -# 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 - - -# variables -my $timer_name = undef; -my $away_status = 0; -my %old_nicks = (); -my %away = (); - -# Register formats -Irssi::theme_register( -[ - 'tmux_away_crap', - '{line_start}{hilight ' . $IRSSI{'name'} . ':} $0' -]); - -# try to find out if we are running in a tmux session -# (see if $ENV{TMUX} is set) -if (!defined($ENV{TMUX})) { - # just return, we will never be called again - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', - "no tmux session!"); - return; -} - -my @args_env = split(',', $ENV{TMUX}); -my $tmux_socket = $args_env[0]; - -# register config variables -Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1); -Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5); -Irssi::settings_add_int('misc', $IRSSI{'name'} . '_grace', 0); -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', ""); - - -# check, set or reset the away status -sub tmux_away { - my ($immediate) = @_; - my ($status, @res); - - # only run, if activated - if (Irssi::settings_get_bool($IRSSI{'name'} . '_active') != 1) { - $away_status = 0; - } else { - if ($away_status == 0) { - # display init message at first time - my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace'); - $grace = ", $grace seconds grace" if $grace; - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', - "activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds$grace)"); - $away_status = 2; - } - - # get actual tmux session status - chomp(@res = `tmux -S '$tmux_socket' lsc 2>&1`); - chomp(my $tmux_session = `tmux -S '$tmux_socket' display -p '#S' 2>/dev/null`); - if ($res[0] =~ /^server not found/ || $? >> 8) { - die "error getting tmux session status."; - } - $status = 1; # away, assumes the session is detached - foreach (@res) { - my @args_st = split(' '); - if ($args_st[1] eq $tmux_session) { - $status = 2; # unaway - } - } - - # unaway -> away - if ($status == 1 and $away_status != 1) { - if (my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace')) { - if (!$immediate) { - Irssi::timeout_add_once($grace * 1000, 'tmux_away', '1'); - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', - "(in grace for away: $grace seconds)"); - return 1; - } - } - 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, 'tmux_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 ..."; - } - foreach (Irssi::servers()) { - if (!$_->{usermode_away}) { - # user isn't yet away - $away{$_->{'tag'}} = 0; - $_->command("^AWAY " . ($_->{chat_type} ne 'SILC' ? "-one " : "") . "$message"); - if ($_->{chat_type} ne 'XMPP' and length(Irssi::settings_get_str($IRSSI{'name'} . '_nick')) > 0) { - # only change if actual nick isn't already the away nick - if (Irssi::settings_get_str($IRSSI{'name'} . '_nick') ne $_->{nick}) { - # keep old nick - $old_nicks{$_->{'tag'}} = $_->{nick}; - # set new nick - $_->command("NICK " . Irssi::settings_get_str($IRSSI{'name'} . '_nick')); - } - } - } else { - # user is already away, remember this - $away{$_->{'tag'}} = 1; - } - } - $away_status = $status; - - # away -> unaway - } elsif ($status == 2 and $away_status != 2) { - if (my $grace = Irssi::settings_get_int($IRSSI{'name'} . '_grace')) { - if (!$immediate) { - Irssi::timeout_add_once($grace * 1000, 'tmux_away', '1'); - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', - "(in grace for unaway: $grace seconds)"); - return 1; - } - } - # unset away - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', "Reset away"); - foreach (Irssi::servers()) { - if ($away{$_->{'tag'}} == 1) { - # user was already away, don't reset away - $away{$_->{'tag'}} = 0; - next; - } - $_->command("^AWAY" . (($_->{chat_type} ne 'SILC') ? " -one" : "")) if ($_->{usermode_away}); - if ($_->{chat_type} ne 'XMPP' and defined($old_nicks{$_->{'tag'}}) and length($old_nicks{$_->{'tag'}}) > 0) { - # set old nick - $_->command("NICK " . $old_nicks{$_->{'tag'}}); - $old_nicks{$_->{'tag'}} = ""; - } - } - $away_status = $status; - } elsif ($immediate) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', - "in grace aborted"); - } - } - # but everytimes install a new timer - register_tmux_away_timer(); - return 0; -} - -# remove old timer and install a new one -sub register_tmux_away_timer { - # add new timer with new timeout (maybe the timeout has been changed) - Irssi::timeout_add_once(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'tmux_away', ''); -} - -# init process -tmux_away(); diff --git a/.config/irssi/scripts/trackbar.pl b/.config/irssi/scripts/trackbar.pl @@ -1,606 +0,0 @@ -## 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 } diff --git a/.config/irssi/scripts/trigger.pl b/.config/irssi/scripts/trigger.pl @@ -1,1257 +0,0 @@ -# trigger.pl - execute a command or replace text, triggered by an event in irssi -# Do /TRIGGER HELP or look at http://wouter.coekaerts.be/irssi/ for help - -# Copyright (C) 2002-2010 Wouter Coekaerts <wouter@coekaerts.be> -# -# 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 strict; -use Irssi 20020324 qw(command_bind command_runsub command signal_add_first signal_continue signal_stop signal_remove); -use Text::ParseWords; -use IO::File; -use vars qw($VERSION %IRSSI); - -$VERSION = '1.2.4'; -%IRSSI = ( - authors => 'Wouter Coekaerts', - contact => 'wouter@coekaerts.be', - name => 'trigger', - description => 'execute a command or replace text, triggered by an event in irssi', - license => 'GPLv2 or later', - url => 'http://wouter.coekaerts.be/irssi/', - changed => '2020-03-10', -); - -sub cmd_help { - Irssi::print (<<'SCRIPTHELP_EOF', MSGLEVEL_CLIENTCRAP); - -TRIGGER LIST -TRIGGER SAVE -TRIGGER RELOAD -TRIGGER MOVE <number> <number> -TRIGGER DELETE <number> -TRIGGER CHANGE <number> ... -TRIGGER ADD ... - -%U%_When to match%_%U -%UOn which types of event to trigger%U - These are simply specified by -name_of_the_type - The normal IRC event types are: - publics, %|privmsgs, (pub|priv)actions, (pub|priv)notices, (pub|priv)ctcps, (pub|priv)ctcpreplies, joins, parts, quits, kicks, topics, invites, nick_changes, dcc_msgs, dcc_actions, dcc_ctcps - mode_channel: %|a mode on the (whole) channel (like +t, +i, +b) - mode_nick: %|a mode on someone in the channel (like +o, +v) - -all is an alias for all of those. - Additionally, there is: - rawin: %|raw text incoming from the server - send_command: %|commands you give to irssi - send_text: %|lines you type that aren't commands - beep: %|when irssi beeps - notify_join: %|someone in you notify list comes online - notify_part: %|someone in your notify list goes offline - notify_away: %|someone in your notify list goes away - notify_unaway: %|someone in your notify list goes unaway - notify_unidle: %|someone in your notify list stops idling - (pub|priv)flood: %|flood in a channel or in private detected. See /set flood. Be careful, these flood signals can trigger many times for one flood (unless you have autoignore enabled) - -%UFilters (conditions) the event has to satisfy%U -They all take one parameter. If you can give a list, seperate elements by space and use quotes around the list. -All filters except for -pattern and -regexp can also be inversed by prefixing with -not_. - -pattern: %|The message must match the given pattern. ? and * can be used as wildcards - -regexp: %|The message must match the given regexp. (see man perlre) - %|if -nocase is given as an option, the regexp or pattern is matched case insensitive - -tags: %|The servertag must be in the given list of tags - -channels: %|The event must be in one of the given list of channels. - Examples: %|-channels '#chan1 #chan2' or -channels 'IRCNet/#channel' - %|-channels 'EFNet/' means every channel on EFNet and is the same as -tags 'EFNet' - -masks: %|The person who triggers it must match one of the given list of masks - -hasmode: %|The person who triggers it must have the give mode - Examples: %|'-o' means not opped, '+ov' means opped OR voiced, '-o&-v' means not opped AND not voiced - -hasflag: %|Only trigger if friends.pl (friends_shasta.pl) or people.pl is loaded and the person who triggers it has the given flag in the script (same syntax as -hasmode) - -other_masks - -other_hasmode - -other_hasflag: %|Same as above but for the victim for kicks or mode_nick. - -%U%_What to do when it matches%_%U - -command: Execute the given Irssi-command - %|You are able to use $1, $2 and so on generated by your regexp pattern. - %|For multiple commands ; can be used as seperator - %|The following variables are also expanded: - $T: %|Server tag - $C: %|Channel name - $O: %|Your nick - $N: %|Nickname of the person who triggered this command - $A: %|His address (foo@bar.com), - $I: %|His ident (foo) - $H: %|His hostname (bar.com) - $M: %|The complete message - ${other}: %|The victim for kicks or mode_nick - ${mode_type}: %|The type ('+' or '-') for a mode_channel or mode_nick - ${mode_char}: %|The mode char ('o' for ops, 'b' for ban,...) - ${mode_arg} : %|The argument to the mode (if there is one) - %|$\X, with X being one of the above expands (e.g. $\M), escapes all non-alphanumeric characters, so it can be used with /eval or /exec. Don't use /eval or /exec without this, it's not safe. - -replace: %|replaces the matching part with the given replacement in the event (requires a -regexp or -pattern) - -once: %|remove the trigger if it is triggered, so it only executes once and then is forgotten. - -stop: %|stops the signal. It won't get displayed by Irssi. Like /IGNORE - -debug: %|print some debugging info - -last: %|Don't process any more triggers for this message - -%U%_Other options%_%U - -disabled: %|Same as removing it, but keeps it in case you might need it later - -name: %|Give the trigger a name. You can refer to the trigger with this name in add/del/change commands - -%U%_Examples%_%U - Knockout people who do a !list: - %#/TRIGGER ADD %|-publics -channels "#channel1 #channel2" -nocase -regexp ^!list -command "KN $N This is not a warez channel!" - React to !echo commands from people who are +o in your friends-script: - %#/TRIGGER ADD %|-publics -regexp '^!echo (.*)' -hasflag '+o' -command 'say echo: $1' - Ignore all non-ops on #channel: - %#/TRIGGER ADD %|-publics -actions -channels "#channel" -hasmode '-o' -stop - Send a mail to yourself every time a topic is changed: - %#/TRIGGER ADD %|-topics -command 'exec echo $\N changed topic of $\C to: $\M | mail you@somewhere.com -s topic' - - -%U%_Examples with -replace%_%U - %|Replace every occurence of shit with sh*t, case insensitive: - %#/TRIGGER ADD %|-all -nocase -regexp shit -replace sh*t - %|Strip all colorcodes from *!lamer@*: - %#/TRIGGER ADD %|-all -masks *!lamer@* -regexp '\x03\d?\d?(,\d\d?)?|\x02|\x1f|\x16|\x06' -replace '' - %|Never let *!bot1@foo.bar or *!bot2@foo.bar hilight you - %|(this works by cutting your nick in 2 different parts, 'myn' and 'ick' here) - %|you don't need to understand the -replace argument, just trust that it works if the 2 parts separately don't hilight: - %#/TRIGGER ADD %|-all masks '*!bot1@foo.bar *!bot2@foo.bar' -regexp '(myn)(ick)' -nocase -replace '$1\x02\x02$2' - %|Avoid being hilighted by !top10 in eggdrops with stats.mod (but show your nick in bold): - %#/TRIGGER ADD %|-publics -regexp '(Top.0\(.*\): 1.*)(my)(nick)' -replace '$1\x02$2\x02\x02$3\x02' - %|Convert a Windows-1252 Euro to an ISO-8859-15 Euro (same effect as euro.pl): - %#/TRIGGER ADD %|-regexp '\x80' -replace '\xA4' - %|Show tabs as spaces, not the inverted I (same effect as tab_stop.pl): - %#/TRIGGER ADD %|-all -regexp '\t' -replace ' ' -SCRIPTHELP_EOF -} # / - -my @triggers; # array of all triggers -my %triggers_by_type; # hash mapping types on triggers of that type -my $recursion_depth = 0; -my $changed_since_last_save = 0; - -############### -### formats ### -############### - -Irssi::theme_register([ - 'trigger_header' => 'Triggers:', - 'trigger_line' => '%#$[-4]0 $1', - 'trigger_added' => 'Trigger $0 added: $1', - 'trigger_not_found' => 'Trigger {hilight $0} not found', - 'trigger_saved' => 'Triggers saved to $0', - 'trigger_loaded' => 'Triggers loaded from $0' -]); - -######################################### -### catch the signals & do your thing ### -######################################### - -# trigger types with a message and a channel -my @allchanmsg_types = qw(publics pubactions pubnotices pubctcps pubctcpreplies parts kicks topics); -# trigger types with a message -my @allmsg_types = (@allchanmsg_types, qw(privmsgs privactions privnotices privctcps privctcpreplies dcc_msgs dcc_actions dcc_ctcps quits)); -# trigger types with a channel -my @allchan_types = (@allchanmsg_types, qw(mode_channel mode_nick joins invites pubflood send_text)); -# trigger types in -all -my @all_types = (@allmsg_types, qw(mode_channel mode_nick joins invites nick_changes)); -# trigger types that can use -masks -my @mask_types = (@all_types, qw(notify_join notify_part notify_away notify_unaway notify_unidle)); -# trigger types with a server -my @all_server_types = (@mask_types, qw(rawin pubflood privflood)); -# all trigger types -my @trigger_types = (@all_server_types, qw(send_command send_text beep)); -#trigger types that are not in -all -#my @notall_types = grep {my $a=$_; return (!grep {$_ eq $a} @all_types);} @trigger_types; -my @notall_types = qw(rawin notify_join notify_part notify_away notify_unaway notify_unidle send_command send_text beep pubflood privflood); - -my @signals = ( -# "message public", SERVER_REC, char *msg, char *nick, char *address, char *target -{ - 'types' => ['publics'], - 'signal' => 'message public', - 'sub' => sub {check_signal_message(\@_,1,$_[0],$_[4],$_[2],$_[3],'publics');}, -}, -# "message private", SERVER_REC, char *msg, char *nick, char *address -{ - 'types' => ['privmsgs'], - 'signal' => 'message private', - 'sub' => sub {check_signal_message(\@_,1,$_[0],undef,$_[2],$_[3],'privmsgs');}, -}, -# "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target -{ - 'types' => ['privactions','pubactions'], - 'signal' => 'message irc action', - 'sub' => sub { - if ($_[4] eq $_[0]->{nick}) { - check_signal_message(\@_,1,$_[0],undef,$_[2],$_[3],'privactions'); - } else { - check_signal_message(\@_,1,$_[0],$_[4],$_[2],$_[3],'pubactions'); - } - }, -}, -# "message irc notice", SERVER_REC, char *msg, char *nick, char *address, char *target -{ - 'types' => ['privnotices','pubnotices'], - 'signal' => 'message irc notice', - 'sub' => sub { - if ($_[4] eq $_[0]->{nick}) { - check_signal_message(\@_,1,$_[0],undef,$_[2],$_[3],'privnotices'); - } else { - check_signal_message(\@_,1,$_[0],$_[4],$_[2],$_[3],'pubnotices'); - } - } -}, -# "message join", SERVER_REC, char *channel, char *nick, char *address -{ - 'types' => ['joins'], - 'signal' => 'message join', - 'sub' => sub {check_signal_message(\@_,-1,$_[0],$_[1],$_[2],$_[3],'joins');} -}, -# "message part", SERVER_REC, char *channel, char *nick, char *address, char *reason -{ - 'types' => ['parts'], - 'signal' => 'message part', - 'sub' => sub {check_signal_message(\@_,4,$_[0],$_[1],$_[2],$_[3],'parts');} -}, -# "message quit", SERVER_REC, char *nick, char *address, char *reason -{ - 'types' => ['quits'], - 'signal' => 'message quit', - 'sub' => sub {check_signal_message(\@_,3,$_[0],undef,$_[1],$_[2],'quits');} -}, -# "message kick", SERVER_REC, char *channel, char *nick, char *kicker, char *address, char *reason -{ - 'types' => ['kicks'], - 'signal' => 'message kick', - 'sub' => sub {check_signal_message(\@_,5,$_[0],$_[1],$_[3],$_[4],'kicks',{'other'=>$_[2]});} -}, -# "message topic", SERVER_REC, char *channel, char *topic, char *nick, char *address -{ - 'types' => ['topics'], - 'signal' => 'message topic', - 'sub' => sub {check_signal_message(\@_,2,$_[0],$_[1],$_[3],$_[4],'topics');} -}, -# "message invite", SERVER_REC, char *channel, char *nick, char *address -{ - 'types' => ['invites'], - 'signal' => 'message invite', - 'sub' => sub {check_signal_message(\@_,-1,$_[0],$_[1],$_[2],$_[3],'invites');} -}, -# "message nick", SERVER_REC, char *newnick, char *oldnick, char *address -{ - 'types' => ['nick_changes'], - 'signal' => 'message nick', - 'sub' => sub {check_signal_message(\@_,-1,$_[0],undef,$_[1],$_[3],'nick_changes',{'other'=>$_[2]});} -}, -# "message dcc", DCC_REC *dcc, char *msg -{ - 'types' => ['dcc_msgs'], - 'signal' => 'message dcc', - 'sub' => sub {check_signal_message(\@_,1,$_[0]->{'server'},undef,$_[0]->{'nick'},undef,'dcc_msgs'); - } -}, -# "message dcc action", DCC_REC *dcc, char *msg -{ - 'types' => ['dcc_actions'], - 'signal' => 'message dcc action', - 'sub' => sub {check_signal_message(\@_,1,$_[0]->{'server'},undef,$_[0]->{'nick'},undef,'dcc_actions');} -}, -# "message dcc ctcp", DCC_REC *dcc, char *cmd, char *data -{ - 'types' => ['dcc_ctcps'], - 'signal' => 'message dcc ctcp', - 'sub' => sub {check_signal_message(\@_,1,$_[0]->{'server'},undef,$_[0]->{'nick'},undef,'dcc_ctcps');} -}, -# "server incoming", SERVER_REC, char *data -{ - 'types' => ['rawin'], - 'signal' => 'server incoming', - 'sub' => sub {check_signal_message(\@_,1,$_[0],undef,undef,undef,'rawin');} -}, -# "send command", char *args, SERVER_REC, WI_ITEM_REC -{ - 'types' => ['send_command'], - 'signal' => 'send command', - 'sub' => sub { - sig_send_text_or_command(\@_,1); - } -}, -# "send text", char *line, SERVER_REC, WI_ITEM_REC -{ - 'types' => ['send_text'], - 'signal' => 'send text', - 'sub' => sub { - sig_send_text_or_command(\@_,0); - } -}, -# "beep" -{ - 'types' => ['beep'], - 'signal' => 'beep', - 'sub' => sub {check_signal_message(\@_,-1,undef,undef,undef,undef,'beep');} -}, -# "event "<cmd>, SERVER_REC, char *args, char *sender_nick, char *sender_address -{ - 'types' => ['mode_channel', 'mode_nick'], - 'signal' => 'event mode', - 'sub' => sub { - my ($server, $event_args, $nickname, $address) = @_; - my ($target, $modes, $modeargs) = split(/ /, $event_args, 3); - return if (!$server->ischannel($target)); - my (@modeargs) = split(/ /,$modeargs); - my ($pos, $type, $event_type, $arg) = (0, '+'); - foreach my $char (split(//,$modes)) { - if ($char eq "+" || $char eq "-") { - $type = $char; - } else { - if ($char =~ /[Oovh]/) { # mode_nick - $event_type = 'mode_nick'; - $arg = $modeargs[$pos++]; - } elsif ($char =~ /[beIqdk]/ || ( $char =~ /[lfJ]/ && $type eq '+')) { # chan_mode with arg - $event_type = 'mode_channel'; - $arg = $modeargs[$pos++]; - } else { # chan_mode without arg - $event_type = 'mode_channel'; - $arg = undef; - } - check_signal_message(\@_,-1,$server,$target,$nickname,$address,$event_type,{ - 'mode_type' => $type, - 'mode_char' => $char, - 'mode_arg' => $arg, - 'other' => ($event_type eq 'mode_nick') ? $arg : undef - }); - } - } - } -}, -# "notifylist joined", SERVER_REC, char *nick, char *user, char *host, char *realname, char *awaymsg -{ - 'types' => ['notify_join'], - 'signal' => 'notifylist joined', - 'sub' => sub {check_signal_message(\@_, 5, $_[0], undef, $_[1], $_[2].'@'.$_[3], 'notify_join', {'realname' => $_[4]});} -}, -{ - 'types' => ['notify_part'], - 'signal' => 'notifylist left', - 'sub' => sub {check_signal_message(\@_, 5, $_[0], undef, $_[1], $_[2].'@'.$_[3], 'notify_left', {'realname' => $_[4]});} -}, -{ - 'types' => ['notify_unidle'], - 'signal' => 'notifylist unidle', - 'sub' => sub {check_signal_message(\@_, 5, $_[0], undef, $_[1], $_[2].'@'.$_[3], 'notify_unidle', {'realname' => $_[4]});} -}, -{ - 'types' => ['notify_away', 'notify_unaway'], - 'signal' => 'notifylist away changed', - 'sub' => sub {check_signal_message(\@_, 5, $_[0], undef, $_[1], $_[2].'@'.$_[3], ($_[5] ? 'notify_away' : 'notify_unaway'), {'realname' => $_[4]});} -}, -# "ctcp msg", SERVER_REC, char *args, char *nick, char *addr, char *target -{ - 'types' => ['pubctcps', 'privctcps'], - 'signal' => 'ctcp msg', - 'sub' => sub { - my ($server, $args, $nick, $addr, $target) = @_; - if ($target eq $server->{'nick'}) { - check_signal_message(\@_, 1, $server, undef, $nick, $addr, 'privctcps'); - } else { - check_signal_message(\@_, 1, $server, $target, $nick, $addr, 'pubctcps'); - } - } -}, -# "ctcp reply", SERVER_REC, char *args, char *nick, char *addr, char *target -{ - 'types' => ['pubctcpreplies', 'privctcpreplies'], - 'signal' => 'ctcp reply', - 'sub' => sub { - my ($server, $args, $nick, $addr, $target) = @_; - if ($target eq $server->{'nick'}) { - check_signal_message(\@_, 1, $server, undef, $nick, $addr, 'privctcpreplies'); - } else { - check_signal_message(\@_, 1, $server, $target, $nick, $addr, 'pubctcpreplies'); - } - } -}, -# "flood", SERVER_REC, char *nick, char *host, int level, char *target -{ - 'types' => ['pubflood', 'privflood'], - 'signal' => 'flood', - 'sub' => sub { - my ($server, $nick, $host, $level, $target) = @_; - if ($target eq $server->{'nick'}) { - check_signal_message(\@_, -1, $server, undef, $nick, $host, 'privflood'); - } else { - check_signal_message(\@_, -1, $server, $target, $nick, $host, 'pubflood'); - } - } -} -); - -sub sig_send_text_or_command { - my ($signal, $iscommand) = @_; - my ($line, $server, $item) = @$signal; - my ($channelname,$nickname,$address) = (undef,undef,undef); - if ($item && (ref($item) eq 'Irssi::Irc::Channel' || ref($item) eq 'Irssi::Silc::Channel')) { - $channelname = $item->{'name'}; - } elsif ($item && ref($item) eq 'Irssi::Irc::Query') { # TODO Silc query ? - $nickname = $item->{'name'}; - $address = $item->{'address'} - } - # TODO pass context also for non-channels (queries and other stuff) - check_signal_message($signal,0,$server,$channelname,$nickname,$address,$iscommand ? 'send_command' : 'send_text'); - -} - -my %filters = ( -'tags' => { - 'types' => \@all_server_types, - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - - if (!defined($server)) { - return 0; - } - my $matches = 0; - foreach my $tag (split(/ /,$param)) { - if (lc($server->{'tag'}) eq lc($tag)) { - $matches = 1; - last; - } - } - return $matches; - } -}, -'channels' => { - 'types' => \@allchan_types, - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - - if (!defined($channelname) || !defined($server)) { - return 0; - } - my $matches = 0; - foreach my $trigger_channel (split(/ /,$param)) { - if (lc($channelname) eq lc($trigger_channel) - || lc($server->{'tag'}.'/'.$channelname) eq lc($trigger_channel) - || lc($server->{'tag'}.'/') eq lc($trigger_channel)) { - $matches = 1; - last; # this channel matches, stop checking channels - } - } - return $matches; - } -}, -'masks' => { - 'types' => \@mask_types, - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - $address //= ''; - return (defined($nickname) && defined($server) && $server->masks_match($param, $nickname, $address)); - } -}, -'other_masks' => { - 'types' => ['kicks', 'mode_nick', 'nick_changes'], - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return 0 unless defined($extra->{'other'}); - my $other_address = ($condition ne 'nick_changes') ? get_address($extra->{'other'}, $server, $channelname) : $address; - return defined($other_address) && $server->masks_match($param, $extra->{'other'}, $other_address); - } -}, -'hasmode' => { - 'types' => \@all_types, - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return hasmode($param, $nickname, $server, $channelname); - } -}, -'other_hasmode' => { - 'types' => ['kicks', 'mode_nick'], - 'sub' => sub { - my ($param,$signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return defined($extra->{'other'}) && hasmode($param, $extra->{'other'}, $server, $channelname); - } -}, -'hasflag' => { - 'types' => \@all_types, - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return 0 unless defined($nickname) && defined($address) && defined($server); - my $flags = get_flags ($server->{'chatnet'},$channelname,$nickname,$address); - return defined($flags) && check_modes($flags,$param); - } -}, -'other_hasflag' => { - 'types' => ['kicks', 'mode_nick'], - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return 0 unless defined($extra->{'other'}); - my $other_address = get_address($extra->{'other'}, $server, $channelname); - return 0 unless defined($other_address); - my $flags = get_flags ($server->{'chatnet'},$channelname,$extra->{'other'},$other_address); - return defined($flags) && check_modes($flags,$param); - } -}, -'mode_type' => { - 'types' => ['mode_channel', 'mode_nick'], - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return (($param) eq $extra->{'mode_type'}); - } -}, -'mode_char' => { - 'types' => ['mode_channel', 'mode_nick'], - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return (($param) eq $extra->{'mode_char'}); - } -}, -'mode_arg' => { - 'types' => ['mode_channel', 'mode_nick'], - 'sub' => sub { - my ($param, $signal,$parammessage,$server,$channelname,$nickname,$address,$condition,$extra) = @_; - return (($param) eq $extra->{'mode_arg'}); - } -} -); - -sub get_address { - my ($nick, $server, $channel) = @_; - my $nickrec = get_nickrec($nick, $server, $channel); - return $nickrec ? $nickrec->{'host'} : undef; -} -sub get_nickrec { - my ($nick, $server, $channel) = @_; - return unless defined($server) && defined($channel) && defined($nick); - my $chanrec = $server->channel_find($channel); - return $chanrec ? $chanrec->nick_find($nick) : undef; -} - -sub hasmode { - my ($param, $nickname, $server, $channelname) = @_; - my $nickrec = get_nickrec($nickname, $server, $channelname); - return 0 unless defined $nickrec; - my $modes = - ($nickrec->{'op'} ? 'o' : '') - . ($nickrec->{'voice'} ? 'v' : '') - . ($nickrec->{'halfop'} ? 'h' : '') - ; - return check_modes($modes, $param); -} - -# list of all switches -my @trigger_switches = (@trigger_types, qw(all nocase stop once debug disabled last)); -# parameters (with an argument) -my @trigger_params = qw(pattern regexp command replace name); -# all options that can be used to set filters, including negative matches (not_<filter>) -my @trigger_filter_options = map(($_,'not_'.$_), keys(%filters)); -# list of all options (including switches) for /TRIGGER ADD -my @trigger_add_options = (@trigger_switches, @trigger_params, @trigger_filter_options); -# same for /TRIGGER CHANGE, this includes the -no<option>'s -my @trigger_options = map(($_,'no'.$_) ,@trigger_add_options); - -# check the triggers on $signal's $parammessage parameter, for triggers with $condition set -# on $server in $channelname, for $nickname!$address -# set $parammessage to -1 if the signal doesn't have a message -# for signal without channel, nick or address, set to undef -sub check_signal_message { - my ($signal, $parammessage, $server, $channelname, $nickname, $address, $condition, $extra) = @_; - my ($changed, $stopped, $context, $need_rebuild); - my $message = ($parammessage == -1) ? '' : $signal->[$parammessage]; - - return if (!$triggers_by_type{$condition}); - - if ($recursion_depth > 10) { - Irssi::print("Trigger error: Maximum recursion depth reached, aborting trigger.", MSGLEVEL_CLIENTERROR); - return; - } - $recursion_depth++; - -TRIGGER: - foreach my $trigger (@{$triggers_by_type{$condition}}) { - # check filters - foreach my $trigfilter (filters_for_trigger($trigger)) { - my $filter_sub = $trigfilter->{'filter'}->{'sub'}; - my $filter_matches = !!(&$filter_sub($trigfilter->{'param'}, $signal, $parammessage, $server, $channelname, $nickname, $address, $condition, $extra)); - if ($filter_matches != $trigfilter->{'must_match'}) { # if it didn't match, or if it's a -not_* filter and it did match - next TRIGGER; - } - } - - # check regexp (and keep matches in @- and @+, so don't make a this a {block}) - next if ($trigger->{'compregexp'} && ($parammessage == -1 || $message !~ m/$trigger->{'compregexp'}/)); - - # if we got this far, it fully matched, and we need to do the replace/command/stop/once - my $expands = $extra; - $expands->{'M'} = $message,; - $expands->{'T'} = (defined($server)) ? $server->{'tag'} : ''; - $expands->{'C'} = $channelname; - $expands->{'O'} = (defined($server)) ? $server->{'nick'} : ''; - $expands->{'N'} = $nickname; - $expands->{'A'} = $address; - $expands->{'I'} = ((!defined($address)) ? '' : substr($address,0,index($address,'@'))); - $expands->{'H'} = ((!defined($address)) ? '' : substr($address,index($address,'@')+1)); - $expands->{'$'} = '$'; - $expands->{';'} = ';'; - - if (defined($trigger->{'replace'})) { # it's a -replace - $message =~ s/$trigger->{'compregexp'}/do_expands(0,$trigger->{'compreplace'},$expands,$message)/ge; - $changed = 1; - } - - if ($trigger->{'command'}) { # it's a (nonempty) -command - my $command = $trigger->{'command'}; - # $1 = the stuff behind the $ we want to expand: a number, or a character from %expands - $command = do_expands(1, $command, $expands, $message); - - if (defined($server)) { - if (defined($channelname) && $server->channel_find($channelname)) { - $context = $server->channel_find($channelname); - } else { - $context = $server; - } - } else { - $context = undef; - } - - if (defined($context)) { - $context->command("eval $command"); - } else { - Irssi::command("eval $command"); - } - } - - if ($trigger->{'debug'}) { - print("DEBUG: trigger $condition pmesg=$parammessage message=$message server=$server->{tag} channel=$channelname nick=$nickname address=$address " . join(' ',map {$_ . '=' . $extra->{$_}} keys(%$extra))); - } - - if ($trigger->{'stop'}) { - $stopped = 1; - } - - if ($trigger->{'once'}) { - # find this trigger in the real trigger list, and remove it - for (my $realindex=0; $realindex < scalar(@triggers); $realindex++) { - if ($triggers[$realindex] == $trigger) { - splice (@triggers,$realindex,1); - last; - } - } - $need_rebuild = 1; - } - if ($trigger->{'last'}) { - last TRIGGER; - } - } - - if ($need_rebuild) { - rebuild(); - $changed_since_last_save = 1; - } - if ($stopped) { # stopped with -stop - signal_stop(); - } elsif ($changed) { # changed with -replace - $signal->[$parammessage] = $message; - signal_continue(@$signal); - } - $recursion_depth--; -} - -# return array of filters for the given trigger -sub filters_for_trigger($) { - my ($trigger) = @_; - return values(%{$trigger->{'filters'}}); -} - -# used in check_signal_message to expand $'s -# $inthis is a string that can contain $ stuff (like 'foo$1bar$N') -sub do_expands { - my ($escape, $inthis, $expands, $from) = @_; - # @+ and @- are copied because there are two s/// nested, and the inner needs the $1 and $2,... of the outer one - my @plus = @+; - my @min = @-; - my $p = \@plus; my $m = \@min; - $inthis =~ s/\$(\\*(\d+|[^0-9x{]|x[0-9a-fA-F][0-9a-fA-F]|{.*?}))/expand_and_escape($escape,$1,$expands,$m,$p,$from)/ge; - return $inthis; -} - -# \ $ and ; may need extra escaping because we use eval for -command -sub expand_and_escape { - my $escape = shift; - my $retval = expand(@_); - if ($escape) { - $retval =~ s/([\\\$;])/\\\1/g; - } - return $retval; -} - -# used in do_expands (via expand_and_escape), to_expand is the part after the $ -sub expand { - my ($to_expand, $expands, $min, $plus, $from) = @_; - if ($to_expand =~ /^\d+$/) { # a number => look up in $vars - # from man perlvar: - # $3 is the same as "substr $var, $-[3], $+[3] - $-[3])" - return ($to_expand > @{$min} ? '' : substr($from,$min->[$to_expand],$plus->[$to_expand]-$min->[$to_expand])); - } elsif ($to_expand =~ s/^\\//) { # begins with \, so strip that from to_expand - my $exp = expand($to_expand,$expands,$min,$plus,$from); # first expand without \ - $exp =~ s/([^a-zA-Z0-9])/\\\1/g; # escape non-word chars - return $exp; - } elsif ($to_expand =~ /^x([0-9a-fA-F]{2})/) { # $xAA - return chr(hex($1)); - } elsif ($to_expand =~ /^{(.*?)}$/) { # ${foo} - return expand($1, $expands, $min, $plus, $from); - } else { # look up in $expands - return $expands->{$to_expand}; - } -} - -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 -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'; - } else { - 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; -} - -######################################################## -### internal stuff called by manage, needed by above ### -######################################################## - -my %mask_to_regexp = (); -foreach my $i (0..255) { - my $ch = chr $i; - $mask_to_regexp{$ch} = "\Q$ch\E"; -} -$mask_to_regexp{'?'} = '(.)'; -$mask_to_regexp{'*'} = '(.*)'; - -sub compile_trigger { - my ($trigger) = @_; - my $regexp; - - if ($trigger->{'regexp'}) { - $regexp = $trigger->{'regexp'}; - } elsif ($trigger->{'pattern'}) { - $regexp = $trigger->{'pattern'}; - $regexp =~ s/(.)/$mask_to_regexp{$1}/g; - } else { - delete $trigger->{'compregexp'}; - return; - } - - if ($trigger->{'nocase'}) { - $regexp = '(?i)' . $regexp; - } - - $trigger->{'compregexp'} = qr/$regexp/; - - if(defined($trigger->{'replace'})) { - (my $replace = $trigger->{'replace'}) =~ s/\$/\$\$/g; - $trigger->{'compreplace'} = Irssi::parse_special($replace); - } -} - -# rebuilds triggers_by_type and updates signal binds -sub rebuild { - %triggers_by_type = (); - foreach my $trigger (@triggers) { - if (!$trigger->{'disabled'}) { - if ($trigger->{'all'}) { - # -all is an alias for all types in @all_types for which the filters can apply -ALLTYPES: - foreach my $type (@all_types) { - # check if all filters can apply to $type - foreach my $trigfilter (filters_for_trigger($trigger)) { - if (! grep {$_ eq $type} @{$trigfilter->{'filter'}->{'types'}}) { - next ALLTYPES; - } - } - push @{$triggers_by_type{$type}}, ($trigger); - } - } - - foreach my $type ($trigger->{'all'} ? @notall_types : @trigger_types) { - if ($trigger->{$type}) { - push @{$triggers_by_type{$type}}, ($trigger); - } - } - } - } - - foreach my $signal (@signals) { - my $should_bind = 0; - foreach my $type (@{$signal->{'types'}}) { - if (defined($triggers_by_type{$type})) { - $should_bind = 1; - } - } - if ($should_bind && !$signal->{'bind'}) { - signal_add_first($signal->{'signal'}, $signal->{'sub'}); - $signal->{'bind'} = 1; - } elsif (!$should_bind && $signal->{'bind'}) { - signal_remove($signal->{'signal'}, $signal->{'sub'}); - $signal->{'bind'} = 0; - } - } -} - -################################ -### manage the triggers-list ### -################################ - -my $trigger_file; # cached setting - -sub sig_setup_changed { - $trigger_file = Irssi::settings_get_str('trigger_file'); -} - -sub autosave { - cmd_save() if ($changed_since_last_save); -} - -# TRIGGER SAVE -sub cmd_save { - my $io = new IO::File $trigger_file, "w"; - if (defined $io) { - $io->print("#Triggers file version $VERSION\n"); - foreach my $trigger (@triggers) { - $io->print(to_string($trigger) . "\n"); - } - $io->close; - } - Irssi::printformat(MSGLEVEL_CLIENTNOTICE, 'trigger_saved', $trigger_file); - $changed_since_last_save = 0; -} - -# save on unload -sub UNLOAD { - cmd_save(); -} - -# TRIGGER LOAD -sub cmd_load { - sig_setup_changed(); # make sure we've read the trigger_file setting - my $converted = 0; - my $io = new IO::File $trigger_file, "r"; - if (not defined $io) { - if (-e $trigger_file) { - Irssi::print("Error opening triggers file", MSGLEVEL_CLIENTERROR); - } - return; - } - if (defined $io) { - @triggers = (); - my $text; - $text = $io->getline; - my $file_version = ''; - if ($text =~ /^#Triggers file version (.*)\n/) { - $file_version = $1; - } - if ($file_version lt '0.6.1+2') { - no strict 'vars'; - $text .= $_ foreach ($io->getlines); - my $rep = eval "$text"; - if (! ref $rep) { - Irssi::print("Error in triggers file"); - return; - } - my @old_triggers = @$rep; - - for (my $index=0;$index < scalar(@old_triggers);$index++) { - my $trigger = $old_triggers[$index]; - - if ($file_version lt '0.6.1') { - # convert old names: notices => pubnotices, actions => pubactions - foreach $oldname ('notices','actions') { - if ($trigger->{$oldname}) { - delete $trigger->{$oldname}; - $trigger->{'pub'.$oldname} = 1; - $converted = 1; - } - } - } - if ($file_version lt '0.6.1+1' && $trigger->{'modifiers'}) { - if ($trigger->{'modifiers'} =~ /i/) { - $trigger->{'nocase'} = 1; - Irssi::print("Trigger: trigger ".($index+1)." had 'i' in it's modifiers, it has been converted to -nocase"); - } - if ($trigger->{'modifiers'} !~ /^[ig]*$/) { - Irssi::print("Trigger: trigger ".($index+1)." had unrecognised modifier '". $trigger->{'modifiers'} ."', which couldn't be converted."); - } - delete $trigger->{'modifiers'}; - $converted = 1; - } - - # convert to text with compat, and then to new trigger hash - $text = to_string($trigger,1); - my @args = &shellwords($text . ' a'); - my $trigger = parse_options({},@args); - if ($trigger) { - push @triggers, $trigger; - } - } - } else { # new format - while ( $text = $io->getline ) { - chop($text); - next if ($text =~ /^[ ]*$|^#/); - my @args = &shellwords($text . ' a'); - my $trigger = parse_options({},@args); - if ($trigger) { - push @triggers, $trigger; - } - } - } - } - Irssi::printformat(MSGLEVEL_CLIENTNOTICE, 'trigger_loaded', $trigger_file); - if ($converted) { - Irssi::print("Trigger: Triggers file will be in new format next time it's saved."); - } - rebuild(); -} - -# escape for printing with to_string -# <<abcdef>> => << 'abcdef' >> -# <<abc'def>> => << "abc'def" >> -# <<abc'def\x02>> => << 'abc'\''def\x02' >> -sub param_to_string { - my ($text) = @_; - # avoid ugly escaping if we can use "-quotes without other escaping (no " or \) - if ($text =~ /^[^"\\]*'[^"\\]$/) { - return ' "' . $text . '" '; - } - # "'" signs without a (odd number of) \ in front of them, need be to escaped as '\'' - # this is ugly :( - $text =~ s/(^|[^\\](\\\\)*)'/$1'\\''/g; - return " '$text' "; -} - -# converts a trigger back to "-switch -options 'foo'" form -# if $compat, $trigger is in the old format (used to convert) -sub to_string { - my ($trigger, $compat) = @_; - my $string; - - foreach my $switch (@trigger_switches) { - if ($trigger->{$switch}) { - $string .= '-'.$switch.' '; - } - } - - if ($compat) { - foreach my $filter (keys(%filters)) { - if ($trigger->{$filter}) { - $string .= '-' . $filter . param_to_string($trigger->{$filter}); - } - } - } else { - foreach my $trigfilter (filters_for_trigger($trigger)) { - $string .= '-' . $trigfilter->{'option'} . param_to_string($trigfilter->{'param'}); - } - } - - foreach my $param (@trigger_params) { - if ($trigger->{$param} || ($param eq 'replace' && defined($trigger->{'replace'}))) { - $string .= '-' . $param . param_to_string($trigger->{$param}); - } - } - return $string; -} - -# find a trigger (for REPLACE and DELETE), returns index of trigger, or -1 if not found -sub find_trigger { - my ($data) = @_; - if ($data =~ /^[0-9]*$/ and defined($triggers[$data-1])) { - return $data-1; - } else { - for (my $i=0; $i < scalar(@triggers); $i++) { - if ($triggers[$i]->{'name'} eq $data) { - return $i; - } - } - } - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trigger_not_found', $data); - return -1; # not found -} - - -# TRIGGER ADD <options> -sub cmd_add { - my ($data, $server, $item) = @_; - my @args = shellwords($data . ' a'); - - my $trigger = parse_options({}, @args); - if ($trigger) { - push @triggers, $trigger; - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trigger_added', scalar(@triggers), to_string($trigger)); - rebuild(); - $changed_since_last_save = 1; - } -} - -# TRIGGER CHANGE <nr> <options> -sub cmd_change { - my ($data, $server, $item) = @_; - my @args = shellwords($data . ' a'); - my $index = find_trigger(shift @args); - if ($index != -1) { - if(parse_options($triggers[$index], @args)) { - Irssi::print("Trigger " . ($index+1) ." changed to: ". to_string($triggers[$index])); - } - rebuild(); - $changed_since_last_save = 1; - } -} - -# parses options for TRIGGER ADD and TRIGGER CHANGE -# if invalid args returns undef, else changes $thetrigger and returns it -sub parse_options { - my ($thetrigger,@args) = @_; - my ($trigger, $option); - - if (pop(@args) ne 'a') { - Irssi::print("Syntax error, probably missing a closing quote", MSGLEVEL_CLIENTERROR); - return undef; - } - - %$trigger = %$thetrigger; # make a copy to prevent changing the given trigger if args doesn't parse -ARGS: for (my $arg = shift @args; $arg; $arg = shift @args) { - # expand abbreviated options, put in $option - $arg =~ s/^-//; - $option = undef; - foreach my $ioption (@trigger_options) { - if (index($ioption, $arg) == 0) { # -$opt starts with $arg - if ($option) { # another already matched - Irssi::print("Ambiguous option: $arg", MSGLEVEL_CLIENTERROR); - return undef; - } - $option = $ioption; - last if ($arg eq $ioption); # exact match is unambiguous - } - } - if (!$option) { - Irssi::print("Unknown option: $arg", MSGLEVEL_CLIENTERROR); - return undef; - } - - # -<param> <value> or -no<param> - foreach my $param (@trigger_params) { - if ($option eq $param) { - $trigger->{$param} = shift @args; - next ARGS; - } - if ($option eq 'no'.$param) { - $trigger->{$param} = undef; - next ARGS; - } - } - - # -[no]<switch> - foreach my $switch (@trigger_switches) { - # -<switch> - if ($option eq $switch) { - $trigger->{$switch} = 1; - next ARGS; - } - # -no<switch> - elsif ($option eq 'no'.$switch) { - $trigger->{$switch} = undef; - next ARGS; - } - } - - # -[not_]<filter> <value> - if ($option =~ /^(not_)?(.*)$/ && $filters{$2}) { - $trigger->{'filters'}->{$option} = { - option => $option, - must_match => ($1 ne 'not_'), # if false, trigger must only be done if filter sub returns false - filter_name => $2, - filter => $filters{$2}, - param => shift @args - }; - - next ARGS; - } - - # -no<filter> - if ($option =~ /^no(.*)$/ && $filters{$1}) { - delete $trigger->{'filters'}->{$1}; - } - } - - if (defined($trigger->{'replace'}) && ! $trigger->{'regexp'} && !$trigger->{'pattern'}) { - Irssi::print("Trigger error: Can't have -replace without -regexp", MSGLEVEL_CLIENTERROR); - return undef; - } - - if ($trigger->{'pattern'} && $trigger->{'regexp'}) { - Irssi::print("Trigger error: Can't have -pattern and -regexp in same trigger", MSGLEVEL_CLIENTERROR); - return undef; - } - - # remove types that are implied by -all - if ($trigger->{'all'}) { - foreach my $type (@all_types) { - delete $trigger->{$type}; - } - } - - # remove types for which the filters don't apply - foreach my $type (@trigger_types) { - if ($trigger->{$type}) { - foreach my $trigfilter (filters_for_trigger($trigger)) { - if (!grep {$_ eq $type} @{$trigfilter->{'filter'}->{'types'}}) { - Irssi::print("Warning: the filter -" . $trigfilter->{'option'} . " can't apply to an event of type -$type, so I'm removing that type from this trigger."); - delete $trigger->{$type}; - } - } - } - } - - # check if it has at least one type - my $has_a_type; - foreach my $type (@trigger_types) { - if ($trigger->{$type}) { - $has_a_type = 1; - last; - } - } - if (!$has_a_type && !$trigger->{'all'}) { - Irssi::print("Warning: this trigger doesn't trigger on any type of message. you probably want to add -publics or -all"); - } - - compile_trigger($trigger); - %$thetrigger = %$trigger; # copy changes to real trigger - return $thetrigger; -} - -# TRIGGER DELETE <num> -sub cmd_del { - my ($data, $server, $item) = @_; - my @args = shellwords($data); - my $index = find_trigger(shift @args); - if ($index != -1) { - Irssi::print("Deleted ". ($index+1) .": ". to_string($triggers[$index])); - splice (@triggers,$index,1); - rebuild(); - $changed_since_last_save = 1; - } -} - -# TRIGGER MOVE <num> <num> -sub cmd_move { - my ($data, $server, $item) = @_; - my @args = &shellwords($data); - my $index = find_trigger(shift @args); - if ($index != -1) { - my $newindex = find_trigger(shift @args); - if ($newindex != -1) { - Irssi::print("Moved from " . ($index+1) . " to " . ($newindex+1) . ": " . to_string($triggers[$index])); - my $trigger = splice (@triggers,$index,1); # remove from old place - splice (@triggers,$newindex,0,($trigger)); # insert at new place - rebuild(); - $changed_since_last_save = 1; - } - } -} - -# TRIGGER LIST -sub cmd_list { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trigger_header'); - my $i=1; - foreach my $trigger (@triggers) { - Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'trigger_line', $i++, to_string($trigger)); - } -} - -###################### -### initialisation ### -###################### - -command_bind('trigger help',\&cmd_help); -command_bind('help trigger',\&cmd_help); -command_bind('trigger add',\&cmd_add); -command_bind('trigger change',\&cmd_change); -command_bind('trigger move',\&cmd_move); -command_bind('trigger list',\&cmd_list); -command_bind('trigger delete',\&cmd_del); -command_bind('trigger save',\&cmd_save); -command_bind('trigger reload',\&cmd_load); -command_bind 'trigger' => sub { - my ( $data, $server, $item ) = @_; - $data =~ s/\s+$//g; - command_runsub('trigger', $data, $server, $item); -}; - -Irssi::signal_add('setup saved', \&autosave); -Irssi::signal_add('setup changed', \&sig_setup_changed); - -# This makes tab completion work -Irssi::command_set_options('trigger add',join(' ',@trigger_add_options)); -Irssi::command_set_options('trigger change',join(' ',@trigger_options)); - -Irssi::settings_add_str($IRSSI{'name'}, 'trigger_file', Irssi::get_irssi_dir()."/triggers"); - -cmd_load(); diff --git a/.config/irssi/scripts/uberprompt.pl b/.config/irssi/scripts/uberprompt.pl @@ -1,774 +0,0 @@ -=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; -} diff --git a/.config/irssi/scripts/vim_mode.pl b/.config/irssi/scripts/vim_mode.pl @@ -1,3781 +0,0 @@ -=pod - -=head1 NAME - -vim_mode.pl - -=head1 DESCRIPTION - -An Irssi script to emulate some of the vi(m) features for the Irssi inputline. - -=head1 INSTALLATION - -Copy into your F<~/.irssi/scripts/> directory and load with -C</SCRIPT LOAD vim_mode.pl>. You may wish to have it autoload in one of the -L<usual ways|https://github.com/shabble/irssi-docs/wiki/Guide#Autorunning_Scripts>. - -=head2 DEPENDENCIES - -For proper :ex mode support, vim-mode requires the installation of F<uberprompt.pl> -Uberprompt can be downloaded from: - -L<https://github.com/shabble/irssi-scripts/raw/master/prompt_info/uberprompt.pl> - -and follow the instructions at the top of that file for installation. - -If you don't need Ex-mode, you can run vim_mode.pl without the -uberprompt.pl script, but it is strongly recommended that you use it. - -=head3 Irssi requirements - -0.8.12 and above should work fine. However the following features are -disabled in irssi < 0.8.13: - -=over 4 - -=item * C<j> C<k> (only with count, they work fine without count in older versions) - -=item * C<gg>, C<G> - -=back - -It is intended to work with at Irssi 0.8.12 and later versions. However some -features are disabled in older versions (see below for details). - -Perl >= 5.8.1 is recommended for UTF-8 support (which can be disabled if -necessary). Please report bugs in older versions as well, we'll try to fix -them. Later versions of Perl are also faster, which is probably beneficial -to a script of this size and complexity. - -=head2 SETUP - -Vim Mode provides certain feedback to the user, such as the currently active -mode (command, insert, ex), and if switching buffers, which buffer(s) currently -match the search terms. - -There are two ways to go about displaying this information, as described in -the following sections: - -=head3 Statusbar Items - -Run the following command to add a statusbar item that shows which mode -you're in. - -C</statusbar window add vim_mode> - -And the following to let C<:b [str]> display a list of channels matching your -search string. - -C</statusbar window add vim_windows> - -B<Note:> Remember to C</save> after adding these statusbar items to make them -permanent. - -B<Note:> If you would rather have these statusbar items on your prompt -line rather than thte window statusbar, please follow these steps. - -For technical reasons, I<uberprompt> must occasionally call C</statusbar prompt -reset>, which will remove or deactivate any manually added items on the prompt -statusbar. To get around this, uberprompt provides two command hooks, -C<uberprompt_load_hook> and C<uberprompt_unload_hook>. Both of these settings -can contain one (or more, using C</EVAL>) commands to be executed when the prompt -is enabled and disabled, respectively. - -See the L<uberprompt documentation|https://github.com/shabble/irssi-scripts/blob/master/prompt_info/README.pod> for further details. - -For I<right-aligned> items (that is, after the input field: - -=over 4 - -=item 1 C</alias vm_add /^statusbar prompt add -after input -alignment right vim_mode> - -=item 2 C</alias vm_del /^statusbar prompt remove vim_mode> - -=item 3 C</set uberprompt_load_hook /^vm_add> - -=item 4 C</set uberprompt_unload_hook /^vm_del> - -=back - -For I<left-aligned> items (before the prompt): - -=over 4 - -=item 1 C</alias vm_add /^statusbar prompt add -before prompt -alignment left vim_mode> - -=item 2 C</alias vm_del /^statusbar prompt remove vim_mode> - -=item 3 C</set uberprompt_load_hook /^vm_add> - -=item 4 C</set uberprompt_unload_hook /^vm_del> - -=back - -If you wish to add both C<vim_mode> and C<vim_windows> items, replace steps 1 and 2 -above with the following (right-aligned): - -=over 4 - -=item 1 C</alias vm_add /^eval /^statusbar prompt add -after input -alightment right vim_mode ; /^statusbar prompt add -after input -alignment right vim_windows> - -=item 2 C</alias vm_del /^eval /^statusbar prompt remove vim_mode ; /^statusbar prompt remove vim_windows> - -=back - -and then complete stages 3 and 4 as above. Replace the C<-after> and C<-alignment> -to suit your location preferences. - -B<Note:> It is also possible to place the items between the prompt and input field, -by specifying C<-after prompt> or C<-before input> as appropriate. - -=head3 Expando Variables - -Vim mode augments the existing Irssi expando (automatic variables) with two -additional ones: C<$vim_cmd_mode> and C<$vim_wins>. - -C<$vim_cmd_mode> is the equivalent of the C<vim_mode> statusbar item, and -C<$vim_wins> is the counterpart of C<vim_windows>. - -They can be added to your theme, or inserted into your uberprompt using -a command such as: - -"C</set uberprompt_format [$vim_cmd_mode] $*$uber] >" - -=head3 FILE-BASED CONFIGURATION - -Additionally to the irssi settings described in L<settings|/SETTINGS>, vim_mode -can be configured through an external configuration file named "vim_moderc" -located in F<~/.irssi/vim_moderc>. If available it's loaded on startup and every -supported ex-command is run. Its syntax is similar to "vimrc". To (re)load it -while vim_mode is running use C<:so[urce]>. - -Currently Supported ex-commands: - -=over 4 - -=item * C<:map> - -=back - -=head1 USAGE - -The following section is divided into the different modes as supported by Vim itself: - -=head2 COMMAND MODE - -It supports most commonly used command mode features: - -=over 2 - -=item * Insert/Command mode. - -C<Esc> and C<Ctrl-C> enter command mode. C</set vim_mode_cmd_seq j> allows -to use C<jj> as Escape (any other character can be used as well). - -=item * Cursor motion: - -C<h l 0 ^ $ E<lt>SpaceE<gt> E<lt>BSE<gt> f t F T> - -=item * History motion: - -C<j k gg G> C<gg> moves to the oldest (first) history line. C<G> without a -count moves to the current input line, with a count it goes to the I<count-th> -history line (1 is the oldest). - -=item * Cursor word motion: - -C<w b ge e W gE B E> - -=item * Word objects (only the following work yet): - -C<aw aW> - -=item * Yank and paste: - - C<y p P> - -=item * Change and delete: - -C<c d> - -=item * Delete at cursor: - -C<x X> - -=item * Replace at cursor: - -C<r> - -=item * Insert mode: - -C<i a I A> - -=item * Switch case: - -C<~> - -=item * Repeat change: - -C<.> - -=item * Repeat - -C<ftFT: ; ,> - -=item * Registers: - -C<"a-"z "" "0 "* "+ "_> (black hole) - -=item * Line-wise shortcuts: - -C<dd cc yy> - -=item * Shortcuts: - -C<s S C D> - -=item * Scroll the scrollback buffer: - -C<Ctrl-E Ctrl-D Ctrl-Y Ctrl-U Ctrl-F Ctrl-B> - -=item * Switch to last active window: - -C<Ctrl-6/Ctrl-^> - -=item * Switch split windows: - -<Ctrl-W j Ctrl-W k> - -=item * Undo/Redo: - -C<u Ctrl-R> - -=back - -Counts and combinations work as well, e.g. C<d5fx> or C<3iabcE<lt>escE<gt>>. Counts also work with mapped ex-commands (see below), e.g. if you map C<gb> to do C<:bn>, then C<2gb> will switch to the second next buffer. Repeat also supports counts. - -=head3 REGISTERS - -=over 4 - -=item * Appending to register with C<"A-"Z> - -=item * C<""> is the default yank/delete register. - -=item * C<"0> contains the last yank (if no register was specified). - -=item * The special registers C<"* "+> both contain irssi's internal cut-buffer. - -=back - -=head2 INSERT MODE - -The following insert mode mappings are supported: - -=over 4 - -=item * Insert register content: Ctrl-R x (where x is the register to insert) - -=back - -=head2 EX-MODE - -Ex-mode (activated by C<:> in command mode) supports the following commands: - -=over 4 - -=item * Command History: - -C<E<lt>uparrowE<gt>> - cycle backwards through history - -C<E<lt>downarrowE<gt>> - cycle forwards through history - -C<:eh> - show ex history - -=item * Switching buffers: - -C<:[N]b [N]> - switch to channel number - -C<:b#> - switch to last channel - -C<:b> E<lt>partial-channel-nameE<gt> - -C<:b> <partial-server>/<partial-channel> - -C<:buffer {args}> (same as C<:b>) - -C<:[N]bn[ext] [N]> - switch to next window - -C<:[N]bp[rev] [N]> - switch to previous window - -=item * Close window: - -C<:[N]bd[elete] [N]> - -=item * Display windows: - -C<:ls>, C<:buffers> - -=item * Display registers: - -C<:reg[isters] {args}>, C<:di[splay] {args}> - -=item * Display undolist: - -C<:undol[ist]> (mostly used for debugging) - -=item * Source files: - -C<:so[urce]> - only sources vim_moderc at the moment, - F<{file}> not supported - -=item * Mappings: - -C<:map> - display custom mappings - -=item * Saving mappings: - -C<:mkv[imrc][!]> - like in Vim, but [file] not supported - -=item * Substitution: - -C<:s///> - I<i> and I<g> are supported as flags, only C<///> can be used as -eparator, and it uses Perl regex syntax instead of Vim syntax. - -=item * Settings: - -C<:se[t]> - display all options - -C<:se[t] {option}> - display all matching options - -C<:se[t] {option} {value}> - change option to value - -=back - -=head3 MAPPINGS - -=head4 Commands - -=over 4 - -=item * C<:map {lhs}> - display mappings starting with {lhs} - -=item * C<:map {lhs} {rhs}> - add mapping - -=item * C<:unm[ap] {lhs}> - remove custom mapping - -=back - -=head4 Parameters - -I<{lhs}> is the key combination to be mapped, I<{rhs}> the target. The -C<E<lt>E<gt>> notation is used - -(e.g. C<E<lt>C-FE<gt>> is I<Ctrl-F>), case is ignored. - Supported C<E<lt>E<gt>> keys are: - -=over 4 - -=item * C<E<lt>C-AE<gt>> - C<E<lt>C-ZE<gt>>, - -=item * C<E<lt>C-^E<gt>>, C<E<lt>C-6E<gt>> - -=item * C<E<lt>SpaceE<gt>> - -=item * C<E<lt>CRE<gt>> - Enter - -=item * C<E<lt>BSE<gt>> - Backspace - -=item * C<E<lt>NopE<gt>> - No-op (Do Nothing). - -=back - -Mapping ex-mode and irssi commands is supported. When mapping ex-mode commands -the trailing C<E<lt>CrE<gt>> is not necessary. Only default mappings can be used -in I<{rhs}>. - -Examples: - -=over 4 - -=item * C<:map w W> - to remap w to work like W - -=item * C<:map gb :bnext> - to map gb to call :bnext - -=item * C<:map gB :bprev> - -=item * C<:map g1 :b 1> - to map g1 to switch to buffer 1 - -=item * C<:map gb :b> - to map gb to :b, 1gb switches to buffer 1, 5gb to 5 - -=item * C<:map E<lt>C-LE<gt> /clear> - map Ctrl-L to irssi command /clear - -=item * C<:map E<lt>C-GE<gt> /window goto 1> - -=item * C<:map E<lt>C-EE<gt> <Nop>> - disable E<lt>C-EE<gt>, it does nothing now - -=item * C<:unmap E<lt>C-EE<gt>> - restore default behavior of C<E<lt>C-EE<gt>> -after disabling it - -=back - -Note that you must use C</> for irssi commands (like C</clear>), the current value -of Irssi's cmdchars does B<not> work! This is necessary do differentiate between -ex-commands and irssi commands. - -=head2 SETTINGS - -The settings are stored as irssi settings and can be set using C</set> as usual -(prepend C<vim_mode_> to setting name) or using the C<:set> ex-command. The -following settings are available: - -=over 4 - -=item * utf8 - Support UTF-8 characters, boolean, default on - -=item * debug - Enable debug output, boolean, default off - -=item * cmd_seq - Char that when double-pressed simulates C<E<lt>EscE<gt>>, string, default '' (disabled) - -=item * start_cmd - Start every line in command mode, boolean, default off - -=item * max_undo_lines - Sze of the undo buffer. Integer, default 50 items. - -=item * ex_history_size - Number of items stored in the ex-mode history. Integer, default 100. - -=item * prompt_leading_space - Ddetermines whether ex mode prepends a space to the displayed input. Boolean, default on - -=back - -In contrast to irssi's settings, C<:set> accepts 0 and 1 as values for boolean -settings, but only vim_mode's settings can be set/displayed. - -Examples: - - :set cmd_seq=j # set cmd_seq to j - :set cmd_seq= # disable cmd_seq - :set debug=on # enable debug - :set debug=off # disable debug - -=head1 KNOWN ISSUES - -If you use tmux and want to use <esc> to exit insert mode you might want to -reduce the escape-time for a better experience (500 is the default value): - - set -s escape-time 100 - -A similar problem exist in GNU screen, the following settings in ~/.screenrc -fix it (thanks to jsbronder for reporting the screen issue and fix): - - maptimeout 0 - defc1 off - -defc1 might not be necessary. - -=head1 SUPPORT - -Any behavior different from Vim (unless explicitly documented) should be -considered a bug and reported. - -B<NOTE:> This script is still under heavy development, and there may be bugs. -Please submit reproducible sequences to the bug-tracker at: -L<http://github.com/shabble/irssi-scripts/issues/new> - -or contact rudi_s or shabble on irc.freenode.net (#irssi and #irssi_vim) - -=head1 AUTHORS - -Copyright E<copy> 2010-2011 Tom Feist C<E<lt>shabble+irssi@metavore.orgE<gt>> and - -Copyright E<copy> 2010-2011 Simon Ruderich C<E<lt>simon@ruderich.orgE<gt>> - -=head1 THANKS - -Particular thanks go to - -=over 4 - -=item * estragib: a lot of testing and many bug reports and feature requests - -=item * iaj: testing - -=item * tmr: explaining how various bits of vim work - -=back - -as well as the rest of C<#irssi> and C<#irssi_vim> on Freenode IRC. - -=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 * - -count before register doesn't work: e.g. 3"ap doesn't work, but "a3p does - -=item * - -mapping an incomplete ex-command doesn't open the ex-mode with the partial -command (e.g. C<:map gb :b> causes an error instead of opening the ex-mode and -displaying C<:bE<lt>cursorE<gt>>) - -=item * - - undo/redo cursor positions are mostly wrong - -=back - -=head1 TODO - -=over 4 - -=item * - -Make sure the input line is empty when entering ex mode. Stuff hanging around -just looks silly. - -=item * - -History: - -=over 4 - -=item * - - C< * /,?,n,N> to search through history (like rl_history_search.pl) - -=back - -=item * - -Window switching (C<:b>) - -=over 4 - -=item * - -Tab completion of window(-item) names - -=item * - -non-sequential matches(?) - -=back - -=back - -See also the TODO file at -L<github|https://github.com/shabble/irssi-scripts/blob/master/vim-mode/TODO> for -many many more things. - -=head2 WONTFIX - -Things we're not ever likely to do: - -=over 4 - -=item * Macros - -=back - -=cut - -use strict; -use warnings; - -use Encode; -use List::Util; - -use Irssi; -use Irssi::TextUI; # for sbar_items_redraw -use Irssi::Irc; # necessary for 0.8.14 - - - -our $VERSION = "1.1.0"; -our %IRSSI = - ( - authors => "Tom Feist (shabble), Simon Ruderich (rudi_s)", - contact => 'shabble+irssi@metavore.org, ' - . 'shabble@#irssi/Freenode, simon@ruderich.org' - . 'rudi_s@#irssi/Freenode', - name => "vim_mode", - description => "Give Irssi Vim-like commands for editing the inputline", - license => "MIT", - changed => "3/2/2012" - ); - - -# CONSTANTS - -# command mode -sub M_CMD () { 1 } -# insert mode -sub M_INS () { 0 } -# extended mode (after a :?) -sub M_EX () { 2 } - -# operator command -sub C_OPERATOR () { 0 } -# normal command, no special handling necessary -sub C_NORMAL () { 1 } -# command taking another key as argument -sub C_NEEDSKEY () { 2 } -# text-object command (i a) -sub C_TEXTOBJECT () { 3 } -# commands entering insert mode -sub C_INSERT () { 4 } -# ex-mode commands -sub C_EX () { 5 } -# irssi commands -sub C_IRSSI () { 6 } -# does nothing -sub C_NOP () { 7 } - -# setting types, match irssi types as they are stored as irssi settings -sub S_BOOL () { 0 } -sub S_INT () { 1 } -sub S_STR () { 2 } -sub S_TIME () { 3 } - -# word and non-word regex, keep in sync with setup_changed()! -my $word = qr/[\w_]/o; -my $non_word = qr/[^\w_\s]/o; - -# COMMANDS - -# All available commands in command mode, they are stored with a char as key, -# but this is not necessarily the key the command is currently mapped to. -my $commands - = { - # operators - c => { char => 'c', func => \&cmd_operator_c, type => C_OPERATOR, - repeatable => 1 }, - d => { char => 'd', func => \&cmd_operator_d, type => C_OPERATOR, - repeatable => 1 }, - y => { char => 'y', func => \&cmd_operator_y, type => C_OPERATOR, - repeatable => 1 }, - - # arrow like movement - h => { char => 'h', func => \&cmd_h, type => C_NORMAL }, - l => { char => 'l', func => \&cmd_l, type => C_NORMAL }, - "\x08" => { char => '<BS>', func => \&cmd_h, type => C_NORMAL }, - "\x7F" => { char => '<BS>', func => \&cmd_h, type => C_NORMAL }, - ' ' => { char => '<Space>', func => \&cmd_l, type => C_NORMAL }, - # history movement - j => { char => 'j', func => \&cmd_j, type => C_NORMAL, - no_operator => 1 }, - k => { char => 'k', func => \&cmd_k, type => C_NORMAL, - no_operator => 1 }, - gg => { char => 'gg', func => \&cmd_gg, type => C_NORMAL, - no_operator => 1 }, - G => { char => 'G', func => \&cmd_G, type => C_NORMAL, - needs_count => 1, no_operator => 1 }, - # char movement, take an additional parameter and use $movement - f => { char => 'f', func => \&cmd_f, type => C_NEEDSKEY, - selection_needs_move_right => 1 }, - t => { char => 't', func => \&cmd_t, type => C_NEEDSKEY, - selection_needs_move_right => 1 }, - F => { char => 'F', func => \&cmd_F, type => C_NEEDSKEY }, - T => { char => 'T', func => \&cmd_T, type => C_NEEDSKEY }, - ';' => { char => ';', func => \&cmd_semicolon, type => C_NORMAL }, - ',' => { char => ',', func => \&cmd_comma, type => C_NORMAL }, - # word movement - w => { char => 'w', func => \&cmd_w, type => C_NORMAL }, - b => { char => 'b', func => \&cmd_b, type => C_NORMAL }, - e => { char => 'e', func => \&cmd_e, type => C_NORMAL, - selection_needs_move_right => 1 }, - ge => { char => 'ge', func => \&cmd_ge, type => C_NORMAL, - selection_needs_move_right => 1 }, - W => { char => 'W', func => \&cmd_W, type => C_NORMAL }, - B => { char => 'B', func => \&cmd_B, type => C_NORMAL }, - E => { char => 'E', func => \&cmd_E, type => C_NORMAL }, - gE => { char => 'gE', func => \&cmd_gE, type => C_NORMAL, - selection_needs_move_right => 1 }, - # text-objects, leading _ means can't be mapped! - _i => { char => 'i', func => \&cmd__i, type => C_TEXTOBJECT }, - _a => { char => 'a', func => \&cmd__a, type => C_TEXTOBJECT }, - # line movement - '0' => { char => '0', func => \&cmd_0, type => C_NORMAL }, - '^' => { char => '^', func => \&cmd_caret, type => C_NORMAL }, - '$' => { char => '$', func => \&cmd_dollar, type => C_NORMAL }, - # delete chars - x => { char => 'x', func => \&cmd_x, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - X => { char => 'X', func => \&cmd_X, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - # C_NORMAL is correct, operator c takes care of insert mode - s => { char => 's', func => \&cmd_s, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - # C_NORMAL is correct, operator c takes care of insert mode - S => { char => 'S', func => \&cmd_S, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - # insert mode - i => { char => 'i', func => \&cmd_i, type => C_INSERT, - repeatable => 1, no_operator => 1 }, - I => { char => 'I', func => \&cmd_I, type => C_INSERT, - repeatable => 1, no_operator => 1 }, - a => { char => 'a', func => \&cmd_a, type => C_INSERT, - repeatable => 1, no_operator => 1 }, - A => { char => 'A', func => \&cmd_A, type => C_INSERT, - repeatable => 1, no_operator => 1 }, - # replace - r => { char => 'r', func => \&cmd_r, type => C_NEEDSKEY, - repeatable => 1, no_operator => 1 }, - # paste - p => { char => 'p', func => \&cmd_p, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - P => { char => 'P', func => \&cmd_P, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - # to end of line - C => { char => 'C', func => \&cmd_C, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - D => { char => 'D', func => \&cmd_D, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - # scrolling - "\x05" => { char => '<C-E>', func => \&cmd_ctrl_d, type => C_NORMAL, - no_operator => 1 }, - "\x04" => { char => '<C-D>', func => \&cmd_ctrl_d, type => C_NORMAL, - needs_count => 1, no_operator => 1 }, - "\x19" => { char => '<C-Y>', func => \&cmd_ctrl_u, type => C_NORMAL, - no_operator => 1 }, - "\x15" => { char => '<C-U>', func => \&cmd_ctrl_u, type => C_NORMAL, - needs_count => 1, no_operator => 1 }, - "\x06" => { char => '<C-F>', func => \&cmd_ctrl_f, type => C_NORMAL, - no_operator => 1 }, - "\x02" => { char => '<C-B>', func => \&cmd_ctrl_b, type => C_NORMAL, - no_operator => 1 }, - # window switching - "\x17j" => { char => '<C-W>j', func => \&cmd_ctrl_wj, type => C_NORMAL, - no_operator => 1 }, - "\x17k" => { char => '<C-W>k', func => \&cmd_ctrl_wk, type => C_NORMAL, - no_operator => 1 }, - "\x1e" => { char => '<C-^>', func => \&cmd_ctrl_6, type => C_NORMAL, - no_operator => 1 }, - # misc - '~' => { char => '~', func => \&cmd_tilde, type => C_NORMAL, - repeatable => 1, no_operator => 1 }, - '"' => { char => '"', func => \&cmd_register, type => C_NEEDSKEY, - no_operator => 1 }, - '.' => { char => '.', type => C_NORMAL, repeatable => 1, - no_operator => 1 }, - ':' => { char => ':', type => C_NORMAL }, - "\n" => { char => '<CR>', type => C_NORMAL }, # return - # undo - 'u' => { char => 'u', func => \&cmd_undo, type => C_NORMAL, - no_operator => 1 }, - "\x12" => { char => '<C-R>', func => \&cmd_redo, type => C_NORMAL, - no_operator => 1 }, - }; - -# All available commands in Ex-Mode. -my $commands_ex - = { - # arrow keys - not actually used, see handle_input_buffer() - # TODO: make these work. - "\e[A" => { char => ':exprev', func => \&ex_history_back, - type => C_EX }, - "\e[B" => { char => ':exnext', func => \&ex_history_fwd, - type => C_EX }, - - # normal Ex mode commands. - eh => { char => ':exhist', func => \&ex_history_show, - type => C_EX }, - s => { char => ':s', func => \&ex_substitute, - type => C_EX }, - bnext => { char => ':bnext', func => \&ex_bnext, - type => C_EX, uses_count => 1 }, - bn => { char => ':bn', func => \&ex_bnext, - type => C_EX, uses_count => 1 }, - bprev => { char => ':bprev', func => \&ex_bprev, - type => C_EX, uses_count => 1 }, - bp => { char => ':bp', func => \&ex_bprev, - type => C_EX, uses_count => 1 }, - bdelete => { char => ':bdelete', func => \&ex_bdelete, - type => C_EX, uses_count => 1 }, - bd => { char => ':bd', func => \&ex_bdelete, - type => C_EX, uses_count => 1 }, - buffer => { char => ':buffer', func => \&ex_buffer, - type => C_EX, uses_count => 1 }, - b => { char => ':b', func => \&ex_buffer, - type => C_EX, uses_count => 1 }, - registers => { char => ':registers', func => \&ex_registers, - type => C_EX }, - reg => { char => ':reg', func => \&ex_registers, - type => C_EX }, - display => { char => ':display', func => \&ex_registers, - type => C_EX }, - di => { char => ':di', func => \&ex_registers, - type => C_EX }, - buffers => { char => ':buffer', func => \&ex_buffers, - type => C_EX }, - ls => { char => ':ls', func => \&ex_buffers, - type => C_EX }, - undolist => { char => ':undolist', func => \&ex_undolist, - type => C_EX }, - undol => { char => ':undol', func => \&ex_undolist, - type => C_EX }, - map => { char => ':map', func => \&ex_map, - type => C_EX }, - unmap => { char => ':unmap', func => \&ex_unmap, - type => C_EX }, - unm => { char => ':unm', func => \&ex_unmap, - type => C_EX }, - source => { char => ':source', func => \&ex_source, - type => C_EX }, - so => { char => ':so', func => \&ex_source, - type => C_EX }, - mkvimrc => { char => ':mkvimrc', func => \&ex_mkvimrc, - type => C_EX }, - mkv => { char => ':mkv', func => \&ex_mkvimrc, - type => C_EX }, - se => { char => ':se', func => \&ex_set, - type => C_EX }, - set => { char => ':set', func => \&ex_set, - type => C_EX }, - itemnext => { char => ':itemnext', func => \&ex_item_next, - type => C_EX }, - inext => { char => ':itemnext', func => \&ex_item_next, - type => C_EX }, - itemprev => { char => ':itemprev', func => \&ex_item_prev, - type => C_EX }, - iprev => { char => ':itemprev', func => \&ex_item_prev, - type => C_EX }, - servernext => { char => ':servernext', func => \&ex_server_next, - type => C_EX }, - snext => { char => ':servernext', func => \&ex_server_next, - type => C_EX }, - serverprev => { char => ':serverprev', func => \&ex_server_prev, - type => C_EX }, - sprev => { char => ':serverprev', func => \&ex_server_prev, - type => C_EX }, - - }; - -# MAPPINGS - -# default command mode mappings -my $maps = {}; - -# current imap still pending (first character entered) -my $imap = undef; - -# maps for insert mode -my $imaps - = { - # CTRL-R, insert register - "\x12" => { map => undef, func => \&insert_ctrl_r }, - }; - - -# GLOBAL VARIABLES - -# all vim_mode settings, must be enabled in vim_mode_init() before usage -my $settings - = { - # print debug output - debug => { type => S_BOOL, value => 0 }, - # use UTF-8 internally for string calculations/manipulations - utf8 => { type => S_BOOL, value => 1 }, - # esc-shortcut in insert mode - cmd_seq => { type => S_STR, value => '' }, - # start every line in command mode - start_cmd => { type => S_BOOL, value => 0 }, - # not used yet - max_undo_lines => { type => S_INT, value => 50 }, - # size of history buffer for Ex mode. - ex_history_size => { type => S_INT, value => 100 }, - # prompt_leading_space - prompt_leading_space => { type => S_BOOL, value => 1 }, - # <Leader> value for prepending to commands. - map_leader => { type => S_STR, value => '\\' }, - # timeout for keys following esc. In milliseconds. - esc_buf_timeout => { type => S_TIME, value => '10ms' }, - - }; - -sub DEBUG { $settings->{debug}->{value} } - -# buffer to keep track of the last N keystrokes, used for Esc detection and -# insert mode mappings -my @input_buf; -my $input_buf_timer; -my $input_buf_enabled = 0; - -# insert mode repeat buffer, used to repeat (.) last insert -my @insert_buf; - -# flag to allow us to emulate keystrokes without re-intercepting them -my $should_ignore = 0; - -# ex mode buffer -my @ex_buf; - -# ex mode history storage. -my @ex_history; -my $ex_history_index = 0; - -# we are waiting for another mapped key (e.g. g pressed, but there are -# multiple mappings like gg gE etc.) -my $pending_map = undef; - -# for commands like 10x -my $numeric_prefix = undef; -# current operator as $command hash -my $operator = undef; -# vi movements, only used when a movement needs more than one key (like f t). -my $movement = undef; -# last vi command, used by . -my $last - = { - 'cmd' => $commands->{i}, # = i to support . when loading the script - 'numeric_prefix' => undef, - 'operator' => undef, - 'movement' => undef, - 'register' => '"', - }; -# last ftFT movement, used by ; and , -my $last_ftFT - = { - type => undef, # f, t, F or T - char => undef, - }; - -# what Vi mode we're in. We start in insert mode. -my $mode = M_INS; - -# current active register -my $register = '"'; - -# vi registers -my $registers - = { - '"' => '', # default register - '0' => '', # yank register - '+' => '', # contains irssi's cut buffer - '*' => '', # same - '_' => '', # black hole register, always empty - }; - -# index into the history list (for j,k) -my $history_index = undef; -# current line, necessary for j,k or the current input line gets destroyed -my $history_input = undef; -# position in input line -my $history_pos = 0; - -# Undo/redo buffer. - -my @undo_buffer; -my $undo_index = undef; - -# tab completion state vars - -my @tab_candidates; -my $completion_active = 0; -my $completion_string = ''; - -sub script_is_loaded { - return exists($Irssi::Script::{shift(@_) . '::'}); -} - - - - -# INSERT MODE COMMANDS - -sub insert_ctrl_r { - my ($key) = @_; - _debug("ctrl-r called"); - my $char = chr($key); - _debug("ctrl-r called with $char"); - - return if not defined $registers->{$char} or $registers->{$char} eq ''; - - my $pos = _insert_at_position($registers->{$char}, 1, _input_pos()); - _input_pos($pos + 1); -} - - -# COMMAND MODE OPERATORS - -sub cmd_operator_c { - my ($old_pos, $new_pos, $move_cmd, $repeat) = @_; - - # Changing a word or WORD doesn't delete the last space before a word, but - # not if we are on that whitespace before the word. - if ($move_cmd and ($move_cmd == $commands->{w} or - $move_cmd == $commands->{W})) { - my $input = _input(); - if ($new_pos - $old_pos > 1 and - substr($input, $new_pos - 1, 1) =~ /\s/) { - $new_pos--; - } - } - - cmd_operator_d($old_pos, $new_pos, $move_cmd, $repeat, 1); - - if (!$repeat) { - _update_mode(M_INS); - } else { - my $pos = _input_pos(); - $pos = _insert_buffer(1, $pos); - _input_pos($pos); - } -} - -sub cmd_operator_d { - my ($old_pos, $new_pos, $move_cmd, $repeat, $change) = @_; - - my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move_cmd); - - # Remove the selected string from the input. - my $input = _input(); - my $string = substr $input, $pos, $length, ''; - if ($register =~ /[A-Z]/) { - $registers->{lc $register} .= $string; - print "Deleted into $register: ", $registers->{lc $register} if DEBUG; - } else { - $registers->{$register} = $string; - print "Deleted into $register: ", $registers->{$register} if DEBUG; - } - _input($input); - - # Prevent moving after the text when we delete the last character. But not - # when changing (C). - $pos-- if $pos == length($input) and !$change; - - _input_pos($pos); -} - -sub cmd_operator_y { - my ($old_pos, $new_pos, $move_cmd, $repeat) = @_; - - my ($pos, $length) = _get_pos_and_length($old_pos, $new_pos, $move_cmd); - - # Extract the selected string and put it in the " register. - my $input = _input(); - my $string = substr $input, $pos, $length; - if ($register =~ /[A-Z]/) { - $registers->{lc $register} .= $string; - print "Yanked into $register: ", $registers->{lc $register} if DEBUG; - } else { - $registers->{$register} = $string; - print "Yanked into $register: ", $registers->{$register} if DEBUG; - if ($register eq '"') { - $registers->{0} = $string; - print "Yanked into 0: ", $registers->{0} if DEBUG; - } - } - - # Always move to the lower position. - if ($old_pos > $new_pos) { - _input_pos($new_pos); - } else { - _input_pos($old_pos); - } -} - -sub _get_pos_and_length { - my ($old_pos, $new_pos, $move_cmd) = @_; - - my $length = $new_pos - $old_pos; - # We need a positive length and $old_pos must be smaller. - if ($length < 0) { - $old_pos = $new_pos; - $length *= -1; - } - - # Some commands don't move one character after the deletion area which is - # necessary for all commands moving to the right. Fix it. - if ($move_cmd->{selection_needs_move_right}) { - $length += 1; - } - - return ($old_pos, $length); -} - -# COMMAND MODE COMMANDS - -sub cmd_h { - my ($count, $pos, $repeat) = @_; - - $pos -= $count; - $pos = 0 if $pos < 0; - return (undef, $pos); -} - -sub cmd_l { - my ($count, $pos, $repeat) = @_; - - my $length = _input_len(); - $pos += $count; - $pos = _fix_input_pos($pos, $length); - return (undef, $pos); -} - -# later history (down) -sub cmd_j { - my ($count, $pos, $repeat) = @_; - - if (Irssi::version < 20090117) { - # simulate a down-arrow - _emulate_keystrokes(0x1b, 0x5b, 0x42); - return (undef, undef); - } - - my @history = Irssi::active_win->get_history_lines(); - - if (defined $history_index) { - $history_index += $count; - print "History Index: $history_index" if DEBUG; - # Prevent destroying the current input when pressing j after entering - # command mode. Not exactly like in default irssi, but simplest solution - # (and S can be used to clear the input line fast, which is what <down> - # does in plain irssi). - } else { - return (undef, undef); - } - - if ($history_index > $#history) { - # Restore the input line. - _input($history_input); - _input_pos($history_pos); - $history_index = $#history + 1; - } elsif ($history_index >= 0) { - my $history = $history[$history_index]; - # History is not in UTF-8! - if ($settings->{utf8}->{value}) { - $history = decode_utf8($history); - } - _input($history); - _input_pos(0); - } - return (undef, undef); -} - -# earlier history (up) -sub cmd_k { - my ($count, $pos, $repeat) = @_; - - if (Irssi::version < 20090117) { - # simulate an up-arrow - _emulate_keystrokes(0x1b, 0x5b, 0x41); - return (undef, undef); - } - - my @history = Irssi::active_win->get_history_lines(); - - if (defined $history_index) { - $history_index -= $count; - $history_index = 0 if $history_index < 0; - } else { - $history_index = $#history; - $history_input = _input(); - $history_pos = _input_pos(); - } - print "History Index: $history_index" if DEBUG; - if ($history_index >= 0) { - my $history = $history[$history_index]; - # History is not in UTF-8! - if ($settings->{utf8}->{value}) { - $history = decode_utf8($history); - } - _input($history); - _input_pos(0); - } - return (undef, undef); -} - -sub cmd_G { - my ($count, $pos, $repeat) = @_; - - if (Irssi::version < 20090117) { - _warn("G and gg not supported in irssi < 0.8.13"); - return; - } - - my @history = Irssi::active_win->get_history_lines(); - - # Go to the current input line if no count was given or it's too big. - if (not $count or $count - 1 >= scalar @history) { - if (defined $history_input and defined $history_pos) { - _input($history_input); - _input_pos($history_pos); - $history_index = undef; - } - return; - } else { - # Save input line so it doesn't get lost. - if (not defined $history_index) { - $history_input = _input(); - $history_pos = _input_pos(); - } - $history_index = $count - 1; - } - - my $history = $history[$history_index]; - # History is not in UTF-8! - if ($settings->{utf8}->{value}) { - $history = decode_utf8($history); - } - _input($history); - _input_pos(0); - - return (undef, undef); -} - -sub cmd_gg { - my ($count, $pos, $repeat) = @_; - - return cmd_G(1, $pos, $repeat); -} - -sub cmd_f { - my ($count, $pos, $repeat, $char) = @_; - - $pos = _next_occurrence(_input(), $char, $count, $pos); - - $last_ftFT = { type => 'f', char => $char }; - return (undef, $pos); -} - -sub cmd_t { - my ($count, $pos, $repeat, $char) = @_; - - $pos = _next_occurrence(_input(), $char, $count, $pos); - if (defined $pos) { - $pos--; - } - - $last_ftFT = { type => 't', char => $char }; - return (undef, $pos); -} - -sub cmd_F { - my ($count, $pos, $repeat, $char) = @_; - - my $input = reverse _input(); - $pos = _next_occurrence($input, $char, $count, length($input) - $pos - 1); - if (defined $pos) { - $pos = length($input) - $pos - 1; - } - - $last_ftFT = { type => 'F', char => $char }; - return (undef, $pos); -} - -sub cmd_T { - my ($count, $pos, $repeat, $char) = @_; - - my $input = reverse _input(); - $pos = _next_occurrence($input, $char, $count, length($input) - $pos - 1); - if (defined $pos) { - $pos = length($input) - $pos - 1 + 1; - } - - $last_ftFT = { type => 'T', char => $char }; - return (undef, $pos); -} - -# Find $count-th next occurrence of $char. -sub _next_occurrence { - my ($input, $char, $count, $pos) = @_; - - while ($count-- > 0) { - $pos = index $input, $char, $pos + 1; - if ($pos == -1) { - return undef; - } - } - return $pos; -} - -sub cmd_semicolon { - my ($count, $pos, $repeat) = @_; - - return (undef, undef) if not defined $last_ftFT->{type}; - - (undef, $pos) - = $commands->{$last_ftFT->{type}} - ->{func}($count, $pos, $repeat, $last_ftFT->{char}); - return (undef, $pos); -} - -sub cmd_comma { - my ($count, $pos, $repeat) = @_; - - return (undef, undef) if not defined $last_ftFT->{type}; - - # Change direction. - my $save = $last_ftFT->{type}; - my $type = $save; - $type =~ tr/ftFT/FTft/; - - (undef, $pos) - = $commands->{$type} - ->{func}($count, $pos, $repeat, $last_ftFT->{char}); - # Restore type as the move functions overwrites it. - $last_ftFT->{type} = $save; - return (undef, $pos); -} - -sub cmd_w { - my ($count, $pos, $repeat) = @_; - - my $input = _input(); - $pos = _beginning_of_word($input, $count, $pos); - $pos = _fix_input_pos($pos, length $input); - return (undef, $pos); -} - -sub cmd_b { - my ($count, $pos, $repeat) = @_; - - my $input = reverse _input(); - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - - $pos = _end_of_word($input, $count, $pos); - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - return (undef, $pos); -} - -sub cmd_e { - my ($count, $pos, $repeat) = @_; - - my $input = _input(); - $pos = _end_of_word($input, $count, $pos); - $pos = _fix_input_pos($pos, length $input); - return (undef, $pos); -} - -sub cmd_ge { - my ($count, $pos, $repeat, $char) = @_; - - my $input = reverse _input(); - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - - $pos = _beginning_of_word($input, $count, $pos); - $pos = length($input) - $pos - 1; - $pos = 0 if ($pos < 0); - - return (undef, $pos); -} - -# Go to the beginning of $count-th word, like vi's w. -sub _beginning_of_word { - my ($input, $count, $pos) = @_; - - while ($count-- > 0) { - # Go to end of next word/non-word. - if (substr($input, $pos) =~ /^$word+/ or - substr($input, $pos) =~ /^$non_word+/) { - $pos += $+[0]; - } - # And skip over any whitespace if necessary. This also happens when - # we're inside whitespace. - if (substr($input, $pos) =~ /^\s+/) { - $pos += $+[0]; - } - } - - return $pos; -} - -# Go to the end of $count-th word, like vi's e. -sub _end_of_word { - my ($input, $count, $pos) = @_; - - while ($count-- > 0 and length($input) > $pos) { - my $skipped = 0; - # Skip over whitespace if in the middle of it or directly after the - # current word/non-word. - if (substr($input, $pos + 1) =~ /^\s+/) { - $pos += $+[0] + 1; - $skipped = 1; - } - elsif (substr($input, $pos) =~ /^\s+/) { - $pos += $+[0]; - $skipped = 1; - } - # We are inside a word/non-word, skip to the end of it. - if (substr($input, $pos) =~ /^$word{2,}/ or - substr($input, $pos) =~ /^$non_word{2,}/) { - $pos += $+[0] - 1; - # We are the border of word/non-word. Skip to the end of the next one. - # But not if we've already jumped over whitespace because there could - # be only one word/non-word char after the whitespace. - } elsif (!$skipped and (substr($input, $pos) =~ /^$word($non_word+)/ or - substr($input, $pos) =~ /^$non_word($word+)/)) { - $pos += $+[0] - 1; - } - } - - # Necessary for correct deletion at the end of the line. - if (length $input == $pos + 1) { - $pos++; - } - - return $pos; -} - -sub cmd_W { - my ($count, $pos, $repeat) = @_; - - my $input = _input(); - $pos = _beginning_of_WORD($input, $count, $pos); - $pos = _fix_input_pos($pos, length $input); - return (undef, $pos); -} - -sub cmd_B { - my ($count, $pos, $repeat) = @_; - - my $input = reverse _input(); - $pos = _end_of_WORD($input, $count, length($input) - $pos - 1); - if ($pos == -1) { - return cmd_0(); - } else { - return (undef, length($input) - $pos - 1); - } -} - -sub cmd_E { - my ($count, $pos, $repeat) = @_; - - $pos = _end_of_WORD(_input(), $count, $pos); - if ($pos == -1) { - return cmd_dollar(); - } else { - return (undef, $pos); - } -} - -sub cmd_gE { - my ($count, $pos, $repeat, $char) = @_; - - my $input = reverse _input(); - $pos = _beginning_of_WORD($input, $count, length($input) - $pos - 1); - if ($pos == -1 or length($input) - $pos - 1 == -1) { - return cmd_0(); - } else { - $pos = length($input) - $pos - 1; - } - - return (undef, $pos); -} - -# Go to beginning of $count-th WORD, like vi's W. -sub _beginning_of_WORD { - my ($input, $count, $pos) = @_; - - # Necessary for correct movement between two words with only one - # whitespace. - if (substr($input, $pos) =~ /^\s\S/) { - $pos++; - $count--; - } - - while ($count-- > 0 and length($input) > $pos) { - if (substr($input, $pos + 1) !~ /\s+/) { - return length($input); - } - $pos += $+[0] + 1; - } - - return $pos; -} - -# Go to end of $count-th WORD, like vi's E. -sub _end_of_WORD { - my ($input, $count, $pos) = @_; - - return $pos if $pos >= length($input); - - # We are inside a WORD, skip to the end of it. - if (substr($input, $pos + 1) =~ /^\S+(\s)/) { - $pos += $-[1]; - $count--; - } - - while ($count-- > 0) { - if (substr($input, $pos) !~ /\s+\S+(\s+)/) { - return -1; - } - $pos += $-[1] - 1; - } - return $pos; -} - -sub cmd__i { - my ($count, $pos, $repeat, $char) = @_; - - _warn("i_ not implemented yet"); - return (undef, undef); -} - -sub cmd__a { - my ($count, $pos, $repeat, $char) = @_; - - my $cur_pos; - my $input = _input(); - - # aw and aW - if ($char eq 'w' or $char eq 'W') { - while ($count-- > 0 and length($input) > $pos) { - if (substr($input, $pos, 1) =~ /\s/) { - # Any whitespace before the word/WORD must be removed. - if (not defined $cur_pos) { - $cur_pos = _find_regex_before($input, '\S', $pos, 0); - if ($cur_pos < 0) { - $cur_pos = 0; - } else { - $cur_pos++; - } - } - # Move before the word/WORD. - if (substr($input, $pos + 1) =~ /^\s+/) { - $pos += $+[0]; - } - # And delete the word. - if ($char eq 'w') { - if (substr($input, $pos) =~ /^\s($word+|$non_word+)/) { - $pos += $+[0]; - } else { - $pos = length($input); - } - # WORD - } else { - if (substr($input, $pos + 1) =~ /\s/) { - $pos += $-[0] + 1; - } else { - $pos = length($input); - } - } - - # word - } elsif ($char eq 'w') { - # Start at the beginning of this WORD. - if (not defined $cur_pos and $pos > 0 - and substr($input, $pos - 1, 2) - !~ /(\s.|$word$non_word|$non_word$word)/) { - - $cur_pos = _find_regex_before - ( - $input, - "^($word+$non_word|$non_word+$word|$word+\\s|$non_word+\\s)", - $pos, 1 - ); - - if ($cur_pos < 0) { - $cur_pos = 0; - } else { - $cur_pos += 2; - } - } - # Delete to the end of the word. - if (substr($input, $pos) =~ - /^($word+$non_word|$non_word+$word|$word+\s+\S|$non_word+\s+\S)/) { - - $pos += $+[0] - 1; - } else { - $pos = length($input); - # If we are at the end of the line, whitespace before - # the word is also deleted. - my $new_pos = _find_regex_before - ($input, - "^($word+\\s+|$non_word+\\s+)", - $pos, 1); - - if ($new_pos != -1 and - (not defined $cur_pos or - $cur_pos > $new_pos + 1)) { - - $cur_pos = $new_pos + 1; - } - } - - # WORD - } else { - # Start at the beginning of this WORD. - if (not defined $cur_pos and $pos > 0 and - substr($input, $pos - 1, 1) !~ /\s/) { - $cur_pos = _find_regex_before($input, '\s', $pos - 1, 0); - if ($cur_pos < 0) { - $cur_pos = 0; - } else { - $cur_pos++; - } - } - # Delete to the end of the word. - if (substr($input, $pos + 1) =~ /^\S*\s+\S/) { - $pos += $+[0]; - } else { - $pos = length($input); - # If we are at the end of the line, whitespace before - # the WORD is also deleted. - my $new_pos = _find_regex_before($input, '\s+', $pos, 1); - if (not defined $cur_pos or $cur_pos > $new_pos + 1) { - $cur_pos = $new_pos + 1; - } - } - } - } - } - - return ($cur_pos, $pos); -} - -# Find regex as close as possible before the current position. If $end is true -# the end of the match is returned, otherwise the beginning. -sub _find_regex_before { - my ($input, $regex, $pos, $end) = @_; - - $input = reverse $input; - $pos = length($input) - $pos - 1; - $pos = 0 if $pos < 0; - - if (substr($input, $pos) =~ /$regex/) { - if (!$end) { - $pos += $-[0]; - } else { - $pos += $+[0]; - } - return length($input) - $pos - 1; - } else { - return -1; - } -} - -sub cmd_0 { - return (undef, 0); -} - -sub cmd_caret { - my $input = _input(); - my $pos; - # No whitespace at all. - if ($input !~ m/^\s/) { - $pos = 0; - # Some non-whitespace, go to first one. - } elsif ($input =~ m/[^\s]/) { - $pos = $-[0]; - # Only whitespace, go to the end. - } else { - $pos = _fix_input_pos(length $input, length $input); - } - return (undef, $pos); -} - -sub cmd_dollar { - my $length = _input_len(); - return (undef, _fix_input_pos($length, $length)); -} - -sub cmd_x { - my ($count, $pos, $repeat) = @_; - - cmd_operator_d($pos, $pos + $count, $commands->{x}, $repeat); - return (undef, undef); -} - -sub cmd_X { - my ($count, $pos, $repeat) = @_; - - return (undef, undef) if $pos == 0; - - my $new = $pos - $count; - $new = 0 if $new < 0; - cmd_operator_d($pos, $new, $commands->{X}, $repeat); - return (undef, undef); -} - -sub cmd_s { - my ($count, $pos, $repeat) = @_; - - $operator = $commands->{c}; - return (undef, $pos + $count); -} - -sub cmd_S { - my ($count, $pos, $repeat) = @_; - - $operator = $commands->{c}; - return (0, _input_len()); -} - -sub cmd_i { - my ($count, $pos, $repeat) = @_; - - if (!$repeat) { - _update_mode(M_INS); - } else { - $pos = _insert_buffer($count, $pos); - } - return (undef, $pos); -} - -sub cmd_I { - my ($count, $pos, $repeat) = @_; - - $pos = cmd_caret(); - if (!$repeat) { - _update_mode(M_INS); - } else { - $pos = _insert_buffer($count, $pos); - } - return (undef, $pos); -} - -sub cmd_a { - my ($count, $pos, $repeat) = @_; - - # Move after current character. Can't use cmd_l() because we need to mover - # after last character at the end of the line. - my $length = _input_len(); - $pos += 1; - $pos = $length if $pos > $length; - - if (!$repeat) { - _update_mode(M_INS); - } else { - $pos = _insert_buffer($count, $pos); - } - return (undef, $pos); -} - -sub cmd_A { - my ($count, $pos, $repeat) = @_; - - $pos = _input_len(); - - if (!$repeat) { - _update_mode(M_INS); - } else { - $pos = _insert_buffer($count, $pos); - } - return (undef, $pos); -} - -# Add @insert_buf to _input() at the given position. -sub _insert_buffer { - my ($count, $pos) = @_; - return _insert_at_position(join('', @insert_buf), $count, $pos); -} - -sub _insert_at_position { - my ($string, $count, $pos) = @_; - - $string = $string x $count; - - my $input = _input(); - # Check if we are not at the end of the line to prevent substr outside of - # string error. - if (length $input > $pos) { - substr($input, $pos, 0) = $string; - } else { - $input .= $string; - } - _input($input); - - return $pos - 1 + length $string; -} - -sub cmd_r { - my ($count, $pos, $repeat, $char) = @_; - - my $input = _input(); - - # Abort if at end of the line. - return (undef, undef) if length($input) < $pos + $count; - - substr $input, $pos, $count, $char x $count; - _input($input); - return (undef, $pos + $count - 1); -} - -sub cmd_p { - my ($count, $pos, $repeat) = @_; - $pos = _paste_at_position($count, $pos + 1); - return (undef, $pos); -} - -sub cmd_P { - my ($count, $pos, $repeat) = @_; - $pos = _paste_at_position($count, $pos); - return (undef, $pos); -} - -sub _paste_at_position { - my ($count, $pos) = @_; - - return if $registers->{$register} eq ''; - return _insert_at_position($registers->{$register}, $count, $pos); -} - -sub cmd_C { - my ($count, $pos, $repeat) = @_; - - $operator = $commands->{c}; - return (undef, _input_len()); -} - -sub cmd_D { - my ($count, $pos, $repeat) = @_; - - $operator = $commands->{d}; - return (undef, _input_len()); -} - -sub cmd_ctrl_d { - my ($count, $pos, $repeat) = @_; - - my $window = Irssi::active_win(); - # no count = half of screen - if (not defined $count) { - $count = $window->{height} / 2; - } - $window->view()->scroll($count); - - Irssi::statusbar_items_redraw('more'); - return (undef, undef); -} - -sub cmd_ctrl_u { - my ($count, $pos, $repeat) = @_; - - my $window = Irssi::active_win(); - # no count = half of screen - if (not defined $count) { - $count = $window->{height} / 2; - } - $window->view()->scroll($count * -1); - - Irssi::statusbar_items_redraw('more'); - return (undef, undef); -} - -sub cmd_ctrl_f { - my ($count, $pos, $repeat) = @_; - - my $window = Irssi::active_win(); - $window->view()->scroll($count * $window->{height}); - - Irssi::statusbar_items_redraw('more'); - return (undef, undef); -} - -sub cmd_ctrl_b { - my ($count, $pos, $repeat) = @_; - - return cmd_ctrl_f($count * -1, $pos, $repeat); -} - -sub cmd_ctrl_wj { - my ($count, $pos, $repeat) = @_; - - while ($count-- > 0) { - Irssi::command('window down'); - } - - return (undef, undef); -} - -sub cmd_ctrl_wk { - my ($count, $pos, $repeat) = @_; - - while ($count-- > 0) { - Irssi::command('window up'); - } - - return (undef, undef); -} - -sub cmd_ctrl_6 { - # like :b# - Irssi::command('window last'); - return (undef, undef); -} - -sub cmd_tilde { - my ($count, $pos, $repeat) = @_; - - my $input = _input(); - my $string = substr $input, $pos, $count; - $string =~ s/(.)/(uc($1) eq $1) ? lc($1) : uc($1)/ge; - substr $input, $pos, $count, $string; - - _input($input); - return (undef, _fix_input_pos($pos + $count, length $input)); -} - -sub cmd_register { - my ($count, $pos, $repeat, $char) = @_; - - if (not exists $registers->{$char} and not exists $registers->{lc $char}) { - print "Wrong register $char, ignoring." if DEBUG; - return (undef, undef); - } - - # make sure black hole register is always empty - if ($char eq '_') { - $registers->{_} = ''; - } - - # + and * contain both irssi's cut-buffer - if ($char eq '+' or $char eq '*') { - $registers->{'+'} = Irssi::parse_special('$U'); - $registers->{'*'} = $registers->{'+'}; - } - - $register = $char; - print "Changing register to $register" if DEBUG; - return (undef, undef); -} - -sub cmd_undo { - print "Undo!" if DEBUG; - - if ($undo_index != $#undo_buffer) { - $undo_index++; - _restore_undo_entry($undo_index); - print "Undoing entry index: $undo_index of " . scalar(@undo_buffer) - if DEBUG; - } else { - print "No further undo." if DEBUG; - } - return (undef, undef); -} - -sub cmd_redo { - print "Redo!" if DEBUG; - - if ($undo_index != 0) { - $undo_index--; - print "Undoing entry index: $undo_index of " . scalar(@undo_buffer) - if DEBUG; - _restore_undo_entry($undo_index); - } else { - print "No further Redo." if DEBUG; - } - return (undef, undef); -} - -# Adapt the input position depending if an operator is active or not. -sub _fix_input_pos { - my ($pos, $length) = @_; - - # Allow moving past the last character when an operator is active to allow - # correct handling of last character in line. - if ($operator) { - $pos = $length if $pos > $length; - # Otherwise forbid it. - } else { - $pos = $length - 1 if $pos > $length - 1; - } - - return $pos; -} - - -# EX MODE COMMANDS - -sub cmd_ex_command { - my $arg_str = join '', @ex_buf; - - if ($arg_str !~ /^(\d*)?([a-z]+)/) { - return _warn("Invalid Ex-mode command!"); - } - - # Abort if command doesn't exist or used with count for unsupported - # commands. - if (not exists $commands_ex->{$2} or - ($1 ne '' and not $commands_ex->{$2}->{uses_count})) { - return _warn("Ex-mode $1$2 doesn't exist!"); - } - - # add this item to the ex mode history - ex_history_add($arg_str); - $ex_history_index = 0; # and reset the history position. - - my $count = $1; - if ($count eq '') { - $count = undef; - } - $commands_ex->{$2}->{func}($arg_str, $count); -} - -sub ex_substitute { - my ($arg_str, $count) = @_; - - # :s/// - if ($arg_str =~ m|^s/(.+)/(.*)/([ig]*)|) { - my ($search, $replace, $flags) = ($1, $2, $3); - print "Searching for $search, replace: $replace, flags; $flags" - if DEBUG; - - my $rep_fun = sub { $replace }; - - my $line = _input(); - my @re_flags = split '', defined $flags?$flags:''; - - if (scalar grep { $_ eq 'i' } @re_flags) { - $search = '(?i)' . $search; - } - - print "Search is $search" if DEBUG; - - my $re_pattern = qr/$search/; - - if (scalar grep { $_ eq 'g' } @re_flags) { - $line =~ s/$re_pattern/$rep_fun->()/eg; - } else { - print "Single replace: $replace" if DEBUG; - $line =~ s/$re_pattern/$rep_fun->()/e; - } - - print "New line is: $line" if DEBUG; - _input($line); - } else { - _warn_ex('s'); - } -} - -sub ex_bnext { - my ($arg_str, $count) = @_; - - if (not defined $count) { - if ($arg_str =~ /^bn(?:ext)?\s(\d+)$/) { - $count = $1; - } else { - $count = 1; - } - } - - while ($count-- > 0) { - Irssi::command('window next'); - } -} - -sub ex_bprev { - my ($arg_str, $count) = @_; - - if (not defined $count) { - if ($arg_str =~ /^bp(?:rev)?\s(\d+)$/) { - $count = $1; - } else { - $count = 1; - } - } - - while ($count-- > 0) { - Irssi::command('window previous'); - } -} - -sub ex_bdelete { - my ($arg_str, $count) = @_; - - if (not defined $count) { - if ($arg_str =~ /^bd(?:elete)?\s(\d+)$/) { - $count = $1; - } - } - - if (defined $count) { - my $window = Irssi::window_find_refnum($count); - if (not $window) { - return; - } - $window->set_active(); - } - Irssi::command('window close'); -} - -sub ex_buffer { - my ($arg_str, $count) = @_; - - # :b[buffer] {args} - if ($arg_str =~ m|^b(?:uffer)?\s*(.+)$| or defined $count) { - my $window; - my $item; - my $buffer = $1; - - # :[N]:b[uffer] - if (defined $count) { - $window = Irssi::window_find_refnum($count); - # Go to window number. - } elsif ($buffer =~ /^[0-9]+$/) { - $window = Irssi::window_find_refnum($buffer); - # Go to previous window. - } elsif ($buffer eq '#') { - Irssi::command('window last'); - # Go to best regex matching window. - } else { - eval { - my $matches = _matching_windows($buffer); - if (scalar @$matches > 0) { - $window = @$matches[0]->{window}; - $item = @$matches[0]->{item}; - } - }; - # Catch errors in /$buffer/ regex. - if ($@) { - _warn($@); - } - } - - if ($window) { - $window->set_active(); - if ($item) { - $item->set_active(); - } - } - } else { - _warn_ex('buffer'); - } -} - -sub ex_item_next { - my ($arg_str, $count) = @_; - my $win = Irssi::active_win; - $count = 1 unless defined $count; - - $win->item_next for (1..$count); -} - -sub ex_item_prev { - my ($arg_str, $count) = @_; - my $win = Irssi::active_win; - $count = 1 unless defined $count; - - $win->item_prev for (1..$count); -} - -# TODO: factor out the shared search code for server next/prev. -sub ex_server_next { - my ($arg_str, $count) = @_; - - my @server_ids = map { $_->{tag} . "\x1d" . $_->{nick} } Irssi::servers; - my $server = Irssi::active_server; - - return unless $server; - - my $current_id = $server->{tag} . "\x1d" . $server->{nick}; - my $next = 0; - my $server_count = scalar @server_ids; - for my $i (0..$server_count - 1) { - my $s_id = $server_ids[$i]; - if (defined($s_id) and ($s_id eq $current_id)) { - print "Found match at $i" if DEBUG; - $next = ($i + 1) % $server_count; - last; - } - } - - my $next_server = $server_ids[$next]; - $next_server =~ s|^([^\x1d]+)\x1d.*$|$1|; - - print "Changing to server: $next: $next_server" if DEBUG; - Irssi::command("window server $next_server"); -} - -sub ex_server_prev { - my ($arg_str, $count) = @_; - - my @server_ids = map { $_->{tag} . "\x1d" . $_->{nick} } Irssi::servers; - my $server = Irssi::active_server; - - return unless $server; - - my $current_id = $server->{tag} . "\x1d" . $server->{nick}; - my $prev = 0; - my $server_count = scalar @server_ids; - - for my $i (0..$server_count - 1) { - my $s_id = $server_ids[$i]; - if (defined($s_id) and ($s_id eq $current_id)) { - print "Found match at $i" if DEBUG; - $prev = ($i - 1) % $server_count; - last; - } - } - - my $prev_server = $server_ids[$prev]; - $prev_server =~ s|^([^\x1d]+)\x1d.*$|$1|; - - print "Changing to server: $prev: $prev_server" if DEBUG; - Irssi::command("window server $prev_server"); - -} - -sub ex_registers { - my ($arg_str, $count) = @_; - - # :reg[isters] {arg} and :di[splay] {arg} - if ($arg_str =~ /^(?:reg(?:isters)?|di(?:splay)?)(?:\s+(.+)$)?/) { - my @regs; - if ($1) { - my $regs = $1; - $regs =~ s/\s+//g; - @regs = split //, $regs; - } else { - @regs = keys %$registers; - } - - # Update "+ and "* registers so correct values are displayed. - $registers->{'+'} = Irssi::parse_special('$U'); - $registers->{'*'} = $registers->{'+'}; - - my @empty_regs; - my $special_regs = { '+' => 1, '*' => 1, '_' => 1, '"' => 1, '0' => 1 }; - - my $active_window = Irssi::active_win; - foreach my $key (sort @regs) { - next if $key eq '_'; # skip black hole - if (defined $registers->{$key}) { - my $register_val = $registers->{$key}; - if (length $register_val or exists $special_regs->{$key}) { - $register_val =~ s/%/%%/g; - $active_window->print("register $key: $register_val"); - } else { - push @empty_regs, $key; - } - } - } - - # coalesce empty registers into a single line. - if (@empty_regs) { - my @runs; - my $run_start; - foreach my $i (0..$#empty_regs) { - my $cur = $empty_regs[$i]; - my $next = $empty_regs[$i+1]; - - $run_start = $cur unless $run_start; - if (defined $next and ord($cur) + 1 == ord($next)) { - # extend range. - } else { - # terminate range and restart - my $run_str = $run_start; - - if ($cur ne $run_start) { - $run_str .= "-$cur"; - } - push @runs, $run_str; - $run_start = undef; - } - } - $active_window->print("Empty registers: " . join(', ', @runs)); - } - } else { - _warn_ex(':registers'); - } -} - -sub ex_buffers { - my ($arg_str, $count) = @_; - - Irssi::command('window list'); -} - -sub ex_undolist { - my ($arg_str, $count) = @_; - - _print_undo_buffer(); -} - -sub ex_map { - my ($arg_str, $count) = @_; - - # :map {lhs} {rhs} - if ($arg_str =~ /^map (\S+) (\S.*)$/) { - my $lhs = _parse_mapping($1); - my $rhs = $2; - - if (not defined $lhs) { - return _warn_ex('map', 'invalid {lhs}'); - } - - # Add new mapping. - my $command; - # Ex-mode command - if (index($rhs, ':') == 0) { - $rhs =~ /^:(\S+)(\s.+)?$/; - if (not exists $commands_ex->{$1}) { - return _warn_ex('map', "$rhs not found"); - } else { - $command = { char => $rhs, - func => $commands_ex->{$1}->{func}, - type => C_EX, - }; - } - # Irssi command - } elsif (index($rhs, '/') == 0) { - $command = { char => $rhs, - func => substr($rhs, 1), - type => C_IRSSI, - }; - # <Nop> does nothing - } elsif (lc $rhs eq '<nop>') { - $command = { char => '<Nop>', - func => undef, - type => C_NOP, - }; - # command-mode command - } else { - $rhs = _parse_mapping($2); - if (not defined $rhs) { - return _warn_ex('map', 'invalid {rhs}'); - } elsif (not exists $commands->{$rhs}) { - return _warn_ex('map', "$2 not found"); - } else { - $command = $commands->{$rhs}; - } - } - add_map($lhs, $command); - - # :map [lhs] - } elsif ($arg_str =~ m/^map\s*$/ or $arg_str =~ m/^map (\S+)$/) { - # Necessary for case insensitive matchings. lc alone won't work. - my $search = $1; - $search = '' if not defined $search; - $search = _parse_mapping_reverse(_parse_mapping($search)); - - my $active_window = Irssi::active_win(); - foreach my $key (sort keys %$maps) { - my $map = $maps->{$key}; - my $cmd = $map->{cmd}; - if (defined $cmd) { - next if $map->{char} eq $cmd->{char}; # skip default mappings - # FIXME: Hack so <C-H> doesn't show up as mapped to <BS>. - next if $map->{char} eq '<C-H>' and $cmd->{char} eq '<BS>'; - next if $map->{char} !~ /^\Q$search\E/; # skip non-matches - $active_window->print(sprintf "%-15s %s", $map->{char}, - $cmd->{char}); - } - } - } else { - _warn_ex('map'); - } -} -sub ex_unmap { - my ($arg_str, $count) = @_; - - # :unm[ap] {lhs} - if ($arg_str !~ /^unm(?:ap)? (\S+)$/) { - return _warn_ex('unmap'); - } - - my $lhs = _parse_mapping($1); - if (not defined $lhs) { - return _warn_ex('unmap', 'invalid {lhs}'); - # Prevent unmapping of unknown or default mappings. - } elsif (not exists $maps->{$lhs} or not defined $maps->{$lhs}->{cmd} or - ($commands->{$lhs} and $maps->{$lhs}->{cmd} == $commands->{$lhs})) { - return _warn_ex('unmap', "$1 not found"); - } - - delete_map($lhs); -} -sub _parse_mapping { - my ($string) = @_; - - $string =~ s/<([^>]+)>/_parse_mapping_bracket($1)/ge; - _debug("Parse mapping: $string"); - if (index($string, '<invalid>') != -1) { - return undef; - } - return $string; -} -sub _parse_mapping_bracket { - my ($string) = @_; - - $string = lc $string; - - # <C-X>, get corresponding CTRL char. - if ($string =~ /^c-([a-z])$/i) { - $string = chr(ord($1) - 96); - # <C-6> and <C-^> - } elsif ($string =~ /^c-[6^]$/i) { - $string = chr(30); - # <Space> - } elsif ($string eq 'space') { - $string = ' '; - # <CR> - } elsif ($string eq 'cr') { - $string = "\n"; - # <BS> - } elsif ($string eq 'bs') { - $string = chr(127); - } elsif ($string eq 'leader') { - $string = $settings->{map_leader}->{value}; - # Invalid char, return special string to recognize the error. - } else { - $string = '<invalid>'; - } - return $string; -} -sub _parse_mapping_reverse { - my ($string) = @_; - - if (not defined $string) { - _warn("Unable to reverse-map command: " . join('', @ex_buf)); - return; - } - - my $escaped_leader = quotemeta($settings->{map_leader}->{value}); - $string =~ s/$escaped_leader/<Leader>/g; - - # Convert char to <char-name>. - $string =~ s/ /<Space>/g; - $string =~ s/\n/<CR>/g; - $string =~ s/\x7F/<BS>/g; - # Convert Ctrl-X to <C-X>. - $string =~ s/([\x01-\x1A])/"<C-" . chr(ord($1) + 64) . ">"/ge; - # Convert Ctrl-6 and Ctrl-^ to <C-^>. - $string =~ s/\x1E/<C-^>/g; - - return $string; -} -sub _parse_partial_command_reverse { - my ($string) = @_; - - my $escaped_leader = quotemeta($settings->{map_leader}->{value}); - $string =~ s/$escaped_leader/<Leader>/g; - - # Convert Ctrl-X to ^X. - $string =~ s/([\x01-\x1A])/"^" . chr(ord($1) + 64)/ge; - # Convert Ctrl-6 and Ctrl-^ to <C-^>. - $string =~ s/\x1E/^^/g; - - return $string; -} - -sub ex_source { - my ($arg_str, $count) = @_; - - # :so[urce], but only loads the vim_moderc file at the moment - - open my $file, '<', Irssi::get_irssi_dir() . '/vim_moderc' or return; - - while (my $line = <$file>) { - next if $line =~ /^\s*$/ or $line =~ /^\s*"/; - - chomp $line; - # :map {lhs} {rhs}, keep in sync with ex_map() - if ($line =~ /^\s*map (\S+) (\S.*)$/) { - ex_map($line); - } else { - _warn_ex('source', "command not supported: $line"); - } - } -} - -sub ex_mkvimrc { - my ($arg_str, $count) = @_; - - # :mkv[imrc][!], [file] not supported - - my $vim_moderc = Irssi::get_irssi_dir(). '/vim_moderc'; - if (-f $vim_moderc and $arg_str !~ /^mkv(?:imrc)?!$/) { - return _warn_ex('mkvimrc', "$vim_moderc already exists"); - } - - open my $file, '>', $vim_moderc or return; - - # copied from ex_map() - foreach my $key (sort keys %$maps) { - my $map = $maps->{$key}; - my $cmd = $map->{cmd}; - if (defined $cmd) { - next if $map->{char} eq $cmd->{char}; # skip default mappings - print $file "map $map->{char} $cmd->{char}\n"; - } - } - - close $file; -} - -sub ex_set { - my ($arg_str, $count) = @_; - - # :se[t] [option] [value] - if ($arg_str =~ /^se(?:t)?(?:\s([^=]+)(?:=(.*)$)?)?/) { - # :se[t] {option} {value} - if (defined $1 and defined $2) { - if (not exists $settings->{$1}) { - return _warn_ex('map', "setting '$1' not found"); - } - my $name = $1; - my $value = $2; - # Also accept numeric values for boolean options. - if ($settings->{$name}->{type} == S_BOOL) { - if ($value =~ /^(on|off)$/i) { - $value = lc $value eq 'on' ? 1 : 0; - } elsif ($value eq '') { - $value = 0; - } - } - _setting_set($name, $value); - setup_changed(); - - # :se[t] [option] - } else { - my $search = defined $1 ? $1 : ''; - my $active_window = Irssi::active_win(); - foreach my $setting (sort keys %$settings) { - next if $setting !~ /^\Q$search\E/; # skip non-matches - my $value = $settings->{$setting}->{value}; - # Irssi only accepts 'on' and 'off' as values for boolean - # options. - if ($settings->{$setting}->{type} == S_BOOL) { - $value = $value ? 'on' : 'off'; - } - $active_window->print($setting . '=' . $value); - } - } - } else { - _warn_ex('map'); - } -} - -sub _warn_ex { - my ($command, $description) = @_; - my $message = "Error in ex-mode command $command"; - if (defined $description) { - $message .= ": $description"; - } - _warn($message); -} - -sub _matching_windows { - my ($buffer) = @_; - - my $server; - - if ($buffer =~ m{^(.+)/(.+)}) { - $server = $1; - $buffer = $2; - } - - print ":b searching for channel $buffer" if DEBUG; - print ":b on server $server" if $server and DEBUG; - - my @matches; - foreach my $window (Irssi::windows()) { - # Matching window names. - if ($window->{name} =~ /$buffer/i) { - my $win_ratio = ($+[0] - $-[0]) / length($window->{name}); - push @matches, { window => $window, - item => undef, - ratio => $win_ratio, - text => $window->{name} }; - print ":b $window->{name}: $win_ratio" if DEBUG; - } - # Matching Window item names (= channels). - foreach my $item ($window->items()) { - # Wrong server. - if ($server and (!$item->{server} or - $item->{server}->{chatnet} !~ /^$server/i)) { - next; - } - if ($item->{name} =~ /$buffer/i) { - my $length = length($item->{name}); - $length-- if index($item->{name}, '#') == 0; - my $item_ratio = ($+[0] - $-[0]) / $length; - push @matches, { window => $window, - item => $item, - ratio => $item_ratio, - text => $item->{name} }; - print ":b $window->{name} $item->{name}: $item_ratio" if DEBUG; - } - } - } - - @matches = sort {$b->{ratio} <=> $a->{ratio}} @matches; - - return \@matches; -} - - -# STATUS ITEMS - -#TODO: give these things better names. -sub vim_mode_cmd { - - my $mode_str = ''; - if ($mode == M_INS) { - $mode_str = 'Insert'; - } elsif ($mode == M_EX) { - $mode_str = '%_Ex%_'; - } else { - $mode_str = 'Normal'; - if ($register ne '"' or $numeric_prefix or $operator or $movement or - $pending_map) { - my $partial = ''; - if ($register ne '"') { - $partial .= '"' . $register; - } - if ($numeric_prefix) { - $partial .= $numeric_prefix; - } - if ($operator) { - $partial .= $operator->{char}; - } - if ($movement) { - $partial .= $movement->{char}; - } - if (defined $pending_map) { - $partial .= $pending_map; - } - $partial = _parse_partial_command_reverse($partial); - $partial =~ s/\\/\\\\\\\\/g; - $mode_str .= " ($partial)"; - } - } - return $mode_str; -} - -sub vim_wins_data { - my $windows = ''; - - # A little code duplication of cmd_ex_command(), but \s+ instead of \s* so - # :bd doesn't display buffers matching d. - my $arg_str = join '', @ex_buf; - if ($arg_str =~ m|^b(?:uffer)?\s+(.+)$|) { - my $buffer = $1; - if ($buffer !~ /^[0-9]$/ and $buffer ne '#') { - # Display matching windows. - eval { - my $matches = _matching_windows($buffer); - $windows = join ',', map { $_->{text} } @$matches; - }; - # Catch errors in /$buffer/ regex. - if ($@) { - _warn($@); - } - } - } - return $windows; -} - -sub vim_exp_mode { - my ($server, $witem, $arg) = @_; - return vim_mode_cmd(); -} - -sub vim_exp_wins { - my ($server, $witem, $arg) = @_; - return vim_wins_data(); -} - -# vi mode status item. -sub vim_mode_cb { - my ($sb_item, $get_size_only) = @_; - my $mode_str = vim_mode_cmd(); - $sb_item->default_handler($get_size_only, "{sb $mode_str}", '', 0); -} - -# :b window list item. -sub b_windows_cb { - my ($sb_item, $get_size_only) = @_; - - my $windows = vim_wins_data(); - - $sb_item->default_handler($get_size_only, "{sb $windows}", '', 0); -} - - -# INPUT HANDLING - -sub got_key { - my ($key) = @_; - - return if ($should_ignore); - - # Esc key - if ($key == 27) { - print "Esc seen, starting buffer" if DEBUG; - $input_buf_enabled = 1; - - # NOTE: this timeout might be too low on laggy systems, but - # it comes at the cost of keystroke latency for things that - # contain escape sequences (arrow keys, etc) - my $esc_buf_timeout = $settings->{esc_buf_timeout}->{value}; - - $input_buf_timer - = Irssi::timeout_add_once($esc_buf_timeout, - \&handle_input_buffer, undef); - - print "Buffer Timer tag: $input_buf_timer" if DEBUG; - - } elsif ($mode == M_INS) { - if ($key == 5) { # Ctrl-C enters command mode - _update_mode(M_CMD); - _stop(); - return; - } elsif ($key == 10) { # enter. - _commit_line(); - - } elsif ($input_buf_enabled and $imap) { - print "Imap $imap active" if DEBUG; - my $map = $imaps->{$imap}; - if (not defined $map->{map} or chr($key) eq $map->{map}) { - $map->{func}($key); - # Clear the buffer so the imap is not printed. - @input_buf = (); - } else { - push @input_buf, $key; - } - flush_input_buffer(); - _stop(); - $imap = undef; - return; - - } elsif (exists $imaps->{chr($key)}) { - print "Imap " . chr($key) . " seen, starting buffer" if DEBUG; - - # start imap pending mode - $imap = chr($key); - - $input_buf_enabled = 1; - push @input_buf, $key; - $input_buf_timer - = Irssi::timeout_add_once(1000, \&flush_input_buffer, undef); - - _stop(); - return; - - # Pressing delete resets insert mode repetition (8 = BS, 127 = DEL). - # TODO: maybe allow it - } elsif ($key == 8 || $key == 127) { - @insert_buf = (); - # All other entered characters need to be stored to allow repeat of - # insert mode. Ignore delete and control characters. - } elsif ($key > 31) { - push @insert_buf, chr($key); - } - } - - if ($input_buf_enabled) { - push @input_buf, $key; - _stop(); - return; - } - - if ($mode == M_CMD) { - my $should_stop = handle_command_cmd($key); - _stop() if $should_stop; - Irssi::statusbar_items_redraw("vim_mode"); - - } elsif ($mode == M_EX) { - - if ($key == 3) { # C-c cancels Ex mdoe as well. - _update_mode(M_CMD); - _stop(); - return; - } - - handle_command_ex($key); - } -} - -# TODO: merge this with 'flush_input_buffer' below. - -sub handle_input_buffer { - - #Irssi::timeout_remove($input_buf_timer); - $input_buf_timer = undef; - # see what we've collected. - print "Input buffer contains: ", join(", ", @input_buf) if DEBUG; - - if (@input_buf == 1 && $input_buf[0] == 27) { - - print "Enter Normal Mode" if DEBUG; - _update_mode(M_CMD); - - } else { - # we have more than a single esc, implying an escape sequence - # (meta-* or esc-*) - - # currently, we only extract escape sequences if: - # a) we're in ex mode - # b) they're arrow keys (for history control) - - if ($mode == M_EX) { - # ex mode - my $key_str = join '', map { chr } @input_buf; - if ($key_str =~ m/^\e\[([ABCD])/) { - my $arrow = $1; - _debug( "Arrow key: $arrow"); - if ($arrow eq 'A') { # up - ex_history_back(); - } elsif ($arrow eq 'B') { # down - ex_history_fwd(); - } else { - $arrow =~ s/C/right/; - $arrow =~ s/D/left/; - _debug("Arrow key $arrow not supported"); - } - } - } else { - # otherwise, we just forward them to irssi. - _emulate_keystrokes(@input_buf); - } - - # Clear insert buffer, pressing "special" keys (like arrow keys) - # resets it. - @insert_buf = (); - } - - @input_buf = (); - $input_buf_enabled = 0; -} - -sub flush_input_buffer { - Irssi::timeout_remove($input_buf_timer) if defined $input_buf_timer; - $input_buf_timer = undef; - # see what we've collected. - print "Input buffer flushed" if DEBUG; - - # Add the characters to @insert_buf so they can be repeated. - push @insert_buf, map chr, @input_buf; - - _emulate_keystrokes(@input_buf); - - @input_buf = (); - $input_buf_enabled = 0; - - $imap = undef; -} - -sub flush_pending_map { - my ($old_pending_map) = @_; - - print "flush_pending_map(): ", $pending_map, ' ', $old_pending_map - if DEBUG; - - return if not defined $pending_map or - $pending_map ne $old_pending_map; - - handle_command_cmd(undef); - Irssi::statusbar_items_redraw("vim_mode"); -} - -sub handle_numeric_prefix { - my ($char) = @_; - my $num = 0+$char; - - if (defined $numeric_prefix) { - $numeric_prefix *= 10; - $numeric_prefix += $num; - } else { - $numeric_prefix = $num; - } -} - -sub handle_command_cmd { - my ($key) = @_; - - my $pending_map_flushed = 0; - - my $char; - if (defined $key) { - $char = chr($key); - # We were called from flush_pending_map(). - } else { - $char = $pending_map; - $key = 0; - $pending_map_flushed = 1; - } - - # Counts - if (!$movement and !$pending_map and - ($char =~ m/[1-9]/ or ($numeric_prefix && $char =~ m/[0-9]/))) { - print "Processing numeric prefix: $char" if DEBUG; - handle_numeric_prefix($char); - return 1; # call _stop() - } - - if (defined $pending_map and not $pending_map_flushed) { - $pending_map = $pending_map . $char; - $char = $pending_map; - } - - my $map; - if ($movement) { - $map = { char => $movement->{char}, - cmd => $movement, - maps => {}, - }; - - } elsif (exists $maps->{$char}) { - $map = $maps->{$char}; - - # We have multiple mappings starting with this key sequence. - if (!$pending_map_flushed and scalar keys %{$map->{maps}} > 0) { - if (not defined $pending_map) { - $pending_map = $char; - } - - # The current key sequence has a command mapped to it, run if - # after a timeout. - if (defined $map->{cmd}) { - Irssi::timeout_add_once(1000, \&flush_pending_map, - $pending_map); - } - return 1; # call _stop() - } - - } else { - print "No mapping found for $char" if DEBUG; - $pending_map = undef; - $numeric_prefix = undef; - return 1; # call _stop() - } - - $pending_map = undef; - - my $cmd = $map->{cmd}; - - # Make sure we have a valid $cmd. - if (not defined $cmd) { - print "Bug in pending_map_flushed() $map->{char}" if DEBUG; - return 1; # call _stop() - } - - # Ex-mode commands can also be bound in command mode. - if ($cmd->{type} == C_EX) { - print "Processing ex-command: $map->{char} ($cmd->{char})" if DEBUG; - - $cmd->{func}->(substr($cmd->{char}, 1), $numeric_prefix); - $numeric_prefix = undef; - - return 1; # call _stop() - # As can irssi commands. - } elsif ($cmd->{type} == C_IRSSI) { - print "Processing irssi-command: $map->{char} ($cmd->{char})" if DEBUG; - - _command_with_context($cmd->{func}); - - $numeric_prefix = undef; - return 1; # call _stop(); - # <Nop> does nothing. - } elsif ($cmd->{type} == C_NOP) { - print "Processing <Nop>: $map->{char}" if DEBUG; - - $numeric_prefix = undef; - return 1; # call _stop(); - } - - # text-objects (i a) are simulated with $movement - if (!$movement and ($cmd->{type} == C_NEEDSKEY or - ($operator and ($char eq 'i' or $char eq 'a')))) { - print "Processing movement: $map->{char} ($cmd->{char})" if DEBUG; - if ($char eq 'i') { - $movement = $commands->{_i}; - } elsif ($char eq 'a') { - $movement = $commands->{_a}; - } else { - $movement = $cmd; - } - - } elsif (!$movement and $cmd->{type} == C_OPERATOR) { - print "Processing operator: $map->{char} ($cmd->{char})" if DEBUG; - # Abort operator if we already have one pending. - if ($operator) { - # But allow cc/dd/yy. - if ($operator == $cmd) { - print "Processing line operator: ", - $map->{char}, " (", - $cmd->{char} ,")" - if DEBUG; - - my $pos = _input_pos(); - $cmd->{func}->(0, _input_len(), undef, 0); - # Restore position for yy. - if ($cmd == $commands->{y}) { - _input_pos($pos); - # And save undo for other operators. - } else { - _add_undo_entry(_input(), _input_pos()); - } - if ($register ne '"') { - print 'Changing register to "' if DEBUG; - $register = '"'; - } - } - $numeric_prefix = undef; - $operator = undef; - $movement = undef; - # Set new operator. - } else { - $operator = $cmd; - } - - # Start Ex mode. - } elsif ($cmd == $commands->{':'}) { - - if (not script_is_loaded('uberprompt')) { - _warn("Warning: Ex mode requires the 'uberprompt' script. " . - "Please load it and try again."); - } else { - _update_mode(M_EX); - _set_prompt(':'); - } - - # Enter key sends the current input line in command mode as well. - } elsif ($key == 10) { - _commit_line(); - return 0; # don't call _stop() - - } else { - print "Processing command: $map->{char} ($cmd->{char})" if DEBUG; - - my $skip = 0; - my $repeat = 0; - - if (!$movement) { - # . repeats the last command. - if ($cmd == $commands->{'.'} and defined $last->{cmd}) { - $cmd = $last->{cmd}; - $char = $last->{char}; - # If . is given a count then it replaces original count. - if (not defined $numeric_prefix) { - $numeric_prefix = $last->{numeric_prefix}; - } - $operator = $last->{operator}; - $movement = $last->{movement}; - $register = $last->{register}; - $repeat = 1; - } elsif ($cmd == $commands->{'.'}) { - print '. pressed but $last->{char} not set' if DEBUG; - $skip = 1; - } - } - - # Ignore invalid operator/command combinations. - if ($operator and $cmd->{no_operator}) { - print "Invalid operator/command: $operator->{char} $cmd->{char}" - if DEBUG; - $skip = 1; - } - - if ($skip) { - print "Skipping movement and operator." if DEBUG; - } else { - # Make sure count is at least 1 except for functions which need to - # know if no count was used. - if (not $numeric_prefix and not $cmd->{needs_count}) { - $numeric_prefix = 1; - } - - my $cur_pos = _input_pos(); - - # If defined $cur_pos will be changed to this. - my $old_pos; - # Position after the move. - my $new_pos; - # Execute the movement (multiple times). - if (not $movement) { - ($old_pos, $new_pos) - = $cmd->{func}->($numeric_prefix, $cur_pos, $repeat); - } else { - ($old_pos, $new_pos) - = $cmd->{func}->($numeric_prefix, $cur_pos, $repeat, - $char); - } - if (defined $old_pos) { - print "Changing \$cur_pos from $cur_pos to $old_pos" if DEBUG; - $cur_pos = $old_pos; - } - if (defined $new_pos) { - _input_pos($new_pos); - } else { - $new_pos = _input_pos(); - } - - # Update input position of last undo entry so that undo/redo - # restores correct position. - if (@undo_buffer and _input() eq $undo_buffer[0]->[0] and - ((defined $operator and $operator == $commands->{d}) or - $cmd->{repeatable})) { - print "Updating history position: $undo_buffer[0]->[0]" - if DEBUG; - $undo_buffer[0]->[1] = $cur_pos; - } - - # If we have an operator pending then run it on the handled text. - # But only if the movement changed the position (this prevents - # problems with e.g. f when the search string doesn't exist). - if ($operator and $cur_pos != $new_pos) { - print "Processing operator: ", $operator->{char} if DEBUG; - $operator->{func}->($cur_pos, $new_pos, $cmd, $repeat); - } - - # Save an undo checkpoint here for operators, all repeatable - # movements, operators and repetition. - if ((defined $operator and $operator == $commands->{d}) or - $cmd->{repeatable}) { - # TODO: why do history entries still show up in undo - # buffer? Is avoiding the commands here insufficient? - - _add_undo_entry(_input(), _input_pos()); - } - - # Store command, necessary for . - if ($operator or $cmd->{repeatable}) { - $last->{cmd} = $cmd; - $last->{char} = $char; - $last->{numeric_prefix} = $numeric_prefix; - $last->{operator} = $operator; - $last->{movement} = $movement; - $last->{register} = $register; - } - } - - # Reset the count unless we go into insert mode, _update_mode() needs - # to know it when leaving insert mode to support insert with counts - # (like 3i). - if ($repeat or $cmd->{type} != C_INSERT) { - $numeric_prefix = undef; - } - $operator = undef; - $movement = undef; - - if ($cmd != $commands->{'"'} and $register ne '"') { - print 'Changing register to "' if DEBUG; - $register = '"'; - } - - } - - return 1; # call _stop() -} - -sub handle_command_ex { - my ($key) = @_; - - # BS key (8) or DEL key (127) - remove last character. - if ($key == 8 || $key == 127) { - print "Delete" if DEBUG; - if (@ex_buf > 0) { - pop @ex_buf; - _set_prompt(':' . join '', @ex_buf); - # Backspacing over : exits ex-mode. - } else { - _update_mode(M_CMD); - } - - # Return key - execute command - } elsif ($key == 10) { - print "Run ex-mode command" if DEBUG; - cmd_ex_command(); - _update_mode(M_CMD); - - } elsif ($key == 9) { # TAB - print "Tab pressed" if DEBUG; - print "Ex buf contains: " . join('', @ex_buf) if DEBUG; - @tab_candidates = _tab_complete(join('', @ex_buf), [keys %$commands_ex]); - _debug("Candidates: " . join(", ", @tab_candidates)); - if (@tab_candidates == 1) { - @ex_buf = ( split('', $tab_candidates[0]), ' '); - _set_prompt(':' . join '', @ex_buf); - } - # Ignore control characters for now. - } elsif ($key > 0 && $key < 32) { - # TODO: use them later, e.g. completion - - # Append entered key - } else { - if ($key != -1) { - # check we're not called from an ex_history_* function - push @ex_buf, chr $key; - } - _set_prompt(':' . join '', @ex_buf); - } - - Irssi::statusbar_items_redraw("vim_windows"); - - _stop(); -} - -sub _tab_complete { - my ($input, $source) = @_; - my @out; - foreach my $item (@$source) { - if ($item =~ m/^\Q$input\E/) { - push @out, $item; - } - } - - return sort { $a cmp $b } @out; -} - -sub vim_mode_init { - Irssi::signal_add_first 'gui key pressed' => \&got_key; - Irssi::statusbar_item_register ('vim_mode', 0, 'vim_mode_cb'); - Irssi::statusbar_item_register ('vim_windows', 0, 'b_windows_cb'); - - Irssi::expando_create('vim_cmd_mode' => \&vim_exp_mode, {}); - Irssi::expando_create('vim_wins' => \&vim_exp_wins, {}); - - - # Register all available settings. - foreach my $name (keys %$settings) { - _setting_register($name); - } - - foreach my $char ('a' .. 'z') { - $registers->{$char} = ''; - } - - setup_changed(); - - Irssi::signal_add 'setup changed' => \&setup_changed; - - # Add all default mappings. - foreach my $char (keys %$commands) { - next if $char =~ /^_/; # skip private commands (text-objects for now) - add_map($char, $commands->{$char}); - } - - # Load the vim_moderc file if it exists. - ex_source('source'); - - setup_changed(); - _reset_undo_buffer(); - - if ($settings->{start_cmd}->{value}) { - _update_mode(M_CMD); - } else { - _update_mode(M_INS); - } -} - -sub setup_changed { - my $value; - - if ($settings->{cmd_seq}->{value} ne '') { - delete $imaps->{$settings->{cmd_seq}->{value}}; - } - $value = _setting_get('cmd_seq'); - if ($value eq '') { - $settings->{cmd_seq}->{value} = $value; - } else { - if (length $value == 1) { - $imaps->{$value} = { 'map' => $value, - 'func' => sub { _update_mode(M_CMD) } - }; - $settings->{cmd_seq}->{value} = $value; - } else { - _warn("Error: vim_mode_cmd_seq must be a single character"); - # Restore the value so $settings and irssi settings are - # consistent. - _setting_set('cmd_seq', $settings->{cmd_seq}->{value}); - } - } - - my $new_utf8 = _setting_get('utf8'); - if ($new_utf8 != $settings->{utf8}->{value}) { - # recompile the patterns when switching to/from utf-8 - $word = qr/[\w_]/o; - $non_word = qr/[^\w_\s]/o; - - $settings->{utf8}->{value} = $new_utf8; - } - if ($new_utf8 and (!$^V or $^V lt v5.8.1)) { - _warn("Warning: UTF-8 isn't supported very well in perl < 5.8.1! " . - "Please disable the vim_mode_utf8 setting."); - } - - # Sync $settings with current irssi values. - foreach my $name (keys %$settings) { - # These were already handled above. - next if $name eq 'cmd_seq' or $name eq 'cmd_seq'; - - $settings->{$name}->{value} = _setting_get($name); - } -} - -sub UNLOAD { - Irssi::signal_remove('gui key pressed' => \&got_key); - Irssi::signal_remove('setup changed' => \&setup_changed); - Irssi::statusbar_item_unregister ('vim_mode'); - Irssi::statusbar_item_unregister ('vim_windows'); -} - -sub _add_undo_entry { - my ($line, $pos) = @_; - - # If we aren't at the top of the history stack, then drop newer entries as - # we can't branch (yet). - while ($undo_index > 0) { - shift @undo_buffer; - $undo_index--; - } - - # check it's not a dupe of the list head - my $current = $undo_buffer[$undo_index]; - if ($line eq $current->[0] && $pos == $current->[1]) { - print "Not adding duplicate to undo list" if DEBUG; - } elsif ($line eq $current->[0]) { - print "Updating position of undo list at $undo_index" if DEBUG; - $undo_buffer[$undo_index]->[1] = $pos; - } else { - print "adding $line ($pos) to undo list" if DEBUG; - # add to the front of the buffer - unshift @undo_buffer, [$line, $pos]; - $undo_index = 0; - } - my $max = $settings->{max_undo_lines}->{value}; -} - -sub _restore_undo_entry { - my $entry = $undo_buffer[$undo_index]; - _input($entry->[0]); - _input_pos($entry->[1]); -} - -sub _print_undo_buffer { - - my $i = 0; - my @buf; - foreach my $entry (@undo_buffer) { - my $str = ''; - if ($i == $undo_index) { - $str .= '* '; - } else { - $str .= ' '; - } - my ($line, $pos) = @$entry; - substr($line, $pos, 0) = '*'; - # substr($line, $pos+3, 0) = '%_'; - - $str .= sprintf('%02d %s [%d]', $i, $line, $pos); - push @buf, $str; - $i++; - } - print "------ undo buffer ------"; - print join("\n", @buf); - print "------------------ ------"; - -} - -sub _reset_undo_buffer { - my ($line, $pos) = @_; - $line = _input() unless defined $line; - $pos = _input_pos() unless defined $pos; - - print "Clearing undo buffer" if DEBUG; - @undo_buffer = ([$line, $pos]); - $undo_index = 0; -} - -sub add_map { - my ($keys, $command) = @_; - - # To allow multiple mappings starting with the same key (like gg, ge, gE) - # also create maps for the keys "leading" to this key (g in this case, but - # can be longer for this like ,ls). When looking for the mapping these - # "leading" maps are followed. - my $tmp = $keys; - while (length $tmp > 1) { - my $map = substr $tmp, -1, 1, ''; - if (not exists $maps->{$tmp}) { - $maps->{$tmp} = { char => _parse_mapping_reverse($tmp), - cmd => undef, - maps => {} - }; - } - if (not exists $maps->{$tmp}->{maps}->{$tmp . $map}) { - $maps->{$tmp}->{maps}->{$tmp . $map} = undef; - } - } - - if (not exists $maps->{$keys}) { - $maps->{$keys} = { char => undef, - cmd => undef, - maps => {} - }; - } - $maps->{$keys}->{char} = _parse_mapping_reverse($keys); - $maps->{$keys}->{cmd} = $command; -} - -sub delete_map { - my ($keys) = @_; - - # Abort for non-existent mappings or placeholder mappings. - return if not exists $maps->{$keys} or not defined $maps->{$keys}->{cmd}; - - my @add = (); - - # If no maps need the current key, then remove it and all other - # unnecessary keys in the "tree". - if (keys %{$maps->{$keys}->{maps}} == 0) { - my $tmp = $keys; - while (length $tmp > 1) { - my $map = substr $tmp, -1, 1, ''; - delete $maps->{$tmp}->{maps}->{$tmp . $map}; - if (not $maps->{$tmp}->{cmd} and keys %{$maps->{$tmp}->{maps}} == 0) { - push @add, $tmp; - delete $maps->{$tmp}; - } else { - last; - } - } - } - - if (keys %{$maps->{$keys}->{maps}} > 0) { - $maps->{$keys}->{cmd} = undef; - } else { - delete $maps->{$keys}; - } - push @add, $keys; - - # Restore default keybindings in case we :unmapped a <Nop> or a remapped - # key. - foreach my $key (@add) { - if (exists $commands->{$key}) { - add_map($key, $commands->{$key}); - } - } -} - - -sub _commit_line { - _update_mode(M_INS); - - # separate from call above as _update_mode() does additional internal work - # and we need to make sure it gets correctly called. - _update_mode(M_CMD) if $settings->{start_cmd}->{value}; - - _reset_undo_buffer('', 0); -} - -sub _input { - my ($data) = @_; - - my $current_data = Irssi::parse_special('$L', 0, 0); - - if ($settings->{utf8}->{value}) { - $current_data = decode_utf8($current_data); - } - - if (defined $data) { - if ($settings->{utf8}->{value}) { - Irssi::gui_input_set(encode_utf8($data)); - } else { - Irssi::gui_input_set($data); - } - } else { - $data = $current_data; - } - - return $data; -} - -sub _input_len { - return length _input(); -} - -sub _input_pos { - my ($pos) = @_; - my $cur_pos = Irssi::gui_input_get_pos(); - # my $dpos = defined $pos?$pos:'undef'; - # my @call = caller(1); - # my $cfunc = $call[3]; - # $cfunc =~ s/^.*?::([^:]+)$/$1/; - # print "pos called from line: $call[2] sub: $cfunc pos: $dpos, cur_pos: $cur_pos" - # if DEBUG; - - if (defined $pos) { - #print "Input pos being set from $cur_pos to $pos" if DEBUG; - Irssi::gui_input_set_pos($pos) if $pos != $cur_pos; - } else { - $pos = $cur_pos; - #print "Input pos retrieved as $pos" if DEBUG; - } - - return $pos; -} - -sub _emulate_keystrokes { - my @keys = @_; - $should_ignore = 1; - for my $key (@keys) { - Irssi::signal_emit('gui key pressed', $key); - } - $should_ignore = 0; -} - -sub _stop() { - Irssi::signal_stop_by_name('gui key pressed'); -} - -sub _update_mode { - my ($new_mode) = @_; - - my $pos; - - if ($mode == M_INS and $new_mode == M_CMD) { - # Support counts with insert modes, like 3i. - if ($numeric_prefix and $numeric_prefix > 1) { - $pos = _insert_buffer($numeric_prefix - 1, _input_pos()); - _input_pos($pos); - $numeric_prefix = undef; - - # In insert mode we are "between" characters, in command mode "on top" - # of keys. When leaving insert mode we have to move on key left to - # accomplish that. - } else { - $pos = _input_pos(); - if ($pos != 0) { - _input_pos($pos - 1); - } - } - # Store current line to allow undo of i/a/I/A. - _add_undo_entry(_input(), _input_pos()); - - # Change mode to i to support insert mode repetition. This doesn't affect - # commands like i/a/I/A because handle_command_cmd() sets $last->{cmd}. - # It's necessary when pressing enter so the next line can be repeated. - } elsif ($mode == M_CMD and $new_mode == M_INS) { - $last->{cmd} = $commands->{i}; - # Make sure prompt is cleared when leaving ex mode. - } elsif ($mode == M_EX and $new_mode != M_EX) { - _set_prompt(''); - } - - $mode = $new_mode; - if ($mode == M_INS) { - $history_index = undef; - $register = '"'; - @insert_buf = (); - # Reset every command mode related status as a fallback in case something - # goes wrong. - } elsif ($mode == M_CMD) { - $numeric_prefix = undef; - $operator = undef; - $movement = undef; - $register = '"'; - - $pending_map = undef; - - # Also clear ex-mode buffer. - @ex_buf = (); - } - - Irssi::statusbar_items_redraw("vim_mode"); - Irssi::statusbar_items_redraw ('uberprompt'); - -} - -sub _set_prompt { - my $msg = shift; - - # add a leading space unless we're trying to clear it entirely. - if (length($msg) and $settings->{prompt_leading_space}->{value}) { - $msg = ' ' . $msg; - } - - # escape % symbols. This prevents any _set_prompt calls from using - # colouring sequences. - $msg =~ s/%/%%/g; - - Irssi::signal_emit('change prompt', $msg, 'UP_INNER'); -} - -sub _setting_get { - my ($name) = @_; - - my $type = $settings->{$name}->{type}; - $name = "vim_mode_$name"; - - my $ret = undef; - - if ($type == S_BOOL) { - $ret = Irssi::settings_get_bool($name); - } elsif ($type == S_INT) { - $ret = Irssi::settings_get_int($name); - } elsif ($type == S_STR) { - $ret = Irssi::settings_get_str($name); - } elsif ($type == S_TIME) { - $ret = Irssi::settings_get_time($name); - } else { - _warn("Unknown setting type '$type', please report."); - } - - return $ret; -} - -sub _setting_set { - my ($name, $value) = @_; - - my $type = $settings->{$name}->{type}; - $name = "vim_mode_$name"; - - if ($type == S_BOOL) { - Irssi::settings_set_bool($name, $value); - } elsif ($type == S_INT) { - Irssi::settings_set_int($name, $value); - } elsif ($type == S_STR) { - Irssi::settings_set_str($name, $value); - } elsif ($type == S_TIME) { - Irssi::settings_set_time($name, $value); - } else { - _warn("Unknown setting type '$type', please report."); - } -} -sub _setting_register { - my ($name) = @_; - - my $value = $settings->{$name}->{value}; - my $type = $settings->{$name}->{type}; - $name = "vim_mode_$name"; - - if ($type == S_BOOL) { - Irssi::settings_add_bool('vim_mode', $name, $value); - } elsif ($type == S_INT) { - Irssi::settings_add_int('vim_mode', $name, $value); - } elsif ($type == S_STR) { - Irssi::settings_add_str('vim_mode', $name, $value); - } elsif ($type == S_TIME) { - Irssi::settings_add_time('vim_mode', $name, $value); - } else { - _warn("Unknown setting type '$type', please report."); - } -} - -sub _warn { - my ($warning) = @_; - - print '%_vim_mode: ', $warning, '%_'; -} - -sub _debug { - return unless DEBUG; - - my ($format, @args) = @_; - my $str = sprintf($format, @args); - print $str; -} - -sub _command_with_context { - my ($command) = @_; - my $context; - my $window = Irssi::active_win; - if (defined $window) { - my $witem = $window->{active}; - if (defined $witem and ref($witem) eq 'Irssi::Windowitem') { - $context = $witem; - } else { - $context = $window; - } - } else { - my $server = Irssi::active_server; - if (defined $server) { - $context = $server; - } - } - if (defined $context) { - print "Command $command Using context: " . ref($context) if DEBUG; - $context->command($command); - } else { - print "Command $command has no context" if DEBUG; - Irssi::command($command); - } -} - -sub ex_history_add { - my ($line) = @_; - - # check it's not an exact dupe of the previous history line - - my $last_hist = $ex_history[$ex_history_index]; - $last_hist = '' unless defined $last_hist; - - return if $last_hist eq $line; - - _debug("Adding $line to ex command history"); - - # add it to the history - unshift @ex_history, $line; - - if ($settings->{ex_history_size}->{value} < @ex_history) { - pop @ex_history; # junk the last entry if we've hit the max. - } -} - -sub ex_history_fwd { - - my $hist_max = $#ex_history; - $ex_history_index++; - if ($ex_history_index > $hist_max) { - $ex_history_index = 0; - _debug("ex history hit top, wrapping to 0"); - } - - my $line = $ex_history[$ex_history_index]; - $line = '' if not defined $line; - - _debug("Ex history line: $line"); - - @ex_buf = split '', $line; - handle_command_ex(-1); -} - -sub ex_history_back { - my $hist_max = $#ex_history; - $ex_history_index--; - if ($ex_history_index == -1) { - $ex_history_index = $hist_max; - _debug("ex history hit bottom, wrapping to $hist_max"); - - } - - my $line = $ex_history[$ex_history_index]; - $line = '' if not defined $line; - - _debug("Ex history line: $line"); - @ex_buf = split '', $line; - handle_command_ex(-1); - -} - -sub ex_history_show { - my $win = Irssi::active_win(); - $win->print("Ex command history:"); - for my $i (0 .. $#ex_history) { - my $flag = $i == $ex_history_index - ? ' <' - : ''; - $win->print("$i " . $ex_history[$i] . $flag); - } -} -vim_mode_init(); diff --git a/.config/irssi/startup b/.config/irssi/startup @@ -1 +1,2 @@ /load perl +/sbar modify -type window -position 0 -visible active prompt diff --git a/.config/irssi/triggers b/.config/irssi/triggers @@ -7,3 +7,53 @@ -all -pattern '¯\_(ツ)_/¯' -replace '*shrug*' -all -pattern '(╯°□°)╯︵ ┻━┻' -replace '*flips table*' -publics -privmsgs -masks 'wfnintr!*@example.com. *!*@irc.haydenvh.com mys!*@mys.' -regexp '^halfop #hlircnet' -command '^msg -hlircnet chanhold halfop #hlircnet $N' -name 'AUTOHOP-#hlircnet' +-all -regexp '\t' -replace ' ' +-all -pattern '00' -replace '99' +-all -pattern '01' -replace '88' +-all -pattern '02' -replace '48' +-all -pattern '03' -replace '56' +-all -pattern '04' -replace '52' +-all -pattern '05' -replace '40' +-all -pattern '06' -replace '50' +-all -pattern '07' -replace '18' +-all -pattern '08' -replace '42' +-all -pattern '09' -replace '56' +-all -pattern '10' -replace '46' +-all -pattern '11' -replace '58' +-all -pattern '12' -replace '48' +-all -pattern '13' -replace '62' +-all -pattern '14' -replace '90' +-all -pattern '15' -replace '96' +-all -pattern '(..),00' -replace '\1,99' +-all -pattern '(..),01' -replace '\1,88' +-all -pattern '(..),02' -replace '\1,48' +-all -pattern '(..),03' -replace '\1,56' +-all -pattern '(..),04' -replace '\1,52' +-all -pattern '(..),05' -replace '\1,40' +-all -pattern '(..),06' -replace '\1,50' +-all -pattern '(..),07' -replace '\1,18' +-all -pattern '(..),08' -replace '\1,42' +-all -pattern '(..),09' -replace '\1,56' +-all -pattern '(..),10' -replace '\1,46' +-all -pattern '(..),11' -replace '\1,58' +-all -pattern '(..),12' -replace '\1,48' +-all -pattern '(..),13' -replace '\1,62' +-all -pattern '(..),14' -replace '\1,90' +-all -pattern '(..),15' -replace '\1,96' +-all -pattern '(.),00' -replace '\1,99' +-all -pattern '(.),01' -replace '\1,88' +-all -pattern '(.),02' -replace '\1,48' +-all -pattern '(.),03' -replace '\1,56' +-all -pattern '(.),04' -replace '\1,52' +-all -pattern '(.),05' -replace '\1,40' +-all -pattern '(.),06' -replace '\1,50' +-all -pattern '(.),07' -replace '\1,18' +-all -pattern '(.),08' -replace '\1,42' +-all -pattern '(.),09' -replace '\1,56' +-all -pattern '(.),10' -replace '\1,46' +-all -pattern '(.),11' -replace '\1,58' +-all -pattern '(.),12' -replace '\1,48' +-all -pattern '(.),13' -replace '\1,62' +-all -pattern '(.),14' -replace '\1,90' +-all -pattern '(.),15' -replace '\1,96' +-all -nocase -channels '#general #test' -regexp '^!hilight (.*)' -command '^wait $1\x100\x100\x100; msg $C $N'