Skip to content

Commit

Permalink
Show typed text as last completion entry (#253).
Browse files Browse the repository at this point in the history
This patch adapts the vim behaviour. If you reach the end of the
possible completion items, the initial content is written to the
inputbox. This makes it easier to change the filter string to reduce the
completion by simply step right to the very last entry with <S-Tab>.
  • Loading branch information
fanglingsu committed Nov 22, 2015
1 parent 5f72908 commit 47db985
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
23 changes: 20 additions & 3 deletions src/completion.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,12 @@ gboolean completion_create(GtkTreeModel *model, CompletionSelectFunc selfunc,
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;
Expand All @@ -171,19 +176,31 @@ void completion_next(gboolean back)
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;
}
}
}

/* get new path and move cursor to it */
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)
Expand Down
2 changes: 1 addition & 1 deletion src/completion.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ typedef void (*CompletionSelectFunc) (char *match);
gboolean completion_create(GtkTreeModel *model, CompletionSelectFunc selfunc,
gboolean back);
void completion_clean(void);
void completion_next(gboolean back);
gboolean completion_next(gboolean back);

#endif /* end of include guard: _COMPLETION_H */
12 changes: 9 additions & 3 deletions src/ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ static struct {
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 {
Expand Down Expand Up @@ -1102,8 +1103,11 @@ static gboolean complete(short direction)
/* 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;
Expand Down Expand Up @@ -1135,7 +1139,6 @@ static gboolean complete(short direction)
* 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) {
Expand All @@ -1155,6 +1158,7 @@ static gboolean complete(short direction)
* 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);
Expand Down Expand Up @@ -1212,6 +1216,7 @@ static gboolean complete(short direction)
} 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. */
Expand All @@ -1225,6 +1230,7 @@ static gboolean complete(short direction)
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;
Expand Down

0 comments on commit 47db985

Please sign in to comment.