From 6089405e6e453169f097c8a8338ff107c955dbcf Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Sat, 12 Sep 2015 19:29:45 +0000 Subject: irssi! --- .irssi/default.theme | 294 ++++++++++++++ .irssi/scripts/autobleh.pl | 732 +++++++++++++++++++++++++++++++++++ .irssi/scripts/autorun/hilightwin.pl | 59 +++ .irssi/scripts/autorun/tmux_away.pl | 182 +++++++++ .irssi/scripts/autorun/trackbar.pl | 408 +++++++++++++++++++ 5 files changed, 1675 insertions(+) create mode 100644 .irssi/default.theme create mode 100644 .irssi/scripts/autobleh.pl create mode 100644 .irssi/scripts/autorun/hilightwin.pl create mode 100644 .irssi/scripts/autorun/tmux_away.pl create mode 100644 .irssi/scripts/autorun/trackbar.pl (limited to '.irssi') diff --git a/.irssi/default.theme b/.irssi/default.theme new file mode 100644 index 00000000..ac99356a --- /dev/null +++ b/.irssi/default.theme @@ -0,0 +1,294 @@ +# 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. "msgownnick" specifies the styling of the + # nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the + # whole line. + + # Example1: You want the message text to be green: + # ownmsgnick = "{msgnick $0 $1-}%g"; + # Example2.1: You want < and > chars to be yellow: + # ownmsgnick = "%Y{msgnick $0 $1-%Y}%n"; + # (you'll also have to remove <> from replaces list above) + # Example2.2: But you still want to keep <> grey for other messages: + # pubmsgnick = "%K{msgnick $0 $1-%K}%n"; + # pubmsgmenick = "%K{msgnick $0 $1-%K}%n"; + # pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n"; + # ownprivmsgnick = "%K{msgnick $*%K}%n"; + # privmsgnick = "%K{msgnick %R$*%K}%n"; + + # $0 = nick mode, $1 = nick + ownmsgnick = "{msgnick $0 $1-}"; + 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"; + + # 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-item already puts + # space there,so we don't use anything by default. + sbstart = ""; + # text at the end of statusbars. Use space so that it's never + # used for anything. + sbend = " "; + + topicsbstart = "{sbstart $*}"; + topicsbend = "{sbend $*}"; + + prompt = "[$*] "; + + 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"; +}; diff --git a/.irssi/scripts/autobleh.pl b/.irssi/scripts/autobleh.pl new file mode 100644 index 00000000..cfca1711 --- /dev/null +++ b/.irssi/scripts/autobleh.pl @@ -0,0 +1,732 @@ +use Irssi; +use Irssi::Irc; +use strict; +use vars qw( $VERSION %IRSSI $DEBUG ); +use LWP::Simple; + +# +# autobleh is an irssi helper script for IRC Channel OPs +# and IRC Network Staff. +# +# Version: +# $Id: autobleh.pl 33 2012-01-19 14:52:21Z sysdef $ +# +# Contact: +# email: sysdef@projectnet.org +# project website: http://autobleh.projectnet.org/ +# support channel: irc://chat.freenode.net/#autobleh +# repository: https://guest:guest@svn.projectnet.org/svn/autobleh/ +# +# This script is licensed under GPL Version 3 +# License - http://www.gnu.org/licenses/gpl.html +# +# Please send all your thanks, money, donations, coffee, code, suggestions, +# fixes and patches or hardware to the projects main contact but please +# write an email first. +# +# Sometimes it's possible to directly send gifts to the developer who needs +# the part you want to give away so we can save additional shipment fees. +# +# You will find your thanks and contributions in-kind listed on the project +# website and details on how it was shared and helped our development or +# developers. +# + +$VERSION = q$Rev: 33 $; +%IRSSI = ( + authors => 'Juergen (sysdef) Heine, Tom (tomaw) Wesley, Nathan (nhandler) Handler. Based on auto_bleh.pl by Don Armstrong', + name => 'autobleh', + description => 'Provides /ak /aq /ab /abr /abrn /arn /amb /amr /at /op /topicset /modeset /af', + license => 'GPL3', + changed => q$Id: autobleh.pl 33 2012-01-19 14:52:21Z sysdef $, +); + +# CHANGELOG +# 2012-01-19 - sysdef - renamed example config file; fixed comment char(;) in config ini file +# 2011-02-02 - nhandler - Allow using $nick and $channel in bleh_remove_message +# 2010-12-13 - nhandler - Remove extra space to fix kick command (Thanks rww) +# 2010-12-04 - nhandler - Change bleh_at_stay_opped from 10 to 300 seconds (5 minutes) +# 2010-07-24 - nhandler - Don't hardcode the path to the irssi directory +# 2010-07-23 - nhandler - Add check for updates and bleh_updates setting +# 2010-07-23 - nhandler - Use new ban forward syntax +# 2010-07-23 - nhandler - Turn $DEBUG insto a setting, bleh_debug +# 2010-07-23 - nhandler - Update quiet/ban exceptions +# 2010-07-23 - nhandler - Fix TIMEOUT default to really be 10 minutes +# 2010-07-23 - nhandler - add '/help autobleh' command +# ????-??-?? - tomaw - add irssi setting bleh_deop_after_action +# 2008-01-08 - sysdef - add irssi setting bleh_remove_message +# 2008-01-08 - sysdef - add command op +# 2008-01-08 - sysdef - add command topicset +# 2008-01-08 - sysdef - add command modeset +# 2008-01-22 - sysdef - solve the 'Unable to find nick: CHANSERV' error +# 2008-01-22 - sysdef - add aliases /remove +# 2008-01-25 - sysdef - add command af (auto forward / forward ban) + +# read the config file +open ( CONF, Irssi::get_irssi_dir()."/autobleh.conf" ) or Irssi::print( "warning: '".Irssi::get_irssi_dir()."/autobleh.conf' doesn't exist. Note there is 'autobleh.conf.example'."); +Irssi::print("loading autobleh config ..."); +my $category; +my $config; +my $val; +my $key; +my $linecount; +foreach my $line ( ) { + chomp $line; + $linecount++; + # filter empty lines + if ( $line =~ /^\s*$/ ) { + # Irssi::print("empty: $line"); + } + # new category + elsif ( $line =~ /^\[/ ) { + $line =~ /\[(.*)\]/; + $category = $1; + Irssi::print("category: $category"); + } + # filter comments + elsif ( $line =~ /^;\s+/ ) { + # Irssi::print("comment: $line"); + } + # get key/value pair + elsif ( $line =~ /^([^ ]+)\s*=\s*([^ ]+)$/ && $category ) { + Irssi::print( "by config.$linecount: $category '$1' => '$2'" ); + $config->{$category}{$1} = $2; + } + # crap line + else { + Irssi::print( "PLEASE FIX YOUR CONFIG, LINE $linecount: '$line'" ); + } +} +close CONF; + +# unless defined $DEBUG; +Irssi::settings_add_bool( $IRSSI{name}, 'bleh_debug', 1 ); +$DEBUG = Irssi::settings_get_bool( 'bleh_debug' ); + +# Check for updates by default +Irssi::settings_add_bool( $IRSSI{name}, 'bleh_updates', 1 ), +check_updates(); + +my ( $actions, %defaults ); + +%defaults = ( + GET_OP => 1, # Should we try to get opped when we bleh? + USE_CHANSERV => 1, # Should we use chanserv to get opped? + EXPIRE => 6000, # Do not try to do anything if the action is more than 6000 seconds old. + TIMEOUT => 600, # Timeout /at bans after 600 seconds (10 minutes) + DEOP => 1, # We want to deop after action +); + +my %command_bindings = ( + + op => 'cmd_op', + + ams => 'cmd_modeset', + modeset => 'cmd_modeset', + + ats => 'cmd_topicset', + topicset => 'cmd_topicset', + + af => 'cmd_af', + forward => 'cmd_af', + + ak => 'cmd_ak', + kick => 'cmd_ak', + + ab => 'cmd_ab', + ban => 'cmd_ab', + + aq => 'cmd_aq', + quit => 'cmd_aq', + + ar => 'cmd_ar', + remove => 'cmd_ar', + + abr => 'cmd_abr', + removeban => 'cmd_abr', + + abk => 'cmd_abk', + kickban => 'cmd_abk', + + abrn => 'cmd_abrn', + removeban_notice => 'cmd_abrn', + + abkn => 'cmd_abkn', + kickban_notice => 'cmd_abkn', + + arn => 'cmd_arn', + remove_notice => 'cmd_arn', + + amb => 'cmd_amb', + massban => 'cmd_amb', + + amr => 'cmd_amr', + massremove => 'cmd_amr', + + at => 'cmd_at', + quiet_temp => 'cmd_at', + + help => 'cmd_help', + +); + +my %bans_to_remove; + + +sub cmd_help{ + my ( $data, $server, $witem ) = @_; + if( $data =~ m/^autobleh$/i ) { + Irssi::print( "/op: Ops teh user given as argument, e.g. /op bofh" ); + Irssi::print( "/ams, /modeset: Sets any mode you want. This is useful for removing bans, e.g. /modeset -b *!*\@trollhost" ); + Irssi::print( "/ats, /topicset: Sets the topic, e.g. /topicset no trolls allowed in here" ); + Irssi::print( "/af, /forward: Sets a forward ban if defined in the config file, e.g. /af sometroll" ); + Irssi::print( "/ak, /kick: Kicks a user, e.g. /ak sometroll" ); + Irssi::print( "/ab, /ban: Sets up a ban on a user's host: /ab sometroll." ); + Irssi::print( "/aq, /quiet: Quiets a user e.g. /aq sometroll" ); + Irssi::print( "/ar, /remove: Remove a user" ); + Irssi::print( "/abr, /removeban: Bans and removes a user from a channel." ); + Irssi::print( "/abk, /kickban: Kickban a user" ); + Irssi::print( "/abrn, /removeban_notice: Bans, removes and sends the user a notice" ); + Irssi::print( "/arn, /remove_notice: Removes the user and sends a notice" ); + Irssi::print( "/amb, /massban: Bans more than one user with one command, e.g. /amb sometroll sometroll2" ); + Irssi::print( "/amr, /massremove: Removes more than one user with one command, e.g. /amr sometroll sometroll2" ); + Irssi::print( "/at, /quiet_temp: Quiets a user for 10 minutes." ); + } +} + + +sub cmd_op{ + my ( $data, $server, $witem ) = @_; + # return get_op($data,$server,$witem); + return do_bleh( 'op', $data, $server, $witem ); +} + + +sub cmd_modeset{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'modeset', $data, $server, $witem ); +} + + +sub cmd_topicset{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'topicset', $data, $server, $witem ); +} + + +sub cmd_at{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'timeout', $data, $server, $witem ); +} + + +sub cmd_ak{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'kick', $data, $server, $witem ); +} + + +sub cmd_af{ + my ( $data, $server, $witem ) = @_; + + if ( defined $config->{forwardban}{$witem->{name}} ) { + # channel -> $config->{forwardban}{ $witem->{name}} + my $targetchannel = $witem; + my $channel = $server->channel_find( $config->{forwardban}{$witem->{name}} ); + if (!$channel) { + Irssi::print( "Error: i'm not in channel " . $config->{forwardban}{$witem->{name}} . " right now." ); + return; + } + # TODO: Check if channel is +i and not +Q + do_bleh( 'modeset', "+I " . $data, $server, $channel ); + return do_bleh( 'forward, kick', $data, $server, $witem ); + } + else { + Irssi::print( 'Error: forward channel for ' . $witem->{name} .' was not set. Please edit section [forwardban] in ~/.irssi/autobleh.conf'); + } +} + + +sub cmd_abk{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'kick,ban', $data, $server, $witem ); +} + + +sub cmd_abkn{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'kick,ban,notice', $data, $server, $witem ); +} + + +sub cmd_amb{ + my ( $data, $server, $witem ) = @_; + my @nicks = split /\s+/, $data; + for ( @nicks ) { + next unless /\w/; + do_bleh( 'ban', $_, $server, $witem ); + } +} + + +sub cmd_ab{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'ban', $data, $server, $witem ); +} + + +sub cmd_aq{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'quiet', $data, $server, $witem ); +} + + +sub cmd_amr{ + my ( $data, $server, $witem ) = @_; + my @nicks = split /\s+/, $data; + for ( @nicks ) { + next unless /\w/; + do_bleh( 'remove', $_, $server, $witem ); + } +} + + +sub cmd_ar{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'remove', $data, $server, $witem ); +} + + +sub cmd_abr{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'remove,ban', $data, $server, $witem ); +} + + +sub cmd_abrn{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'remove,ban,notice', $data, $server, $witem ); +} + + +sub cmd_arn{ + my ( $data, $server, $witem ) = @_; + return do_bleh( 'remove,notice', $data, $server, $witem ); +} + + +sub do_bleh{ + my ( $cmd, $data, $server, $witem, $duration ) = @_; + + if ( !$server || !$server->{connected} ) { + Irssi::print( 'Not connected to server' ); + return; + } + + # fix the error: "Can't use string ("0") as a HASH ref while "strict refs" in use at..." + if ( $witem eq 0 ) { + Irssi::print( 'Can\'t autokick on a non-channel.' ); + return; + } + + if ( $witem->{type} ne 'CHANNEL' ) { + Irssi::print( 'Can\'t autokick on a non-channel. [' . $witem->{type} . ']' ); + return; + } + + # set the network that we're on, the channel and the nick to kick + # once we've been opped + $data =~ /^\s*([^\s]+)\s*(\d+)?\s*(.+?|)\s*$/; + my $nick = $1; + my $timeout = $2; + my $reason = $3; + $timeout = $defaults{TIMEOUT} if not defined $timeout or $timeout eq ''; + + if ( $cmd =~ /^(topicset|modeset)$/ ) { + $reason = $nick . ' ' . $reason; + $nick = "CHANSERV"; + } + else { + $reason = Irssi::settings_get_str( 'bleh_remove_message' ) if not defined $reason or $reason eq ''; + } + + $reason =~ s/\$nick/$nick/g; + $reason =~ s/\$channel/$witem->{name}/g; + + my $nick_rec = $witem->nick_find( $nick ); + if ( $nick ne 'CHANSERV' ) { + if ( not defined $nick_rec ) { + Irssi::print( 'Unable to find nick: ' . $nick); + return; + } + } + + my $hostname = $nick_rec->{host} if defined $nick_rec; + if ( $nick ne 'CHANSERV' ) { + Irssi::print( 'Unable to find hostname for ' . $nick ) if not defined $hostname or $hostname eq ''; + } + my $username = $hostname; + $hostname =~ s/.+\@//; + $username =~ s/@.*//; + $username =~ s/.*=//; + + Irssi::print( 'Nick set to \'' . $nick . '\' from \'' . $data . '\', reason set to \'' . $reason . '\'.' ) if $DEBUG; + + my $action = { + type => $cmd, + nick => $nick, + nick_rec => $nick_rec, + network => $witem->{server}->{chatnet}, + server => $witem->{server}, + completed => 0, + inserted => time, + channel => $witem->{name}, + reason => $reason, + hostname => $hostname, + username => $username, + timeout => $timeout, + }; + + Irssi::print( i_want( $action ) ) if $DEBUG; + + if ( $witem->{chanop} ) { + Irssi::print( 'DEBUG: take action ' . $action ) if $DEBUG; + take_action( $action, $server, $witem ); + } + else { + Irssi::print( 'DEBUG: try to get op in ' . $action->{channel} ) if $DEBUG; + $actions->{$data . $action->{inserted}}=$action; + get_op( $server, $action->{channel} ) if $defaults{GET_OP}; + } + +} + + +sub get_op{ + my ( $server,$channel) = @_; + Irssi::print("QUOTE CS op $channel") if $DEBUG; + $server->command("QUOTE CS op $channel") if $defaults{USE_CHANSERV}; +} + + +sub i_want{ + my $action = shift; + return 'I\'ve wanted to ' + . $action->{type} . ' ' + . $action->{nick} . ' in ' + . $action->{channel} . ' on ' + . $action->{network} . ' since ' + . $action->{inserted}; +} + + +sub take_action { + my ( $action, $server, $channel ) = @_; + + local $_ = $action->{type}; + # Now support multiple actions against a single nick (to FE, kick ban, or remove ban). See /abr foo + + if ( /op/ ) { + Irssi::print( 'Give OP only' ) if $DEBUG; + %defaults->{DEOP} = 0; + } + + if ( /modeset/ ) { + Irssi::print( 'Setmode on ' . $action->{channel} ) if $DEBUG; + # Set channel mode + $channel->command( '/mode ' . $action->{reason} ); + } + + if ( /topicset/ ) { + Irssi::print( 'Settopic on ' . $action->{channel} ) if $DEBUG; + # Set topic + $channel->command( '/topic ' . $action->{reason} ); + # we have to deop us here becaue we receive no modechange + if ( Irssi::settings_get_bool( 'bleh_deop_after_action' ) ) { + Irssi::print( 'MODE ' . $channel->{name} . ' -o ' . $channel->{ownnick}->{nick} ) if $DEBUG; + $channel->command( '/deop ' . $channel->{ownnick}->{nick} ); + } + } + + if ( /timeout/ ) { + if ( $action->{hostname} =~ /(gateway\/shell\/.+\/)x-.+/ || $action->{hostname} =~ /((?:conference|nat)\/.+\/)x-.+/ ) { + Irssi::print( 'Quieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with username ' + . $action->{username} . ' for ' + . $action->{timeout} . ' seconds') if $DEBUG; + #quiet username + $channel->command( '/quote MODE ' . $action->{channel} . ' +q *!' . $action->{username} . '@' . $1 . '*' ) + if $action->{username} ne ''; + } + else { + Irssi::print( 'Quieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with hostname ' + . $action->{hostname} . ' for ' + . $action->{timeout} . ' seconds' ) if $DEBUG; + #quiet hostname + $channel->command( '/quote MODE ' . $action->{channel} . ' +q *!*@' . $action->{hostname} ) + if $action->{hostname} ne ''; + } + $bans_to_remove{"$action->{nick}$action->{inserted}"} = $action; + # don't deop on a short time + if ( $action->{timeout} < Irssi::settings_get_str( 'bleh_at_stay_opped' ) ) { + Irssi::print( 'I\'ll stay opped until unquiet because ' . $action->{timeout} . ' < ' . Irssi::settings_get_str( 'bleh_at_stay_opped' ) ) if $DEBUG; + %defaults->{DEOP} = 0; + } + else { + Irssi::print( 'I\'ll NOT stay opped until unquiet because ' . $action->{timeout} . ' < ' . Irssi::settings_get_str( 'bleh_at_stay_opped' ) ) if $DEBUG; + } + } + + if ( /quiet/ ) { + if ( $action->{hostname} =~ /(gateway\/shell\/.+\/)x-.+/ || $action->{hostname} =~ /((?:conference|nat)\/.+\/)x-.+/ ) { + Irssi::print( 'Quieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with username ' + . $action->{username} ) if $DEBUG; + # Find hostname and quiet username + $channel->command( '/quote MODE ' . $action->{channel} . ' +q *!' . $action->{username} . '@' . $1 . '*' ) + if $action->{username} ne ''; + } + else { + Irssi::print( 'Quieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with hostname ' + . $action->{hostname} ) if $DEBUG; + # Find hostname and quiet hostname + $channel->command( '/quote MODE ' . $action->{channel} . ' +q *!*@' . $action->{hostname} ) + if $action->{hostname} ne ''; + } + } + + if ( /ban/ ) { + if ( $action->{hostname} =~ /(gateway\/shell\/.+\/)x-.+/ || $action->{hostname} =~ /((?:conference|nat)\/.+\/)x-.+/ ) { + Irssi::print( 'Banning ' + . $action->{nick} . ' from ' + . $action->{channel} . ' with username ' + . $action->{username} ) if $DEBUG; + # ban username + $channel->command( '/quote MODE ' . $action->{channel} . ' +b *!' . $action->{username} . '@' . $1 . '*' ) + if $action->{username} ne ''; + } + else { + Irssi::print( 'Banning ' + . $action->{nick}. ' from ' + . $action->{channel} . ' with hostname ' + . $action->{hostname} ) if $DEBUG; + # ban hostname + $channel->command( '/quote MODE ' . $action->{channel} . ' +b *!*@' . $action->{hostname} ) + if $action->{hostname} ne ''; + } + } + + if ( /set_invite/ ) { + Irssi::print( 'Set +I for ' + . $action->{nick} . ' in ' + . $action->{channel} . ' with hostname ' + . $action->{hostname} ) if $DEBUG; + $channel->command( '/quote MODE ' . $action->{channel} . ' +I ' . $action->{nick} . '!*@' . $action->{hostname} ) + if $action->{hostname} ne ''; + } + + + if ( /forward/ ) { + if ( defined $config->{forwardban}{$action->{channel}} ) { + my $fwchan = $config->{forwardban}{$action->{channel}}; + Irssi::print( 'Forward ' + . $action->{nick} . ' from ' + . $action->{channel} . ' to ' + . $fwchan . ' with hostname ' + . $action->{hostname} ) if $DEBUG; + # ban hostname + $channel->command( '/quote MODE ' . $action->{channel} . ' +b ' . $action->{nick} . '!*@' . $action->{hostname} . '$' . ${fwchan} ) + if $action->{hostname} ne ''; + + # # invite user to fwchan + # Irssi::print("INVITE user to $fwchan") if $DEBUG; + # $channel->command("/quote invite $action->{nick} $fwchan"); + + # notice user + $channel->command( '/NOTICE ' + . $action->{nick} . ' You got a FORWARD BAN from ' + . $action->{channel} . ' to ' + . $fwchan . '. Please rejoin channel ' + . $action->{channel} ); + } + else { + Irssi::print( 'ATTENTION: add line \'' . $action->{channel} . ' \' to [forwardban] section in ./irssi/autobleh.conf' ); + return; + } + } + + if ( /kick/) { + Irssi::print( 'Kicking ' + . $action->{nick} . ' from ' + . $action->{channel} ) if $DEBUG; + #wtf? -> if ($action->{reason} =~ /\s/) { + $channel->command( '/quote KICK ' . $action->{channel} . ' ' . $action->{nick} . ' :' . $action->{reason} ); + #} + #else { + # $channel->command("/quote REMOVE $action->{channel} $action->{nick} $action->{reason}"); + #} + } + + if ( /remove/ ) { + Irssi::print( 'Removing ' + . $action->{nick} . ' from ' + . $action->{channel} ) if $DEBUG; + if ( $action->{reason} =~ /\s/ ) { + $channel->command( '/quote REMOVE ' . $action->{channel} . ' ' . $action->{nick} . ' :' . $action->{reason} ); + } else { + $channel->command( '/quote REMOVE ' . $action->{channel} . ' ' . $action->{nick} . ' ' . $action->{reason}); + } + } + + if ( /notice/ ) { + Irssi::print( 'Noticing ' + . $action->{nick} . ' with ' + . $action->{reason} ) if $DEBUG; + $channel->command( '/NOTICE ' . $action->{nick} . ' ' . $action->{reason} ); + } + + if ( /teiuq/ ) { + if ( $action->{hostname} =~ /(gateway\/shell\/.+\/)x-.+/ || $action->{hostname} =~ /((?:conference|nat)\/.+\/)x-.+/ ) { + Irssi::print( 'Unquieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with username ' + . $action->{username} ) if $DEBUG; + $channel->command( '/quote MODE ' . $action->{channel} . ' -q *!' . $action->{username} . '@' . $1 . '*' ); + } + else { + Irssi::print( 'Unquieting ' + . $action->{nick} . ' on ' + . $action->{channel} . ' with hostname ' + . $action->{hostname} ) if $DEBUG; + $channel->command("/quote MODE $action->{channel} -q *!*@".$action->{hostname}); + } + } + return; #for now. +} + + +sub deop_us{ + my ($rec) = @_; + my $channel = $rec->{channel}; + my $server = $rec->{server}; + + Irssi::print( 'MODE ' . $channel->{name} . ' -o ' . $channel->{ownnick}->{nick} ) if $DEBUG; + $channel->command( '/deop ' . $channel->{ownnick}->{nick} ); +} + + +sub sig_mode_change{ + my ( $channel, $nick ) = @_; + + # Are there any actions to process? + # See if we got opped. + return if scalar( keys %$actions ) eq 0; + + my @deop_array; + if ( $channel->{server}->{nick} eq $nick->{nick} and $nick->{op} ) { + Irssi::print( 'We\'ve been opped' ) if $DEBUG; + foreach ( keys %$actions ) { + # See if this action is too old + if ( time - $actions->{$_}->{inserted} > $defaults{EXPIRE} ) { + Irssi::print( 'Expiring action: "' . i_want( $actions->{$_} ) . '" because of timeout' ) if $DEBUG; + delete $actions->{$_}; + next; + } + Irssi::print( i_want( $actions->{$_} ) ) if $DEBUG; + # Find the server to take action on + my $server = $actions->{$_}->{server}; + Irssi::print( 'Unable to find server for chatnet: ' . $actions->{$_}->{network} ) and return if not defined $server; + Irssi::print( 'Found server for chatnet: ' . $actions->{$_}->{network} ) if $DEBUG; + # Find the channel to take action on + my $channel = $server->channel_find( $actions->{$_}->{channel} ); + Irssi::print( 'Unable to find channel for channel: ' . $actions->{$_}->{channel} ) and return if not defined $channel; + Irssi::print( 'Found channel for channel: ' . $actions->{$_}->{channel} ) if $DEBUG; + Irssi::print( 'We are opped on the channel!' ) if $DEBUG; + take_action( $actions->{$_}, $server, $channel ); + if ( Irssi::settings_get_bool( 'bleh_deop_after_action' ) and %defaults->{DEOP} eq 1 ) { + push @deop_array, {server=>$server,channel=>$channel}; + } + %defaults->{DEOP} = 1; + # Do not repeat this action. + delete $actions->{$_}; + } + foreach ( @deop_array ) { + deop_us( $_ ); + } + } else { + Irssi::print( 'Fooey. Not opped.' ) if $DEBUG; + } +} + + +sub try_to_remove_bans{ + return unless keys %bans_to_remove; + for my $key ( keys %bans_to_remove ) { + if ( ( $bans_to_remove{$key}{inserted} + $bans_to_remove{$key}{timeout} ) < time ) { + $bans_to_remove{$key}{type} = 'teiuq'; + $actions->{$key} = $bans_to_remove{$key}; + delete $bans_to_remove{$key}; + + # TODO: only try to get op if we're not opped + # if ($witem->{chanop}) { + # Irssi::print("DEBUG: take action $action") if $DEBUG; + # take_action($action,$server,$witem); + # } + # else { + # Irssi::print("DEBUG: try to get op in $action->{channel}") if $DEBUG; + # $actions->{$data.$action->{inserted}}=$action; + # get_op($server, $action->{channel}) if $defaults{GET_OP}; + # } + + get_op( $actions->{$key}{server}, $actions->{$key}{channel} ) if $defaults{GET_OP}; + } + } +} + + +sub check_updates{ + return unless Irssi::settings_get_bool( 'bleh_updates' ); + my $url = 'http://autobleh.projectnet.org/version'; + my $latest = get( $url ); + chomp $latest; + my( $current ) = $VERSION =~ m/(\d+)/; + $current = sprintf( "%4.2f", $current / 100 ); + if( defined $latest ) { + if( $latest > $current ) { + Irssi::print( 'A new version of autobleh (' . $latest . ') is available at http://autobleh.projectnet.org/downloads/autobleh-' . $latest . '.tar.gz' ); + Irssi::print( 'autobleh ' . $current . ' is currently installed.' ); + } + else { + Irssi::print( 'autobleh (' . $current . ') is up-to-date.' ); + } + } + else { + Irssi::print( 'Failed to check for updates to autobleh.' ); + } +} + + +# call the try to remove bans function every minute +Irssi::timeout_add( 1000 * 5, 'try_to_remove_bans', undef ); +Irssi::signal_add_last( 'nick mode changed', 'sig_mode_change' ); +my ( $command, $function ); + +while ( ( $command, $function ) = each %command_bindings ) { + Irssi::command_bind( $command, $function, 'bleh' ); +} + +Irssi::settings_add_bool( $IRSSI{name}, 'bleh_deop_after_action', 1 ); +Irssi::settings_add_str( $IRSSI{name}, 'bleh_remove_message', 'you should know better' ); +Irssi::settings_add_str( $IRSSI{name}, 'bleh_at_stay_opped', 300 ); # 5 minutes + +# find text for antispam +#Irssi::signal_add_last( "message public", "msg_public" ); + +1; + diff --git a/.irssi/scripts/autorun/hilightwin.pl b/.irssi/scripts/autorun/hilightwin.pl new file mode 100644 index 00000000..d735e1b7 --- /dev/null +++ b/.irssi/scripts/autorun/hilightwin.pl @@ -0,0 +1,59 @@ +# +# Print hilighted messages & private messages to window named "hilight" for +# irssi 0.7.99 by Timo Sirainen +# +# Modded a tiny bit by znx to stop private messages entering the hilighted +# window (can be toggled) and to put up a timestamp. +# + +use strict; +use Irssi; +use POSIX; +use vars qw($VERSION %IRSSI); + +$VERSION = "0.03"; +%IRSSI = ( + authors => "Timo \'cras\' Sirainen, Mark \'znx\' Sangster", + contact => "tss\@iki.fi, znxster\@gmail.com", + name => "hilightwin", + description => "Print hilighted messages to window named \"hilight\"", + license => "Public Domain", + url => "http://irssi.org/", + changed => "Sun May 25 18:59:57 BST 2008" +); + +sub sig_printtext { + my ($dest, $text, $stripped) = @_; + + my $opt = MSGLEVEL_HILIGHT; + + if(Irssi::settings_get_bool('hilightwin_showprivmsg')) { + $opt = MSGLEVEL_HILIGHT|MSGLEVEL_MSGS; + } + + if( + ($dest->{level} & ($opt)) && + ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0 + ) { + my $window = Irssi::window_find_name('hilight'); + + if ($dest->{level} & MSGLEVEL_PUBLIC) { + $text = $dest->{target}.": ".$text; + } + $text = strftime( + Irssi::settings_get_str('timestamp_format')." ", + localtime + ).$text; + $text =~ s/%/%%/g; + $window->print($text, MSGLEVEL_NEVER) if ($window); + } +} + +my $window = Irssi::window_find_name('hilight'); +Irssi::print("Create a window named 'hilight'") if (!$window); + +Irssi::settings_add_bool('hilightwin','hilightwin_showprivmsg',1); + +Irssi::signal_add('print text', 'sig_printtext'); + +# vim:set ts=4 sw=4 et: diff --git a/.irssi/scripts/autorun/tmux_away.pl b/.irssi/scripts/autorun/tmux_away.pl new file mode 100644 index 00000000..f0f0cce2 --- /dev/null +++ b/.irssi/scripts/autorun/tmux_away.pl @@ -0,0 +1,182 @@ +use Irssi; +use strict; +use FileHandle; + +use vars qw($VERSION %IRSSI); + +$VERSION = "2.0"; +%IRSSI = ( + authors => 'John C. Vernaleo', + contact => 'john@netpurgatory.com', + name => 'tmux_away', + description => 'set (un)away if tmux session is attached/detached', + license => 'GPL v2', + url => 'http://www.netpurgatory.com/tmux_away.html', +); + +# tmux_away irssi module +# +# Written by Colin Didier and heavily based on +# screen_away irssi module version 0.9.7.1 written by Andreas 'ads' Scherbaum +# . +# +# Updated by John C. Vernaleo 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 +# +# there are 5 settings available: +# +# /set tmux_away_active ON/OFF/TOGGLE +# /set tmux_away_repeat +# /set tmux_away_message +# /set tmux_away_window +# /set tmux_away_nick +# +# 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 +# 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}); + +# Get session name. Must be connected for this to work, but since this either +# happens at startup or based on user command, should be okay. +my $tmux_session = `tmux display-message -p '#S'`; +chomp($tmux_session); + +# register config variables +Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1); +Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5); +Irssi::settings_add_str('misc', $IRSSI{'name'} . '_message', "not here..."); +Irssi::settings_add_str('misc', $IRSSI{'name'} . '_window', "1"); +Irssi::settings_add_str('misc', $IRSSI{'name'} . '_nick', ""); + + +# check, set or reset the away status +sub tmux_away { + 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 + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', + "activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds)"); + $away_status = 2; + } + + # get actual tmux session status + @res = `tmux list-clients -t $tmux_session`; + if (@res[0] =~ /^failed to connect to server/) { + Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'tmux_away_crap', + "error getting tmux session status."); + return; + } + $status = 1; # away, assumes the session is detached + if ($#res != -1) { + $status = 2; # unaway + } + + # unaway -> away + if ($status == 1 and $away_status != 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) { + # 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; + } + } + # 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 { + if (defined($timer_name)) { + Irssi::timeout_remove($timer_name); + } + # add new timer with new timeout (maybe the timeout has been changed) + $timer_name = Irssi::timeout_add(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'tmux_away', ''); +} + +# init process +tmux_away(); diff --git a/.irssi/scripts/autorun/trackbar.pl b/.irssi/scripts/autorun/trackbar.pl new file mode 100644 index 00000000..ee660910 --- /dev/null +++ b/.irssi/scripts/autorun/trackbar.pl @@ -0,0 +1,408 @@ +# trackbar.pl +# +# Track what you read last when switching to a window. +# +# Copyright (C) 2003 Peter Leurs +# +# 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# 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. +# +# Usage: +# +# The script works right out of the box, but if you want you can change +# the working by /set'ing the following variables: +# +# trackbar_string The characters to repeat to draw the bar +# "---" => U+2500 => a line +# "===" => U+2550 => a double line +# "___" => U+2501 => a wide line +# "# #" => U+25ad.U+0020 => a white rectangle and a space +# trackbar_style The style for the bar, %r is red for example +# See formats.txt that came with irssi +# trackbar_hide_windows Comma seperated list of window names where the +# trackbar should not be drawn. +# trackbar_timestamp Prints a timestamp at the start of the bar +# trackbar_timestamp_styled When enabled, the timestamp respects +# trackbar_style +# +# /tb or /tb scroll is a command that will scroll to trackbar. +# +# /tb mark is a command that will redraw the line at the bottom. However! +# This requires irssi version after 20021228. otherwise you'll get the +# error redraw: unknown command, and your screen is all goofed up :) +# +# /upgrade & buf.pl notice: This version tries to remove the trackbars +# before the upgrade is done, so buf.pl does not restore them, as they are +# not removeable afterwards by trackbar. Unfortunately, to make this work, +# trackbar and buf.pl need to be loaded in a specific order. Please +# experiment to see which order works for you (strangely, it differs from +# configuration to configuration, something I will try to fix in a next +# version) +# +# 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: +# 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 +# +# Contacts +# https://github.com/mjholtkamp/irssi-trackbar +# +# Known bugs: +# - if you /clear a window, it will be uncleared when returning to the window +# - changing the trackbar style is only visible after returning to a window +# however, changing style/resize takes in effect after you left the window. +# +# Whishlist/todo: +# - instead of drawing a line, just invert timestamp or something, +# to save a line (but I don't think this is possible with current irssi) +# - <@coekie> kinlo: if i switch to another window, in another split window, i +# want the trackbar to go down in the previouswindow in that splitwindow :) +# - < bob_2> anyway to clear the line once the window is read? +# +# BTW: when you have feature requests, mailing a patch that works is the fastest way +# to get it added :p + +# IRSSI RESIZE BUG: +# when resizing from a larger window to a smaller one, the width of the +# trackbar causes some lines at the bottom not to be shown. This only happens +# if the trackbar was not the last line. This glitch can be 'fixed' by +# resetting the trackbar to the last line (e.g. by switching to another window +# and back) and then resize twice (e.g. to a bigger size and back). Of course, +# this is not convenient for the user. +# This script works around this problem by printing not one, but two lines and +# then removing the second line. My guess is that irssi does something to the +# previous line (or the line cache) whenever a line is 'completed' (i.e. the +# EOL is sent). When only one line is printed, it is not 'completed', but when +# printing the second line, the first line is 'completed'. The second line is +# still not completed, but since we delete it straight away, it doesn't matter. +# +# Some effects from older versions (<1.6) of trackbar.pl can still screw up your +# buffer so we recommend to restart your irssi, or do an "/upgrade". After +# installing this version of trackbar.pl + +use strict; +use 5.6.1; +use Irssi 20140701; +use Irssi::TextUI; +use POSIX qw(strftime); +use utf8; + +our $VERSION = "1.9"; + +our %IRSSI = ( + authors => "Peter 'kinlo' Leurs, Uwe Dudenhoeffer, " . + "Michiel Holtkamp, Nico R. Wohlgemuth", + contact => "irssi-trackbar\@supermind.nl", + name => "trackbar", + description => "Shows a bar where you've last read a window", + license => "GPLv2", + url => "http://github.com/mjholtkamp/irssi-trackbar/", + changed => "2015-01-15 08:00", +); + +my %config; + +my $screen_resizing = 0; # terminal is being resized + +# This could be '(status)' if you want to hide the status window +Irssi::settings_add_str('trackbar', 'trackbar_hide_windows' => ''); +$config{'trackbar_hide_windows'} = Irssi::settings_get_str('trackbar_hide_windows'); + +Irssi::settings_add_str('trackbar', 'trackbar_string' => '-'); +$config{'trackbar_string'} = Irssi::settings_get_str('trackbar_string'); + +Irssi::settings_add_str('trackbar', 'trackbar_style' => '%K'); +$config{'trackbar_style'} = Irssi::settings_get_str('trackbar_style'); + +Irssi::settings_add_bool('trackbar', 'trackbar_timestamp' => 0); +$config{'trackbar_timestamp'} = Irssi::settings_get_bool('trackbar_timestamp'); + +Irssi::settings_add_bool('trackbar', 'trackbar_timestamp_styled' => 1); +$config{'trackbar_timestamp_styled'} = Irssi::settings_get_bool('trackbar_timestamp_styled'); + +$config{'timestamp_format'} = Irssi::settings_get_str('timestamp_format'); + +Irssi::signal_add( + 'setup changed' => sub { + $config{'trackbar_string'} = Irssi::settings_get_str('trackbar_string'); + $config{'trackbar_style'} = Irssi::settings_get_str('trackbar_style'); + $config{'trackbar_hide_windows'} = Irssi::settings_get_str('trackbar_hide_windows'); + $config{'trackbar_timestamp'} = Irssi::settings_get_bool('trackbar_timestamp'); + $config{'trackbar_timestamp_styled'} = Irssi::settings_get_bool('trackbar_timestamp_styled'); + $config{'timestamp_format'} = Irssi::settings_get_str('timestamp_format'); + if ($config{'trackbar_style'} =~ /(? sub { + my (undef, $oldwindow) = @_; + + draw_bar($oldwindow); + } +); + +# handel the line creation and the removing of the old lines +sub draw_bar ($) { + (my $window) = @_; + if ($window) { + my $line = $window->view()->get_bookmark('trackbar'); + + if (defined $line) { + $window->view()->remove_line($line); + $window->view()->redraw(); + } + + my $hidden =$config{'trackbar_hide_windows'}; + my $wname =$window->{'name'}; + + if ($wname eq "" || $hidden !~ $wname) { + $window->print(line($window->{'width'}), MSGLEVEL_NEVER); + $window->view()->set_bookmark_bottom('trackbar'); + } + } +} + +# terminal resize code inspired on nicklist.pl +sub sig_terminal_resized { + if ($screen_resizing) { + # prevent multiple resize_trackbars from running + return; + } + $screen_resizing = 1; + Irssi::timeout_add_once(10,\&resize_trackbars,[]); +} + +sub resize_trackbars { + my $active_win = Irssi::active_win(); + for my $window (Irssi::windows) { + next unless defined $window; + my $line = $window->view()->get_bookmark('trackbar'); + next unless defined $line; + + # first add new trackbar line, then remove the old one. For some reason + # this works better than removing the old one, then adding a new one + $window->print_after($line, MSGLEVEL_NEVER, line($window->{'width'})); + my $next = $line->next(); + $window->view()->set_bookmark('trackbar', $next); + $window->view()->remove_line($line); + + # This hack exists to work around a bug: see IRSSI RESIZE BUG above. + # Add a line after the trackbar and delete it immediately + $window->print_after($next, MSGLEVEL_NEVER, line(1)); + $window->view()->remove_line($next->next); + } + $active_win->view()->redraw(); + $screen_resizing = 0; +} + +Irssi::signal_add('terminal resized' => \&sig_terminal_resized); + +sub line { + my $width = shift; + my $string = $config{'trackbar_string'}; + + my $tslen = 0; + + if ($config{'trackbar_timestamp'}) { + $tslen = int(1 + length $config{'timestamp_format'}); + } + + if (!defined($string) || $string eq '') { + $string = '-'; + } + + # There is a bug in (irssi's) utf-8 handling on config file settings, as you + # can reproduce/see yourself by the following code sniplet: + # + # my $quake = pack 'U*', 8364; # EUR symbol + # Irssi::settings_add_str 'temp', 'temp_foo' => $quake; + # $a= length($quake); + # # $a => 1 + # $a= length(Irssi::settings_get_str 'temp_foo'); + # # $a => 3 + # $a= utf8::is_utf8(Irssi::settings_get_str 'temp_foo'); + # # $a => false + + utf8::decode($string); + + if ($string =~ m/---/) { + $string = pack('U*', 0x2500); + } + + if ($string =~ m/===/) { + $string = pack('U*', 0x2550); + } + + if ($string =~ m/___/) { + $string = pack('U*', 0x2501); + } + + if ($string =~ m/# #/) { + $string = pack('U*', 0x25ad)." "; + } + + my $length = length $string; + + my $times = $width / $length - $tslen; + $times = int(1 + $times) if $times != int($times); + $string =~ s/%/%%/g; + + if ($tslen) { + # why $config{'timestamp_format'} won't work here? + my $ts = strftime(Irssi::settings_get_str('timestamp_format')." ", localtime); + + if ($config{'trackbar_timestamp_styled'}) { + return $config{'trackbar_style'} . $ts . substr($string x $times, 0, $width); + } else { + return $ts . $config{'trackbar_style'} . substr($string x $times, 0, $width); + } + } else { + return $config{'trackbar_style'} . substr($string x $times, 0, $width); + } +} + +# Remove trackbars on upgrade - but this doesn't really work if the scripts are not loaded in the correct order... watch out! + +Irssi::signal_add_first('session save' => sub { + for my $window (Irssi::windows) { + next unless defined $window; + my $line = $window->view()->get_bookmark('trackbar'); + $window->view()->remove_line($line) if defined $line; + } +} +); + +sub cmd_mark { + my $window = Irssi::active_win(); + + draw_bar($window); +} + + +# mark all visible windows with a line +sub cmd_mark_visual { + my $w= Irssi::active_win(); + my $refs =$w->{refnum}; + my $refa; + + cmd_mark(); + + do { + Irssi::command('window down'); + $w= Irssi::active_win(); + $refa =$w->{refnum}; + + if ($refs != $refa) { + cmd_mark(); + } + + } while ($refs != $refa) +} + +# /tb or /trackbar +sub cmd_tb { + if ($#_ >=0 ) { + my $sc = shift @_; + $sc =~ s/\s+$//; + + if ($sc eq "mark") { + cmd_mark(); + } elsif ($sc eq "help") { + cmd_help("trackbar"); + } elsif ($sc eq "vmark") { + cmd_mark_visual(); + } else { + cmd_scroll(); + } + } +} + +sub cmd_scroll { + my $window = Irssi::active_win(); + my $line = $window->view()->get_bookmark('trackbar'); + $window->view()->scroll_line($line) if defined $line; +} + +sub cmd_help { + my $help = <