[gtksourceview/wip/fix-completion-words: 2/3] CompletionWords buffer: work with strings for scanning the words
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/fix-completion-words: 2/3] CompletionWords buffer: work with strings for scanning the words
- Date: Sat, 8 Jun 2013 16:32:58 +0000 (UTC)
commit f2f8f182035366682a84001bf2674810c9c29e79
Author: Sébastien Wilmet <swilmet gnome org>
Date: Sat Jun 8 15:54:25 2013 +0200
CompletionWords buffer: work with strings for scanning the words
Instead of working with GtkTextIters. It normally improves the
performances.
And there was maybe a bug with the previous code (warning messages).
.../words/gtksourcecompletionwordsbuffer.c | 75 ++++----------
.../words/gtksourcecompletionwordslibrary.c | 1 +
.../words/gtksourcecompletionwordsutils.c | 106 ++++++++++++++++----
.../words/gtksourcecompletionwordsutils.h | 9 +-
4 files changed, 109 insertions(+), 82 deletions(-)
---
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
index 036fd2b..be483de 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.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
@@ -201,70 +202,32 @@ gtk_source_completion_words_buffer_init (GtkSourceCompletionWordsBuffer *self)
(GDestroyNotify)proposal_cache_free);
}
-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)
-{
- return !g_unichar_isdigit (ch);
-}
-
static GSList *
scan_line (GtkSourceCompletionWordsBuffer *buffer,
GtkTextIter *start)
{
- GSList *ret = NULL;
- GtkTextIter end;
- gint line = gtk_text_iter_get_line (start);
+ GtkTextIter end = *start;
+ gchar *text_line;
+ GSList *words;
- while (line == gtk_text_iter_get_line (start))
+ if (!gtk_text_iter_starts_line (start))
{
- gchar *word;
-
- while (!gtk_text_iter_ends_line (start) &&
- !valid_word_char (gtk_text_iter_get_char (start), NULL))
- {
- gtk_text_iter_forward_char (start);
- }
-
- if (gtk_text_iter_ends_line (start))
- {
- break;
- }
-
- end = *start;
-
- if (!gtk_source_completion_words_utils_forward_word_end (&end,
- valid_word_char,
- NULL))
- {
- break;
- }
+ g_warning ("scan line: 'start' doesn't start a line.");
+ gtk_text_iter_set_line_offset (start, 0);
+ }
- if (valid_start_char (gtk_text_iter_get_char (start)))
- {
- if (gtk_text_iter_get_offset (&end) -
- gtk_text_iter_get_offset (start) >= buffer->priv->minimum_word_size)
- {
- word = gtk_text_iter_get_text (start, &end);
- ret = g_slist_prepend (ret, word);
- }
- }
+ gtk_text_iter_forward_to_line_end (&end);
- *start = end;
+ text_line = gtk_text_buffer_get_text (buffer->priv->buffer,
+ start,
+ &end,
+ FALSE);
- if (!gtk_text_iter_forward_char (start))
- {
- break;
- }
- }
+ words = _gtk_source_completion_words_utils_scan_words (text_line,
+ buffer->priv->minimum_word_size);
- return ret;
+ g_free (text_line);
+ return words;
}
static void
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordslibrary.c
b/gtksourceview/completion-providers/words/gtksourcecompletionwordslibrary.c
index 1e898d4..8f70fd2 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordslibrary.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordslibrary.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
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
index edc1a8c..d27034b 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
@@ -23,42 +23,108 @@
#include "gtksourcecompletionwordsutils.h"
#include <string.h>
-gboolean
-gtk_source_completion_words_utils_forward_word_end (GtkTextIter *iter,
- CharacterCheck valid,
- gpointer data)
+/* Here, we work on strings. It is more efficient than working with
+ * GtkTextIters to traverse the text. Both techniques are equally difficult to
+ * implement.
+ */
+
+static gboolean
+valid_word_char (gunichar ch)
+{
+ return g_unichar_isprint (ch) && (ch == '_' || g_unichar_isalnum (ch));
+}
+
+static gboolean
+valid_start_char (gunichar ch)
+{
+ return !g_unichar_isdigit (ch);
+}
+
+/* Find the next word in @text, beginning at the index @start_idx.
+ * Use only valid_word_char() to find the word boundaries.
+ * Store in @start_idx and @end_idx the word boundaries. The character at
+ * @start_idx is included in the word, but the character at @end_idx is not
+ * included in the word (it is the next char, or '\0').
+ *
+ * Returns %TRUE if a word has been found.
+ */
+static gboolean
+find_next_word (gchar *text,
+ guint *start_idx,
+ guint *end_idx)
{
- /* Go backward as long as there are word characters */
+ gchar *cur_char;
+
+ /* Find the start of the next word */
+
+ cur_char = text + *start_idx;
+
while (TRUE)
{
- /* Ending a line is good */
- if (gtk_text_iter_ends_line (iter))
+ gunichar ch = g_utf8_get_char (cur_char);
+
+ if (ch == '\0')
{
- break;
+ return FALSE;
}
- /* Check if the next character is a valid word character */
- if (!valid (gtk_text_iter_get_char (iter), data))
+ if (valid_word_char (ch))
{
+ *start_idx = cur_char - text;
break;
}
- gtk_text_iter_forward_char (iter);
+ cur_char = g_utf8_next_char (cur_char);
}
- return TRUE;
-}
+ /* Find the end of the word */
-static gboolean
-valid_word_char (gunichar ch)
-{
- return g_unichar_isprint (ch) && (ch == '_' || g_unichar_isalnum (ch));
+ while (TRUE)
+ {
+ gunichar ch;
+
+ cur_char = g_utf8_next_char (cur_char);
+ ch = g_utf8_get_char (cur_char);
+
+ if (ch == '\0' ||
+ !valid_word_char (ch))
+ {
+ *end_idx = cur_char - text;
+ return TRUE;
+ }
+ }
}
-static gboolean
-valid_start_char (gunichar ch)
+/* Get the list of words in @text.
+ * You must free the data with g_free(), and free the list with
+ * g_slist_free().
+ */
+GSList *
+_gtk_source_completion_words_utils_scan_words (gchar *text,
+ guint minimum_word_size)
{
- return !g_unichar_isdigit (ch);
+ GSList *words = NULL;
+ guint start_idx = 0;
+ guint end_idx = 0;
+
+ while (find_next_word (text, &start_idx, &end_idx))
+ {
+ gint word_size = end_idx - start_idx;
+ gunichar ch = g_utf8_get_char (text + start_idx);
+
+ g_assert (word_size >= 0);
+
+ if (word_size >= minimum_word_size &&
+ valid_start_char (ch))
+ {
+ gchar *new_word = g_strndup (text + start_idx, word_size);
+ words = g_slist_prepend (words, new_word);
+ }
+
+ start_idx = end_idx;
+ }
+
+ return words;
}
/* Get the word at the end of @text.
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
index 5d6650c..7c4f100 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
@@ -27,15 +27,12 @@
G_BEGIN_DECLS
-typedef gboolean (*CharacterCheck)(gunichar ch, gpointer data);
-
G_GNUC_INTERNAL
-gboolean gtk_source_completion_words_utils_forward_word_end (GtkTextIter *iter,
- CharacterCheck valid,
- gpointer data);
+GSList *_gtk_source_completion_words_utils_scan_words (gchar *text,
+ guint minimum_word_size);
G_GNUC_INTERNAL
-gchar *_gtk_source_completion_words_utils_get_end_word (gchar *text);
+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]