return true;
}
-void completion_next(gboolean back)
+/**
+ * Moves the selection to the next/previous tree item.
+ * If the end/beginning is reached return false and start on the opposite end
+ * on the next call.
+ */
+gboolean completion_next(gboolean back)
{
int rows;
GtkTreePath *path;
if (back) {
/* step back */
if (--comp.active < 0) {
- comp.active = rows - 1;
+ if (comp.active == -1) {
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(GTK_TREE_VIEW(comp.tree)));
+ return false;
+ } else {
+ comp.active = rows - 1;
+ }
}
} else {
/* step forward */
if (++comp.active >= rows) {
- comp.active = 0;
+ if (comp.active == rows) {
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(GTK_TREE_VIEW(comp.tree)));
+ return false;
+ } else {
+ comp.active = 0;
+ }
}
}
path = gtk_tree_path_new_from_indices(comp.active, -1);
gtk_tree_view_set_cursor(tree, path, NULL, false);
gtk_tree_path_free(path);
+
+ return true;
}
void completion_clean(void)
guint count;
char *prefix; /* completion prefix like :, ? and / */
char *current; /* holds the current written input box content */
+ char *token; /* initial filter content */
} excomp;
static struct {
/* if completion was already started move to the next/prev item */
if (vb.mode->flags & FLAG_COMPLETION) {
if (excomp.current && !strcmp(input, excomp.current)) {
- /* step through the next/prev completion item */
- completion_next(direction < 0);
+ /* Step through the next/prev completion item. */
+ if (!completion_next(direction < 0)) {
+ /* If we stepped over the last/first item - put the initial content in */
+ completion_select(excomp.token);
+ }
g_free(input);
return true;
* there is a space after the command and the optional '!' bang. */
if (parse_command_name(&in, arg) && parse_bang(&in, arg) && VB_IS_SPACE(*in)) {
const char *token;
-
/* Get only the last word of input string for the completion for
* bookmark tag completion. */
if (arg->code == EX_BMA) {
* the ':open ' if ':open something' is completed. This means that
* the completion will only the none prefix part of the input */
OVERWRITE_NSTRING(excomp.prefix, input, token - input + 1);
+ OVERWRITE_STRING(excomp.token, token + 1);
/* the token points to a space, skip this */
skip_whitespace(&token);
} else { /* complete command names */
/* restore the 'in' pointer after try to parse command name */
in = before_cmdname;
+ OVERWRITE_STRING(excomp.token, in);
/* Backup the parsed data so we can access them in
* completion_select function. */
free_cmdarg(arg);
} else if (*in == '/' || *in == '?') {
if (history_fill_completion(store, HISTORY_SEARCH, in + 1)) {
+ OVERWRITE_STRING(excomp.token, in + 1);
OVERWRITE_NSTRING(excomp.prefix, in, 1);
sort = true;
found = true;