Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
180 lines (144 sloc) 4.5 KB
# - Lets you tab over a number of people who've recently spoken in channel
# - Removes people from the list who leave the channel
# - Tabcomplete works only from an empty input line and will complete to
# the person who last spoke
# - The same nick is only included once in the list
# - When at the end of the list, empties the input line and lets you begin
# from the start again
# - /set completion_keep_publics decides how many nicks to remember
use strict;
use warnings;
use Irssi::TextUI;
use Data::Dumper;
{ package Irssi::Nick; }
use vars qw($VERSION %IRSSI);
$VERSION = '1.1';
%IRSSI = (
authors => 'vague',
contact => 'vague!#irssi@freenode on irc',
name => 'tabcompletenick',
description => 'tabcomplete, on an empty input buffer, over /set completion_keep_publics nicks in channel, parts for any reason(kick, part, quit) are removed from the tabcomplete list',
license => 'GPL2',
url => "http://gplus.to/vague",
changed => "24 Nov 16:00:00 CET 2015",
);
my $lastspokehash;
my $expand_next = 0;
Irssi::signal_add_first('gui key pressed', sub {
my ($key) = @_;
return unless exists Irssi::active_win->{active} && Irssi::active_win->{active}->{type} eq "CHANNEL";
my $prompt = Irssi::parse_special('$L');
my $pos = Irssi::gui_input_get_pos();
my $witem = Irssi::active_win()->{active};
my $server = Irssi::active_server();
my $arr = $lastspokehash->{$server->{tag}}->{$witem->{name}} || [];
if(!$expand_next) {
return unless $key == 9;
return unless $pos == 0;
return unless @{$arr};
$expand_next++;
}
else {
if($key != 9) {
$expand_next = 0;
return;
}
if($expand_next < @$arr) {
$expand_next++;
} else {
$expand_next = 0;
}
}
my $last = Irssi::parse_special('$LASTSPOKE');
if($last ne '') {
$prompt = $last . Irssi::settings_get_str('completion_char') . " ";
} else {
$prompt = $last;
}
Irssi::gui_input_set($prompt);
Irssi::gui_input_set_pos(length($prompt));
Irssi::signal_stop();
});
sub expando_lastspoke {
my ($server, $witem) = @_;
$server = Irssi::active_server() unless $server;
$witem = Irssi::active_win()->{active} unless $witem;
return '' if $expand_next == 0;
return '' unless ref($witem) eq 'Irssi::Irc::Channel';
my $arr = $lastspokehash->{$server->{tag}}->{$witem->{name}};
return '' unless @$arr;
return '' unless $expand_next <= @$arr;
return @{$lastspokehash->{$server->{tag}}->{$witem->{name}}}[$expand_next - 1];
}
sub act_public {
my ($server, $msg, $nick, $address, $target) = @_;
return if $target eq '';
my $i = 0;
my $arr = $lastspokehash->{$server->{tag}}->{$target};
foreach(@$arr) {
if($_ eq $nick) {
splice @$arr, $i, 1;
last;
}
$i++;
}
unshift @{$lastspokehash->{$server->{tag}}->{$target}}, $nick;
splice @{$lastspokehash->{$server->{tag}}->{$target}}, Irssi::settings_get_int('completion_keep_publics');
}
sub _part {
my ($server, $channel, $nick) = @_;
if(!$channel) {
foreach my $chan (keys %{$lastspokehash->{$server->{tag}}}) {
my $arr = $lastspokehash->{$server->{tag}}->{$chan};
my $i = 0;
foreach(@{$arr}) {
if($_ eq $nick) {
splice @{$arr}, $i, 1;
last;
}
$i++;
}
}
}
else {
my $arr = $lastspokehash->{$server->{tag}}->{$channel};
my $i = 0;
foreach(@{$arr}) {
if($_ eq $nick) {
splice @{$arr}, $i, 1;
last;
}
$i++;
}
}
delete $lastspokehash->{$server->{tag}} unless keys %{$lastspokehash->{$server->{tag}}};
}
Irssi::signal_add_first('message quit', sub {
my ($server, $nick, $address, $reason) = @_;
_part($server, undef, $nick);
});
Irssi::signal_add_first('message part', sub {
my ($server, $channel, $nick, $address, $reason) = @_;
_part($server, $channel, $nick);
});
Irssi::signal_add_first('message kick', sub {
my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
_part($server, $channel, $nick);
});
Irssi::signal_add_first('message nick', sub {
my ($server, $newnick, $oldnick, $address) = @_;
foreach my $chan (keys %{$lastspokehash->{$server->{tag}}}) {
my $arr = $lastspokehash->{$server->{tag}}->{$chan};
my $i = 0;
foreach(@{$arr}) {
if($_ eq $oldnick) {
@{$arr}[$i] = $newnick;
last;
}
$i++;
}
}
});
Irssi::signal_add('message public', \&act_public);
Irssi::signal_add('message irc action', \&act_public);
Irssi::expando_create('LASTSPOKE', \&expando_lastspoke, {});