diff options
| author | mh | 2015-12-10 16:24:53 +0100 |
|---|---|---|
| committer | mh | 2015-12-10 16:24:53 +0100 |
| commit | 1af0bdc429dfa4ba4554a4185a43de6b5b2a139d (patch) | |
| tree | 721846622cf05bf3927e7badefc8c69b24ecbdbc /scripts/mh_hold_mode.pl | |
| parent | 27ad9d2cb9196a8c912da635a6e81ef7a1edadd4 (diff) | |
| download | scripts.irssi.org-1af0bdc429dfa4ba4554a4185a43de6b5b2a139d.tar.bz2 | |
mh_hold_mode.pl v1.02
Emulation of ircII per-window hold_mode
known issues:
in the github version of irssi this script will not accept the keypad enter key
changes:
now accepts both 10 and 13 as keycode for enter, required to work in upcomming irssi
Diffstat (limited to 'scripts/mh_hold_mode.pl')
| -rw-r--r-- | scripts/mh_hold_mode.pl | 488 |
1 files changed, 488 insertions, 0 deletions
diff --git a/scripts/mh_hold_mode.pl b/scripts/mh_hold_mode.pl new file mode 100644 index 0000000..b6d64fd --- /dev/null +++ b/scripts/mh_hold_mode.pl @@ -0,0 +1,488 @@ +############################################################################## +# +# mh_hold_mode.pl v1.02 (20151210) +# +# Copyright (c) 2007, 2015 Michael Hansen +# +# Permission to use, copy, modify, and distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL +# THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +############################################################################## +# +# Emulation of ircII per-window hold_mode +# +# known issues: +# +# in the github version of irssi this script will not accept the +# keypad enter key +# +# upgrading from v0.xx to v1.xx: +# +# the statusbar item have changed name from mh_more to mh_sbmore, you +# can remove the old item with '/statusbar window remove mh_more' and +# follow the instructions below to add the new item +# +# instructions: +# +# add the mh_sbmore statusbar item with '/statusbar window add -after window_empty mh_sbmore' +# (For better control of the placement of mh_sbmore see '/HELP STATUSBAR' +# +# mh_sbmore *should* fully replace Irssi's standard more, so you could +# remove it with '/STATUSBAR WINDOW REMOVE more' +# +# when the script is loaded it will reset all windows and scroll them +# to the last line (without losing backlog) and from then on you will +# have to do '/HOLD_MODE ON' or '/HOLD_MODE OFF' in a given window to +# enable/disable hold_mode for it (off by default) +# +# should the buffer become too much for you to bother to read it, you +# can jump to the bottom with '/HOLD_MODE FLUSH' (although '/CLEAR' +# will do the same) +# +# when hold_mode is on, it will scroll untill the last line you said or +# command you send, then hold untill you press enter (and depending on +# the 'scroll_always' value it will either scroll on any enter, or only on +# enter with empty commandline). enter will scroll by 1 page (minus 1 line) +# unless you have moved around in the scrollback buffer with pg-up/dn, in +# which case it will scroll to where you left (except when you pg-dn to +# end of buffer, this will reset the scroll stop point to that line) +# +# (also, you can reset the point to scroll to at any time by just +# pressing enter when in "live" view, the current line will then be set +# as the scroll stop point) +# +# it is not a true-to-ircII hold_mode emulation, as some things are slightly +# different, over time they might be made optional to be able to go back +# to as close to ircII as possible. +# +# (i hope i didn't forget anything :-) +# +# history: +# v1.02 (20151210) +# now accepts both 10 and 13 as keycode for enter, required to work in upcomming irssi +# v1.01 (20151204) +# nicer (imho) mh_sbmore +# v1.00 (20151201) +# cleanup and re-release, this have been in active use since 2007 without any issues +# v0.12 (unknown 2007) +# added scroll_always option: /HOLD_MODE scroll_always [on|off|toggle] +# Defaults to always scroll on, even if the line is not empty when you +# press enter - the ircII way. If you like to only scroll on empty lines +# set '/HOLD_MODE scroll_always off' +# added '/HOLD_MODE toggle' for ircII emulation completenes +# + +use v5.14.2; + +use strict; + +############################################################################## +# +# irssi head +# +############################################################################## + +use Irssi 20100403; +use Irssi::TextUI; + +our $VERSION = '1.02'; +our %IRSSI = +( + 'name' => 'mh_hold_mode', + 'description' => 'Emulation of ircII per-window hold_mode', + 'license' => 'BSD', + 'authors' => 'Michael Hansen', + 'contact' => 'mh on IRCnet #help', + 'url' => 'https://github.com/mh-source/irssi-scripts', +); + +############################################################################## +# +# global variables +# +############################################################################## + +our $KEYCODE_ENTER1 = 10; +our $KEYCODE_ENTER2 = 13; + +our %config; +$config{'DEFAULT'}{'hold_mode'} = 0; # default: 0 +$config{'DEFAULT'}{'scroll_always'} = 0; # default: 1 + +our $lastcommand = ''; +our $more = 0; + +############################################################################## +# +# common support functions +# +############################################################################## + +sub trim_space +{ + my ($string) = @_; + + if (defined($string)) + { + $string =~ s/^\s+//g; + $string =~ s/\s+$//g; + + } else { + + $string = ''; + } + + return($string); +} + +############################################################################## +# +# script functions +# +############################################################################## + +sub config_window_get +{ + my ($windowrec) = @_; + + if (!$windowrec) + { + return(undef); + } + + my $windowid = $windowrec->{'_irssi'}; + + if (!exists($config{'WINDOW'}{$windowid})) + { + for my $setting (keys(%{$config{'DEFAULT'}})) + { + $config{'WINDOW'}{$windowid}{$setting} = $config{'DEFAULT'}{$setting}; + } + } + + return(\%{$config{'WINDOW'}{$windowid}}); +} + +sub config_window_del +{ + my ($windowrec) = @_; + + if (!$windowrec) + { + return(undef); + } + + my $windowid = $windowrec->{'_irssi'}; + + if (exists($config{'WINDOW'}{$windowid})) + { + delete($config{'WINDOW'}{$windowid}); + return(1); + } + + return(undef); +} + +sub window_bookmark_compare +{ + my ($bookmark1, $bookmark2) = @_; + + if (!$bookmark1 or !$bookmark2) + { + return(0); + } + + if ($bookmark1->{'_irssi'} == $bookmark2->{'_irssi'}) + { + return(1); + } + + return(0); +} + +sub window_refresh +{ + my $windowrec = Irssi::active_win(); + + if ($windowrec->view()->{'empty_linecount'}) + { + return; + } + + my $bookmark = $windowrec->view()->get_bookmark('mh_hold_mode'); + + if (not $bookmark) + { + $windowrec->view()->set_bookmark('mh_hold_mode', $windowrec->view()->{'startline'}); + $bookmark = $windowrec->view()->get_bookmark('mh_hold_mode'); + + if (not $bookmark) + { + return; + } + } + + $windowrec->view()->scroll_line($bookmark); + statusbar_more_redraw(); +} + +sub window_scroll +{ + my $windowrec = Irssi::active_win(); + + my $bookmark = $windowrec->view()->{'startline'}; + window_refresh(); + my $bookmark_new = $windowrec->view()->{'startline'}; + + if (window_bookmark_compare($bookmark_new, $bookmark)) + { + $windowrec->view()->scroll(($windowrec->{'height'} - 1)); + + if ($windowrec->view()->{'bottom'}) + { + $windowrec->view()->set_bookmark_bottom('mh_hold_mode'); + + } else { + + $windowrec->view()->set_bookmark('mh_hold_mode', $windowrec->view()->{'startline'}); + } + } + + statusbar_more_redraw(); +} + +sub statusbar_more_redraw +{ + Irssi::statusbar_items_redraw('mh_sbmore'); +} + +############################################################################## +# +# irssi signal handlers +# +############################################################################## + +sub signal_gui_key_pressed_first +{ + my ($keycode) = @_; + + if (($keycode == $KEYCODE_ENTER1) or ($keycode == $KEYCODE_ENTER2)) + { + $lastcommand = Irssi::parse_special('$L'); + my $windowrec = Irssi::active_win(); + + if (($lastcommand eq '' or config_window_get($windowrec)->{'scroll_always'}) and $more) + { + window_scroll(); + } + } +} + +sub signal_gui_key_pressed_last +{ + my ($keycode) = @_; + + if (($keycode == $KEYCODE_ENTER1) or ($keycode == $KEYCODE_ENTER2)) + { + my $windowrec = Irssi::active_win(); + + if (not config_window_get($windowrec)->{'hold_mode'}) + { + return; + } + + if ($windowrec->view()->{'bottom'}) + { + $windowrec->view()->set_bookmark_bottom('mh_hold_mode'); + + if ($more) + { + $windowrec->view()->scroll($more); + window_refresh(); + } + + } else { + + window_refresh(); + } + } +} + +sub signal_window_changed +{ + my ($windowrec_new, $windowrec_old) = @_; + + if (config_window_get($windowrec_new)->{'hold_mode'}) + { + window_refresh(); + } +} + +sub signal_print_text_last +{ + my ($textdest, $text, $stripped) = @_; + + my $windowrec = Irssi::active_win(); + my $window = config_window_get($windowrec); + + if ($textdest->{'window'}->{'refnum'} == $windowrec->{'refnum'} and config_window_get($windowrec)->{'hold_mode'} and $more <= $windowrec->{'height'}) + { + window_refresh(); + } +} + +############################################################################## +# +# irssi command functions +# +############################################################################## + +sub command_hold_mode +{ + my ($data, $server, $windowitem) = @_; + + my $windowrec = Irssi::active_win(); + my $window = config_window_get($windowrec); + my $showstatus = 1; + + if (defined($data)) + { + $data = trim_space($data); + + if ($data ne '') + { + + if ($data =~ m/^toggle$/i) + { + $data = (($window->{'hold_mode'}) ? 'off' : 'on' ); + + } elsif ($data =~ m/^on$/i) + { + $window->{'hold_mode'} = 1; + $windowrec->view()->set_bookmark_bottom('mh_hold_mode'); + window_refresh(); + + } elsif ($data =~ m/^off$/i) + { + $window->{'hold_mode'} = 0; + $windowrec->view()->set_bookmark_bottom('mh_hold_mode'); + window_refresh(); + + } elsif ($data =~ m/^flush$/i) + { + $showstatus = 0; + $windowrec->view()->set_bookmark_bottom('mh_hold_mode'); + window_refresh(); + + } elsif ($data =~ m/^scroll_always(.*)$/i) + { + $showstatus = 0; + + if (defined($1)) + { + $data = trim_space($1); + + if ($data =~ m/^toggle$/i) + { + $data = (($window->{'scroll_always'}) ? 'off' : 'on' ); + } + + if ($data =~ m/^on$/i) + { + $window->{'scroll_always'} = 1; + + } elsif ($data =~ m/^off$/i) + { + $window->{'scroll_always'} = 0; + } + } + + $windowrec->print('hold_mode (' . (($window->{'hold_mode'}) ? 'on' : 'off' ) . '): scroll_always is ' . (($window->{'scroll_always'}) ? 'on' : 'off' ), MSGLEVEL_CLIENTCRAP); + } + } + } + + if ($showstatus) + { + $windowrec->print('hold_mode is ' . (($window->{'hold_mode'}) ? 'on' : 'off' ), MSGLEVEL_CLIENTCRAP); + } +} + +############################################################################## +# +# statusbar item handlers +# +############################################################################## + +sub statusbar_more +{ + my ($statusbaritem, $get_size_only) = @_; + + my $window = Irssi::active_win(); + + my $local_more = 0; + + $local_more = ($window->view()->{'ypos'} - $window->view()->{'height'} + $window->view()->{'empty_linecount'} + 1); + $more = $local_more; + + if ($more) + { + $statusbaritem->default_handler($get_size_only, "{sb $more more}", '', 0); + + } else { + + $statusbaritem->default_handler($get_size_only, '', '', 0); + } +} + +############################################################################## +# +# script on load +# +############################################################################## + +Irssi::command('^SET SCROLL ON'); + +Irssi::signal_add_last('window created', 'config_window_get'); +Irssi::signal_add_last('window destroyed', 'config_window_del'); + +for my $window (Irssi::windows) +{ + $window->view()->set_scroll(1); + $window->view()->set_bookmark_bottom('mh_hold_mode'); + config_window_get($window); +} + +Irssi::statusbar_item_register('mh_sbmore', '', 'statusbar_more'); +Irssi::statusbars_recreate_items(); + +statusbar_more_redraw(); +Irssi::timeout_add(1000, 'statusbar_more_redraw', undef); + +Irssi::command('^REDRAW'); + +Irssi::signal_add_first('gui key pressed', 'signal_gui_key_pressed_first'); +Irssi::signal_add_last('gui key pressed', 'signal_gui_key_pressed_last'); +Irssi::signal_add_last('window changed', 'signal_window_changed_last'); +Irssi::signal_add_last('print text', 'signal_print_text_last'); + +Irssi::command_bind('hold_mode', 'command_hold_mode', 'mh_hold_mode'); + +1; + +############################################################################## +# +# eof mh_hold_mode.pl +# +############################################################################## |
