[gnome-text-editor] spellcheck: plumb support for extra word characters



commit 724707d22d1a91390bbcb8d2f5974f351e18b4e9
Author: Christian Hergert <chergert redhat com>
Date:   Sun Jul 18 08:29:56 2021 -0700

    spellcheck: plumb support for extra word characters
    
    Based on the language, we might need to extend beyond what GtkTextIter
    considers part of a word (from breaking rules). For example, we might get
    "re" instead of "we're" in English unless we consider ' as part of the
    word.
    
    Further work is needed to introduce this into the forward_word_end() and
    backward_word_start().

 src/editor-spell-checker.c                  | 11 ++++++++
 src/editor-spell-checker.h                  | 31 ++++++++++----------
 src/editor-spell-cursor.c                   |  5 +++-
 src/editor-spell-cursor.h                   |  3 +-
 src/editor-spell-language.c                 | 11 ++++++++
 src/editor-spell-language.h                 | 44 +++++++++++++++--------------
 src/editor-text-buffer-spell-adapter.c      |  4 ++-
 src/enchant/editor-enchant-spell-language.c | 11 ++++++++
 src/test-spell-cursor.c                     |  4 +--
 9 files changed, 83 insertions(+), 41 deletions(-)
---
diff --git a/src/editor-spell-checker.c b/src/editor-spell-checker.c
index f4aae26..18f5605 100644
--- a/src/editor-spell-checker.c
+++ b/src/editor-spell-checker.c
@@ -311,3 +311,14 @@ editor_spell_checker_ignore_word (EditorSpellChecker *self,
   if (self->language != NULL)
     editor_spell_language_ignore_word (self->language, word);
 }
+
+const char *
+editor_spell_checker_get_extra_word_chars (EditorSpellChecker *self)
+{
+  g_return_val_if_fail (EDITOR_IS_SPELL_CHECKER (self), NULL);
+
+  if (self->language != NULL)
+    return editor_spell_language_get_extra_word_chars (self->language);
+
+  return "";
+}
diff --git a/src/editor-spell-checker.h b/src/editor-spell-checker.h
index 2553f06..94c94df 100644
--- a/src/editor-spell-checker.h
+++ b/src/editor-spell-checker.h
@@ -28,20 +28,21 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (EditorSpellChecker, editor_spell_checker, EDITOR, SPELL_CHECKER, GObject)
 
-EditorSpellChecker   *editor_spell_checker_new              (EditorSpellProvider *provider,
-                                                             const char          *language);
-EditorSpellProvider  *editor_spell_checker_get_provider     (EditorSpellChecker  *self);
-const char           *editor_spell_checker_get_language     (EditorSpellChecker  *self);
-void                  editor_spell_checker_set_language     (EditorSpellChecker  *self,
-                                                             const char          *language);
-gboolean              editor_spell_checker_check_word       (EditorSpellChecker  *self,
-                                                             const char          *word,
-                                                             gssize               word_len);
-char                **editor_spell_checker_list_corrections (EditorSpellChecker  *self,
-                                                             const char          *word);
-void                  editor_spell_checker_add_word         (EditorSpellChecker  *self,
-                                                             const char          *word);
-void                  editor_spell_checker_ignore_word      (EditorSpellChecker  *self,
-                                                             const char          *word);
+EditorSpellChecker   *editor_spell_checker_new                  (EditorSpellProvider *provider,
+                                                                 const char          *language);
+EditorSpellProvider  *editor_spell_checker_get_provider         (EditorSpellChecker  *self);
+const char           *editor_spell_checker_get_language         (EditorSpellChecker  *self);
+void                  editor_spell_checker_set_language         (EditorSpellChecker  *self,
+                                                                 const char          *language);
+gboolean              editor_spell_checker_check_word           (EditorSpellChecker  *self,
+                                                                 const char          *word,
+                                                                 gssize               word_len);
+char                **editor_spell_checker_list_corrections     (EditorSpellChecker  *self,
+                                                                 const char          *word);
+void                  editor_spell_checker_add_word             (EditorSpellChecker  *self,
+                                                                 const char          *word);
+void                  editor_spell_checker_ignore_word          (EditorSpellChecker  *self,
+                                                                 const char          *word);
+const char           *editor_spell_checker_get_extra_word_chars (EditorSpellChecker  *self);
 
 G_END_DECLS
diff --git a/src/editor-spell-cursor.c b/src/editor-spell-cursor.c
index d641c36..8b6cb79 100644
--- a/src/editor-spell-cursor.c
+++ b/src/editor-spell-cursor.c
@@ -51,6 +51,7 @@ struct _EditorSpellCursor
   RegionIter region;
   TagIter tag;
   WordIter word;
+  const char *extra_word_chars;
 };
 
 static void
@@ -227,7 +228,8 @@ word_iter_seek (WordIter          *self,
 EditorSpellCursor *
 editor_spell_cursor_new (GtkTextBuffer *buffer,
                          CjhTextRegion *region,
-                         GtkTextTag    *no_spell_check_tag)
+                         GtkTextTag    *no_spell_check_tag,
+                         const char    *extra_word_chars)
 {
   EditorSpellCursor *self;
 
@@ -239,6 +241,7 @@ editor_spell_cursor_new (GtkTextBuffer *buffer,
   region_iter_init (&self->region, buffer, region);
   tag_iter_init (&self->tag, buffer, no_spell_check_tag);
   word_iter_init (&self->word, buffer);
+  self->extra_word_chars = extra_word_chars ? g_intern_string (extra_word_chars) : "";
 
   return self;
 }
diff --git a/src/editor-spell-cursor.h b/src/editor-spell-cursor.h
index f813199..9765537 100644
--- a/src/editor-spell-cursor.h
+++ b/src/editor-spell-cursor.h
@@ -29,7 +29,8 @@ typedef struct _CjhTextRegion     CjhTextRegion;
 
 EditorSpellCursor *editor_spell_cursor_new  (GtkTextBuffer     *buffer,
                                              CjhTextRegion     *region,
-                                             GtkTextTag        *no_spell_check_tag);
+                                             GtkTextTag        *no_spell_check_tag,
+                                             const char        *extra_word_chars);
 void               editor_spell_cursor_free (EditorSpellCursor *cursor);
 gboolean           editor_spell_cursor_next (EditorSpellCursor *cursor,
                                              GtkTextIter       *word_begin,
diff --git a/src/editor-spell-language.c b/src/editor-spell-language.c
index a60b145..af5aa60 100644
--- a/src/editor-spell-language.c
+++ b/src/editor-spell-language.c
@@ -164,3 +164,14 @@ editor_spell_language_ignore_word (EditorSpellLanguage *self,
   if (EDITOR_SPELL_LANGUAGE_GET_CLASS (self)->ignore_word)
     EDITOR_SPELL_LANGUAGE_GET_CLASS (self)->ignore_word (self, word);
 }
+
+const char *
+editor_spell_language_get_extra_word_chars (EditorSpellLanguage *self)
+{
+  g_return_val_if_fail (EDITOR_IS_SPELL_LANGUAGE (self), NULL);
+
+  if (EDITOR_SPELL_LANGUAGE_GET_CLASS (self)->get_extra_word_chars)
+    EDITOR_SPELL_LANGUAGE_GET_CLASS (self)->get_extra_word_chars (self);
+
+  return "";
+}
diff --git a/src/editor-spell-language.h b/src/editor-spell-language.h
index 8c2055b..da213a1 100644
--- a/src/editor-spell-language.h
+++ b/src/editor-spell-language.h
@@ -32,31 +32,33 @@ struct _EditorSpellLanguageClass
 {
   GObjectClass parent_class;
 
-  gboolean    (*contains_word)    (EditorSpellLanguage *self,
-                                   const char          *word,
-                                   gssize               word_len);
-  char      **(*list_corrections) (EditorSpellLanguage *self,
-                                   const char          *word,
-                                   gssize               word_len);
-  void        (*add_word)         (EditorSpellLanguage *self,
-                                   const char          *word);
-  void        (*ignore_word)      (EditorSpellLanguage *self,
-                                   const char          *word);
+  gboolean     (*contains_word)        (EditorSpellLanguage *self,
+                                        const char          *word,
+                                        gssize               word_len);
+  char       **(*list_corrections)     (EditorSpellLanguage *self,
+                                        const char          *word,
+                                        gssize               word_len);
+  void         (*add_word)             (EditorSpellLanguage *self,
+                                        const char          *word);
+  void         (*ignore_word)          (EditorSpellLanguage *self,
+                                        const char          *word);
+  const char  *(*get_extra_word_chars) (EditorSpellLanguage *self);
 
   /*< private >*/
   gpointer _reserved[8];
 };
 
-const char  *editor_spell_language_get_code         (EditorSpellLanguage *self);
-gboolean     editor_spell_language_contains_word    (EditorSpellLanguage *self,
-                                                     const char          *word,
-                                                     gssize               word_len);
-char       **editor_spell_language_list_corrections (EditorSpellLanguage *self,
-                                                     const char          *word,
-                                                     gssize               word_len);
-void         editor_spell_language_add_word         (EditorSpellLanguage *self,
-                                                     const char          *word);
-void         editor_spell_language_ignore_word      (EditorSpellLanguage *self,
-                                                     const char          *word);
+const char  *editor_spell_language_get_code             (EditorSpellLanguage *self);
+gboolean     editor_spell_language_contains_word        (EditorSpellLanguage *self,
+                                                         const char          *word,
+                                                         gssize               word_len);
+char       **editor_spell_language_list_corrections     (EditorSpellLanguage *self,
+                                                         const char          *word,
+                                                         gssize               word_len);
+void         editor_spell_language_add_word             (EditorSpellLanguage *self,
+                                                         const char          *word);
+void         editor_spell_language_ignore_word          (EditorSpellLanguage *self,
+                                                         const char          *word);
+const char  *editor_spell_language_get_extra_word_chars (EditorSpellLanguage *self);
 
 G_END_DECLS
diff --git a/src/editor-text-buffer-spell-adapter.c b/src/editor-text-buffer-spell-adapter.c
index 4ec6702..8ead9e1 100644
--- a/src/editor-text-buffer-spell-adapter.c
+++ b/src/editor-text-buffer-spell-adapter.c
@@ -190,6 +190,7 @@ editor_text_buffer_spell_adapter_update_range (EditorTextBufferSpellAdapter *sel
 {
   g_autoptr(EditorSpellCursor) cursor = NULL;
   GtkTextIter word_begin, word_end, begin;
+  const char *extra_word_chars;
   gboolean ret = FALSE;
   guint checked = 0;
 
@@ -199,7 +200,8 @@ editor_text_buffer_spell_adapter_update_range (EditorTextBufferSpellAdapter *sel
   if (editor_document_get_busy (EDITOR_DOCUMENT (self->buffer)))
     return TRUE;
 
-  cursor = editor_spell_cursor_new (self->buffer, self->region, self->no_spell_check_tag);
+  extra_word_chars = editor_spell_checker_get_extra_word_chars (self->checker);
+  cursor = editor_spell_cursor_new (self->buffer, self->region, self->no_spell_check_tag, extra_word_chars);
 
   /* Get the first unchecked position so that we can remove the tag
    * from it up to the first word match.
diff --git a/src/enchant/editor-enchant-spell-language.c b/src/enchant/editor-enchant-spell-language.c
index 04da11e..0480c82 100644
--- a/src/enchant/editor-enchant-spell-language.c
+++ b/src/enchant/editor-enchant-spell-language.c
@@ -174,6 +174,16 @@ editor_enchant_spell_language_ignore_word (EditorSpellLanguage *language,
   enchant_dict_add_to_session (self->native, word, -1);
 }
 
+static const char *
+editor_enchant_spell_language_get_extra_word_chars (EditorSpellLanguage *language)
+{
+  EditorEnchantSpellLanguage *self = (EditorEnchantSpellLanguage *)language;
+
+  g_assert (EDITOR_IS_SPELL_LANGUAGE (language));
+
+  return enchant_dict_get_extra_word_characters (self->native);
+}
+
 static void
 editor_enchant_spell_language_constructed (GObject *object)
 {
@@ -256,6 +266,7 @@ editor_enchant_spell_language_class_init (EditorEnchantSpellLanguageClass *klass
   spell_language_class->list_corrections = editor_enchant_spell_language_list_corrections;
   spell_language_class->add_word = editor_enchant_spell_language_add_word;
   spell_language_class->ignore_word = editor_enchant_spell_language_ignore_word;
+  spell_language_class->get_extra_word_chars = editor_enchant_spell_language_get_extra_word_chars;
 
   properties [PROP_NATIVE] =
     g_param_spec_pointer ("native",
diff --git a/src/test-spell-cursor.c b/src/test-spell-cursor.c
index b6f5b33..2062193 100644
--- a/src/test-spell-cursor.c
+++ b/src/test-spell-cursor.c
@@ -19,7 +19,7 @@ test_cursor (void)
 {
   g_autoptr(GtkTextBuffer) buffer = gtk_text_buffer_new (NULL);
   CjhTextRegion *region = _cjh_text_region_new (NULL, NULL);
-  g_autoptr(EditorSpellCursor) cursor = editor_spell_cursor_new (buffer, region, NULL);
+  g_autoptr(EditorSpellCursor) cursor = editor_spell_cursor_new (buffer, region, NULL, NULL);
   char *word;
 
   gtk_text_buffer_set_text (buffer, test_text, -1);
@@ -54,7 +54,7 @@ test_cursor_in_word (void)
 {
   g_autoptr(GtkTextBuffer) buffer = gtk_text_buffer_new (NULL);
   CjhTextRegion *region = _cjh_text_region_new (NULL, NULL);
-  g_autoptr(EditorSpellCursor) cursor = editor_spell_cursor_new (buffer, region, NULL);
+  g_autoptr(EditorSpellCursor) cursor = editor_spell_cursor_new (buffer, region, NULL, NULL);
   const char *pos = strstr (test_text, "ries "); /* se|ries */
   gsize offset = pos - test_text;
   char *word;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]