Moved stateful history processing to ex.c.
authorDaniel Carl <danielcarl@gmx.de>
Mon, 30 Sep 2013 21:12:50 +0000 (23:12 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Mon, 30 Sep 2013 21:12:50 +0000 (23:12 +0200)
src/ex.c
src/history.c
src/history.h
src/normal.c

index 599f57a..b39ca62 100644 (file)
--- a/src/ex.c
+++ b/src/ex.c
@@ -112,7 +112,8 @@ static gboolean ex_shortcut(const ExArg *arg);
 
 static gboolean ex_complete(short direction);
 static void ex_completion_select(char *match);
-static gboolean ex_history(short direction);
+static gboolean ex_history(gboolean prev);
+static void ex_history_rewind(void);
 
 /* The order of following command names is significant. If there exists
  * ambiguous commands matching to the users input, the first defined will be
@@ -167,6 +168,12 @@ static struct {
     char  *current; /* holds the current written input box content */
 } excomp;
 
+static struct {
+    char  *prefix;  /* prefix that is prepended to the history item to for the complete command */
+    char  *query;   /* part of input text to match the history items */
+    GList *active;
+} exhist;
+
 extern VbCore vb;
 
 
@@ -227,11 +234,11 @@ VbResult ex_keypress(unsigned int key)
             break;
 
         case CTRL('P'): /* up */
-            ex_history(-1);
+            ex_history(true);
             break;
 
         case CTRL('N'): /* down */
-            ex_history(1);
+            ex_history(false);
             break;
 
         /* basic command line editing */
@@ -967,18 +974,74 @@ static void ex_completion_select(char *match)
     vb_set_input_text(excomp.current);
 }
 
-static gboolean ex_history(short direction)
+static gboolean ex_history(gboolean prev)
 {
-    char *input = vb_get_input_text();
-    char *entry = history_get(input, direction < 0);
-    g_free(input);
+    int type;
+    char *input, prefix[2] = {0};
+    const char *in;
+    GList *new = NULL;
 
-    if (entry) {
-        vb_set_input_text(entry);
-        g_free(entry);
+    input = vb_get_input_text();
+    if (exhist.active) {
+        /* calculate the actual content of the inpubox from history data, if
+         * the theoretical content and the actual given input are different
+         * rewind the history to recreate it later new */
+        char *current = g_strconcat(exhist.prefix, (char*)exhist.active->data, NULL);
+        if (strcmp(input, current)) {
+            ex_history_rewind();
+        }
+        g_free(current);
+    }
 
-        return true;
+    /* create the history list if the lookup is started or input was changed */
+    if (!exhist.active) {
+        in = (const char*)input;
+
+        skip_whitespace(&in);
+
+        /* save the first char as prefix - this should be : / or ? */
+        prefix[0] = *in;
+
+        /* check which type of history we should use */
+        if (*in == ':') {
+            type = VB_INPUT_COMMAND;
+            in++;
+        } else if (*in == '/' || *in == '?') {
+            /* the history does not distinguish between forward and backward
+             * search, so we don't need the backward search here too */
+            type = VB_INPUT_SEARCH_FORWARD;
+            in++;
+        }
+        exhist.active = history_get_list(type, in);
+        if (!exhist.active) {
+            g_free(input);
+
+            return false;
+        }
+        OVERWRITE_STRING(exhist.prefix, prefix);
     }
+    g_free(input);
 
-    return false;
+    if (prev) {
+        if ((new = g_list_next(exhist.active))) {
+            exhist.active = new;
+        }
+    } else if ((new = g_list_previous(exhist.active))) {
+        exhist.active = new;
+    }
+
+    vb_echo_force(VB_MSG_NORMAL, false, "%s%s", exhist.prefix, (char*)exhist.active->data);
+
+    return true;
+}
+
+static void ex_history_rewind(void)
+{
+    if (exhist.active) {
+        /* free temporary used history list */
+        g_list_free_full(exhist.active, (GDestroyNotify)g_free);
+        exhist.active = NULL;
+
+        OVERWRITE_STRING(exhist.prefix, NULL);
+    }
 }
index 05d1231..0221f24 100644 (file)
@@ -37,13 +37,6 @@ typedef struct {
     char *second;
 } History;
 
-static struct {
-    char  *prefix;  /* prefix that is prepended to the history item to for the complete command */
-    char  *query;   /* part of input text to match the history items */
-    GList *active;
-} history;
-
-static GList *get_list(VbInputType type, const char *query);
 static const char *get_file_by_type(HistoryType type);
 static GList *load(const char *file);
 static void write_to_file(GList *list, const char *file);
@@ -85,64 +78,6 @@ void history_add(HistoryType type, const char *value, const char *additional)
     }
 }
 
-/**
- * Retrieves the item from history to be shown in input box.
- * The result must be freed by the caller.
- */
-char *history_get(const char *input, gboolean prev)
-{
-    VbInputType type;
-    const char *prefix, *query;
-    GList *new = NULL;
-
-    if (history.active) {
-        /* calculate the actual content of the inpubox from history data, if
-         * the theoretical content and the actual given input are different
-         * rewind the history to recreate it later new */
-        char *current = g_strconcat(history.prefix, (char*)history.active->data, NULL);
-        if (strcmp(input, current)) {
-            history_rewind();
-        }
-        g_free(current);
-    }
-
-    /* create the history list if the lookup is started or input was changed */
-    if (!history.active) {
-        type = vb_get_input_parts(
-            input, VB_INPUT_COMMAND|VB_INPUT_SEARCH_FORWARD|VB_INPUT_SEARCH_BACKWARD,
-            &prefix, &query
-        );
-        history.active = get_list(type, query);
-        if (!history.active) {
-            return NULL;
-        }
-        OVERWRITE_STRING(history.query, query);
-        OVERWRITE_STRING(history.prefix, prefix);
-    }
-
-    if (prev) {
-        if ((new = g_list_next(history.active))) {
-            history.active = new;
-        }
-    } else if ((new = g_list_previous(history.active))) {
-        history.active = new;
-    }
-
-    return g_strconcat(history.prefix, (char*)history.active->data, NULL);
-}
-
-void history_rewind(void)
-{
-    if (history.active) {
-        /* free temporary used history list */
-        g_list_free_full(history.active, (GDestroyNotify)g_free);
-
-        OVERWRITE_STRING(history.prefix, NULL);
-        OVERWRITE_STRING(history.query, NULL);
-        history.active = NULL;
-    }
-}
-
 gboolean history_fill_completion(GtkListStore *store, HistoryType type, const char *input)
 {
     char **parts;
@@ -215,7 +150,7 @@ gboolean history_fill_completion(GtkListStore *store, HistoryType type, const ch
  * Retrieves the list of matching history items.
  * The list must be freed.
  */
-static GList *get_list(VbInputType type, const char *query)
+GList *history_get_list(VbInputType type, const char *query)
 {
     GList *result = NULL, *src = NULL;
 
index e1219dd..e30e8a0 100644 (file)
@@ -30,10 +30,7 @@ typedef enum {
 
 void history_cleanup(void);
 void history_add(HistoryType type, const char *value, const char *additional);
-GList *history_get_all(HistoryType type);
-GList *history_get_by_tags(HistoryType type, const char *tags);
-char *history_get(const char *input, gboolean prev);
-void history_rewind(void);
 gboolean history_fill_completion(GtkListStore *store, HistoryType type, const char *input);
+GList *history_get_list(VbInputType type, const char *query);
 
 #endif /* end of include guard: _HISTORY_H */
index fffa101..44396ca 100644 (file)
@@ -208,7 +208,6 @@ void normal_enter(void)
 {
     dom_clear_focus(vb.gui.webview);
     gtk_widget_grab_focus(GTK_WIDGET(vb.gui.webview));
-    history_rewind();
     hints_clear();
 }