diff options
| author | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
|---|---|---|
| committer | Alexander Færøy | 2014-05-31 13:10:46 +0200 | 
| commit | 2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1 (patch) | |
| tree | 1c5e6d817c88e67b46e216a50e0aef5428bf63df /scripts/spellcheck.pl | |
| parent | 2d080422d79d1fd49d6c5528593ccaaff9bfc583 (diff) | |
| download | scripts.irssi.org-2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1.tar.bz2 | |
Import scripts from scripts.irssi.org
Diffstat (limited to 'scripts/spellcheck.pl')
| -rw-r--r-- | scripts/spellcheck.pl | 213 | 
1 files changed, 213 insertions, 0 deletions
| diff --git a/scripts/spellcheck.pl b/scripts/spellcheck.pl new file mode 100644 index 0000000..158ea3c --- /dev/null +++ b/scripts/spellcheck.pl @@ -0,0 +1,213 @@ +#!/usr/bin/perl -w + +# ** This script is a 10-minutes-hack, so it's EXPERIMENTAL. ** +# +# Requires: +#  - Irssi 0.8.12 or newer (http://irssi.org/). +#  - GNU Aspell with appropriate dictionaries (http://aspell.net/). +#  - Perl module Text::Aspell (available from CPAN). +# +# +# Description: +#  Works as you type, printing suggestions when Aspell thinks +#  your last word was misspelled.  +#  It also adds suggestions to the list of tabcompletions, +#  so once you know last word is wrong, you can go back  +#  and tabcomplete through what Aspell suggests. +# +# +# Settings: +# +#  spellcheck_languages  -- a list of space and/or comma +#    separated languages to use on certain networks/channels. +#    Example:  +#    /set spellcheck_languages netA/#chan1/en_US, #chan2/fi_FI, netB/!chan3/pl_PL +#    will use en_US for #chan1 on network netA, fi_FI for #chan2 +#    on every network, and pl_PL for !chan3 on network netB. +#    By default this setting is empty. +# +#  spellcheck_default_language  -- language to use in empty +#    windows, or when nothing from spellcheck_languages matches. +#    Defaults to 'en_US'. +# +#  spellcheck_enabled [ON/OFF]  -- self explaining. Sometimes +#    (like when pasting foreign-language text) you don't want +#    the script to spit out lots of suggestions, and turning it +#    off for a while is the easiest way. By default it's ON. +# +# +# BUGS: +#  - won't catch all mistakes +#  - picking actual words from what you type is very kludgy, +#    you may occasionally see some leftovers like digits or punctuation +#  - works every time you press space or a dot (so won't work for +#    the last word before pressing enter, unless you're using dot +#    to finish your sentences) +#  - when you press space and realize that the word is wrong, +#    you can't tabcomplete to the suggestions right away - you need +#    to use backspace and then tabcomplete. With dot you get an extra +#    space after tabcompletion. +#  - all words will be marked and no suggestions given if  +#    dictionary is missing (ie. wrong spellcheck_default_language) +#  - probably more, please report to $IRSSI{'contact'} +# +# +# $Id: spellcheck.pl 5 2008-05-28 22:31:06Z shasta $ +# + +use strict; +use vars qw($VERSION %IRSSI); +use Irssi 20070804; +use Text::Aspell; + +$VERSION = '0.3'; +%IRSSI = ( +    authors     => 'Jakub Jankowski', +    contact     => 'shasta@toxcorp.com', +    name        => 'Spellcheck', +    description => 'Checks for spelling errors using Aspell.', +    license     => 'GPLv2', +    url         => 'http://toxcorp.com/irc/irssi/spellcheck/', +); + +my %speller; + +sub spellcheck_setup +{ +    return if (exists $speller{$_[0]} && defined $speller{$_[0]}); +    $speller{$_[0]} = Text::Aspell->new or return undef; +    $speller{$_[0]}->set_option('lang', $_[0]) or return undef; +    $speller{$_[0]}->set_option('sug-mode', 'fast') or return undef; +    return 1; +} + +# add_rest means "add (whatever you chopped from the word before +# spellchecking it) to the suggestions returned" +sub spellcheck_check_word +{ +    my ($lang, $word, $add_rest) = @_; +    my $win = Irssi::active_win(); +    my @suggestions = (); + +    # setup Text::Aspell for that lang if needed +    if (!exists $speller{$lang} || !defined $speller{$lang}) +    { +	if (!spellcheck_setup($lang)) +	{ +	    $win->print("Error while setting up spellchecker for $lang"); +	    # don't change the message +	    return @suggestions; +	} +    } + +    # do the spellchecking +    my ($stripped, $rest) = $word =~ /([^[:punct:][:digit:]]{2,})(.*)/; # HAX +    # Irssi::print("Debug: stripped $word is '$stripped', rest is '$rest'"); +    if (defined $stripped && !$speller{$lang}->check($stripped)) +    { +	push(@suggestions, $add_rest ? $_ . $rest : $_) for ($speller{$lang}->suggest($stripped)); +    } +    return @suggestions; +} + +sub spellcheck_find_language +{ +    my ($network, $target) = @_; +    return Irssi::settings_get_str('spellcheck_default_language') unless (defined $network && defined $target); + +    # support !channels correctly +    $target = '!' . substr($target, 6) if ($target =~ /^\!/); + +    # lowercase net/chan +    $network = lc($network); +    $target  = lc($target); + +    # possible settings: network/channel/lang  or  channel/lang +    my @languages = split(/[ ,]/, Irssi::settings_get_str('spellcheck_languages')); +    for my $langstr (@languages) +    { +	# strip trailing slashes +	$langstr =~ s=/+$==; +	# Irssi::print("Debug: checking network $network target $target against langstr $langstr"); +	my ($s1, $s2, $s3) = split(/\//, $langstr, 3); +	my ($t, $c, $l); +	if (defined $s3 && $s3 ne '') +	{ +	    # network/channel/lang +	    $t = lc($s1); $c = lc($s2); $l = $s3; +	} +	else +	{ +	    # channel/lang +	    $c = lc($s1); $l = $s2; +	} + +	if ($c eq $target && (!defined $t || $t eq $network)) +	{ +	    # Irssi::print("Debug: language found: $l"); +	    return $l; +	} +    } + +    # Irssi::print("Debug: language not found, using default"); +    # no match, use defaults +    return Irssi::settings_get_str('spellcheck_default_language'); +} + +sub spellcheck_key_pressed +{ +    my ($key) = @_; +    my $win = Irssi::active_win(); + +    # I know no way to *mark* misspelled words in the input line, +    # that's why there's no spellcheck_print_suggestions - +    # because printing suggestions is our only choice. +    return unless Irssi::settings_get_bool('spellcheck_enabled'); + +    # don't bother unless pressed key is space or dot +    return unless (chr $key eq ' ' or chr $key eq '.'); + +    # get current inputline +    my $inputline = Irssi::parse_special('$L'); + +    # check if inputline starts with any of cmdchars +    # we shouldn't spellcheck commands +    my $cmdchars = Irssi::settings_get_str('cmdchars'); +    my $re = qr/^[$cmdchars]/; +    return if ($inputline =~ $re); + +    # get last bit from the inputline +    my ($word) = $inputline =~ /\s*([^\s]+)$/; + +    # find appropriate language for current window item +    my $lang = spellcheck_find_language($win->{active_server}->{tag}, $win->{active}->{name}); + +    my @suggestions = spellcheck_check_word($lang, $word, 0); +    # Irssi::print("Debug: spellcheck_check_word($word) returned array of " . scalar @suggestions); +    return if (scalar @suggestions == 0); + +    # we found a mistake, print suggestions +    $win->print("Suggestions for $word - " . join(", ", @suggestions)); +} + + +sub spellcheck_complete_word +{ +    my ($complist, $win, $word, $lstart, $wantspace) = @_; + +    return unless Irssi::settings_get_bool('spellcheck_enabled'); + +    # find appropriate language for the current window item +    my $lang = spellcheck_find_language($win->{active_server}->{tag}, $win->{active}->{name}); + +    # add suggestions to the completion list +    push(@$complist, spellcheck_check_word($lang, $word, 1)); +} + + +Irssi::settings_add_bool('spellcheck', 'spellcheck_enabled', 1); +Irssi::settings_add_str( 'spellcheck', 'spellcheck_default_language', 'en_US'); +Irssi::settings_add_str( 'spellcheck', 'spellcheck_languages', ''); + +Irssi::signal_add_first('gui key pressed', 'spellcheck_key_pressed'); +Irssi::signal_add_last('complete word', 'spellcheck_complete_word'); | 
