]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
[spellcheck] v0.9
authorJakub Wilk <redacted>
Tue, 19 Feb 2019 17:16:20 +0000 (18:16 +0100)
committerbw1 <redacted>
Thu, 23 Dec 2021 00:17:52 +0000 (01:17 +0100)
scripts/spellcheck.pl

index d25b45badd9e427f65745645036ac262cc4248d7..850defa036ac6abc6d7e65861a0eb721cb97be5d 100644 (file)
@@ -1,5 +1,5 @@
 # Copyright © 2008 Jakub Jankowski <shasta@toxcorp.com>
-# Copyright © 2012-2016 Jakub Wilk <jwilk@jwilk.net>
+# Copyright © 2012-2019 Jakub Wilk <jwilk@jwilk.net>
 # Copyright © 2012 Gabriel Pettier <gabriel.pettier@gmail.com>
 #
 # This program is free software; you can redistribute it and/or modify
@@ -16,11 +16,13 @@ use warnings;
 
 use vars qw($VERSION %IRSSI);
 use Irssi 20070804;
+use Irssi::TextUI;
+use Encode;
 use Text::Aspell;
 
-$VERSION = '0.8';
+$VERSION = '0.9';
 %IRSSI = (
-    authors     => 'Jakub Wilk, Jakub Jankowski, Gabriel Pettier',
+    authors     => 'Jakub Wilk, Jakub Jankowski, Gabriel Pettier, Nei',
     name        => 'spellcheck',
     description => 'checks for spelling errors using Aspell',
     license     => 'GPLv2',
@@ -135,31 +137,51 @@ sub spellcheck_key_pressed
 
     return unless Irssi::settings_get_bool('spellcheck_enabled');
 
-    # 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.
-
     # hide correction window when message is sent
     if (chr($key) =~ /\A[\r\n]\z/ && $correction_window) {
-        $correction_window->command("window hide $window_name");
+        $correction_window->command("^window hide $window_name");
+        if (Irssi->can('gui_input_clear_extents')) {
+            Irssi::gui_input_clear_extents(0, 9999);
+        }
     }
 
-    # 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');
+    my $utf8 = lc Irssi::settings_get_str('term_charset') eq 'utf-8';
+    if ($utf8) {
+        Encode::_utf8_on($inputline);
+    }
+
+    # ensure that newly added characters are not colored
+    # when correcting a colored word
+    # FIXME: this works at EOL, but not elsewhere
+    if (Irssi->can('gui_input_set_extent')) {
+        Irssi::gui_input_set_extent(length $inputline, '%n');
+    }
+
+    # don't bother unless pressed key is space
+    # or a terminal punctuation mark
+    return unless grep { chr $key eq $_ } (' ', qw(. ? !));
+
+    $inputline = substr $inputline, 0, Irssi::gui_input_get_pos();
 
     # check if inputline starts with any of cmdchars
     # we shouldn't spell-check commands
     my $cmdchars = Irssi::settings_get_str('cmdchars');
-    my $re = qr/^[$cmdchars]/;
+    my $re = qr/^[\Q$cmdchars\E]/;
     return if ($inputline =~ $re);
 
     # get last bit from the inputline
-    my ($word) = $inputline =~ /\s*(\S+)$/;
+    my ($word) = $inputline =~ /\s*(\S+)\s*$/;
     defined $word or return;
 
+    # remove color from the last word
+    # (we will add it back later if needed)
+    my $start = $-[1];
+    if (Irssi->can('gui_input_clear_extents')) {
+        Irssi::gui_input_clear_extents($start, length $word);
+    }
+
     my $lang = spellcheck_find_language($win);
 
     return if $lang eq 'und';
@@ -168,10 +190,23 @@ sub spellcheck_key_pressed
 
     return unless defined $suggestions;
 
+    # strip leading and trailing punctuation
+    $word =~ s/^([[:punct:]]+)// and $start += length $1;
+    $word =~ s/[[:punct:]]+$//;
+
+    # add color to the misspelled word
+    my $color = Irssi::settings_get_str('spellcheck_word_input_color');
+    if ($color && Irssi->can('gui_input_set_extents')) {
+        Irssi::gui_input_set_extents($start, length $word, $color, '%n');
+    }
+
+    return unless Irssi::settings_get_bool('spellcheck_print_suggestions');
+
     # show corrections window if hidden
     if ($correction_window) {
-        $win->command("window show $window_name");
-        $correction_window->command('window stick off');
+        $win->command("^window show $window_name");
+        $correction_window->command('^window stick off');
+        $win->set_active;
         $correction_window->command("window size $window_height");
     } else {
         $correction_window = $win;
@@ -180,8 +215,11 @@ sub spellcheck_key_pressed
     # we found a mistake, print suggestions
 
     $word =~ s/%/%%/g;
-    my $color = Irssi::settings_get_str('spellcheck_word_color');
+    $color = Irssi::settings_get_str('spellcheck_word_color');
     if (scalar @$suggestions > 0) {
+        if ($utf8) {
+            Encode::_utf8_on($_) for @$suggestions;
+        }
         $correction_window->print("Suggestions for $color$word%N - " . join(', ', @$suggestions));
     } else {
         $correction_window->print("No suggestions for $color$word%N");
@@ -198,6 +236,8 @@ sub spellcheck_complete_word
 
     my $lang = spellcheck_find_language($win);
 
+    return if $lang eq 'und';
+
     # add suggestions to the completion list
     my $suggestions = spellcheck_check_word($lang, $word, 1);
     push(@$complist, @$suggestions) if defined $suggestions;
@@ -239,13 +279,19 @@ sub spellcheck_add_word
 Irssi::command_bind('spellcheck_add', 'spellcheck_add_word');
 
 Irssi::settings_add_bool('spellcheck', 'spellcheck_enabled', 1);
+Irssi::settings_add_bool('spellcheck', 'spellcheck_print_suggestions', 1);
 Irssi::settings_add_str( 'spellcheck', 'spellcheck_default_language', 'en_US');
 Irssi::settings_add_str( 'spellcheck', 'spellcheck_languages', '');
 Irssi::settings_add_str( 'spellcheck', 'spellcheck_word_color', '%R');
+Irssi::settings_add_str( 'spellcheck', 'spellcheck_word_input_color', '%U');
 Irssi::settings_add_str( 'spellcheck', 'spellcheck_window_name', '');
 Irssi::settings_add_str( 'spellcheck', 'spellcheck_window_height', 10);
 
-Irssi::signal_add_first('gui key pressed', 'spellcheck_key_pressed');
+Irssi::signal_add_last('key word_completion', sub{spellcheck_key_pressed(ord '.')});
+Irssi::signal_add_last('key word_completion_backward', sub{spellcheck_key_pressed(ord '.')});
+Irssi::signal_add_last('gui key pressed', 'spellcheck_key_pressed');
 Irssi::signal_add_last('complete word', 'spellcheck_complete_word');
 
+1;
+
 # vim:ts=4 sts=4 sw=4 et
git clone https://git.99rst.org/PROJECT