1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 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;
}
|