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