Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
139 lines (114 sloc) 4.15 KB
#!/usr/bin/perl -w
#
# Michael Kowalchuk <michael_kowalchuk@umanitoba.ca> presents:
#
# A spell checker for irssi
# Requires Lingua::Ispell and ispell
#
# Usage:
# Load the script
# Type /bind meta-s /_spellcheck
# Hit meta+s (alt+s) to check your spelling
#
# This script also implements /spell <line> which shows more spelling suggestions than
# the hotkey (99).
#
# Options:
# spell_max_guesses (def: 1)
# spell_error_effect (def: %U = underline, others are %8 = reverse, %9 = bold)
# see http://irssi.org/documentation/formats
# spell_ispell_path (default: "/usr/local/bin/ispell")
# spell_use_dictionary (default: "")
#
# History
# First version: inline spellchecking, terrible, unreleased [Tue Aug 2 00:32:27 CDT 2005]
# 1.0 Spellcheck on request [Mon Jan 2 17:02:12 CST 2006]
# 1.1 new options spell_ispell_path spell_use_dictionary [2018-09-05]
#
# Todo
# Is there a way for a script to clear its mess like '/lastlog -clear' does?
#
use strict;
use Irssi;
use List::Util qw( min );
use Irssi::TextUI;
use Lingua::Ispell;
use vars qw($VERSION %IRSSI);
$VERSION = '1.1';
%IRSSI = (
authors => 'Michael Kowalchuk',
contact => 'michael_kowalchuk@umanitoba.ca',
name => 'spell',
description => 'A spell checker for irssi. Hit alt+s and your line will echoed to the active window with mistakes underlined and suggestions noted. /spell is also provided. Requires Lingua::Ispell and Ispell.',
license => 'MIT',
url => 'http://home.cc.umanitoba.ca/~umkowa17/',
changed => '2018-09-05'
);
sub check_line {
my ($inputline, $guesses) = @_;
my $error_start = Irssi::settings_get_str($IRSSI{'name'}.'_error_effect');
my $error_end = "%n"; # previous colour
# ISpell has a limit of 99 characters in a word
if ( $inputline =~ /\w{99}/ ) {
return "unable to spellcheck";
}
# Reads in a list of hashes for each error with the keys term, type, and offset
my @errs = Lingua::Ispell::spellcheck( $inputline );
if( @errs > 0 ) {
# Reconstruct the line with suggestions built in
my $outputline;
my $last_end = 0;
foreach(@errs) {
my $off=$_->{'offset'}-1; # ispell counts from 1
my $before = substr($inputline, $last_end, $off - $last_end);
$last_end = $off + length($_->{'term'});
# Give speling [spelling, spelunking?] suggestions
my $extra_info = "";
if( $guesses > 0 ) {
if( $_->{'type'} eq 'miss' ) {
# Show near-misses, there will be 1..n of them
my @misses = @{$_->{'misses'}};
my $miss_len = @misses;
my $shown_guesses = min( $miss_len, $guesses);
my @shown = @misses[0..$shown_guesses - 1];
$extra_info = " (" . join(", ", @shown ) . "?)";
}
elsif( $_->{'type'} eq 'root' ) {
# Show root suggestions, there will be exactly 1
$extra_info = " (" . $_->{'root'} . "?)";
}
}
$outputline .= $before . $error_start . $_->{'term'} . $error_end . $extra_info;
}
$outputline .= substr($inputline, $last_end);
return $outputline;
}
else {
return "no errors";
}
}
# Read from the input line
sub cmd_spellcheck {
my $inputline = Irssi::parse_special("\$L");
my $guesses = Irssi::settings_get_int($IRSSI{'name'}.'_max_guesses');
Irssi::active_win()->print("spell: " . check_line($inputline, $guesses), MSGLEVEL_CRAP );
}
# Read from the argument list
sub cmd_spell {
my ($inputline) = @_;
my $guesses = 99;
Irssi::active_win()->print("spell: " . check_line($inputline, $guesses), MSGLEVEL_CRAP );
}
sub sig_config {
$Lingua::Ispell::path=Irssi::settings_get_str($IRSSI{'name'}.'_ispell_path');
my $dic=Irssi::settings_get_str($IRSSI{'name'}.'_use_dictionary');
Lingua::Ispell::use_dictionary($dic) if ($dic ne "") ;
}
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_use_dictionary', "");
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_ispell_path', "/usr/local/bin/ispell");
Irssi::settings_add_str('misc', $IRSSI{'name'} . '_error_effect', "%U");
Irssi::settings_add_int('misc', $IRSSI{'name'} . '_max_guesses', 1);
Irssi::command_bind('_spellcheck', 'cmd_spellcheck');
Irssi::command_bind('spell', 'cmd_spell');
Irssi::signal_add("setup changed",\&sig_config);
sig_config();