From a9576d151b98712866783d167b2da0be8313550b Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Mon, 30 Sep 2013 23:12:50 +0200 Subject: [PATCH] Moved stateful history processing to ex.c. --- src/ex.c | 87 ++++++++++++++++++++++++++++++++++++++++++++------- src/history.c | 67 +-------------------------------------- src/history.h | 5 +-- src/normal.c | 1 - 4 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/ex.c b/src/ex.c index 599f57a..b39ca62 100644 --- 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); + } } diff --git a/src/history.c b/src/history.c index 05d1231..0221f24 100644 --- a/src/history.c +++ b/src/history.c @@ -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; diff --git a/src/history.h b/src/history.h index e1219dd..e30e8a0 100644 --- a/src/history.h +++ b/src/history.h @@ -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 */ diff --git a/src/normal.c b/src/normal.c index fffa101..44396ca 100644 --- a/src/normal.c +++ b/src/normal.c @@ -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(); } -- 2.20.1