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"
#include "hints.h"
#include "util.h"
#include "searchengine.h"
+#include "history.h"
static CommandInfo cmd_list[] = {
/* command function arg mode */
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;
}
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);
}
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 */
SearchDirection search_dir;
char* search_query;
GList* downloads;
+ int history_pointer;
+ char* history_prefix;
} State;
/* behaviour */
GString* modkeys;
GSList* searchengines;
GList* history;
- int history_pointer;
} Behaviour;
typedef struct {