diff options
Diffstat (limited to 'scripts/intercept.pl')
-rw-r--r-- | scripts/intercept.pl | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/scripts/intercept.pl b/scripts/intercept.pl new file mode 100644 index 0000000..4fef6f6 --- /dev/null +++ b/scripts/intercept.pl @@ -0,0 +1,217 @@ +# Some elements borrowed from ideas developed by shabble@freenode(https://github.com/shabble/irssi-docs/wiki ) +# +# You can change what intercept.pl considers a linestart by setting +# /set intercept_linestart to a regular expression that fits your needs. +# For most, a simple whitespace or . pattern will stop most accidental +# inputs. +# +# You can also tell which patterns should be ignored, for example +# /set intercept_exceptions s/\w+/[\w\s\d]+/ wouldn't consider +# s/word a mistyped command if it is followed by a slash, string of +# valid characters and a final slash. +# You can enter several patterns separated by a space. + +use strict; +use warnings; +use Data::Dumper; +use Carp qw( croak ); +use Irssi; +use Data::Munge 'list2re'; + +use vars qw($VERSION %IRSSI); + +$VERSION = "0.3"; +%IRSSI = ( + authors => "Jari Matilainen", + contact => 'vague!#irssi@libera.chat on irc', + name => "intercept", + description => "Intercept misprinted commands and offer to remove the first character before sending it on", + license => "Public Domain", + url => "https://irssi.org", + changed => "04 Mar 16:00:00 CET 2022", + ); + +my $active = 0; +my $permit_pending = 0; +my $pending_input = {}; +my $verbose = 0; +my $isword = 0; +my $cmdregexp = list2re map {$_->{cmd}} Irssi::commands(); + +sub script_is_loaded { + return exists($Irssi::Script::{$_[0] . '::'}); +} + +if (script_is_loaded('uberprompt')) { + app_init(); +} +else { + print "This script requires 'uberprompt.pl' in order to work. " + . "Attempting to load it now..."; + + Irssi::signal_add('script error', 'load_uberprompt_failed'); + Irssi::command("script load uberprompt.pl"); + + unless(script_is_loaded('uberprompt')) { + load_uberprompt_failed("File does not exist"); + } + app_init(); +} + +sub load_uberprompt_failed { + Irssi::signal_remove('script error', 'load_uberprompt_failed'); + + print "Script could not be loaded. Script cannot continue. " + . "Check you have uberprompt.pl installed in your scripts directory and " + . "try again. Otherwise, it can be fetched from: "; + print "https://github.com/shabble/irssi-scripts/raw/master/" + . "prompt_info/uberprompt.pl"; + + croak "Script Load Failed: " . join(" ", @_); +} + +sub sig_send_text { + my ($data, $server, $witem) = @_; + + if($permit_pending == 1) { + $pending_input = {}; + $permit_pending = 0; + Irssi::signal_continue(@_); + } + elsif($permit_pending == 2) { + my $regexp = Irssi::settings_get_str('intercept_linestart'); + $pending_input = {}; + $permit_pending = 0; + Irssi::signal_stop(); + $data =~ s/^$regexp//; + + if(ref $witem && $witem->{type} eq 'CHANNEL') { + $witem->command($data); + } + else { + $server->command($data); + } + } + elsif($permit_pending == 3) { + $pending_input = {}; + $permit_pending = 0; + $isword = 0; + Irssi::signal_stop(); + + if(ref $witem && $witem->{type} eq 'CHANNEL') { + $witem->command($data); + } + else { + $server->command($data); + } + } + else { + (my $cmdchars = Irssi::settings_get_str('cmdchars')) =~ s/(.)(.)/$1|$2/; + my @exceptions = split / /, Irssi::settings_get_str('intercept_exceptions'); + + foreach(@exceptions) { + return if($data =~ m{$_}i); + } + + my ($first) = split ' ', $data; + + my $regexp = Irssi::settings_get_str('intercept_linestart'); + $regexp =~ s/(^[\^])|([\$]$)//g; + if($data =~ /^($regexp)($cmdchars)/i) { + my $text = "You have " . ($1 eq ' '?'a space':$1) . " infront of your cmdchar '$2', is this what you wanted? [y/F/c]"; + $pending_input = { + text => $data, + server => $server, + win_item => $witem, + }; + + Irssi::signal_stop(); + require_confirmation($text); + } + elsif($data =~ /^\s*($cmdregexp)\b/i) { + my $text = "The first word, '$1', looks like a command, is this what you wanted? [y/F/c]"; + $isword = 1; + $pending_input = { + text => $data, + server => $server, + win_item => $witem, + }; + + Irssi::signal_stop(); + require_confirmation($text); + } + } +} + +sub sig_gui_keypress { + my ($key) = @_; + + return if not $active; + + my $char = chr($key); + + # we support f, F, enter for Fix. + if($char =~ m/^f?$/i) { + $permit_pending = 2 + $isword; + Irssi::signal_stop(); + Irssi::signal_emit('send text', + $pending_input->{text}, + $pending_input->{server}, + $pending_input->{win_item}); + $active = 0; + set_prompt(''); + } + elsif($char =~ m/^y$/i) { + # y or Y for send as is + $permit_pending = 1; + Irssi::signal_stop(); + Irssi::signal_emit('send text', + $pending_input->{text}, + $pending_input->{server}, + $pending_input->{win_item}); + $active = 0; + set_prompt(''); + } + elsif ($char =~ m/^c$/i or $key == 3 or $key == 7) { + # we support c, C, Ctrl-C, and Ctrl-G for don't send + Irssi::signal_stop(); + set_prompt(''); + $permit_pending = 0; + $active = 0; + $pending_input = {}; + } + else { + Irssi::signal_stop(); + return; + } +} + +sub app_init { + Irssi::signal_add_first("send text" => \&sig_send_text); + Irssi::signal_add_first('gui key pressed' => \&sig_gui_keypress); + Irssi::signal_add("commandlist new" => + sub { + $cmdregexp = list2re map {$_->{cmd}} Irssi::commands(); + }); + Irssi::settings_add_str('Intercept', 'intercept_exceptions', 's/\w+/[\w\s\d]+/'); + Irssi::settings_add_str('Intercept', 'intercept_linestart', '\s'); +} + +sub require_confirmation { + $active = 1; + set_prompt(shift); +} + +sub set_prompt { + my ($msg) = @_; + $msg = ': ' . $msg if length $msg; + Irssi::signal_emit('change prompt', $msg, 'UP_INNER'); +} + +sub _debug { + return unless $verbose; + + my ($msg, @params) = @_; + my $str = sprintf($msg, @params); + print $str; +} |