From ddf244569fd70f1e117cb36941649daf955e4ff1 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Wed, 27 Mar 2013 00:17:54 +0100 Subject: [PATCH] Fixed wrong history prefixes. If the ':' was typed into input box and the history search started and a history item with :open ... was put into input box, the next history step used the ':open ' as a new prefix for commands to fill. Now the input is only processed at the start of the history searching, so that later changes won't corrupt the printed items. Also fixed missed first item in stepping forward through the history. Al least the global variables out of the vb struct where removed to start to decentralize the data stores and to them from the rest of the application. --- src/command.c | 25 +++--------------- src/history.c | 70 ++++++++++++++++++++++++++++++++++++++++----------- src/history.h | 2 +- src/main.h | 6 ----- 4 files changed, 61 insertions(+), 42 deletions(-) diff --git a/src/command.c b/src/command.c index 7a185aa..32a3f36 100644 --- a/src/command.c +++ b/src/command.c @@ -517,33 +517,16 @@ gboolean command_zoom(const Arg* arg) gboolean command_history(const Arg* arg) { - const char* input = GET_TEXT(); int step = vb.state.count ? vb.state.count * arg->i : arg->i; - const char* entry = NULL; - char* prefix = NULL; - - /* use the right history type according to current input text */ - if (!strncmp(input, ":open ", 6)) { - entry = history_get(HISTORY_URL, step, input + 6); - prefix = ":open "; - } else if (!strncmp(input, ":tabopen ", 9)) { - entry = history_get(HISTORY_URL, step, input + 9); - prefix = ":tabopen "; - } else if (*input == ':') { - entry = history_get(HISTORY_COMMAND, step, input + 1); - prefix = ":"; - } else if (*input == '/' || *input == '?') { - entry = history_get(HISTORY_SEARCH, step, input + 1); - prefix = *input == '/' ? "/" : "?"; - } + const char* input = GET_TEXT(); + char* entry = history_get(input, step); if (!entry) { return FALSE; } - char* value = g_strconcat(prefix, entry, NULL); - command_write_input(value); - g_free(value); + command_write_input(entry); + g_free(entry); return TRUE; } diff --git a/src/history.c b/src/history.c index 89afd4e..8760e7c 100644 --- a/src/history.c +++ b/src/history.c @@ -29,6 +29,13 @@ static const VbFile file_map[HISTORY_LAST] = { FILES_HISTORY }; +static struct { + unsigned int pointer; + char* prefix; + char* query; + GList* active; +} history; + static const char* history_get_file_by_type(HistoryType type); static GList* history_load(const char* file); static void history_write_to_file(GList* list, const char* file); @@ -71,46 +78,81 @@ GList* history_get_all(HistoryType type) return history_load(history_get_file_by_type(type)); } -const char* history_get(HistoryType type, int step, const char* query) +/** + * Retrieves the command from history to be shown in input box. + * The result must be freed by the caller. + */ +char* history_get(const char* input, int step) { - const char* command; + char* command = NULL; + unsigned int len; /* get the search prefix only on start of history search */ - if (!vb.state.history_active) { - OVERWRITE_STRING(vb.state.history_prefix, query); + if (!history.active) { + HistoryType type; + + /* get the right history type and command prefix */ + if (!strncmp(input, ":open ", 6)) { + type = HISTORY_URL; + OVERWRITE_STRING(history.query, input + 6); + OVERWRITE_STRING(history.prefix, ":open "); + } else if (!strncmp(input, ":tabopen ", 9)) { + type = HISTORY_URL; + OVERWRITE_STRING(history.query, input + 9); + OVERWRITE_STRING(history.prefix, ":tabopen "); + } else if (*input == ':') { + type = HISTORY_COMMAND; + OVERWRITE_STRING(history.query, input + 1); + OVERWRITE_STRING(history.prefix, ":"); + } else if (*input == '/' || *input == '?') { + type = HISTORY_SEARCH; + OVERWRITE_STRING(history.query, input + 1); + OVERWRITE_STRING(history.prefix, (*input == '/') ? "/" : "?"); + } else { + return NULL; + } GList* src = history_load(history_get_file_by_type(type)); /* generate new history list with the matching items */ for (GList* l = src; l; l = l->next) { char* value = (char*)l->data; - if (g_str_has_prefix(value, vb.state.history_prefix)) { - vb.state.history_active = g_list_prepend(vb.state.history_active, g_strdup(value)); + if (g_str_has_prefix(value, history.query)) { + history.active = g_list_prepend(history.active, g_strdup(value)); } } + + /* if the list is searched forward we would move the history pointer + * to the element with index 1, but we should start with 0 */ + step = step > 0 ? step - 1 : step; } - const int len = g_list_length(vb.state.history_active); + len = g_list_length(history.active); if (!len) { return NULL; } /* if reached end/beginnen start at the opposit site of list again */ - vb.state.history_pointer = (len + vb.state.history_pointer + step) % len; + history.pointer = (len + history.pointer + step) % len; - command = (char*)g_list_nth_data(vb.state.history_active, vb.state.history_pointer); + command = g_strconcat( + history.prefix, + g_list_nth_data(history.active, history.pointer), + NULL + ); return command; } void history_rewind(void) { - if (vb.state.history_active) { - OVERWRITE_STRING(vb.state.history_prefix, NULL); - vb.state.history_pointer = 0; + if (history.active) { /* free temporary used history list */ - g_list_free_full(vb.state.history_active, (GDestroyNotify)g_free); - vb.state.history_active = NULL; + g_list_free_full(history.active, (GDestroyNotify)g_free); + + OVERWRITE_STRING(history.prefix, NULL); + history.active = NULL; + history.pointer = 0; } } diff --git a/src/history.h b/src/history.h index 4928353..e241597 100644 --- a/src/history.h +++ b/src/history.h @@ -31,7 +31,7 @@ typedef enum { void history_cleanup(void); void history_add(HistoryType type, const char* value); GList* history_get_all(HistoryType type); -const char* history_get(HistoryType type, int step, const char* query); +char* history_get(const char* input, int step); void history_rewind(void); void history_list_free(GList** list); diff --git a/src/main.h b/src/main.h index bb9fd9e..517b2cc 100644 --- a/src/main.h +++ b/src/main.h @@ -244,12 +244,6 @@ typedef struct { SearchDirection search_dir; char* search_query; GList* downloads; - /* points to the actual shown history entry */ - int history_pointer; - /* search string for that is searched in history */ - char* history_prefix; - /* list holding matching items according to history_prefix */ - GList* history_active; } State; /* behaviour */ -- 2.20.1