changeset 30077:69decc147e5b

history-search action for text-entries.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 02 Apr 2010 21:01:42 +0000
parents ca77ea5de98d
children 51f997e2347f
files ChangeLog doc/finch.1.in finch/libgnt/gntentry.c finch/libgnt/gntentry.h
diffstat 4 files changed, 76 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Apr 02 16:37:10 2010 +0000
+++ b/ChangeLog	Fri Apr 02 21:01:42 2010 +0000
@@ -81,6 +81,10 @@
 	* Retrieve the pager server address from Yahoo!'s servers directly.
 	* Removed the "Pager server" account option, as it is no longer needed.
 
+	Finch:
+	* New action 'history-search', with default binding ctrl+r, to search
+	  the entered string in the input history.
+
 version 2.6.6 (02/18/2010):
 	libpurple:
 	* Fix 'make check' on OS X. (David Fang)
--- a/doc/finch.1.in	Fri Apr 02 16:37:10 2010 +0000
+++ b/doc/finch.1.in	Fri Apr 02 21:01:42 2010 +0000
@@ -348,6 +348,16 @@
 a-d = delete-next-word
 .br
 c-v = clipboard-paste
+.br
+c-p = history-prev
+.br
+c-n = history-next
+.br
+c-r = history-search
+.br
+c-up = history-prev
+.br
+c-down = history-next
 
 .br
 [GntTree::binding]
--- a/finch/libgnt/gntentry.c	Fri Apr 02 16:37:10 2010 +0000
+++ b/finch/libgnt/gntentry.c	Fri Apr 02 21:01:42 2010 +0000
@@ -55,6 +55,11 @@
 	GntEntryAction last;
 };
 
+struct _GntEntrySearch
+{
+	char *needle;
+};
+
 static guint signals[SIGS] = { 0 };
 
 static GntWidgetClass *parent_class = NULL;
@@ -471,6 +476,55 @@
 }
 
 static gboolean
+history_search(GntBindable *bind, GList *null)
+{
+	GntEntry *entry = GNT_ENTRY(bind);
+	GList *iter;
+	const char *current , *pos;
+	int len;
+	
+	if (entry->history->prev && entry->search->needle)
+		current = entry->search->needle;
+	else
+		current = gnt_entry_get_text(entry);
+
+	if (!entry->histlength || !entry->history->next || !*current)
+		return FALSE;
+
+	len = g_utf8_strlen(current, -1);
+
+	for (iter = entry->history->next; iter; iter = iter->next) {
+		const char *str = iter->data;
+		/* A more utf8-friendly version of strstr would have been better, but
+		 * for now, this will have to do. */
+		if ((pos = strstr(str, current)))
+			break;
+	}
+
+	if (!iter)
+		return TRUE;
+
+	if (entry->history->prev == NULL) {
+		/* We are doing it for the first time. Save the current contents */
+		char *text = g_strdup(gnt_entry_get_text(entry));
+
+		g_free(entry->search->needle);
+		entry->search->needle = g_strdup(current);
+
+		g_free(entry->history->data);
+		entry->history->data = text;
+	}
+
+	entry->history = iter;
+	gnt_entry_set_text_internal(entry, entry->history->data);
+	destroy_suggest(entry);
+	entry_text_changed(entry);
+
+	update_kill_ring(entry, ENTRY_JAIL, NULL, 0);
+	return TRUE;
+}
+
+static gboolean
 clipboard_paste(GntBindable *bind, GList *n)
 {
 	GntEntry *entry = GNT_ENTRY(bind);
@@ -833,6 +887,9 @@
 		gnt_widget_destroy(entry->ddown->parent);
 	}
 
+	g_free(entry->search->needle);
+	g_free(entry->search);
+
 	jail_killring(entry->killring);
 }
 
@@ -935,6 +992,8 @@
 				GNT_KEY_CTRL_UP, NULL);
 	gnt_bindable_register_binding(bindable, "history-prev", GNT_KEY_CTRL_P, NULL);
 	gnt_bindable_register_binding(bindable, "history-next", GNT_KEY_CTRL_N, NULL);
+	gnt_bindable_class_register_action(bindable, "history-search", history_search,
+				GNT_KEY_CTRL_R, NULL);
 	gnt_bindable_class_register_action(bindable, "clipboard-paste", clipboard_paste,
 				GNT_KEY_CTRL_V, NULL);
 
@@ -966,6 +1025,7 @@
 	entry->always = FALSE;
 	entry->suggests = NULL;
 	entry->killring = new_killring();
+	entry->search = g_new0(GntEntrySearch, 1);
 
 	GNT_WIDGET_SET_FLAGS(GNT_WIDGET(entry),
 			GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW | GNT_WIDGET_CAN_TAKE_FOCUS);
--- a/finch/libgnt/gntentry.h	Fri Apr 02 16:37:10 2010 +0000
+++ b/finch/libgnt/gntentry.h	Fri Apr 02 21:01:42 2010 +0000
@@ -49,6 +49,7 @@
 typedef struct _GntEntryPriv		GntEntryPriv;
 typedef struct _GntEntryClass	GntEntryClass;
 typedef struct _GntEntryKillRing    GntEntryKillRing;
+typedef struct _GntEntrySearch		GntEntrySearch;
 
 typedef enum
 {
@@ -86,6 +87,7 @@
 	gboolean always;    /* Should the list of suggestions show at all times, or only on tab-press? */
 	GntWidget *ddown;   /* The dropdown with the suggested list */
 	GntEntryKillRing *killring; /**< @since 2.3.0 */
+	GntEntrySearch *search;		/**< @since 2.7.0 */
 };
 
 struct _GntEntryClass