From: Daniel Carl Date: Sun, 14 Jul 2013 19:56:41 +0000 (+0200) Subject: Save also page title in history file (#46). X-Git-Url: https://git.owens.tech///git?a=commitdiff_plain;h=871224a7e74b429011345ffd4d8f0d2a8f903c2b;p=vimb.git Save also page title in history file (#46). --- diff --git a/src/history.c b/src/history.c index dcdd853..d71ff6e 100644 --- a/src/history.c +++ b/src/history.c @@ -30,6 +30,11 @@ static const VbFile file_map[HISTORY_LAST] = { FILES_HISTORY }; +typedef struct { + char *first; + char *second; +} History; + static struct { char *prefix; char *query; @@ -40,6 +45,9 @@ static GList *get_list(const char *input); 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); +static History *line_to_history(const char *line); +static int history_comp(History *a, History *b); +static void free_history(History *item); /** @@ -58,15 +66,18 @@ void history_cleanup(void) /** * Write a new history entry to the end of history file. */ -void history_add(HistoryType type, const char *value) +void history_add(HistoryType type, const char *value, const char *additional) { FILE *f; const char *file = get_file_by_type(type); if ((f = fopen(file, "a+"))) { file_lock_set(fileno(f), F_WRLCK); - - fprintf(f, "%s\n", value); + if (additional) { + fprintf(f, "%s\t%s\n", value, additional); + } else { + fprintf(f, "%s\n", value); + } file_lock_set(fileno(f), F_UNLCK); fclose(f); @@ -82,29 +93,31 @@ GList *history_get_by_tags(HistoryType type, const char *tags) GList *res = NULL, *src = NULL; char **parts; unsigned int len; + History *item; src = load(get_file_by_type(type)); if (!tags || *tags == '\0') { /* without any tags return all items */ for (GList *l = src; l; l = l->next) { - res = g_list_prepend(res, g_strdup((char*)l->data)); + item = l->data; + res = g_list_prepend(res, g_strdup(item->first)); } } else if (HISTORY_URL == type) { parts = g_strsplit(tags, " ", 0); len = g_strv_length(parts); for (GList *l = src; l; l = l->next) { - char *value = (char*)l->data; - if (util_string_contains_all_tags(value, parts, len)) { - res = g_list_prepend(res, g_strdup(value)); + item = l->data; + if (util_string_contains_all_tags(item->first, parts, len)) { + res = g_list_prepend(res, g_strdup(item->first)); } } g_strfreev(parts); } else { for (GList *l = src; l; l = l->next) { - char *value = (char*)l->data; - if (g_str_has_prefix(value, tags)) { - res = g_list_prepend(res, g_strdup(value)); + item = l->data; + if (g_str_has_prefix(item->first, tags)) { + res = g_list_prepend(res, g_strdup(item->first)); } } } @@ -114,7 +127,7 @@ GList *history_get_by_tags(HistoryType type, const char *tags) } /** - * Retrieves the command from history to be shown in input box. + * 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) @@ -188,11 +201,12 @@ static GList *get_list(const char *input) /* generate new history list with the matching items */ for (GList *l = src; l; l = l->next) { - char *value = (char*)l->data; - if (g_str_has_prefix(value, history.query)) { - result = g_list_prepend(result, g_strdup(value)); + History *item = l->data; + if (g_str_has_prefix(item->first, history.query)) { + result = g_list_prepend(result, g_strdup(item->first)); } } + g_list_free_full(src, (GDestroyNotify)free_history); return result; } @@ -208,38 +222,12 @@ static const char *get_file_by_type(HistoryType type) static GList *load(const char *file) { /* read the history items from file */ - GList *list = NULL; - char buf[BUF_SIZE] = {0}; - FILE *f; + GList *list = NULL; - if (!(f = fopen(file, "r"))) { - return list; - } - - file_lock_set(fileno(f), F_RDLCK); - while (fgets(buf, sizeof(buf), f)) { - g_strstrip(buf); - - /* skip empty lines */ - if (!*buf) { - continue; - } - /* if the value is already in history, remove this entry */ - for (GList *l = list; l; l = l->next) { - if (*buf && !g_strcmp0(buf, (char*)l->data)) { - g_free(l->data); - list = g_list_delete_link(list, l); - break; - } - } - - list = g_list_prepend(list, g_strdup(buf)); - } - file_lock_set(fileno(f), F_UNLCK); - fclose(f); - - /* reverse to not use the slow g_list_last */ - list = g_list_reverse(list); + list = util_file_to_unique_list( + file, (Util_Content_Func)line_to_history, (GCompareFunc)history_comp, + (GDestroyNotify)free_history + ); /* if list is too long - remove items from end (oldest entries) */ if (vb.config.history_max < g_list_length(list)) { @@ -264,12 +252,57 @@ static void write_to_file(GList *list, const char *file) /* overwrite the history file with new unique history items */ for (GList *link = list; link; link = link->next) { - fprintf(f, "%s\n", (char*)link->data); + History *item = link->data; + if (item->second) { + fprintf(f, "%s\t%s\n", item->first, item->second); + } else { + fprintf(f, "%s\n", item->first); + } } file_lock_set(fileno(f), F_UNLCK); fclose(f); } - g_list_free_full(list, (GDestroyNotify)g_free); + g_list_free_full(list, (GDestroyNotify)free_history); +} + +static History *line_to_history(const char *line) +{ + char **parts; + int len; + + while (g_ascii_isspace(*line)) { + line++; + } + if (*line == '\0') { + return NULL; + } + + History *item = g_new0(History, 1); + + parts = g_strsplit(line, "\t", 2); + len = g_strv_length(parts); + if (len == 2) { + item->first = g_strdup(parts[0]); + item->second = g_strdup(parts[1]); + } else { + item->first = g_strdup(parts[0]); + } + g_strfreev(parts); + + return item; +} + +static int history_comp(History *a, History *b) +{ + /* compare only the first part */ + return g_strcmp0(a->first, b->first); +} + +static void free_history(History *item) +{ + g_free(item->first); + g_free(item->second); + g_free(item); } diff --git a/src/history.h b/src/history.h index 739cb0c..4b46399 100644 --- a/src/history.h +++ b/src/history.h @@ -29,7 +29,7 @@ typedef enum { } HistoryType; void history_cleanup(void); -void history_add(HistoryType type, const char *value); +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); diff --git a/src/main.c b/src/main.c index ff7793d..3da038d 100644 --- a/src/main.c +++ b/src/main.c @@ -466,7 +466,7 @@ static void webview_load_status_cb(WebKitWebView *view, GParamSpec *pspec) dom_check_auto_insert(view); - history_add(HISTORY_URL, uri); + history_add(HISTORY_URL, uri, webkit_web_view_get_title(view)); break; case WEBKIT_LOAD_FAILED: @@ -505,13 +505,13 @@ static void inputbox_activate_cb(GtkEntry *entry) case '?': a.i = *text == '/' ? VB_SEARCH_FORWARD : VB_SEARCH_BACKWARD; a.s = (command + 1); - history_add(HISTORY_SEARCH, command + 1); + history_add(HISTORY_SEARCH, command + 1, NULL); command_search(&a); break; case ':': completion_clean(); - history_add(HISTORY_COMMAND, command + 1); + history_add(HISTORY_COMMAND, command + 1, NULL); command_run_string((command + 1)); break; } diff --git a/src/util.c b/src/util.c index 13128f9..03c81bb 100644 --- a/src/util.c +++ b/src/util.c @@ -98,6 +98,44 @@ char **util_get_lines(const char *filename) return lines; } +GList *util_file_to_unique_list(const char *filename, Util_Content_Func func, + GCompareFunc unique_func, GDestroyNotify free_func) +{ + GList *gl = NULL; + char *line, **lines = util_get_lines(filename); + void *value; + int len; + + len = g_strv_length(lines); + if (!len) { + return gl; + } + + for (int i = 0; i < len; i++) { + line = lines[i]; + g_strstrip(line); + if (*line == '\0') { + continue; + } + + if ((value = func(line))) { + /* if the value is already in list, remove this entry */ + for (GList *l = gl; l; l = l->next) { + if (!unique_func(value, l->data)) { + free_func(l->data); + gl = g_list_delete_link(gl, l); + break; + } + } + gl = g_list_prepend(gl, value); + } + } + g_strfreev(lines); + gl = g_list_reverse(gl); + + return gl; +} + char *util_strcasestr(const char *haystack, const char *needle) { unsigned char c1, c2; diff --git a/src/util.h b/src/util.h index c48c4f9..f93e6b1 100644 --- a/src/util.h +++ b/src/util.h @@ -23,6 +23,7 @@ #include "main.h" typedef gboolean (*Util_Comp_Func)(const char*, const char*); +typedef void *(*Util_Content_Func)(const char*); char* util_get_config_dir(void); char* util_get_cache_dir(void); @@ -31,6 +32,8 @@ void util_create_dir_if_not_exists(const char* dirpath); void util_create_file_if_not_exists(const char* filename); char* util_get_file_contents(const char* filename, gsize* length); char** util_get_lines(const char* filename); +GList *util_file_to_unique_list(const char *filename, Util_Content_Func func, + GCompareFunc unique_func, GDestroyNotify free_func); char* util_strcasestr(const char* haystack, const char* needle); gboolean util_array_contains_all_tags(char **src, unsigned int s, char **query, unsigned int q); gboolean util_string_contains_all_tags(char *src, char **query, unsigned int q);