[gtksourceview/wip/fix-completion-words: 1/3] CompletionWords: get_word_at_iter(): work on strings



commit 04a1f7258bcae1345c2fec826e23ba1cfd86c154
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sat May 25 16:09:26 2013 +0200

    CompletionWords: get_word_at_iter(): work on strings
    
    Before this commit, get_word_at_iter() used GtkTextIter to traverse the
    buffer char by char, to find the word boundaries.
    
    Now, the text of the line at the iter is retrieved, and the traversal is
    done directly on the string. The code is simpler.
    
    It is maybe less efficient, but the performances here are not really
    important (it's at most one line of text).
    
    The parsing of the buffer to fill the words library is still done
    entirely with GtkTextIters. It is planned to parse the buffer line by
    line, by retrieving the text of the buffer and by working on strings.
    In this case, the performances are more important, and working on
    strings will be more efficient.
    
    So the idea is to work everywhere on strings instead of working with
    GtkTextIters, to be consistent.

 .../words/gtksourcecompletionwords.c               |   85 +++++--------------
 .../words/gtksourcecompletionwordsbuffer.c         |   19 -----
 .../words/gtksourcecompletionwordsbuffer.h         |    3 -
 .../words/gtksourcecompletionwordsutils.c          |   83 ++++++++++++-------
 .../words/gtksourcecompletionwordsutils.h          |    6 +-
 5 files changed, 78 insertions(+), 118 deletions(-)
---
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c 
b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
index 58eba66..c8c590e 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
@@ -3,6 +3,7 @@
  * This file is part of GtkSourceView
  *
  * Copyright (C) 2009 - Jesse van den Kieboom
+ * Copyright (C) 2013 - Sébastien Wilmet
  *
  * gtksourceview is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -42,8 +43,6 @@
 
 #define BUFFER_KEY "GtkSourceCompletionWordsBufferKey"
 
-#define GET_WORDS_BUFFER(buf) (((BufferBinding *)g_object_get_data(G_OBJECT(buf), BUFFER_KEY))->buffer)
-
 enum
 {
        PROP_0,
@@ -187,51 +186,24 @@ add_in_idle (GtkSourceCompletionWords *words)
        return !finished;
 }
 
-static gboolean
-valid_word_char (gunichar ch,
-                 gpointer data)
-{
-       return g_unichar_isprint (ch) && (ch == '_' || g_unichar_isalnum (ch));
-}
-
-static gboolean
-valid_start_char (gunichar ch,
-                  gpointer data)
-{
-       return !g_unichar_isdigit (ch);
-}
-
 static gchar *
-get_word_at_iter (GtkTextIter    *iter,
-                  CharacterCheck  valid,
-                  CharacterCheck  valid_start,
-                  gpointer        data)
+get_word_at_iter (GtkTextIter *iter)
 {
-       GtkTextIter end = *iter;
+       GtkTextBuffer *buffer;
+       GtkTextIter start_line;
+       gchar *line_text;
+       gchar *word;
 
-       if (!gtk_source_completion_words_utils_forward_word_end (iter, valid, data) ||
-           !gtk_text_iter_equal (iter, &end))
-       {
-               return NULL;
-       }
+       buffer = gtk_text_iter_get_buffer (iter);
+       start_line = *iter;
+       gtk_text_iter_set_line_offset (&start_line, 0);
 
-       if (!gtk_source_completion_words_utils_backward_word_start (iter,
-                                                                   valid,
-                                                                   valid_start,
-                                                                   data))
-       {
-               return NULL;
-       }
+       line_text = gtk_text_buffer_get_text (buffer, &start_line, iter, FALSE);
 
-       if (gtk_text_iter_equal (iter, &end))
-       {
-               return NULL;
-       }
-       else
-       {
-               return gtk_text_iter_get_text (iter, &end);
-       }
+       word = _gtk_source_completion_words_utils_get_end_word (line_text);
 
+       g_free (line_text);
+       return word;
 }
 
 static void
@@ -241,19 +213,13 @@ gtk_source_completion_words_populate (GtkSourceCompletionProvider *provider,
        GtkSourceCompletionWords *words = GTK_SOURCE_COMPLETION_WORDS (provider);
        GtkTextIter iter;
        gchar *word;
-       GtkTextBuffer *buffer;
-       GtkSourceCompletionWordsBuffer *buf;
 
        gtk_source_completion_context_get_iter (context, &iter);
-       buffer = gtk_text_iter_get_buffer (&iter);
 
        g_free (words->priv->word);
        words->priv->word = NULL;
 
-       word = get_word_at_iter (&iter,
-                                valid_word_char,
-                                valid_start_char,
-                                words);
+       word = get_word_at_iter (&iter);
 
        if (word == NULL ||
            g_utf8_strlen (word, -1) < words->priv->minimum_word_size)
@@ -277,11 +243,6 @@ gtk_source_completion_words_populate (GtkSourceCompletionProvider *provider,
        words->priv->word = word;
        words->priv->word_len = strlen (word);
 
-       buf = GET_WORDS_BUFFER (buffer);
-       gtk_text_buffer_move_mark (buffer,
-                                  gtk_source_completion_words_buffer_get_mark (buf),
-                                  &iter);
-
        /* Do first right now */
        if (add_in_idle (words))
        {
@@ -523,18 +484,18 @@ gtk_source_completion_words_get_start_iter (GtkSourceCompletionProvider *provide
                                             GtkSourceCompletionProposal *proposal,
                                             GtkTextIter                 *iter)
 {
-       GtkTextBuffer *buffer;
-       GtkSourceCompletionWordsBuffer *buf;
-       GtkTextIter it;
+       gchar *word;
+       glong nb_chars;
+
+       gtk_source_completion_context_get_iter (context, iter);
 
-       gtk_source_completion_context_get_iter (context, &it);
+       word = get_word_at_iter (iter);
+       g_return_val_if_fail (word != NULL, FALSE);
 
-       buffer = gtk_text_iter_get_buffer (&it);
-       buf = GET_WORDS_BUFFER (buffer);
+       nb_chars = g_utf8_strlen (word, -1);
+       gtk_text_iter_backward_chars (iter, nb_chars);
 
-       gtk_text_buffer_get_iter_at_mark (buffer,
-                                         iter,
-                                         gtk_source_completion_words_buffer_get_mark (buf));
+       g_free (word);
        return TRUE;
 }
 
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
index e946c07..036fd2b 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
@@ -54,7 +54,6 @@ struct _GtkSourceCompletionWordsBufferPrivate
        guint scan_batch_size;
        guint minimum_word_size;
 
-       GtkTextMark *mark;
        GHashTable *words;
 };
 
@@ -149,13 +148,6 @@ gtk_source_completion_words_buffer_dispose (GObject *object)
        GtkSourceCompletionWordsBuffer *buffer =
                GTK_SOURCE_COMPLETION_WORDS_BUFFER (object);
 
-       if (buffer->priv->mark)
-       {
-               gtk_text_buffer_delete_mark (gtk_text_mark_get_buffer (buffer->priv->mark),
-                                            buffer->priv->mark);
-               buffer->priv->mark = NULL;
-       }
-
        if (buffer->priv->words != NULL)
        {
                remove_words (buffer);
@@ -691,7 +683,6 @@ gtk_source_completion_words_buffer_new (GtkSourceCompletionWordsLibrary *library
                                         GtkTextBuffer                   *buffer)
 {
        GtkSourceCompletionWordsBuffer *ret;
-       GtkTextIter iter;
 
        g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_WORDS_LIBRARY (library), NULL);
        g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
@@ -707,8 +698,6 @@ gtk_source_completion_words_buffer_new (GtkSourceCompletionWordsLibrary *library
                                 ret,
                                 G_CONNECT_SWAPPED);
 
-       gtk_text_buffer_get_start_iter (buffer, &iter);
-       ret->priv->mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, TRUE);
        g_signal_connect_object (ret->priv->library,
                                 "unlock",
                                 G_CALLBACK (on_library_unlock),
@@ -747,11 +736,3 @@ gtk_source_completion_words_buffer_set_minimum_word_size (GtkSourceCompletionWor
 
        buffer->priv->minimum_word_size = size;
 }
-
-GtkTextMark *
-gtk_source_completion_words_buffer_get_mark (GtkSourceCompletionWordsBuffer *buffer)
-{
-       g_return_val_if_fail (GTK_SOURCE_IS_COMPLETION_WORDS_BUFFER (buffer), NULL);
-
-       return buffer->priv->mark;
-}
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.h 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.h
index b5556cc..b7bb090 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.h
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.h
@@ -69,9 +69,6 @@ G_GNUC_INTERNAL
 void            gtk_source_completion_words_buffer_set_minimum_word_size       
(GtkSourceCompletionWordsBuffer  *buffer,
                                                                                 guint                        
    size);
 
-G_GNUC_INTERNAL
-GtkTextMark     *gtk_source_completion_words_buffer_get_mark                   
(GtkSourceCompletionWordsBuffer  *buffer);
-
 G_END_DECLS
 
 #endif /* __GTK_SOURCE_COMPLETION_WORDS_BUFFER_H__ */
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
index 5695008..edc1a8c 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
@@ -3,6 +3,7 @@
  * This file is part of GtkSourceView
  *
  * Copyright (C) 2009 - Jesse van den Kieboom
+ * Copyright (C) 2013 - Sébastien Wilmet
  *
  * gtksourceview is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,66 +21,88 @@
  */
 
 #include "gtksourcecompletionwordsutils.h"
+#include <string.h>
 
 gboolean
-gtk_source_completion_words_utils_backward_word_start (GtkTextIter    *iter,
-                                                       CharacterCheck  valid,
-                                                       CharacterCheck  valid_start,
-                                                       gpointer        data)
+gtk_source_completion_words_utils_forward_word_end (GtkTextIter    *iter,
+                                                    CharacterCheck  valid,
+                                                    gpointer        data)
 {
-       GtkTextIter prev = *iter;
-
        /* Go backward as long as there are word characters */
        while (TRUE)
        {
-               /* Starting a line is good */
-               if (gtk_text_iter_starts_line (&prev))
+               /* Ending a line is good */
+               if (gtk_text_iter_ends_line (iter))
                {
                        break;
                }
 
-               gtk_text_iter_backward_char (&prev);
-
-               /* Check if the previous character is a valid word character */
-               if (!valid (gtk_text_iter_get_char (&prev), data))
+               /* Check if the next character is a valid word character */
+               if (!valid (gtk_text_iter_get_char (iter), data))
                {
                        break;
                }
 
-               *iter = prev;
+               gtk_text_iter_forward_char (iter);
        }
 
-       if (!valid (gtk_text_iter_get_char (iter), data))
-       {
-               return FALSE;
-       }
+       return TRUE;
+}
 
-       /* Go forward with while !valid_start */
-       return valid_start (gtk_text_iter_get_char (iter), data);
+static gboolean
+valid_word_char (gunichar ch)
+{
+       return g_unichar_isprint (ch) && (ch == '_' || g_unichar_isalnum (ch));
 }
 
-gboolean
-gtk_source_completion_words_utils_forward_word_end (GtkTextIter    *iter,
-                                                    CharacterCheck  valid,
-                                                    gpointer        data)
+static gboolean
+valid_start_char (gunichar ch)
 {
-       /* Go backward as long as there are word characters */
+       return !g_unichar_isdigit (ch);
+}
+
+/* Get the word at the end of @text.
+ * Returns %NULL if not found.
+ * Free the return value with g_free().
+ */
+gchar *
+_gtk_source_completion_words_utils_get_end_word (gchar *text)
+{
+       gchar *cur_char = text + strlen (text);
+       gboolean word_found = FALSE;
+       gunichar ch;
+
        while (TRUE)
        {
-               /* Ending a line is good */
-               if (gtk_text_iter_ends_line (iter))
+               gchar *prev_char = g_utf8_find_prev_char (text, cur_char);
+
+               if (prev_char == NULL)
                {
                        break;
                }
 
-               /* Check if the next character is a valid word character */
-               if (!valid (gtk_text_iter_get_char (iter), data))
+               ch = g_utf8_get_char (prev_char);
+
+               if (!valid_word_char (ch))
                {
                        break;
                }
 
-               gtk_text_iter_forward_char (iter);
+               word_found = TRUE;
+               cur_char = prev_char;
        }
 
-       return TRUE;
+       if (!word_found)
+       {
+               return NULL;
+       }
+
+       ch = g_utf8_get_char (cur_char);
+
+       if (!valid_start_char (ch))
+       {
+               return NULL;
+       }
+
+       return g_strdup (cur_char);
 }
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h 
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
index bedd94d..5d6650c 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
@@ -3,6 +3,7 @@
  * This file is part of GtkSourceView
  *
  * Copyright (C) 2009 - Jesse van den Kieboom
+ * Copyright (C) 2013 - Sébastien Wilmet
  *
  * gtksourceview is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,10 +35,7 @@ gboolean      gtk_source_completion_words_utils_forward_word_end     (GtkTextIter    *i
                                                                         gpointer        data);
 
 G_GNUC_INTERNAL
-gboolean        gtk_source_completion_words_utils_backward_word_start  (GtkTextIter    *iter,
-                                                                        CharacterCheck  valid,
-                                                                        CharacterCheck  valid_start,
-                                                                        gpointer        data);
+gchar          *_gtk_source_completion_words_utils_get_end_word        (gchar          *text);
 
 G_END_DECLS
 


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