irssi softignore script

A few weeks ago, my friend Steven wrote about a softignore script he wrote for X-Chat. The idea is that instead of completely blocking what a user says, the script captures their text and colors it in a way that the text “blends” with the background, so you can more easily ignore what these people say.

I’m an irssi fan myself, but I was a bit jealous of his script and quite surprised not to find anything like it in irssi’s script repository. So I decided to go ahead and write my own. Irssi is scripted in Perl, of which I have a little bit of knowledge, but definitely no expertise. The documentation on how to script Irssi is a bit thin; you can find a little on their web site, a little on the site of a guy who wrote a mini-tutorial and a little on the #irssi channel.

After a couple hours of hacking, I had a script that did what I wanted. There are three commands, /softignore_add, /softignore_remove and /softignore_list. The parameter to the add and remove commands is a regular expression to match the nickname. The list is kept in memory as well as in a plain text file with one regex string per line. I imagine that the more advanced Perl programmers will suggest better ways to accomplish this, but for the time being, this works well enough.

I have not made the color configurable yet, so if you need a color other than dark grey, just edit the script file and change the value of the $COLOR variable.

I implemented a few functions (slurp, spit and trim) that are most likely available in CPAN modules; however I did not want my simple script to have external dependencies, so I knowingly violated the DRY principle.

Here is the code for the script. Just copy it in ~/.irssi/scripts/ and use the /script load softignore command to load it.

use strict;
use warnings;

use Irssi qw(command_bind signal_add signal_continue command);

# Irssi globals
our $VERSION = "0.00";
our %IRSSI = (
    authors     => "Vincent Foley",
    contact     => "vfoleybourgon at yahoo dot ca",
    name        => "Soft Ignore",
    description => "Ignore users by putting their messages in a dim color.",
    license     => "MIT",
);

# Soft ignore globals
our $FILENAME = "$ENV{HOME}/.irssi/saved_softignore";
our $COLOR    = 14;
our @ignores  = slurp($FILENAME);

sub slurp {
    my ($filename) = @_;

    my $lines;
    {
        local $/;
        open(my $fd, '<', $filename) or return ();
        $lines = <$fd>;
    }
    return split(/\n/, $lines);
}

sub spit {
    my ($filename, @lines) = @_;

    open(my $fd, '>', $filename) or return;
    for my $line (@lines) {
        print {$fd} $line."\n";
    }
    close($fd);
}

sub trim {
    my ($str) = @_;

    $str =~ s/^\s*(\S+)\s*$/$1/;
    return $str;
}

sub softignore_add {
    my ($data, $server, $witem) = @_;

    push(@ignores, trim($data));
    spit($FILENAME, @ignores);
}

sub softignore_remove {
    my ($data, $server, $witem) = @_;

    @ignores = grep { $_ ne trim($data) } @ignores;
    spit($FILENAME, @ignores);
}

sub softignore_list {
    my ($data, $server, $witem) = @_;

    return unless $witem;

    if (@ignores == 0) {
        $witem->print("No soft ignore entries.");
    }
    else {
        $witem->print("Soft ignore list:");
        for my $ignore (@ignores) {
            $witem->print("* " . $ignore);
        }
    }
}

sub softignore_message {
    my ($server, $msg, $nick, $address, $target) = @_;

    for my $ignore (@ignores) {
        if ($nick =~ /$ignore/i) {
            signal_continue($server, "03$COLOR$msg",
                            $nick, $address, $target);
        }
    }
}

command_bind softignore_list   => \&softignore_list;
command_bind softignore_add    => \&softignore_add;
command_bind softignore_remove => \&softignore_remove;

signal_add "message public" => \&softignore_message;

Leave a Reply