diff --git a/database-plain.c b/database-plain.c index fcc0558..90de64c 100644 --- a/database-plain.c +++ b/database-plain.c @@ -1,6 +1,7 @@ /* See LICENSE file for license and copyright information */ #define _POSIX_SOURCE +#define _XOPEN_SOURCE 500 #include #include @@ -10,11 +11,13 @@ #include #include #include +#include #include "database-plain.h" #define BOOKMARKS "bookmarks" #define HISTORY "history" +#define INPUT_HISTORY "input-history" #define KEY_PAGE "page" #define KEY_OFFSET "offset" @@ -37,9 +40,11 @@ #endif static void zathura_database_interface_init(ZathuraDatabaseInterface* iface); +static void io_interface_init(GiraraInputHistoryIOInterface* iface); G_DEFINE_TYPE_WITH_CODE(ZathuraPlainDatabase, zathura_plaindatabase, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init)) + G_IMPLEMENT_INTERFACE(ZATHURA_TYPE_DATABASE, zathura_database_interface_init) + G_IMPLEMENT_INTERFACE(GIRARA_TYPE_INPUT_HISTORY_IO, io_interface_init)) static void plain_finalize(GObject* object); static bool plain_add_bookmark(zathura_database_t* db, const char* file, @@ -54,6 +59,8 @@ static bool plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* file_info); static void plain_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); +static void plain_io_append(GiraraInputHistoryIO* db, const char*); +static girara_list_t* plain_io_read(GiraraInputHistoryIO* db); /* forward declaration */ static bool zathura_db_check_file(const char* path); @@ -70,6 +77,8 @@ typedef struct zathura_plaindatabase_private_s { char* history_path; GKeyFile* history; GFileMonitor* history_monitor; + + char* input_history_path; } zathura_plaindatabase_private_t; #define ZATHURA_PLAINDATABASE_GET_PRIVATE(obj) \ @@ -105,6 +114,14 @@ zathura_database_interface_init(ZathuraDatabaseInterface* iface) iface->get_fileinfo = plain_get_fileinfo; } +static void +io_interface_init(GiraraInputHistoryIOInterface* iface) +{ + /* initialize interface */ + iface->append = plain_io_append; + iface->read = plain_io_read; +} + static void zathura_plaindatabase_class_init(ZathuraPlainDatabaseClass* class) { @@ -126,12 +143,13 @@ zathura_plaindatabase_init(ZathuraPlainDatabase* db) { zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db); - priv->bookmark_path = NULL; - priv->bookmark_monitor = NULL; - priv->bookmarks = NULL; - priv->history_path = NULL; - priv->history_monitor = NULL; - priv->history = NULL; + priv->bookmark_path = NULL; + priv->bookmark_monitor = NULL; + priv->bookmarks = NULL; + priv->history_path = NULL; + priv->history_monitor = NULL; + priv->history = NULL; + priv->input_history_path = NULL; } zathura_database_t* @@ -208,6 +226,12 @@ plain_db_init(ZathuraPlainDatabase* db, const char* dir) goto error_free; } + /* input history */ + priv->input_history_path = g_build_filename(dir, INPUT_HISTORY, NULL); + if (zathura_db_check_file(priv->input_history_path) == false) { + goto error_free; + } + return; error_free: @@ -239,6 +263,10 @@ error_free: g_key_file_free(priv->history); priv->history = NULL; } + + /* input history */ + g_free(priv->input_history_path); + priv->input_history_path = NULL; } static void @@ -283,6 +311,9 @@ plain_finalize(GObject* object) g_key_file_free(priv->history); } + /* input history */ + g_free(priv->input_history_path); + G_OBJECT_CLASS(zathura_plaindatabase_parent_class)->finalize(object); } @@ -595,3 +626,76 @@ cb_zathura_db_watch_file(GFileMonitor* UNUSED(monitor), GFile* file, GFile* UNUS g_free(path); } + +static girara_list_t* +plain_io_read(GiraraInputHistoryIO* db) +{ + zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db); + + /* open file */ + FILE* file = fopen(priv->input_history_path, "r"); + if (file == NULL) { + return NULL; + } + + /* read input history file */ + file_lock_set(fileno(file), F_RDLCK); + char* content = girara_file_read2(file); + file_lock_set(fileno(file), F_UNLCK); + fclose(file); + + girara_list_t* res = girara_list_new2(g_free); + char** tmp = g_strsplit(content, "\n", 0); + for (size_t i = 0; tmp[i] != NULL; ++i) { + if (strlen(tmp[i]) == 0 || strchr(":/", tmp[i][0]) == NULL) { + continue; + } + girara_list_append(res, g_strdup(tmp[i])); + } + g_strfreev(tmp); + free(content); + + return res; +} + +#include + +static void +plain_io_append(GiraraInputHistoryIO* db, const char* input) +{ + zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db); + + /* open file */ + FILE* file = fopen(priv->input_history_path, "r+"); + if (file == NULL) { + return; + } + + /* read input history file */ + file_lock_set(fileno(file), F_WRLCK); + char* content = girara_file_read2(file); + + rewind(file); + if (ftruncate(fileno(file), 0) != 0) { + free(content); + file_lock_set(fileno(file), F_UNLCK); + fclose(file); + return; + } + + char** tmp = g_strsplit(content, "\n", 0); + free(content); + + /* write input history file */ + for (size_t i = 0; tmp[i] != NULL; ++i) { + if (strlen(tmp[i]) == 0 || strchr(":/", tmp[i][0]) == NULL || strcmp(tmp[i], input) == 0) { + continue; + } + fprintf(file, "%s\n", tmp[i]); + } + g_strfreev(tmp); + fprintf(file, "%s\n", input); + + file_lock_set(fileno(file), F_UNLCK); + fclose(file); +} diff --git a/zathura.c b/zathura.c index 5af318a..b110a6d 100644 --- a/zathura.c +++ b/zathura.c @@ -219,9 +219,6 @@ zathura_init(zathura_t* zathura) girara_debug("Using sqlite database backend."); char* tmp = g_build_filename(zathura->config.data_dir, "bookmarks.sqlite", NULL); zathura->database = zathura_sqldatabase_new(tmp); - if (zathura->database != NULL) { - g_object_set(zathura->ui.session->global.command_history, "io", zathura->database, NULL); - } g_free(tmp); #endif } else { @@ -231,6 +228,8 @@ zathura_init(zathura_t* zathura) if (zathura->database == NULL) { girara_error("Unable to initialize database. Bookmarks won't be available."); + } else { + g_object_set(zathura->ui.session->global.command_history, "io", zathura->database, NULL); } /* bookmarks */