aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/sign.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/sign.c')
-rw-r--r--src/nvim/sign.c115
1 files changed, 77 insertions, 38 deletions
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index 079e95ada8..e22a177178 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -1608,10 +1608,44 @@ static enum
EXP_SUBCMD, // expand :sign sub-commands
EXP_DEFINE, // expand :sign define {name} args
EXP_PLACE, // expand :sign place {id} args
+ EXP_LIST, // expand :sign place args
EXP_UNPLACE, // expand :sign unplace"
- EXP_SIGN_NAMES // expand with name of placed signs
+ EXP_SIGN_NAMES, // expand with name of placed signs
+ EXP_SIGN_GROUPS, // expand with name of placed sign groups
} expand_what;
+// Return the n'th sign name (used for command line completion)
+static char_u *get_nth_sign_name(int idx)
+ FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
+{
+ // Complete with name of signs already defined
+ int current_idx = 0;
+ for (sign_T *sp = first_sign; sp != NULL; sp = sp->sn_next) {
+ if (current_idx++ == idx) {
+ return sp->sn_name;
+ }
+ }
+ return NULL;
+}
+
+// Return the n'th sign group name (used for command line completion)
+static char_u *get_nth_sign_group_name(int idx)
+{
+ // Complete with name of sign groups already defined
+ int current_idx = 0;
+ int todo = (int)sg_table.ht_used;
+ for (hashitem_T *hi = sg_table.ht_array; todo > 0; hi++) {
+ if (!HASHITEM_EMPTY(hi)) {
+ todo--;
+ if (current_idx++ == idx) {
+ signgroup_T *const group = HI2SG(hi);
+ return group->sg_name;
+ }
+ }
+ }
+ return NULL;
+}
+
/// Function given to ExpandGeneric() to obtain the sign command
/// expansion.
char_u * get_sign_name(expand_T *xp, int idx)
@@ -1629,20 +1663,18 @@ char_u * get_sign_name(expand_T *xp, int idx)
"buffer=", NULL };
return (char_u *)place_arg[idx];
}
+ case EXP_LIST: {
+ char *list_arg[] = { "group=", "file=", "buffer=", NULL };
+ return (char_u *)list_arg[idx];
+ }
case EXP_UNPLACE: {
char *unplace_arg[] = { "group=", "file=", "buffer=", NULL };
return (char_u *)unplace_arg[idx];
}
- case EXP_SIGN_NAMES: {
- // Complete with name of signs already defined
- int current_idx = 0;
- for (sign_T *sp = first_sign; sp != NULL; sp = sp->sn_next) {
- if (current_idx++ == idx) {
- return sp->sn_name;
- }
- }
- }
- return NULL;
+ case EXP_SIGN_NAMES:
+ return get_nth_sign_name(idx);
+ case EXP_SIGN_GROUPS:
+ return get_nth_sign_group_name(idx);
default:
return NULL;
}
@@ -1651,7 +1683,6 @@ char_u * get_sign_name(expand_T *xp, int idx)
/// Handle command line completion for :sign command.
void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
{
- char_u *p;
char_u *end_subcmd;
char_u *last;
int cmd_idx;
@@ -1675,26 +1706,6 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// |
// begin_subcmd_args
begin_subcmd_args = skipwhite(end_subcmd);
- p = skiptowhite(begin_subcmd_args);
- if (*p == NUL) {
- //
- // Expand first argument of subcmd when possible.
- // For ":jump {id}" and ":unplace {id}", we could
- // possibly expand the ids of all signs already placed.
- //
- xp->xp_pattern = begin_subcmd_args;
- switch (cmd_idx) {
- case SIGNCMD_LIST:
- case SIGNCMD_UNDEFINE:
- // :sign list <CTRL-D>
- // :sign undefine <CTRL-D>
- expand_what = EXP_SIGN_NAMES;
- break;
- default:
- xp->xp_context = EXPAND_NOTHING;
- }
- return;
- }
// Expand last argument of subcmd.
//
@@ -1703,6 +1714,7 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
// p
// Loop until reaching last argument.
+ char_u *p = begin_subcmd_args;
do {
p = skipwhite(p);
last = p;
@@ -1722,7 +1734,20 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
expand_what = EXP_DEFINE;
break;
case SIGNCMD_PLACE:
- expand_what = EXP_PLACE;
+ // List placed signs
+ if (ascii_isdigit(*begin_subcmd_args)) {
+ // :sign place {id} {args}...
+ expand_what = EXP_PLACE;
+ } else {
+ // :sign place {args}...
+ expand_what = EXP_LIST;
+ }
+ break;
+ case SIGNCMD_LIST:
+ case SIGNCMD_UNDEFINE:
+ // :sign list <CTRL-D>
+ // :sign undefine <CTRL-D>
+ expand_what = EXP_SIGN_NAMES;
break;
case SIGNCMD_JUMP:
case SIGNCMD_UNPLACE:
@@ -1736,19 +1761,33 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg)
xp->xp_pattern = p + 1;
switch (cmd_idx) {
case SIGNCMD_DEFINE:
- if (STRNCMP(last, "texthl", p - last) == 0
- || STRNCMP(last, "linehl", p - last) == 0
- || STRNCMP(last, "numhl", p - last) == 0) {
+ if (STRNCMP(last, "texthl", 6) == 0
+ || STRNCMP(last, "linehl", 6) == 0
+ || STRNCMP(last, "numhl", 5) == 0) {
xp->xp_context = EXPAND_HIGHLIGHT;
- } else if (STRNCMP(last, "icon", p - last) == 0) {
+ } else if (STRNCMP(last, "icon", 4) == 0) {
xp->xp_context = EXPAND_FILES;
} else {
xp->xp_context = EXPAND_NOTHING;
}
break;
case SIGNCMD_PLACE:
- if (STRNCMP(last, "name", p - last) == 0) {
+ if (STRNCMP(last, "name", 4) == 0) {
expand_what = EXP_SIGN_NAMES;
+ } else if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
+ } else {
+ xp->xp_context = EXPAND_NOTHING;
+ }
+ break;
+ case SIGNCMD_UNPLACE:
+ case SIGNCMD_JUMP:
+ if (STRNCMP(last, "group", 5) == 0) {
+ expand_what = EXP_SIGN_GROUPS;
+ } else if (STRNCMP(last, "file", 4) == 0) {
+ xp->xp_context = EXPAND_BUFFERS;
} else {
xp->xp_context = EXPAND_NOTHING;
}