[gtksourceview: 5/5] words-completion: work by words instead of lines



commit 3e4e186c04d24d482523ef3a2c753d92013061c2
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat May 31 22:05:15 2014 +0200

    words-completion: work by words instead of lines
    
    For example, if I insert a character in this line (at the cursor
    position |):
    word1 word2 | word3
    
    Before this commit: before the text insertion, word1 word2 and word3 are
    removed from the library. If these words are not present elsewhere in
    the buffer, they are not available for completion when I insert the
    text.
    
    After this commit: instead of working line by line, the region to scan
    (either for removing or adding words) is adjusted to word boundaries,
    not line boundaries. So word1, word2 and word3 are available for
    completion.

 .../words/gtksourcecompletionwordsbuffer.c         |   46 +++++++-------------
 .../words/gtksourcecompletionwordsutils.c          |   32 ++++++++++++++
 .../words/gtksourcecompletionwordsutils.h          |    4 ++
 3 files changed, 52 insertions(+), 30 deletions(-)
---
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
index 6a250b5..1615ae4 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
@@ -492,8 +492,9 @@ compute_remove_region (GtkSourceCompletionWordsBuffer *buffer,
        return remove_region;
 }
 
-/* If some lines between @start and @end are not in the scan region, remove the
- * words in those lines.
+/* Remove the words between @start and @end that are not in the scan region.
+ * @start and @end are adjusted to word boundaries, if they touch or are inside
+ * a word.
  */
 static void
 invalidate_region (GtkSourceCompletionWordsBuffer *buffer,
@@ -504,15 +505,7 @@ invalidate_region (GtkSourceCompletionWordsBuffer *buffer,
        GtkTextIter end_iter = *end;
        GtkTextRegion *remove_region;
 
-       if (!gtk_text_iter_starts_line (&start_iter))
-       {
-               gtk_text_iter_set_line_offset (&start_iter, 0);
-       }
-
-       if (!gtk_text_iter_ends_line (&end_iter))
-       {
-               gtk_text_iter_forward_to_line_end (&end_iter);
-       }
+       _gtk_source_completion_words_utils_adjust_region (&start_iter, &end_iter);
 
        remove_region = compute_remove_region (buffer, &start_iter, &end_iter);
 
@@ -528,15 +521,7 @@ add_to_scan_region (GtkSourceCompletionWordsBuffer *buffer,
        GtkTextIter start_iter = *start;
        GtkTextIter end_iter = *end;
 
-       if (!gtk_text_iter_starts_line (&start_iter))
-       {
-               gtk_text_iter_set_line_offset (&start_iter, 0);
-       }
-
-       if (!gtk_text_iter_ends_line (&end_iter))
-       {
-               gtk_text_iter_forward_to_line_end (&end_iter);
-       }
+       _gtk_source_completion_words_utils_adjust_region (&start_iter, &end_iter);
 
        gtk_text_region_add (buffer->priv->scan_region,
                             &start_iter,
@@ -567,10 +552,10 @@ on_insert_text_after_cb (GtkTextBuffer                  *textbuffer,
 
        gtk_text_iter_backward_chars (&start_iter, nb_chars);
 
-       /* If add_to_scan_region() is called before the text insertion, if the
-        * line is empty, the TextRegion is empty too and it is not added to the
+       /* If add_to_scan_region() is called before the text insertion, the
+        * created GtkTextRegion can be empty and is thus not added to the
         * scan region. After the text insertion, we are sure that the
-        * TextRegion is not empty and that the words will be scanned.
+        * GtkTextRegion is not empty and that the words will be scanned.
         */
        add_to_scan_region (buffer, &start_iter, location);
 }
@@ -607,13 +592,14 @@ on_delete_range_after_cb (GtkTextBuffer                  *text_buffer,
                          GtkTextIter                    *end,
                          GtkSourceCompletionWordsBuffer *buffer)
 {
-       /* start = end, but add_to_scan_region() moves the iters to the start
-        * and the end of the line. If the line is empty, the TextRegion won't
-        * be added to the scan region. If we call add_to_scan_region() when the
-        * text is not already deleted, the TextRegion is not empty and will be
-        * added to the scan region, and when the TextRegion becomes empty after
-        * the text deletion, the TextRegion is not removed from the scan
-        * region. Hence two callbacks: before and after the text deletion.
+       /* start = end, but add_to_scan_region() adjusts the iters to word
+        * boundaries if needed. If the adjusted [start,end] region is empty, it
+        * won't be added to the scan region. If we call add_to_scan_region()
+        * when the text is not already deleted, the GtkTextRegion is not empty
+        * and will be added to the scan region, and when the GtkTextRegion
+        * becomes empty after the text deletion, the GtkTextRegion is not
+        * removed from the scan region. Hence two callbacks: before and after
+        * the text deletion.
         */
        add_to_scan_region (buffer, start, end);
 }
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
index ad39e74..f8317f1 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
@@ -172,3 +172,35 @@ _gtk_source_completion_words_utils_get_end_word (gchar *text)
 
        return g_strdup (cur_char);
 }
+
+/* Adjust @start and @end to word boundaries, if they touch or are inside a
+ * word. Uses only valid_word_char().
+ */
+void
+_gtk_source_completion_words_utils_adjust_region (GtkTextIter *start,
+                                                 GtkTextIter *end)
+{
+       g_return_if_fail (gtk_text_iter_compare (start, end) <= 0);
+
+       while (TRUE)
+       {
+               GtkTextIter iter = *start;
+
+               if (!gtk_text_iter_backward_char (&iter))
+               {
+                       break;
+               }
+
+               if (!valid_word_char (gtk_text_iter_get_char (&iter)))
+               {
+                       break;
+               }
+
+               *start = iter;
+       }
+
+       while (valid_word_char (gtk_text_iter_get_char (end)))
+       {
+               gtk_text_iter_forward_char (end);
+       }
+}
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
index 7c4f100..04b0fc5 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
@@ -34,6 +34,10 @@ GSList               *_gtk_source_completion_words_utils_scan_words          (gchar *text,
 G_GNUC_INTERNAL
 gchar          *_gtk_source_completion_words_utils_get_end_word        (gchar *text);
 
+G_GNUC_INTERNAL
+void            _gtk_source_completion_words_utils_adjust_region       (GtkTextIter *start,
+                                                                        GtkTextIter *end);
+
 G_END_DECLS
 
 #endif /* __GTK_SOURCE_COMPLETION_WORDS_UTILS_H__ */


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