static gboolean ex_complete(short direction);
static void ex_completion_select(char *match);
-static gboolean ex_history(short direction);
+static gboolean ex_history(gboolean prev);
+static void ex_history_rewind(void);
/* The order of following command names is significant. If there exists
* ambiguous commands matching to the users input, the first defined will be
char *current; /* holds the current written input box content */
} excomp;
+static struct {
+ 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;
+} exhist;
+
extern VbCore vb;
break;
case CTRL('P'): /* up */
- ex_history(-1);
+ ex_history(true);
break;
case CTRL('N'): /* down */
- ex_history(1);
+ ex_history(false);
break;
/* basic command line editing */
vb_set_input_text(excomp.current);
}
-static gboolean ex_history(short direction)
+static gboolean ex_history(gboolean prev)
{
- char *input = vb_get_input_text();
- char *entry = history_get(input, direction < 0);
- g_free(input);
+ int type;
+ char *input, prefix[2] = {0};
+ const char *in;
+ GList *new = NULL;
- if (entry) {
- vb_set_input_text(entry);
- g_free(entry);
+ input = vb_get_input_text();
+ if (exhist.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(exhist.prefix, (char*)exhist.active->data, NULL);
+ if (strcmp(input, current)) {
+ ex_history_rewind();
+ }
+ g_free(current);
+ }
- return true;
+ /* create the history list if the lookup is started or input was changed */
+ if (!exhist.active) {
+ in = (const char*)input;
+
+ skip_whitespace(&in);
+
+ /* save the first char as prefix - this should be : / or ? */
+ prefix[0] = *in;
+
+ /* check which type of history we should use */
+ if (*in == ':') {
+ type = VB_INPUT_COMMAND;
+ in++;
+ } else if (*in == '/' || *in == '?') {
+ /* the history does not distinguish between forward and backward
+ * search, so we don't need the backward search here too */
+ type = VB_INPUT_SEARCH_FORWARD;
+ in++;
+ }
+ exhist.active = history_get_list(type, in);
+ if (!exhist.active) {
+ g_free(input);
+
+ return false;
+ }
+ OVERWRITE_STRING(exhist.prefix, prefix);
}
+ g_free(input);
- return false;
+ if (prev) {
+ if ((new = g_list_next(exhist.active))) {
+ exhist.active = new;
+ }
+ } else if ((new = g_list_previous(exhist.active))) {
+ exhist.active = new;
+ }
+
+ vb_echo_force(VB_MSG_NORMAL, false, "%s%s", exhist.prefix, (char*)exhist.active->data);
+
+ return true;
+}
+
+static void ex_history_rewind(void)
+{
+ if (exhist.active) {
+ /* free temporary used history list */
+ g_list_free_full(exhist.active, (GDestroyNotify)g_free);
+ exhist.active = NULL;
+
+ OVERWRITE_STRING(exhist.prefix, NULL);
+ }
}
char *second;
} History;
-static struct {
- 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(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);
}
}
-/**
- * Retrieves the item from history to be shown in input box.
- * The result must be freed by the caller.
- */
-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) {
- 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) {
- if ((new = g_list_next(history.active))) {
- history.active = new;
- }
- } else if ((new = g_list_previous(history.active))) {
- history.active = new;
- }
-
- return g_strconcat(history.prefix, (char*)history.active->data, NULL);
-}
-
-void history_rewind(void)
-{
- if (history.active) {
- /* free temporary used history list */
- g_list_free_full(history.active, (GDestroyNotify)g_free);
-
- OVERWRITE_STRING(history.prefix, NULL);
- OVERWRITE_STRING(history.query, NULL);
- history.active = NULL;
- }
-}
-
gboolean history_fill_completion(GtkListStore *store, HistoryType type, const char *input)
{
char **parts;
* Retrieves the list of matching history items.
* The list must be freed.
*/
-static GList *get_list(VbInputType type, const char *query)
+GList *history_get_list(VbInputType type, const char *query)
{
GList *result = NULL, *src = NULL;
void history_cleanup(void);
void history_add(HistoryType type, const char *value, const char *additional);
-GList *history_get_all(HistoryType type);
-GList *history_get_by_tags(HistoryType type, const char *tags);
-char *history_get(const char *input, gboolean prev);
-void history_rewind(void);
gboolean history_fill_completion(GtkListStore *store, HistoryType type, const char *input);
+GList *history_get_list(VbInputType type, const char *query);
#endif /* end of include guard: _HISTORY_H */
{
dom_clear_focus(vb.gui.webview);
gtk_widget_grab_focus(GTK_WIDGET(vb.gui.webview));
- history_rewind();
hints_clear();
}