# uncomment this if you don't want time stamping # timestamp off # uncomment this if you want ctcp cloaking # cloak on # *** key bindings *** bind ^[1 parse_command window swap 1 bind ^[2 parse_command window swap 2 bind ^[3 parse_command window swap 3 bind ^[4 parse_command window swap 4 bind ^[5 parse_command window swap 5 bind ^[6 parse_command window swap 6 bind ^[7 parse_command window swap 7 bind ^[8 parse_command window swap 8 bind ^[9 parse_command window swap 9 # *** variable sets *** set -continued_line set dcc_auto_send_rejects off set dcc_timeout 60 set dcc_sliding_window 1000 set auto_rejoin off set mirc_broken_dcc_resume on set status_format 16,12%T [%R] %=%@%N%*%#%S%H%B%Q%A%C%+%I%O%M%F%L %D # *** aliases *** alias ban { if ([$0] == []) { xecho -b Usage: /ban return } userhost $0 -cmd { @:usr_nick = [$0] @:usr_id = [$3] @:usr_host = [$4] } @:re = regcomp(^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\$) if (regexec($re $usr_host)) { @:usr_dom = count(. $usr_host) > 1 ? [*.$after(-2 . $usr_host)] : [*.$usr_host] } { @:usr_dom = [$before(-1 . $usr_host).*] } switch ($1) { (1) { //mode $C +b $usr_nick!*@* } (2) { //mode $C +b *!*@$usr_host } (3) { //mode $C +b *!*$usr_id@$usr_dom } (4) { //mode $C +b *!*@$usr_dom } (*) { ban $0 2 } } } alias bans { if ( [$0] ) { mode $0 +b } { mode $C +b } } alias chanserv { quote chanserv $* } alias clearall { //clear -all } alias client { ctcp $0 VERSION } alias cloak { switch ($0) { (on) { ^on ctcp_request -"*" ^on ^ctcp_request "*" ^on -ctcp_request ^"% % ACTION *" ^on -ctcp_request ^"% % DCC *" ^on -ctcp_request ^"% % PING *" xecho -b -w 1 ctcp cloaking is now on } (all) { ^on ctcp_request -"*" ^on ^ctcp_request "*" ^on -ctcp_request ^"% % ACTION *" ^on -ctcp_request ^"% % DCC *" xecho -b -w 1 complete ctcp cloaking is now on } (off) { ^on ctcp_request -"*" } (*) { xecho -b -w 1 you must specify on, off, or all } } } alias cs chanserv alias ctcpreply { eval notice $0 $chr(1)$1-$chr(1)} alias cycle { @:chan_name = C @:chan_key = key($C) leave * wait join $chan_name $chan_key } alias dccallow { quote dccallow $* } alias dns { userhost $0 -cmd { echo Looking up $4 ... exec host $4 } } alias dop { fe ($*) n1 n2 n3 n4 { mode $C -oooo $n1 $n2 $n3 $n4 } } alias dvoice { fe ($*) n1 n2 n3 n4 { mode $C -vvvv $n1 $n2 $n3 $n4 } } alias finger { ctcp $0 FINGER } alias format_idle_time { if ( [$0] >= 3600 ) { return ${[$0] / 3600} hours ${([$0] % 3600) / 60} mins ${[$0] % 60} sec } if ( [$0] >= 60 ) { return ${([$0] % 3600) / 60} mins ${[$0] % 60} sec } return ${[$0] % 60} seconds } alias k { kick $C $* } alias kb { ban $0 k $* } alias memoserv { quote memoserv $* } alias mdop { fe ($remw($N $chops())) n1 n2 n3 n4 { mode $C -oooooo $n1 $n2 $n3 $n4 } } alias mop { fe ($nochops()) n1 n2 n3 n4 { mode $C +oooooo $n1 $n2 $n3 $n4 } } alias names scan alias nickserv { quote nickserv $* } alias ns nickserv alias o onotice alias onotice { quote notice @$C :ops: $* xecho -c $ts()-> ops: $* } alias op { fe ($*) n1 n2 n3 n4 { mode $C +oooo $n1 $n2 $n3 $n4 } } alias operserv { quote operserv $* } alias os operserv alias q query alias sc scan alias scan { @:num = 0 if (ischannel($0)) { @:chan = [$0] } { @:chan = C } xecho -w $winchan($chan) xecho -w $winchan($chan) -b 16Users on $chan: fe ($strip(?. $channel($chan))) n1 n2 n3 n4 { xecho -w $winchan($chan) 14| 13$[17]n1 $[17]n2 $[17]n3 $[17]n414 | if (n4) { @:num += 4 } { if (n3) { @:num += 3 } { if (n2) { @:num += 2 } { @:num++ } } } } xecho -w $winchan($chan) Total number of users on $chan: $num xecho -w $winchan($chan) } # sping from wd's anduril alias sping (server) { if (server == []) @:server = builtin_expando(S) @a.server.sping #= [$server $utime() ] quote ping $server $server xecho -w 1 $ts()$banner Sent PING to $server } # tdiff3 from wd's anduril alias tdiff3 { if (![$0]) { return 0s } @:y=:m=:w=0 @:t=[$0] ^local r @:y=floor(${t/31536000}) @:t%=31536000 @:m=floor(${t/2419200}) @:t%=2419200 @:w=floor(${t/604800}) @:t%=604800 @:l=tdiff2($t) if (y) { @:r=[${y}y ] } if (m) { @:r#=[${m}m ] } if (w) { @r#=[${w}w ] } return $r$l } alias timestamp { switch ($0) { (off) { @time_stamp = [off] xecho -b -w 1 Time stamping is now off } (on) { @time_stamp = [on] xecho -b -w 1 Time stamping is now on } (*) { if (time_stamp == [off]) { xecho -b -w 1 Time stamping is currently off } { xecho -b -w 1 Time stamping is currently on } } } } alias ts { if (time_stamp == [off]) { return } { return 10$strftime($time() (%I:%M:%S %P)) 15 } } alias untopic { if (ischannel($0)) { @:chan = [$0] } { @:chan = C } quote TOPIC $chan : } alias ver client alias voice { fe ($*) n1 n2 n3 n4 { mode $C +vvvv $n1 $n2 $n3 $n4 } } alias wall { fe ($remw($N $onchannel())) n1 { quote notice $n1 :wall: $* } xecho -c -> $C/wall: $* } alias wii { whois $0 $0 } alias wk { window kill } alias wops { fe ($remw($N $chops())) n1 { quote notice $n1 :ops: $* xecho -c -> $n1: ops: $* } } alias ws { window swap $0 } # *** named on hooks *** on ^action "*" { if (rmatch($1 #* &* +*)) { if ([$1] == winchan($winchan($1))) { xecho -w $winchan($1) $ts()* $0 $2- } { xecho -w $winchan($1) $ts()* $0/$1 $2- } } { xecho -w queries $ts()* $0 $2- } } on ^channel_nick "*" { xecho -w $winchan($0) $ts()$banner 16Nick: 10$1 15is now known as 8$2 } on ^channel_signoff "*" { xecho -w $winchan($0) $ts()$banner 16Quit: 10$1 15has quit irc \($2-\) } on ^ctcp "*" { xecho -w 1 $ts()$banner CTCP $2 request from $0 to $1: $3- } on ^ctcp_reply "*" { xecho -w 1 $ts()$banner CTCP $2 reply from $0 to $1: $3- } on ^dcc_chat "*" { xecho -w queries $ts()=$0= $1- } on ^dcc_connect "*" { xecho -w queries $ts()$banner DCC $1 connection with $0[$2:$3] established } on ^dcc_lost "*" { xecho -w queries $ts()$banner DCC $1 connection with $0 stopped \($2-\) } on ^dcc_request "% CHAT *" { xecho -w 1 $ts()$banner DCC CHAT request received from $0!$userhost() [$3:$4] } on ^dcc_request "% SEND *" { xecho -w 1 $ts()$banner DCC SEND \($5 $6\) request received from $0!$userhost() [$3:$4] } on ^exec_exit * # on ^general_notice "% @% *" { xecho -w $winchan($rest($1)) -- $ts()-13$0:$115- $2- } on ^general_notice "% #% *" { xecho -w $winchan($1) -- $ts()13$0:$115- $2- } on ^invite "*" { xecho -w 1 $ts()$banner 16Invite: 10$0 15invites you to join $1 } on ^join "*" { xecho -w $winchan($1) $ts()$banner 16Join: 10$0 15\(10$215\) has joined $1 } on ^kick "*" { if ( [$0] == N ) { xecho $ts()$banner 16Kick: 15You have been kicked from $2 by $1 \($3-\) } { xecho -w $winchan($2) $ts()$banner 16Kick: 10$0 15has been kicked from $2 by $1 \($3-\) } } on ^leave "*" { if ([$0] == N) { xecho -w $winchan($1) $ts()$banner You have left $1 \($3-\) } { xecho -w $winchan($1) $ts()$banner 16Part: 10$0 15has left $1 \($3-\) } } on ^mode "*" { if ([$1] == N) { xecho -w 1 $ts()$banner 16Mode: 11$1 $2- by $0 } { xecho -w $winchan($1) $ts()$banner 16Mode: 11$1 $2- by $0 } } on ^msg "*" { xecho -w queries $ts()*$0* $1- } on ^msg "% @% %" { xecho -w $winchan($rest($1)) -- $ts()<-$0:$1\-> $2- } on ^notice "*" { xecho -w 1 -- $ts()-13$015- $1- } on ^notify_signoff "*" { xecho -w 1 $ts()$banner 16Signoff: 10$015 has left } on ^notify_signon "*" { xecho -w 1 $ts()$banner 16Signon: 10$0 15\(10$115\) is on } # pong on hook from wd's anduril on ^pong "% % %" { @:ind = findw($0 $a.server.sping) if (ind == -1) { xecho -w 1 $ts()$banner $0\: PONG received from $1 \($2\) } else { @:ut = utime() @:usec = word(${ind + 2} $a.server.sping) @:sec = word(${ind + 1} $a.server.sping) @a.server.sping = remw($0 $remw($sec $remw($usec $a.server.sping))) @:sec = word(0 $ut) - sec @:usec = word(1 $ut) - usec if (usec < 0) { @:usec += 1000000 , sec-- } @:sec = tdiff3($sec) if (pass(s $sec) == []) { @:sec = [${sec}0.$left(3 $usec)s] } else { @:sec = [$before(s $sec).$left(3 $usec)s] } xecho -w 1 $ts()$banner PONG received from $1 in $sec } } on ^public "*" { xecho -w $winchan($1) $ts()14<15$014> 15$2- } on ^public_msg "*" { xecho -w $winchan($1) $ts()14<15$0:$114> 15$2- } on ^public_other "*" { xecho -w $winchan($1) $ts()14<15$0:$114> 15$2- } on ^send_action "*" { if (rmatch($0 #* &* +*) ) { xecho -w $winchan($0) $ts()* $N $1- } { xecho -w queries $ts()*> $0: $N $1- } } on ^send_dcc_chat "*" { xecho -w queries $ts()=$0=> $1- } on ^send_msg "*" { xecho -w queries $ts()*$0*> $1- } on ^send_notice "*" { xecho -w 1 -- $ts()-> $0: $1- } on ^send_notice "#% *" { xecho -w $winchan($rest($0)) -- $ts()-> $0: $1- } on ^send_public "*" { if ([$0] == C) { xecho -w $winchan($0) $ts()14<15$N14> 15$1- } { xecho -w $winchan($0) $ts()14<15$N:$014> 15$1- } } on ^topic "*" { xecho -w $winchan($1) $ts()$banner 16Topic: 10$0 15has changed the topic on $1 to: $2- } on ^window "% % SWAP: Window % is not hidden!" on ^window "% % SWAP: No such window: %" on ^yell "*" { xecho -w 1 $ts()$banner $* } on ^yell ^"Defaulting % to CHANMODE type D" # *** numeric hooks *** on ^317 "*" { xecho -w 1 $banner $1 has been idle $format_idle_time($2), Signon $strftime($3 %c) } on ^331 "*" { xecho -w $winchan($1) $ts()$banner $1- } on ^332 "*" { xecho -w $winchan($1) $ts()$banner Topic for $1: $2- } on ^333 "*" { xecho -w $winchan($1) $ts()$banner Topic set by $2 $strftime($3 %c) } on ^367 "*" { xecho -w 1 $banner $1 $2 $3 $strftime($4 %c) } # tabkey.jm: a full-featured tab key module for epic # # written by nsx # # # Here's the plan: # # First off, the word fragment (which may not be a fragment at all, but # rather, a complete word, though we have no way of knowing this yet) that # we're going to attempt to complete is determined. If the current word # pointed to by the input line cursor is quoted, then that word becomes the # word fragment we'll attempt to complete. If the word is not quoted, then all # characters from the beginning of the word pointed to by the input line cursor # to the cursor itself become the fragment we'll try to complete. # # We now analyze the input line to see if it matches certain patterns, and # determine which method of completion we'll use based on which pattern it # matches. # # If our input line matches "/msg ", we recall the item in our # nickname history pointed to by our nickname history index. We then type out # the command "/msg ", where is that nickname we recalled # from the history. If there are no nicknames in the history, nothing at all # is done. # # If our input line matches "/dcc ", then dcc command completion is # attempted. This matches the word fragment against all known dcc commands. # # If our input line begins with "/dcc send " or "/load", we # attempt file name completion. This matches the word fragment against any # local path name that exists. # # If our input line matches "/" we attempt command completion. This # matches the word fragment against both internal commands and aliases. # # If our input line is empty, we attempt nickname history cycling as described # above. # # If our input line matches none of the above, we analyze the first character # of the fragment. If it begins with a '#' or a '&', channel name completion # is attempted. This matches the word fragment against all channels we're # currently on. # # If our fragment does not begin with '#' or '&', nickname completion is # attempted. This matches the word fragment against all nicknames in the # current channel. If no matches are found, we then match the word fragment # against all nicknames in all other channels we're on. # # If there was multiple matches for the word fragment, we replace the word # fragment with the common prefix for these matches, if any. We also display # all of the possible matches on the screen, unless they're the same list of # possible matches we displayed less than 5 seconds ago. This way, we hope to # avoid unnecessary repetition. # # If there was only one match for the word fragment, we replace the word # fragment with that match. We also append a space unless nickname completion # took place, and the completed word is the only word in the input line. Most # of the time this occurs, I assume people are trying to address somebody. I # do this so that the optional colon can be appended after the nickname, # without having to backspace. # # If we perform file name completion and the completed path name is a # directory, we treat the completed word as if it's a partial completion (in # that no space is appended), since we cannot be certain whether or not the # path name is complete, unless it's a file. # # If the completed word (partial or complete) needs to be enclosed in # quotation marks, we meet this provision. If the completed word is partial, # we place the cursor on the enclosing quotation mark, so that further # completion can take place without having to manually reposition the cursor. # # For each outgoing msg or outgoing DCC CHAT message, we add the recipient # to our nickname history. # # For each incoming msg or incoming DCC CHAT message, we add the sender to # our nickname history. # # For each DCC CHAT connection that takes place, we add the other party to # our nickname history. # # Each time a nickname is added to our nickname history, we first remove any # prior occurrences of the nickname that may exist. We then check to see if # our nickname history is at its capacity (10 nicknames). If it is, the oldest # nickname in our history is discarded. Next, we add the nickname to the # history. Lastly, we set our nickname index to point to the nickname that was # just added. # *** global variables *** # nickname history array @delarray(nick_hist) # nickname history index @nick_index = -1 # the matches from the last tab key press @last_matches = [] # how far the cursor is from the end of the word fragment @end_offset = 0 # whether or not the word fragment needs to be quoted (0 or 1) @word_fragq = 0 bind ^I parse_command do_tabkey alias do_tabkey { @:cur_pos = curpos() @:cur_word = word($indextoword($cur_pos $L ) $L ) @:frag_start = wordtoindex($indextoword($cur_pos $L ) $L ) if (index("$chr($jot(32 1))" $cur_word) == -1) { @word_fragq = 0 @end_offset = 0 @:word_frag = mid($frag_start ${cur_pos - frag_start} $L) } { @word_fragq = 1 @end_offset = (frag_start + @cur_word - cur_pos) + 2 @:word_frag = cur_word if (end_offset < 0) { return } } if (leftw(1 $L) == [/msg] && #L == 2 && mid(${@L - 1} 1 $L) == [ ]) { @msg_cycle() return } switch ($L) { (/dcc %) { @dcc_complete($word_frag) } (/dcc send % *) (/load *) { @file_complete($word_frag) } (/%) { @command_complete($right(${@L - 1} $L)) } () { @msg_cycle() } (*) { @:firstc = left(1 $word_frag) if (firstc == [#] || firstc == [&]) { @chan_complete($word_frag) } { @nick_complete($word_frag) } } } } # replace_fragment (frag_len, matches...) # # This function replaces the word fragment. If given a single match, the word # fragment is replaced with that match. If multiple matches are given, the # common prefix for those matches replaces the word fragment. If no matches # are given, this function does nothing. # # It expects the fragment length (so it can know how many times to backspace) # to be its first argument, and all matches for the word fragment to be the # rest of its arguments. This function also expects the global variable # end_offset to be set, so that it can position the cursor after the word # fragment, if needed, before backspacing to clear it. This needs to be done, # for example, when the tab key was pressed while the cursor was in the middle # of a quoted word. alias replace_fragment { @:matches = [$1-] @:match_pfx = prefix($1-) @:frag_len = word_fragq ? [$0] + 2 : [$0] if (#matches && #match_pfx) { repeat $end_offset parsekey forward_character repeat $frag_len parsekey backspace if (index("$chr($jot(32 1))" $match_pfx) != -1) { @:match_pfx = ["$match_pfx"] @word_fragq = 1 } if (#matches > 1) { unless (matches == last_matches) { xecho -c Possible matches: xecho -c $matches xecho -c @last_matches = matches timer 5 @last_matches = [] } xtype -l $match_pfx if (word_fragq) { parsekey backward_character } } { xtype -l $matches$chr(32) } } } alias chan_complete { @:word_frag = [$*] @:frag_matches = pattern("$word_frag*" $mychannels()) @replace_fragment($@word_frag $frag_matches) } alias command_complete { @:word_frag = [$*] @:frag_matches = getcommands($word_frag*) @push(frag_matches $aliasctl(alias pmatch $word_frag*)) @replace_fragment($@word_frag $frag_matches) } alias dcc_complete { @:word_frag = [$*] @:dcc_cmds = [chat close closeall get list raw rename resume send] @:frag_matches = pattern($word_frag% $dcc_cmds) @replace_fragment($@word_frag $frag_matches) } alias file_complete { @:word_frag = [$*] @:frag_matches = glob("$word_frag*") @replace_fragment($@word_frag $frag_matches) if (#frag_matches == 1) { @:stat_ret = stat($frag_matches) if (left(1 $word(2 $stat_ret)) == 4) { parsekey backspace if (word_fragq) { parsekey backward_character } } } } alias nick_complete { @:word_frag = [$*] @:frag_matches = pattern("$word_frag*" $onchannel()) if (frag_matches == []) { ^local nick_list fe ($remw($C $mychannels())) channel { @push(nick_list $onchannel($channel)) } @:nick_list = uniq($nick_list) @:frag_matches = pattern($word_frag% $nick_list) } @replace_fragment($@word_frag $frag_matches) if (#L == 1 && #frag_matches == 1) { parsekey backspace } } alias add_nickname { @:nick_items = numitems(nick_hist) @:prev_oc = finditem(nick_hist $0) if (prev_oc > -1) { @delitem(nick_hist $prev_oc) @:nick_items-- } if (nick_items > 9) { @delitem(nick_hist 0) @:nick_items-- } @setitem(nick_hist $nick_items $0) @nick_index = nick_items } alias msg_cycle { @:nick_items = numitems(nick_hist) if (!(nick_items)) { return } parsekey erase_line xtype -l /msg $getitem(nick_hist $nick_index)$chr(32) @nick_index = nick_index == 0 ? nick_items - 1 : nick_index - 1 } on #^dcc_chat 10 "*" { @add_nickname(=$0) } on #^dcc_connect 10 "% CHAT *" { @add_nickname(=$0) } on #^msg 10 "*" { @add_nickname($0) } on #^send_dcc_chat 10 "*" { @add_nickname(=$0) } on #^send_msg 10 "*" { @add_nickname($0) }