summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Carl <danielcarl@gmx.de>2013-02-24 20:24:05 +0100
committerDaniel Carl <danielcarl@gmx.de>2013-02-24 20:24:05 +0100
commit880612a9dc867edd0cabb71086a42cec46963894 (patch)
treee4341a0be2f581217be687749841062fee2fef58
parent4404ba3667a34bcc6343b0e3dc15415bbdb979d0 (diff)
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.
-rw-r--r--doc/vimp.1.txt2
-rw-r--r--src/command.c21
-rw-r--r--src/history.c38
-rw-r--r--src/history.h1
-rw-r--r--src/main.h3
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 {