From 31f6ea0eb61ad76ea4b78e3f3c3d4d7436d24a45 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sun, 11 Nov 2012 18:22:08 +0100 Subject: [PATCH] Added basic completion of settings. For the moment we have to type :set and can complete from this the settings, but it would be a better solution to complete first the command and add a space and type TAB to complete the settings. --- src/completion.c | 51 +++++++++++++++++++++++++++--------------------- src/completion.h | 6 +----- src/keybind.c | 2 +- src/main.c | 7 ++++++- src/main.h | 3 +++ src/setting.c | 12 +++++------- 6 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/completion.c b/src/completion.c index 4565507..bd3f2a8 100644 --- a/src/completion.c +++ b/src/completion.c @@ -22,17 +22,19 @@ typedef struct { GtkWidget* label; GtkWidget* event; + gchar* prefix; } Completion; -static GList* completion_init_completion(GList* target, GList* source); +static GList* completion_init_completion(GList* target, GList* source, const gchar* prefix); static GList* completion_update(GList* completion, GList* active, gboolean back); static void completion_show(gboolean back); static void completion_set_color(Completion* completion, const GdkColor* fg, const GdkColor* bg, PangoFontDescription* font); static void completion_set_entry_text(Completion* completion); -static Completion* completion_get_new(const gchar* label); +static Completion* completion_get_new(const gchar* label, const gchar* prefix); -gboolean completion_complete(const CompletionType type, gboolean back) +gboolean completion_complete(gboolean back) { + const gchar* input = NULL; GList* source = NULL; if (vp.comps.completions @@ -44,14 +46,8 @@ gboolean completion_complete(const CompletionType type, gboolean back) return TRUE; } - /* create new completion */ - switch (type) { - case COMPLETE_COMMAND: - source = g_hash_table_get_keys(vp.behave.commands); - source = g_list_sort(source, (GCompareFunc)g_strcmp0); - break; - } + /* create new completion */ #if _HAS_GTK3 vp.gui.compbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_homogeneous(GTK_BOX(vp.gui.compbox), TRUE); @@ -60,7 +56,17 @@ gboolean completion_complete(const CompletionType type, gboolean back) #endif gtk_box_pack_start(GTK_BOX(vp.gui.box), vp.gui.compbox, FALSE, FALSE, 0); - vp.comps.completions = completion_init_completion(vp.comps.completions, source); + input = GET_TEXT(); + /* TODO move these decision to a more generic place */ + if (g_str_has_prefix(input, ":set ")) { + source = g_hash_table_get_keys(vp.settings); + source = g_list_sort(source, (GCompareFunc)g_strcmp0); + vp.comps.completions = completion_init_completion(vp.comps.completions, source, ":set "); + } else { + source = g_hash_table_get_keys(vp.behave.commands); + source = g_list_sort(source, (GCompareFunc)g_strcmp0); + vp.comps.completions = completion_init_completion(vp.comps.completions, source, ":"); + } if (!vp.comps.completions) { return FALSE; @@ -91,21 +97,21 @@ void completion_clean(void) vp.state.mode &= ~VP_MODE_COMPLETE; } -static GList* completion_init_completion(GList* target, GList* source) +static GList* completion_init_completion(GList* target, GList* source, const gchar* prefix) { - const gchar* input = gtk_entry_get_text(GTK_ENTRY(vp.gui.inputbox)); + const gchar* input = GET_TEXT(); gchar* command = NULL; gchar* data = NULL; gboolean match; gchar **token = NULL; - if (input && input[0] == ':') { - input++; - } - /* remove counts before command and save it to print it later in inputbox */ vp.comps.count = g_ascii_strtoll(input, &command, 10); + if (g_str_has_prefix(command, prefix)) { + command = command + strlen(prefix); + } + token = g_strsplit(command, " ", -1); for (GList* l = source; l; l = l->next) { @@ -124,7 +130,7 @@ static GList* completion_init_completion(GList* target, GList* source) } } if (match) { - Completion* c = completion_get_new(data); + Completion* c = completion_get_new(data, prefix); gtk_box_pack_start(GTK_BOX(vp.gui.compbox), c->event, FALSE, FALSE, 0); target = g_list_append(target, c); } @@ -246,7 +252,7 @@ static void completion_set_color(Completion* completion, const GdkColor* fg, con static void completion_set_entry_text(Completion* completion) { - GString* string = g_string_new(":"); + GString* string = g_string_new(completion->prefix); const gchar* text; text = gtk_label_get_text(GTK_LABEL(completion->label)); @@ -262,14 +268,15 @@ static void completion_set_entry_text(Completion* completion) g_string_free(string, TRUE); } -static Completion* completion_get_new(const gchar* label) +static Completion* completion_get_new(const gchar* label, const gchar* prefix) { /* TODO make this configurable */ const gint padding = 2; Completion* c = g_new0(Completion, 1); - c->label = gtk_label_new(label); - c->event = gtk_event_box_new(); + c->label = gtk_label_new(label); + c->event = gtk_event_box_new(); + c->prefix = g_strdup(prefix); #if _HAS_GTK3 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); diff --git a/src/completion.h b/src/completion.h index 29d1692..af74a99 100644 --- a/src/completion.h +++ b/src/completion.h @@ -22,11 +22,7 @@ #include "main.h" -typedef enum { - COMPLETE_COMMAND -} CompletionType; - void completion_clean(void); -gboolean completion_complete(const CompletionType type, gboolean back); +gboolean completion_complete(gboolean back); #endif /* end of include guard: COMPLETION_H */ diff --git a/src/keybind.c b/src/keybind.c index 0824429..6ba3a5b 100644 --- a/src/keybind.c +++ b/src/keybind.c @@ -209,7 +209,7 @@ static gboolean keybind_keypress_callback(WebKitWebView* webview, GdkEventKey* e /* TODO should we use a command for that too? */ if (event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) { - completion_complete(COMPLETE_COMMAND, event->keyval == GDK_ISO_Left_Tab); + completion_complete(event->keyval == GDK_ISO_Left_Tab); return TRUE; } diff --git a/src/main.c b/src/main.c index 9486e55..87eee77 100644 --- a/src/main.c +++ b/src/main.c @@ -161,6 +161,10 @@ static void vp_gotheaders_cb(SoupMessage* message, gpointer data) } #endif +/** + * Processed input from input box without trailing : or ? /, input from config + * file and default config. + */ static gboolean vp_process_input(const char* input) { gboolean success; @@ -264,7 +268,8 @@ void vp_clean_up(void) static gboolean vp_hide_message(void) { /* do not clean in command mode */ - if (vp.state.mode == VP_MODE_COMMAND) { + /* TODO add a CLEAN_MODE macro to get only the main modes */ + if (vp.state.mode & VP_MODE_COMMAND) { return FALSE; } diff --git a/src/main.h b/src/main.h index fad01b2..5d84953 100644 --- a/src/main.h +++ b/src/main.h @@ -43,6 +43,8 @@ #define TIMER_END #endif +#define GET_TEXT() (gtk_entry_get_text(GTK_ENTRY(vp.gui.inputbox))) + /* enums */ typedef enum _vp_mode { VP_MODE_NORMAL = 1<<0, @@ -196,6 +198,7 @@ typedef struct { Config config; Completions comps; Style style; + GHashTable* settings; #if 0 Ssl ssl; Communication comm; diff --git a/src/setting.c b/src/setting.c index de9fedf..8da2135 100644 --- a/src/setting.c +++ b/src/setting.c @@ -99,18 +99,16 @@ static Setting default_settings[] = { {"completion-bg-active", TYPE_CHAR, setting_completion_style, {.s = "#777777"}}, }; -static GHashTable* settings = NULL; - void setting_init(void) { Setting* s; guint i; - settings = g_hash_table_new(g_str_hash, g_str_equal); + vp.settings = g_hash_table_new(g_str_hash, g_str_equal); for (i = 0; i < LENGTH(default_settings); i++) { s = &default_settings[i]; - g_hash_table_insert(settings, (gpointer)s->name, s); + g_hash_table_insert(vp.settings, (gpointer)s->name, s); /* set the default settings */ s->func(s); @@ -119,8 +117,8 @@ void setting_init(void) void setting_cleanup(void) { - if (settings) { - g_hash_table_destroy(settings); + if (vp.settings) { + g_hash_table_destroy(vp.settings); } } @@ -128,7 +126,7 @@ gboolean setting_run(const gchar* name, const gchar* param) { Arg* a = NULL; gboolean result = FALSE; - Setting* s = g_hash_table_lookup(settings, name); + Setting* s = g_hash_table_lookup(vp.settings, name); if (!s) { vp_echo(VP_MSG_ERROR, "Config '%s' not found", name); return FALSE; -- 2.20.1