From 698d988f588227204d5ea47f3597059ac30dc533 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sat, 28 Sep 2013 23:53:05 +0200 Subject: Moved parts of completion logic to ex.c. This change makes it easier to control the found matches and it allowed to complete also abbreviated commands like ':o !tag'. --- src/completion.c | 167 +++++++++++-------------------------------------------- 1 file changed, 31 insertions(+), 136 deletions(-) (limited to 'src/completion.c') diff --git a/src/completion.c b/src/completion.c index ea48a6d..a0479b4 100644 --- a/src/completion.c +++ b/src/completion.c @@ -20,152 +20,49 @@ #include "config.h" #include "main.h" #include "completion.h" -#include "util.h" -#include "history.h" -#include "bookmark.h" -#include "command.h" -#include "setting.h" -#include "ex.h" - -#define TAG_INDICATOR '!' extern VbCore vb; static struct { GtkWidget *win; GtkWidget *tree; - int count; /* command count before the completed content */ - char *prefix; /* prefix that marks the completion ':', '/', ':open', ... */ int active; /* number of the current active tree item */ - char *text; /* text of the current active tree item */ + CompletionSelectFunc selfunc; } comp; -static void init_completion(GtkTreeModel *model, const char *prefix); -static void show(gboolean back); -static void move_cursor(gboolean back); static gboolean tree_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data); -gboolean completion_complete(gboolean back) +gboolean completion_create(GtkTreeModel *model, CompletionSelectFunc selfunc, + gboolean back) { - VbInputType type; - char *input; - const char *prefix, *suffix; - GtkListStore *store = NULL; - GtkTreeModel *model; - gboolean res = false, sort = true; - - /* TODO give the type of completion to this function - because we have to - * handle also abreviated commands like ':op foo' */ - input = vb_get_input_text(); - type = vb_get_input_parts(input, VB_INPUT_ALL, &prefix, &suffix); - if (vb.mode->flags & FLAG_COMPLETION) { - if (comp.text && !strcmp(input, comp.text)) { - /* step through the next/prev completion item */ - move_cursor(back); - g_free(input); - return true; - } - /* if current input isn't the content of the completion item, stop - * completion and start it after that again */ - completion_clean(); - } - - /* create the list store model */ - store = gtk_list_store_new(COMPLETION_STORE_NUM, G_TYPE_STRING, G_TYPE_STRING); - if (type == VB_INPUT_SET) { - res = setting_fill_completion(store, suffix); - } else if (type == VB_INPUT_OPEN || type == VB_INPUT_TABOPEN) { - /* if search string begins with TAG_INDICATOR lookup the bookmarks */ - if (suffix && *suffix == TAG_INDICATOR) { - res = bookmark_fill_completion(store, suffix + 1); - } else { - res = history_fill_completion(store, HISTORY_URL, suffix); - } - sort = false; - } else if (type == VB_INPUT_COMMAND) { - char *command = NULL; - /* remove counts before command and save it to print it later in inputbox */ - comp.count = g_ascii_strtoll(suffix, &command, 10); - - res = ex_fill_completion(store, command); - /* we have a special sorting of the ex commands so we don't should - * reorder them for the completion */ - sort = false; - } else if (type == VB_INPUT_SEARCH_FORWARD || type == VB_INPUT_SEARCH_BACKWARD) { - res = history_fill_completion(store, HISTORY_SEARCH, suffix); - } else if (type == VB_INPUT_BOOKMARK_ADD) { - res = bookmark_fill_tag_completion(store, suffix); - } - - if (!res) { - g_free(input); - return false; - } + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + GtkTreeViewColumn *column; + GtkRequisition size; + GtkTreePath *path; + GtkTreeIter iter; + int height, width; - model = GTK_TREE_MODEL(store); /* if there is only one match - don't build the tree view */ if (gtk_tree_model_iter_n_children(model, NULL) == 1) { char *value; - GtkTreePath *path = gtk_tree_path_new_from_indices(0, -1); - GtkTreeIter iter; + path = gtk_tree_path_new_from_indices(0, -1); if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, COMPLETION_STORE_FIRST, &value, -1); - if (comp.count) { - vb_echo_force(VB_MSG_NORMAL, false, "%s%d%s", prefix, comp.count, value); - } else { - vb_echo_force(VB_MSG_NORMAL, false, "%s%s", prefix, value); - } + /* call the select function */ + selfunc(value); + g_free(value); + g_object_unref(model); - g_object_unref(G_OBJECT(store)); - g_free(input); return false; } } - /* apply the default sorting to the first tree model comlumn */ - if (sort) { - gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), COMPLETION_STORE_FIRST, GTK_SORT_ASCENDING); - } - - init_completion(GTK_TREE_MODEL(store), prefix); - show(back); - g_free(input); - - return true; -} - -void completion_clean(void) -{ - if (vb.mode->flags & FLAG_COMPLETION) { - /* remove completion flag from mode */ - vb.mode->flags &= ~FLAG_COMPLETION; - - if (comp.win) { - gtk_widget_destroy(comp.win); - comp.win = comp.tree = NULL; - } - OVERWRITE_STRING(comp.prefix, NULL); - OVERWRITE_STRING(comp.text, NULL); - comp.count = 0; - } -} - -static void init_completion(GtkTreeModel *model, const char *prefix) -{ - GtkCellRenderer *renderer; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkRequisition size; - int height, width; - - /* set the submode flag */ - vb.mode->flags |= FLAG_COMPLETION; - - OVERWRITE_STRING(comp.prefix, prefix); + comp.selfunc = selfunc; /* prepare the tree view */ comp.win = gtk_scrolled_window_new(NULL, NULL); @@ -241,10 +138,7 @@ static void init_completion(GtkTreeModel *model, const char *prefix) gtk_widget_set_size_request(comp.win, -1, height); } #endif -} -static void show(gboolean back) -{ /* this prevents the first item to be placed out of view if the completion * is shown */ gtk_widget_show_all(comp.win); @@ -254,10 +148,12 @@ static void show(gboolean back) /* set to -1 to have the cursor on first or last item set in move_cursor */ comp.active = -1; - move_cursor(back); + completion_next(back); + + return true; } -static void move_cursor(gboolean back) +void completion_next(gboolean back) { int rows; GtkTreePath *path; @@ -282,6 +178,14 @@ static void move_cursor(gboolean back) gtk_tree_path_free(path); } +void completion_clean(void) +{ + if (comp.win) { + gtk_widget_destroy(comp.win); + comp.win = comp.tree = NULL; + } +} + static gboolean tree_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean selected, gpointer data) { @@ -292,18 +196,9 @@ static gboolean tree_selection_func(GtkTreeSelection *selection, * interested in */ if (!selected && gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, COMPLETION_STORE_FIRST, &value, -1); - /* save the content of the selected item so wen can access it easy */ - if (comp.text) { - g_free(comp.text); - comp.text = NULL; - } - if (comp.count) { - comp.text = g_strdup_printf("%s%d%s", comp.prefix, comp.count, value); - } else { - comp.text = g_strconcat(comp.prefix, value, NULL); - } - /* print the text also into inputbox */ - vb_set_input_text(comp.text); + + comp.selfunc(value); + g_free(value); } -- cgit v1.2.3