}
}
+gboolean command_exists(const gchar* name)
+{
+ return g_hash_table_contains(vp.behave.commands, name);
+}
+
gboolean command_run(const gchar* name, const gchar* param)
{
CommandInfo* c = NULL;
void command_init(void);
+gboolean command_exists(const gchar* name);
gboolean command_run(const gchar* name, const gchar* param);
#endif /* end of include guard: COMMAND_H */
static GString* modkeys = NULL;
static GSList* keybind_find(int mode, guint modkey, guint modmask, guint keyval);
+static void keybind_str_to_keybind(gchar* str, Keybind* key);
+static guint keybind_str_to_modmask(const gchar* str);
static gboolean keybind_keypress_callback(WebKitWebView* webview, GdkEventKey* event);
g_signal_connect(G_OBJECT(vp.gui.window), "key-press-event", G_CALLBACK(keybind_keypress_callback), NULL);
}
-void keybind_add(int mode, guint modkey, guint modmask, guint keyval, const gchar* command)
+void keybind_add_from_string(const gchar* str, const Mode mode)
{
- Keybind* keybind = g_new0(Keybind, 1);
+ if (str == NULL || *str == '\0') {
+ return;
+ }
+ gchar* line = g_strdup(str);
+ g_strstrip(line);
+
+ /* split into keybinding and command */
+ char **string = g_strsplit(line, " ", 2);
+
+ guint len = g_strv_length(string);
+ if (len == 2 && command_exists(string[1])) {
+ Keybind* keybind = g_new0(Keybind, 1);
+ keybind->mode = mode;
+ keybind->command = g_strdup(string[1]);
- keybind->mode = mode;
- keybind->modkey = modkey;
- keybind->modmask = modmask;
- keybind->keyval = keyval;
- keybind->command = g_strdup(command);
+ keybind_str_to_keybind(string[0], keybind);
- keys = g_slist_prepend(keys, keybind);
+ /* add the keybinding to the list */
+ keys = g_slist_prepend(keys, keybind);
- /* save the modkey also in the modkey string */
- if (modkey) {
- g_string_append_c(modkeys, modkey);
+ /* save the modkey also in the modkey string */
+ if (keybind->modkey) {
+ g_string_append_c(modkeys, keybind->modkey);
+ }
+ } else {
+ fprintf(stderr, "could not add keybind from '%s'", line);
}
+
+ g_strfreev(string);
+ g_free(line);
}
-void keybind_remove(int mode, guint modkey, guint modmask, guint keyval)
+void keybind_remove_from_string(const gchar* str, const Mode mode)
{
- GSList* link = keybind_find(mode, modkey, modmask, keyval);
+ gchar* line = NULL;
+ Keybind keybind = {0};
+
+ if (str == NULL || *str == '\0') {
+ return;
+ }
+ line = g_strdup(str);
+ g_strstrip(line);
+
+ /* fill the keybind with data from given string */
+ keybind_str_to_keybind(line, &keybind);
+
+ GSList* link = keybind_find(keybind.mode, keybind.modkey, keybind.modmask, keybind.keyval);
if (link) {
keys = g_slist_delete_link(keys, link);
}
/* TODO remove eventually no more used modkeys */
}
-GSList* keybind_find(int mode, guint modkey, guint modmask, guint keyval)
+static GSList* keybind_find(int mode, guint modkey, guint modmask, guint keyval)
{
GSList* link;
for (link = keys; link != NULL; link = link->next) {
return NULL;
}
+static void keybind_str_to_keybind(gchar* str, Keybind* keybind)
+{
+ gchar** string = NULL;
+ guint len = 0;
+
+ if (str == NULL || *str == '\0') {
+ return;
+ }
+ g_strstrip(str);
+
+ /* [modkey[<modmask>]]keyval */
+ string = g_strsplit_set(str, "<>", 3);
+ len = g_strv_length(string);
+
+ if (len == 1) { /* no modmask set */
+ if (strlen(string[0]) == 2) {
+ keybind->modkey = string[0][0];
+ keybind->keyval = string[0][1];
+ } else {
+ keybind->keyval = string[0][0];
+ }
+ } else { /* contains modmask */
+ keybind->modkey = (string[0][0] != '\0') ? string[0][0] : 0;
+ keybind->modmask = keybind_str_to_modmask(string[1]);
+ keybind->keyval = string[2][0];
+ }
+ g_strfreev(string);
+}
+
+static guint keybind_str_to_modmask(const gchar* str)
+{
+ if (!g_ascii_strcasecmp(str, "ctrl")) {
+ return GDK_CONTROL_MASK;
+ }
+ if (!g_ascii_strcasecmp(str, "shift")) {
+ return GDK_SHIFT_MASK;
+ }
+
+ return 0;
+}
+
static gboolean keybind_keypress_callback(WebKitWebView* webview, GdkEventKey* event)
{
GdkModifierType irrelevant;
} Keybind;
void keybind_init(void);
-void keybind_add(int mode, guint modkey, guint modmask, guint keyval, const gchar* command);
-void keybind_remove(int mode, guint modkey, guint modmask, guint keyval);
+void keybind_add_from_string(const gchar* str, const Mode mode);
+void keybind_remove_from_string(const gchar* str, const Mode mode);
#endif /* end of include guard: KEYBIND_H */
#include "config.h"
#include "main.h"
+#include "util.h"
#include "command.h"
#include "keybind.h"
static void vp_print_version(void);
static void vp_init(void);
static void vp_init_gui(void);
+static void vp_init_files(void);
static void vp_set_widget_font(GtkWidget* widget, const gchar* font_definition, const gchar* bg_color, const gchar* fg_color);
static void vp_setup_settings(void);
static void vp_setup_signals(void);
}
void vp_close_browser(const Arg* arg)
+{
+ vp_clean_up();
+ gtk_main_quit();
+}
+
+void vp_clean_up(void)
{
if (vp.behave.commands) {
g_hash_table_destroy(vp.behave.commands);
vp.behave.commands = NULL;
}
- gtk_main_quit();
+ for (int i = FILES_FIRST; i < FILES_LAST; i++) {
+ g_free(vp.files[i]);
+ }
}
void vp_view_source(const Arg* arg)
vp_init_gui();
/* initialize the commands hash map */
command_init();
+ /* initialize the config files */
+ vp_init_files();
/* initialize the keybindings */
keybind_init();
/* TODO read the key bindings from config file */
- keybind_add(VP_MODE_NORMAL, GDK_g, 0, GDK_f, "source");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_colon, "input");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_o, "inputopen");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_O, "inputopencurrent");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_d, "quit");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_o, "back");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_i, "forward");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_r, "reload");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_R, "reload!");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_c, "stop");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_f, "pagedown");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_b, "pageup");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_d, "halfpagedown");
- keybind_add(VP_MODE_NORMAL, 0, GDK_CONTROL_MASK, GDK_u, "halfpageup");
- keybind_add(VP_MODE_NORMAL, GDK_g, 0, GDK_g, "jumptop");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_G, "jumpbottom");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_0, "jumpleft");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_dollar, "jumpright");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_h, "scrollleft");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_l, "scrollright");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_k, "scrollup");
- keybind_add(VP_MODE_NORMAL, 0, 0, GDK_j, "scrolldown");
+ keybind_add_from_string("gf source", VP_MODE_NORMAL);
+ keybind_add_from_string(": input", VP_MODE_NORMAL);
+ keybind_add_from_string("o inputopen", VP_MODE_NORMAL);
+ keybind_add_from_string("O inputopencurrent", VP_MODE_NORMAL);
+ keybind_add_from_string("d quit", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>o back", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>i forward", VP_MODE_NORMAL);
+ keybind_add_from_string("r reload", VP_MODE_NORMAL);
+ keybind_add_from_string("R reload!", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>c stop", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>f pagedown", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>b pageup", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>d halfpagedown", VP_MODE_NORMAL);
+ keybind_add_from_string("<ctrl>u halfpageup", VP_MODE_NORMAL);
+ keybind_add_from_string("gg jumptop", VP_MODE_NORMAL);
+ keybind_add_from_string("G jumpbottom", VP_MODE_NORMAL);
+ keybind_add_from_string("0 jumpleft", VP_MODE_NORMAL);
+ keybind_add_from_string("$ jumpright", VP_MODE_NORMAL);
+ keybind_add_from_string("h scrollleft", VP_MODE_NORMAL);
+ keybind_add_from_string("l scrollright", VP_MODE_NORMAL);
+ keybind_add_from_string("k scrollup", VP_MODE_NORMAL);
+ keybind_add_from_string("j scrolldown", VP_MODE_NORMAL);
}
static void vp_init_gui(void)
gtk_widget_show_all(gui->window);
}
+static void vp_init_files(void)
+{
+ gchar* path = util_get_config_dir();
+
+ vp.files[FILES_CONFIG] = g_build_filename(path, "config", NULL);
+ util_create_file_if_not_exists(vp.files[FILES_CONFIG]);
+
+ g_free(path);
+}
+
static void vp_set_widget_font(GtkWidget* widget, const gchar* font_definition, const gchar* bg_color, const gchar* fg_color)
{
GdkColor fg, bg;
VP_MSG_ERROR
} MessageType;
+enum {
+ FILES_FIRST = 0,
+ FILES_CONFIG = 0,
+ FILES_LAST
+};
+
/* structs */
typedef struct {
gint i;
Gui gui;
State state;
Behaviour behave;
+ gchar* files[FILES_LAST];
#if 0
Network net;
Ssl ssl;
void vp_navigate(const Arg* arg);
void vp_scroll(const Arg* arg);
void vp_close_browser(const Arg* arg);
+void vp_clean_up(void);
void vp_view_source(const Arg* arg);
void vp_set_mode(const Arg* arg);
void vp_input(const Arg* arg);
--- /dev/null
+#include "util.h"
+#include <stdio.h>
+#include <glib.h>
+
+char* util_get_config_dir(void)
+{
+ char *path = g_build_filename(g_get_user_config_dir(), PROJECT, NULL);
+ util_create_dir_if_not_exists(path);
+
+ return path;
+}
+
+char* util_get_cache_dir(void)
+{
+ char *path = g_build_filename(g_get_user_cache_dir(), PROJECT, NULL);
+ util_create_dir_if_not_exists(path);
+
+ return path;
+}
+
+void util_create_dir_if_not_exists(const gchar* dirpath)
+{
+ if (!g_file_test(dirpath, G_FILE_TEST_IS_DIR)) {
+ g_mkdir_with_parents(dirpath, 0755);
+ }
+}
+
+void util_create_file_if_not_exists(const char* filename) {
+ if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
+ FILE* f = fopen(filename, "a");
+ fclose(f);
+ }
+}
--- /dev/null
+#ifndef UTIL_H
+#define UTIL_H
+
+char* util_get_config_dir(void);
+char* util_get_cache_dir(void);
+void util_create_dir_if_not_exists(const char* dirpath);
+void util_create_file_if_not_exists(const char* filename);
+
+#endif /* end of include guard: UTIL_H */