From: Daniel Carl Date: Sat, 23 Mar 2013 15:13:40 +0000 (+0100) Subject: Simplified history saving. X-Git-Url: https://git.owens.tech/assets/static/git.owens.tech/assets/static/git.owens.tech/git?a=commitdiff_plain;h=ddf005b4d252c2a378824551a0bda210c59f72b4;p=vimb.git Simplified history saving. The url history is written to the end of the history file. The history isn't read into list if not required. Every time we need the history we read it new from file, so we would always see item added by another browser instance. If the browser is closed the history files loaded again, duplicates will be removed and the list shortened to the max history length and written back to the file. --- diff --git a/doc/vimb.1.txt b/doc/vimb.1.txt index 02b1ad5..3f4fac8 100644 --- a/doc/vimb.1.txt +++ b/doc/vimb.1.txt @@ -318,8 +318,7 @@ Holds the URI of the last closed browser window. .RE .I $XDG_CONFIG_HOME/PROJECT/history .RS -This file holds the history of opened URIs. Note that this file is only -written if last window of the browser is closed. +This file holds the history of unique opened URIs. .RE .I $XDG_CONFIG_HOME/PROJECT/scripts.js .RS diff --git a/src/main.c b/src/main.c index e1ea5b2..dfa2726 100644 --- a/src/main.c +++ b/src/main.c @@ -733,7 +733,6 @@ static void vb_init_core(void) command_init(); keybind_init(); vb_read_config(); - url_history_init(); vb_update_status_style(); vb_update_input_style(VB_MSG_NORMAL); diff --git a/src/main.h b/src/main.h index 6ad8a78..f62a21c 100644 --- a/src/main.h +++ b/src/main.h @@ -257,7 +257,6 @@ typedef struct { GString* modkeys; GSList* searchengines; GList* history; - GList* url_history; } Behaviour; typedef struct { diff --git a/src/url_history.c b/src/url_history.c index d8ee6b8..cea7666 100644 --- a/src/url_history.c +++ b/src/url_history.c @@ -21,47 +21,130 @@ #include "url_history.h" extern VbCore vb; +static unsigned int url_history_add_unique(GList** list, const char* url, const char* title); +static GList* url_history_load(void); +static void url_history_write_to_file(GList* list); +static void url_history_clear(GList** list); static void url_history_free(UrlHist* item); -void url_history_init(void) +void url_history_cleanup(void) +{ + url_history_write_to_file(url_history_load()); +} + +/** + * Write a new history entry to the end of history file. + */ +void url_history_add(const char* uri, const char* title) +{ + FILE* file = fopen(vb.files[FILES_HISTORY], "a+"); + if (file) { + file_lock_set(fileno(file), F_WRLCK); + + char* name = g_shell_quote(title ? title : ""); + char* new = g_strdup_printf("%s %s\n", uri, name); + + fwrite(new, strlen(new), 1, file); + + g_free(name); + g_free(new); + + file_lock_set(fileno(file), F_UNLCK); + fclose(file); + } +} + +/** + * Appends all url history entries form history file to given list. + */ +void url_history_get_all(GList** list) +{ + GList* src = url_history_load(); + + for (GList* link = src; link; link = link->next) { + UrlHist* hi = (UrlHist*)link->data; + /* put only the url in the list - do not allocate new memory */ + *list = g_list_prepend(*list, hi->uri); + } + + *list = g_list_reverse(*list); +} + +/** + * Loads history items form file but elemiate duplicates. + */ +static GList* url_history_load(void) { /* read the history items from file */ - char buf[512] = {0}; - guint max = vb.config.url_history_max; - FILE* file = fopen(vb.files[FILES_HISTORY], "r"); - if (!file) { - return; + GList* list = NULL; + char buf[512] = {0}; + unsigned int max = vb.config.url_history_max; + unsigned int added = 0; + FILE* file; + + if (!(file = fopen(vb.files[FILES_HISTORY], "r"))) { + return list; } file_lock_set(fileno(file), F_WRLCK); - - for (guint i = 0; i < max && fgets(buf, sizeof(buf), file); i++) { + while (added < max && fgets(buf, sizeof(buf), file)) { char** argv = NULL; - gint argc = 0; + int argc = 0; if (g_shell_parse_argv(buf, &argc, &argv, NULL)) { - url_history_add(argv[0], argc > 1 ? argv[1] : NULL); + added += url_history_add_unique(&list, argv[0], argc > 1 ? argv[1] : NULL); } g_strfreev(argv); } - file_lock_set(fileno(file), F_UNLCK); fclose(file); - /* reverse the history because we read it from lates to old from file */ - vb.behave.url_history = g_list_reverse(vb.behave.url_history); + /* if list is too long - remove items from end (oldest entries) */ + while (vb.config.url_history_max < g_list_length(list)) { + GList* last = g_list_last(list); + url_history_free((UrlHist*)last->data); + list = g_list_delete_link(list, last); + } + + return list; } -void url_history_cleanup(void) +static unsigned int url_history_add_unique(GList** list, const char* url, const char* title) +{ + unsigned int num_added = 1; + /* if the url is already in history, remove this entry */ + for (GList* link = *list; link; link = link->next) { + UrlHist* hi = (UrlHist*)link->data; + if (!g_strcmp0(url, hi->uri)) { + url_history_free(hi); + *list = g_list_delete_link(*list, link); + num_added = 0; + break; + } + } + + UrlHist* item = g_new0(UrlHist, 1); + item->uri = g_strdup(url); + item->title = title ? g_strdup(title) : NULL; + + *list = g_list_prepend(*list, item); + + return num_added; +} + +/** + * Loads the entries from file, make them unique and write them back to file. + */ +static void url_history_write_to_file(GList* list) { FILE* file = fopen(vb.files[FILES_HISTORY], "w"); if (file) { file_lock_set(fileno(file), F_WRLCK); - /* write the history to the file */ - GList* link; - for (link = vb.behave.url_history; link != NULL; link = link->next) { + /* overwrite the history file with new unique history items */ + for (GList* link = g_list_reverse(list); link; link = link->next) { UrlHist* item = (UrlHist*)link->data; + char* title = g_shell_quote(item->title ? item->title : ""); char* new = g_strdup_printf("%s %s\n", item->uri, title); @@ -70,54 +153,19 @@ void url_history_cleanup(void) g_free(title); g_free(new); } + file_lock_set(fileno(file), F_UNLCK); fclose(file); } - - if (vb.behave.url_history) { - g_list_free_full(vb.behave.url_history, (GDestroyNotify)url_history_free); - } + url_history_clear(&list); } -void url_history_add(const char* url, const char* title) +static void url_history_clear(GList** list) { - /* if the url is already in history, remove this entry */ - /* TODO use g_list_find_custom for this task */ - for (GList* link = vb.behave.url_history; link; link = link->next) { - UrlHist* hi = (UrlHist*)link->data; - if (!g_strcmp0(url, hi->uri)) { - url_history_free(hi); - vb.behave.url_history = g_list_delete_link(vb.behave.url_history, link); - break; - } - } - - while (vb.config.url_history_max < g_list_length(vb.behave.url_history)) { - /* if list is too long - remove items from end */ - GList* last = g_list_last(vb.behave.url_history); - url_history_free((UrlHist*)last->data); - vb.behave.url_history = g_list_delete_link(vb.behave.url_history, last); - } - - UrlHist* item = g_new0(UrlHist, 1); - item->uri = g_strdup(url); - item->title = title ? g_strdup(title) : NULL; - - vb.behave.url_history = g_list_prepend(vb.behave.url_history, item); -} - -/** - * Appends the url history entries to given list. - */ -void url_history_get_all(GList** list) -{ - for (GList* link = vb.behave.url_history; link; link = link->next) { - UrlHist* hi = (UrlHist*)link->data; - /* put only the url in the list - do not allocate new memory */ - *list = g_list_prepend(*list, hi->uri); + if (*list) { + g_list_free_full(*list, (GDestroyNotify)url_history_free); + *list = NULL; } - - *list = g_list_reverse(*list); } static void url_history_free(UrlHist* item) diff --git a/src/url_history.h b/src/url_history.h index 68012db..ee4a159 100644 --- a/src/url_history.h +++ b/src/url_history.h @@ -25,9 +25,8 @@ typedef struct { char* title; } UrlHist; -void url_history_init(void); void url_history_cleanup(void); -void url_history_add(const char* url, const char* title); +void url_history_add(const char* uri, const char* title); void url_history_get_all(GList** list); #endif /* end of include guard: _URL_HISTORY_H */