From 880612a9dc867edd0cabb71086a42cec46963894 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sun, 24 Feb 2013 20:24:05 +0100 Subject: [PATCH] Implemented prefix aware history searching (#7). If ':set' is already typed in the inputbox, the history will only step over those items that matches this prefix. Now vimp behave a little bit more like the great vim editor. --- doc/vimp.1.txt | 2 ++ src/command.c | 21 ++++++++------------- src/history.c | 38 +++++++++++++++++++++++++++++++++++++- src/history.h | 1 + src/main.h | 3 ++- 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/doc/vimp.1.txt b/doc/vimp.1.txt index c4f1187..0454140 100644 --- a/doc/vimp.1.txt +++ b/doc/vimp.1.txt @@ -287,6 +287,8 @@ Reset the zoomlevel to the default value. Prints the previous or next cammand from history into inputbox. If \fIPREFIX\fP is given, this will be used as prefix for the inserted command, else the default ':' will be used. +If there is already text in the input box this will be used to get previous +history items. .SS Misc .TP .BI [ N "]search-forward, [" N "]search-backward" diff --git a/src/command.c b/src/command.c index 02398a6..3a96bdb 100644 --- a/src/command.c +++ b/src/command.c @@ -25,6 +25,7 @@ #include "hints.h" #include "util.h" #include "searchengine.h" +#include "history.h" static CommandInfo cmd_list[] = { /* command function arg mode */ @@ -529,23 +530,17 @@ gboolean command_zoom(const Arg* arg) gboolean command_history(const Arg* arg) { - const int len = g_list_length(core.behave.history); - char* message = NULL; + char* msg = NULL; const int count = vp.state.count ? vp.state.count : 1; + const gint step = count * (arg->i == VP_SEARCH_BACKWARD ? -1 : 1); + const char* entry = history_get(step); - if (!len) { + if (!entry) { return FALSE; } - if (arg->i == VP_SEARCH_BACKWARD) { - core.behave.history_pointer = (len + core.behave.history_pointer - count) % len; - } else { - core.behave.history_pointer = (len + core.behave.history_pointer + count) % len; - } - - const char* command = (char*)g_list_nth_data(core.behave.history, core.behave.history_pointer); - message = g_strconcat(arg->s, command, NULL); - command_write_input(message); - g_free(message); + msg = g_strconcat(arg->s, entry, NULL); + command_write_input(msg); + g_free(msg); return TRUE; } diff --git a/src/history.c b/src/history.c index 817005f..0b0c087 100644 --- a/src/history.c +++ b/src/history.c @@ -36,7 +36,43 @@ void history_append(const char* line) core.behave.history = g_list_append(core.behave.history, g_strdup(line)); } +const char* history_get(const int step) +{ + const char* command; + GList* history = NULL; + + /* get the search prefix only on start of history search */ + if (!vp.state.history_prefix) { + const char* text = GET_TEXT(); + /* TODO at the moment we skip only the first char of input box but + * maybe we'll have history items that have a longer or no prefix */ + OVERWRITE_STRING(vp.state.history_prefix, (text + 1)); + } + + for (GList* l = core.behave.history; l; l = l->next) { + char* entry = (char*)l->data; + if (g_str_has_prefix(entry, vp.state.history_prefix)) { + history = g_list_prepend(history, entry); + } + } + + const int len = g_list_length(history); + if (!len) { + return NULL; + } + + history = g_list_reverse(history); + + /* if reached end/beginnen start at the opposit site of list again */ + vp.state.history_pointer = (len + vp.state.history_pointer + step) % len; + + command = (char*)g_list_nth_data(history, vp.state.history_pointer); + + return command; +} + void history_rewind(void) { - core.behave.history_pointer = 0; + vp.state.history_pointer = 0; + OVERWRITE_STRING(vp.state.history_prefix, NULL); } diff --git a/src/history.h b/src/history.h index 476a46c..d6c3ccf 100644 --- a/src/history.h +++ b/src/history.h @@ -22,6 +22,7 @@ void history_cleanup(void); void history_append(const char* line); +const char* history_get(const int step); void history_rewind(void); #endif /* end of include guard: _HISTORY_H */ diff --git a/src/main.h b/src/main.h index 7c80029..a794b12 100644 --- a/src/main.h +++ b/src/main.h @@ -228,6 +228,8 @@ typedef struct { SearchDirection search_dir; char* search_query; GList* downloads; + int history_pointer; + char* history_prefix; } State; /* behaviour */ @@ -237,7 +239,6 @@ typedef struct { GString* modkeys; GSList* searchengines; GList* history; - int history_pointer; } Behaviour; typedef struct { -- 2.20.1