} 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);
*/
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) {
g_list_free_full(history.active, (GDestroyNotify)g_free);
OVERWRITE_STRING(history.prefix, NULL);
+ OVERWRITE_STRING(history.query, NULL);
history.active = NULL;
}
}
* 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;
}
* ...) 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;
{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;
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 {
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);