From: Daniel Carl Date: Mon, 22 Jul 2013 17:38:18 +0000 (+0200) Subject: Allow to change input in history lookup. X-Git-Url: https://git.owens.tech/projects.html/projects.html/git?a=commitdiff_plain;h=27b84ec6ef3e6f2fb8aff1ea13d45d319dcb00bd;p=vimb.git Allow to change input in history lookup. In previous version it does not work to lookup commands like ':r' and change the input after the history was initialized. This caused none working lookup if the first attempt did not find any item. For example if ':foo' did not find any item and the user change the inputbox into ':o' which should match items, this retrieved also no item. This patch fixes also none working lookup of set commands like ':set s'. --- diff --git a/src/completion.c b/src/completion.c index b1ce400..fecf725 100644 --- a/src/completion.c +++ b/src/completion.c @@ -53,7 +53,7 @@ gboolean completion_complete(gboolean back) gboolean res = false, sort = true; input = GET_TEXT(); - type = vb_get_input_parts(input, &prefix, &suffix); + type = vb_get_input_parts(input, VB_INPUT_ALL, &prefix, &suffix); if (vb.state.mode & VB_MODE_COMPLETE) { if (comp.text && !strcmp(input, comp.text)) { diff --git a/src/history.c b/src/history.c index 4e08ef6..9545242 100644 --- a/src/history.c +++ b/src/history.c @@ -37,12 +37,12 @@ typedef struct { } History; static struct { - char *prefix; - char *query; + 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(const char *input); +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); @@ -91,13 +91,33 @@ void history_add(HistoryType type, const char *value, const char *additional) */ 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) { - history.active = get_list(input); - /* start with latest added items */ - history.active = g_list_first(history.active); - history.active = g_list_prepend(history.active, g_strdup("")); + 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) { @@ -118,6 +138,7 @@ void history_rewind(void) g_list_free_full(history.active, (GDestroyNotify)g_free); OVERWRITE_STRING(history.prefix, NULL); + OVERWRITE_STRING(history.query, NULL); history.active = NULL; } } @@ -194,44 +215,38 @@ 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(const char *input) +static GList *get_list(VbInputType type, const char *query) { - VbInputType input_type; - HistoryType type; - GList *result = NULL; - const char *prefix, *suffix; - - input_type = vb_get_input_parts(input, &prefix, &suffix); - - /* get the right history type and command prefix */ - if (input_type == VB_INPUT_COMMAND - || input_type == VB_INPUT_OPEN - || input_type == VB_INPUT_TABOPEN - ) { - type = HISTORY_COMMAND; - OVERWRITE_STRING(history.query, suffix); - OVERWRITE_STRING(history.prefix, prefix); - } else if (input_type == VB_INPUT_SEARCH_FORWARD - || input_type == VB_INPUT_SEARCH_BACKWARD - ) { - type = HISTORY_SEARCH; - OVERWRITE_STRING(history.query, suffix); - OVERWRITE_STRING(history.prefix, prefix); - } else { - return NULL; - } + GList *result = NULL, *src = NULL; + + switch (type) { + case VB_INPUT_COMMAND: + src = load(get_file_by_type(HISTORY_COMMAND)); + break; - GList *src = load(get_file_by_type(type)); + case VB_INPUT_SEARCH_FORWARD: + case VB_INPUT_SEARCH_BACKWARD: + src = load(get_file_by_type(HISTORY_SEARCH)); + break; + + default: + return NULL; + } /* generate new history list with the matching items */ for (GList *l = src; l; l = l->next) { History *item = l->data; - if (g_str_has_prefix(item->first, history.query)) { + if (g_str_has_prefix(item->first, query)) { result = g_list_prepend(result, g_strdup(item->first)); } } g_list_free_full(src, (GDestroyNotify)free_history); + /* prepend the original query as own item like done in vim to have the + * origianl input string in input box if we step before the first real + * item */ + result = g_list_prepend(result, g_strdup(query)); + return result; } diff --git a/src/main.c b/src/main.c index b821b3a..e1cec33 100644 --- a/src/main.c +++ b/src/main.c @@ -333,7 +333,8 @@ void vb_update_urlbar(const char *uri) * ...) and set the given prefix pointer to the found prefix and the given * suffix pointer to the suffix. */ -VbInputType vb_get_input_parts(const char* input, const char **prefix, const char **clean) +VbInputType vb_get_input_parts(const char* input, unsigned int use, + const char **prefix, const char **clean) { static const struct { VbInputType type; @@ -350,6 +351,10 @@ VbInputType vb_get_input_parts(const char* input, const char **prefix, const cha {VB_INPUT_SEARCH_BACKWARD, "?", 1}, }; for (unsigned int i = 0; i < LENGTH(types); i++) { + /* process only those types given with use */ + if (!(types[i].type & use)) { + continue; + } if (!strncmp(input, types[i].prefix, types[i].len)) { *prefix = types[i].prefix; *clean = input + types[i].len; diff --git a/src/main.h b/src/main.h index 3bdb210..9aa74da 100644 --- a/src/main.h +++ b/src/main.h @@ -124,12 +124,13 @@ typedef enum _vb_mode { typedef enum { VB_INPUT_UNKNOWN, - VB_INPUT_SET, - VB_INPUT_OPEN, - VB_INPUT_TABOPEN, - VB_INPUT_COMMAND, - VB_INPUT_SEARCH_FORWARD, - VB_INPUT_SEARCH_BACKWARD + VB_INPUT_SET = 1<<0, + VB_INPUT_OPEN = 1<<1, + VB_INPUT_TABOPEN = 1<<2, + VB_INPUT_COMMAND = 1<<3, + VB_INPUT_SEARCH_FORWARD = 1<<4, + VB_INPUT_SEARCH_BACKWARD = 1<<5, + VB_INPUT_ALL = VB_INPUT_OPEN | VB_INPUT_TABOPEN | VB_INPUT_SET | VB_INPUT_COMMAND | VB_INPUT_SEARCH_FORWARD | VB_INPUT_SEARCH_BACKWARD, } VbInputType; enum { @@ -325,7 +326,8 @@ void vb_update_statusbar(void); void vb_update_status_style(void); void vb_update_input_style(void); void vb_update_urlbar(const char *uri); -VbInputType vb_get_input_parts(const char* input, const char **prefix, const char **clean); +VbInputType vb_get_input_parts(const char* input, unsigned int use, + const char **prefix, const char **clean); gboolean vb_download(WebKitWebView *view, WebKitDownload *download, const char *path); void vb_quit(void);