# 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 = <