[gtksourceview/gtksourcecompletion] Hopefully fixed finding word boundaries



commit e7079f224e7e8e3598a5dcb4ea31d5154ab0a125
Author: Jesse van den Kieboom <jessevdk gnome org>
Date:   Wed Sep 23 21:33:33 2009 +0200

    Hopefully fixed finding word boundaries

 .../completion-providers/words/Makefile.am         |    4 +-
 .../words/gtksourcecompletionwords.c               |  110 ++++++++++----------
 .../words/gtksourcecompletionwordsbuffer.c         |   94 +++++------------
 .../words/gtksourcecompletionwordsutils.c          |   86 +++++++++++++++
 .../words/gtksourcecompletionwordsutils.h          |   38 +++++++
 5 files changed, 208 insertions(+), 124 deletions(-)
---
diff --git a/gtksourceview/completion-providers/words/Makefile.am b/gtksourceview/completion-providers/words/Makefile.am
index bd4b286..3c9e07f 100644
--- a/gtksourceview/completion-providers/words/Makefile.am
+++ b/gtksourceview/completion-providers/words/Makefile.am
@@ -11,7 +11,8 @@ noinst_LTLIBRARIES = libgtksourcecompletionwords.la
 NOINST_H_FILES =				\
 	gtksourcecompletionwordslibrary.h	\
 	gtksourcecompletionwordsproposal.h	\
-	gtksourcecompletionwordsbuffer.h
+	gtksourcecompletionwordsbuffer.h	\
+	gtksourcecompletionwordsutils.h
 
 libgtksourcecompletionwords_headers = 		\
 	gtksourcecompletionwords.h
@@ -21,6 +22,7 @@ libgtksourcecompletionwords_la_SOURCES =	\
 	gtksourcecompletionwordslibrary.c	\
 	gtksourcecompletionwordsproposal.c	\
 	gtksourcecompletionwordsbuffer.c	\
+	gtksourcecompletionwordsutils.c		\
 	$(libgtksourcecompletionwords_headers)	\
 	$(NOINST_H_FILES)
 
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
index 1f3d5d2..0c504e4 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
@@ -23,6 +23,7 @@
 #include "gtksourcecompletionwords.h"
 #include "gtksourcecompletionwordslibrary.h"
 #include "gtksourcecompletionwordsbuffer.h"
+#include "gtksourcecompletionwordsutils.h"
 
 #include <gtksourceview/gtksourcecompletion.h>
 #include <gtksourceview/gtksourceview-i18n.h>
@@ -98,13 +99,6 @@ gtk_source_completion_words_get_icon (GtkSourceCompletionProvider *self)
 	return GTK_SOURCE_COMPLETION_WORDS (self)->priv->icon;
 }
 
-static gboolean
-is_word_char (gunichar ch)
-{
-	return g_unichar_isprint (ch) && 
-	       (g_unichar_isalnum (ch) || ch == g_utf8_get_char ("_"));
-}
-
 static void
 population_finished (GtkSourceCompletionWords *words)
 {
@@ -131,39 +125,6 @@ population_finished (GtkSourceCompletionWords *words)
 	}
 }
 
-static gchar *
-get_word_at_iter (GtkSourceCompletionWords *words,
-                  GtkTextIter              *iter)
-{
-	GtkTextIter start = *iter;
-	gint line = gtk_text_iter_get_line (iter);
-	gboolean went_back = TRUE;
-	
-	if (!gtk_text_iter_backward_char (&start))
-	{
-		return NULL;
-	}
-
-	while (went_back &&
-	       line == gtk_text_iter_get_line (&start) && 
-	       is_word_char (gtk_text_iter_get_char (&start)))
-	{
-		went_back = gtk_text_iter_backward_char (&start);
-	}
-	
-	if (went_back)
-	{
-		gtk_text_iter_forward_char (&start);
-	}
-	
-	if (gtk_text_iter_equal (iter, &start))
-	{
-		return NULL;
-	}
-
-	return gtk_text_iter_get_text (&start, iter);
-}
-
 static gboolean
 add_in_idle (GtkSourceCompletionWords *words)
 {
@@ -171,18 +132,6 @@ add_in_idle (GtkSourceCompletionWords *words)
 	GList *ret = NULL;
 	gboolean finished;
 	
-	/* Don't complete empty string (when word == NULL) */
-	if (words->priv->word == NULL || 
-	    g_utf8_strlen (words->priv->word, -1) < words->priv->minimum_word_size)
-	{
-		gtk_source_completion_context_add_proposals (words->priv->context,
-	                                                     GTK_SOURCE_COMPLETION_PROVIDER (words),
-	                                                     NULL,
-	                                                     TRUE);
-		population_finished (words);
-		return FALSE;
-	}
-	
 	if (words->priv->populate_iter == NULL)
 	{
 		words->priv->populate_iter = 
@@ -229,6 +178,51 @@ add_in_idle (GtkSourceCompletionWords *words)
 }
 
 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)
+{
+	GtkTextIter end = *iter;
+	
+	if (!gtk_source_completion_words_utils_forward_word_end (iter, valid, data) ||
+	    !gtk_text_iter_equal (iter, &end))
+	{
+		return NULL;
+	}
+	
+	if (!gtk_source_completion_words_utils_backward_word_start (iter,
+	                                                            valid,
+	                                                            valid_start,
+	                                                            data))
+	{
+		return NULL;
+	}
+	
+	if (gtk_text_iter_equal (iter, &end))
+	{
+		return NULL;
+	}
+	else
+	{
+		return gtk_text_iter_get_text (iter, &end);
+	}
+}
+static gboolean
 gtk_source_completion_words_match (GtkSourceCompletionProvider *provider,
                                    GtkSourceCompletionContext  *context)
 {
@@ -238,7 +232,10 @@ gtk_source_completion_words_match (GtkSourceCompletionProvider *provider,
 	gboolean ret;
 
 	gtk_source_completion_context_get_iter (context, &iter);
-	word = get_word_at_iter (words, &iter);
+	word = get_word_at_iter (&iter,
+	                         valid_word_char,
+	                         valid_start_char,
+	                         words);
 	
 	ret = word != NULL && g_utf8_strlen (word, -1) >= words->priv->minimum_word_size;
 	g_free (word);
@@ -257,7 +254,12 @@ gtk_source_completion_words_populate (GtkSourceCompletionProvider *provider,
 	gtk_source_completion_context_get_iter (context, &iter);
 
 	g_free (words->priv->word);
-	word = get_word_at_iter (words, &iter);
+	words->priv->word = NULL;
+
+	word = get_word_at_iter (&iter,
+	                         valid_word_char,
+	                         valid_start_char,
+	                         words);
 	
 	if (word == NULL || 
 	    g_utf8_strlen (word, -1) < words->priv->minimum_word_size)
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
index 56c5dcf..6f042b6 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsbuffer.c
@@ -21,6 +21,7 @@
  */
 
 #include "gtksourcecompletionwordsbuffer.h"
+#include "gtksourcecompletionwordsutils.h"
 
 #define GTK_SOURCE_COMPLETION_WORDS_BUFFER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GTK_TYPE_SOURCE_COMPLETION_WORDS_BUFFER, GtkSourceCompletionWordsBufferPrivate))
 
@@ -176,54 +177,16 @@ on_insert_text_cb (GtkTextBuffer                  *textbuffer,
 }
 
 static gboolean
-is_word_char (gunichar ch)
+valid_word_char (gunichar ch, 
+                 gpointer data)
 {
-	return g_unichar_isprint (ch) && 
-	       (g_unichar_isalnum (ch) || ch == g_utf8_get_char ("_"));
+	return g_unichar_isprint (ch) && (ch == '_' || g_unichar_isalnum (ch));
 }
 
 static gboolean
-iter_at_word_start (GtkTextIter *iter)
+valid_start_char (gunichar ch)
 {
-	GtkTextIter prev = *iter;
-	
-	if (!gtk_text_iter_starts_word (iter) ||
-	    g_unichar_isdigit (gtk_text_iter_get_char (iter)))
-	{
-		return FALSE;
-	}
-	
-	if (!gtk_text_iter_is_start (&prev) && 
-	    !gtk_text_iter_starts_line (&prev))
-	{
-		gtk_text_iter_backward_char (&prev);
-		
-		return !is_word_char (gtk_text_iter_get_char (&prev));
-	}
-	else
-	{
-		return TRUE;
-	}
-}
-
-static gboolean
-iter_at_word_end (GtkTextIter *iter)
-{
-	if (!gtk_text_iter_ends_word (iter) || 
-	    g_unichar_isdigit (gtk_text_iter_get_char (iter)))
-	{
-		return FALSE;
-	}
-	
-	if (!gtk_text_iter_is_end (iter) && 
-	    !gtk_text_iter_ends_line (iter))
-	{
-		return !is_word_char (gtk_text_iter_get_char (iter));
-	}
-	else
-	{
-		return TRUE;
-	}
+	return !g_unichar_isdigit (ch);
 }
 
 static GList *
@@ -240,49 +203,42 @@ scan_line (GtkSourceCompletionWordsBuffer *buffer,
 	{
 		gchar *word;
 		
-		/* Forward start to next word start */
-		while (!iter_at_word_start (&start) && 
-		       !gtk_text_iter_ends_line (&start))
+		while (!gtk_text_iter_ends_line (&start) &&
+		       !valid_word_char (gtk_text_iter_get_char (&start), NULL))
 		{
-			if (!gtk_text_iter_forward_char (&start))
-			{
-				break;
-			}
+			gtk_text_iter_forward_char (&start);
 		}
 		
 		if (gtk_text_iter_ends_line (&start))
 		{
 			break;
 		}
-		
+
 		end = start;
 		
-		if (!gtk_text_iter_forward_char (&end))
+		if (!gtk_source_completion_words_utils_forward_word_end (&end,
+		                                                         valid_word_char,
+		                                                         NULL))
 		{
 			break;
 		}
 		
-		/* Forward end to next word end */
-		while (!iter_at_word_end (&end))
+		if (valid_start_char (gtk_text_iter_get_char (&start)))
 		{
-			if (!gtk_text_iter_forward_char (&end))
+			if (gtk_text_iter_get_offset (&end) - 
+			    gtk_text_iter_get_offset (&start) >= buffer->priv->minimum_word_size)
 			{
-				break;
-			}
-		}
-		
-		if (gtk_text_iter_get_offset (&end) - gtk_text_iter_get_offset (&start) > 2)
-		{
-			GtkSourceCompletionWordsProposal *proposal;
+				GtkSourceCompletionWordsProposal *proposal;
 			
-			word = gtk_text_iter_get_text (&start, &end);
-			proposal = gtk_source_completion_words_library_add_word (buffer->priv->library,
-			                                                         word);
+				word = gtk_text_iter_get_text (&start, &end);
+				proposal = gtk_source_completion_words_library_add_word (buffer->priv->library,
+					                                                 word);
 			
-			if (proposal != NULL)
-			{
-				ret = g_list_prepend (ret, proposal);
-				g_free (word);
+				if (proposal != NULL)
+				{
+					ret = g_list_prepend (ret, proposal);
+					g_free (word);
+				}
 			}
 		}
 		
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
new file mode 100644
index 0000000..bf1424e
--- /dev/null
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.c
@@ -0,0 +1,86 @@
+/*
+ * gtksourcecompletionwordsutils.c
+ * This file is part of gtksourceview
+ *
+ * Copyright (C) 2009 - Jesse van den Kieboom
+ *
+ * gtksourceview is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gtksourceview is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gtksourceview; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#include "gtksourcecompletionwordsutils.h"
+
+gboolean
+gtk_source_completion_words_utils_backward_word_start (GtkTextIter    *iter,
+                                                       CharacterCheck  valid,
+                                                       CharacterCheck  valid_start,
+                                                       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))
+		{
+			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))
+		{
+			break;
+		}
+		
+		*iter = prev;
+	}
+	
+	if (!valid (gtk_text_iter_get_char (iter), data))
+	{
+		return FALSE;
+	}
+	
+	/* Go forward with while !valid_start */
+	return valid_start (gtk_text_iter_get_char (iter), data);
+}
+
+gboolean
+gtk_source_completion_words_utils_forward_word_end (GtkTextIter    *iter,
+                                                    CharacterCheck  valid,
+                                                    gpointer        data)
+{
+	/* Go backward as long as there are word characters */
+	while (TRUE)
+	{
+		/* Ending a line is good */
+		if (gtk_text_iter_ends_line (iter))
+		{
+			break;
+		}
+		
+		gtk_text_iter_forward_char (iter);
+		
+		/* Check if the next character is a valid word character */
+		if (!valid (gtk_text_iter_get_char (iter), data))
+		{
+			break;
+		}
+	}
+	
+	return TRUE;
+}
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
new file mode 100644
index 0000000..6e03e56
--- /dev/null
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwordsutils.h
@@ -0,0 +1,38 @@
+/*
+ * gtksourcecompletionwordsutils.h
+ * This file is part of gtksourceview
+ *
+ * Copyright (C) 2009 - Jesse van den Kieboom
+ *
+ * gtksourceview is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gtksourceview is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gtksourceview; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, 
+ * Boston, MA  02110-1301  USA
+ */
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef gboolean (*CharacterCheck)(gunichar ch, gpointer data);
+
+gboolean	 gtk_source_completion_words_utils_forward_word_end 	(GtkTextIter    *iter,
+									 CharacterCheck  valid,
+									 gpointer        data);
+
+gboolean	 gtk_source_completion_words_utils_backward_word_start 	(GtkTextIter    *iter,
+									 CharacterCheck  valid,
+									 CharacterCheck  valid_start,
+									 gpointer        data);
+
+G_END_DECLS



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