summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRichard Hitt <rbh00@localhost.localdomain>2013-09-18 15:25:50 -0700
committerRichard Hitt <rbh00@localhost.localdomain>2013-09-18 15:25:50 -0700
commitcd825ac735303393f2b36bfcd3dc99e1cf93b1db (patch)
treed003b999671f1796d4cc90cadfe21d6cecd6c824
parent1007af9506dc94f3ab41ee52e4899182a48c8dec (diff)
Improve text repositioning when searchbar string is modified.
-rw-r--r--src/fe-gtk/xtext.c56
-rw-r--r--src/fe-gtk/xtext.h15
2 files changed, 44 insertions, 27 deletions
diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c
index 3850b3be..44ac9cc5 100644
--- a/src/fe-gtk/xtext.c
+++ b/src/fe-gtk/xtext.c
@@ -96,20 +96,6 @@
 
 static GtkWidgetClass *parent_class = NULL;
 
-/*
- * offsets_t is used for retaining search information.
- * It is stored in the 'data' member of a GList,
- * as chained from ent->marks.  It saves starting and
- * ending+1 offset of a found occurrence.
- */
-typedef union offsets_u {
-	struct offsets_s {
-		guint16	start;
-		guint16	end;
-	} o;
-	guint32 u;
-} offsets_t;
-
 struct textentry
 {
 	struct textentry *next;
@@ -5265,7 +5251,7 @@ gtk_xtext_unstrip_color (gint start, gint end, GSList *slp, GList **gl, gint max
 	while (cursl)
 	{
 		offlen_t ol;
-		ol.u = GPOINTER_TO_UINT(cursl->data);
+		ol.u = GPOINTER_TO_UINT (cursl->data);
 		if (start < ol.o.len)
 		{
 			off1 = ol.o.off + start;
@@ -5281,7 +5267,7 @@ gtk_xtext_unstrip_color (gint start, gint end, GSList *slp, GList **gl, gint max
 	while (cursl)
 	{
 		offlen_t ol;
-		ol.u = GPOINTER_TO_UINT(cursl->data);
+		ol.u = GPOINTER_TO_UINT (cursl->data);
 		if (end < ol.o.len)
 		{
 			off2 = ol.o.off + end;
@@ -5393,6 +5379,7 @@ gtk_xtext_search_textentry_del (xtext_buffer *buf, textentry *ent)
 	{
 		buf->cursearch = NULL;
 		buf->curmark = NULL;
+		buf->curdata.u = 0;
 	}
 	if (buf->pagetop_ent == ent)
 	{
@@ -5429,6 +5416,7 @@ gtk_xtext_search_fini (xtext_buffer *buf)
 	buf->search_flags = 0;
 	buf->cursearch = NULL;
 	buf->curmark = NULL;
+	/* but leave buf->curdata.u alone! */
 	if (buf->search_re)
 	{
 		g_regex_unref (buf->search_re);
@@ -5475,6 +5463,7 @@ gtk_xtext_search_init (xtext_buffer *buf, const gchar *text, gtk_xtext_search_fl
 	buf->search_flags = flags;
 	buf->cursearch = NULL;
 	buf->curmark = NULL;
+	/* but leave buf->curdata.u alone! */
 	return FALSE;
 }
 
@@ -5565,24 +5554,36 @@ gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags fl
 					}
 				}
 			}
-#if 0
+
 			/* If user changed the search, let's look starting where he was */
 			else if (buf->hintsearch)
 			{
-				for (ent = buf->hintsearch; ent; ent = BACKWARD? ent->prev: ent->next)
-					if (ent->marks)
-						break;
-				if (ent == NULL)
-					for (ent = buf->hintsearch; ent; ent = BACKWARD? ent->next: ent->prev)
+				GList *mark;
+				offsets_t last, this;
+				/*
+				 * If we already have a 'current' item from the last search, and if
+				 * the first character of an occurrence on this line for this new search
+				 * is within that former item, use the occurrence as current.
+				 */
+				ent = buf->hintsearch;
+				last.u = buf->curdata.u;
+				for (mark = ent->marks; mark; mark = mark->next)
+				{
+					this.u = GPOINTER_TO_UINT (mark->data);
+					if (this.o.start >= last.o.start && this.o.start < last.o.end)
+					break;
+				}
+				if (mark == NULL)
+				{
+					for (ent = buf->hintsearch; ent; ent = BACKWARD? ent->prev: ent->next)
 						if (ent->marks)
 							break;
-				if (ent)
-				{
-					buf->cursearch = g_list_find (buf->search_found, ent);
-					buf->curmark = FIRSTLAST (ent->marks);
+					mark = ent? FIRSTLAST (ent->marks): NULL;
 				}
+				buf->cursearch = g_list_find (buf->search_found, ent);
+				buf->curmark = mark;
 			}
-#endif
+
 			/* This is a fresh search */
 			else
 			{
@@ -5590,6 +5591,7 @@ gtk_xtext_search (GtkXText * xtext, const gchar *text, gtk_xtext_search_flags fl
 				ent = buf->cursearch->data;
 				buf->curmark = FIRSTLAST (ent->marks);
 			}
+			buf->curdata.u = (buf->curmark)? GPOINTER_TO_UINT (buf->curmark->data): 0;
 		}
 	}
 	buf->hintsearch = ent;
diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h
index 446708be..32e26af6 100644
--- a/src/fe-gtk/xtext.h
+++ b/src/fe-gtk/xtext.h
@@ -64,6 +64,20 @@ typedef struct _GtkXText GtkXText;
 typedef struct _GtkXTextClass GtkXTextClass;
 typedef struct textentry textentry;
 
+/*
+ * offsets_t is used for retaining search information.
+ * It is stored in the 'data' member of a GList,
+ * as chained from ent->marks.  It saves starting and
+ * ending+1 offset of a found occurrence.
+ */
+typedef union offsets_u {
+	struct offsets_s {
+		guint16	start;
+		guint16	end;
+	} o;
+	guint32 u;
+} offsets_t;
+
 typedef struct {
 	GtkXText *xtext;					/* attached to this widget */
 
@@ -105,6 +119,7 @@ typedef struct {
 	gtk_xtext_search_flags search_flags;	/* match, bwd, highlight */
 	GList *cursearch;			/* GList whose 'data' pts to current textentry */
 	GList *curmark;			/* current item in ent->marks */
+	offsets_t curdata;		/* current offset info, from *curmark */
 	GRegex *search_re;		/* Compiled regular expression */
 	textentry *hintsearch;	/* textentry found for last search */
 } xtext_buffer;