summaryrefslogtreecommitdiffstats
path: root/scripts/mh_hold_mode.pl
diff options
context:
space:
mode:
authormh2015-12-10 16:24:53 +0100
committermh2015-12-10 16:24:53 +0100
commit1af0bdc429dfa4ba4554a4185a43de6b5b2a139d (patch)
tree721846622cf05bf3927e7badefc8c69b24ecbdbc /scripts/mh_hold_mode.pl
parent27ad9d2cb9196a8c912da635a6e81ef7a1edadd4 (diff)
downloadscripts.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.pl488
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
+#
+##############################################################################