diff options
-rw-r--r-- | src/ex_cmds.c | 246 | ||||
-rw-r--r-- | src/ex_docmd.c | 8 | ||||
-rw-r--r-- | src/ex_getln.c | 5 | ||||
-rw-r--r-- | src/proto/ex_cmds.pro | 4 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 1 |
6 files changed, 239 insertions, 27 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c index d95a3c23b..250050e91 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -6543,20 +6543,7 @@ static int last_sign_typenr = MAX_TYPENR; /* is decremented */ static void sign_list_defined __ARGS((sign_T *sp)); static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev)); -/* - * ":sign" command - */ - void -ex_sign(eap) - exarg_T *eap; -{ - char_u *arg = eap->arg; - char_u *p; - int idx; - sign_T *sp; - sign_T *sp_prev; - buf_T *buf; - static char *cmds[] = { +static char *cmds[] = { "define", #define SIGNCMD_DEFINE 0 "undefine", @@ -6569,22 +6556,51 @@ ex_sign(eap) #define SIGNCMD_UNPLACE 4 "jump", #define SIGNCMD_JUMP 5 + NULL #define SIGNCMD_LAST 6 - }; +}; + +/* + * Find index of a ":sign" subcmd from its name. + * "*end_cmd" must be writable. + */ + static int +sign_cmd_idx(begin_cmd, end_cmd) + char *begin_cmd; /* begin of sign subcmd */ + char *end_cmd; /* just after sign subcmd */ +{ + int idx; + char save = *end_cmd; + + *end_cmd = NUL; + for (idx = 0; ; ++idx) + if (cmds[idx] == NULL || STRCMP(begin_cmd, cmds[idx]) == 0) + break; + *end_cmd = save; + return idx; +} + +/* + * ":sign" command + */ + void +ex_sign(eap) + exarg_T *eap; +{ + char_u *arg = eap->arg; + char_u *p; + int idx; + sign_T *sp; + sign_T *sp_prev; + buf_T *buf; /* Parse the subcommand. */ p = skiptowhite(arg); - if (*p != NUL) - *p++ = NUL; - for (idx = 0; ; ++idx) + idx = sign_cmd_idx(arg, p); + if (idx == SIGNCMD_LAST) { - if (idx == SIGNCMD_LAST) - { - EMSG2(_("E160: Unknown sign command: %s"), arg); - return; - } - if (STRCMP(arg, cmds[idx]) == 0) - break; + EMSG2(_("E160: Unknown sign command: %s"), arg); + return; } arg = skipwhite(p); @@ -7110,6 +7126,186 @@ free_signs() } #endif +#if defined(FEAT_CMDL_COMPL) || defined(PROTO) +static enum +{ + EXP_SUBCMD, /* expand :sign sub-commands */ + EXP_DEFINE, /* expand :sign define {name} args */ + EXP_PLACE, /* expand :sign place {id} args */ + EXP_UNPLACE, /* expand :sign unplace" */ + EXP_SIGN_NAMES /* expand with name of placed signs */ +} expand_what; + +/* + * Function given to ExpandGeneric() to obtain the sign command + * expansion. + */ +/*ARGSUSED*/ + char_u * +get_sign_name(xp, idx) + expand_T *xp; + int idx; +{ + sign_T *sp; + int current_idx; + + switch (expand_what) + { + case EXP_SUBCMD: + return (char_u *)cmds[idx]; + case EXP_DEFINE: + { + char *define_arg[] = + { + "icon=", "linehl=", "text=", "texthl=", NULL + }; + return (char_u *)define_arg[idx]; + } + case EXP_PLACE: + { + char *place_arg[] = + { + "line=", "name=", "file=", "buffer=", NULL + }; + return (char_u *)place_arg[idx]; + } + case EXP_UNPLACE: + { + char *unplace_arg[] = { "file=", "buffer=", NULL }; + return (char_u *)unplace_arg[idx]; + } + case EXP_SIGN_NAMES: + /* Complete with name of signs already defined */ + current_idx = 0; + for (sp = first_sign; sp != NULL; sp = sp->sn_next) + if (current_idx++ == idx) + return sp->sn_name; + return NULL; + default: + return NULL; + } +} + +/* + * Handle command line completion for :sign command. + */ + void +set_context_in_sign_cmd(xp, arg) + expand_T *xp; + char_u *arg; +{ + char_u *p; + char_u *end_subcmd; + char_u *last; + int cmd_idx; + char_u *begin_subcmd_args; + + /* Default: expand subcommands. */ + xp->xp_context = EXPAND_SIGN; + expand_what = EXP_SUBCMD; + xp->xp_pattern = arg; + + end_subcmd = skiptowhite(arg); + if (*end_subcmd == NUL) + /* expand subcmd name + * :sign {subcmd}<CTRL-D>*/ + return; + + cmd_idx = sign_cmd_idx(arg, end_subcmd); + + /* :sign {subcmd} {subcmd_args} + * | + * 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 */ + + /* :sign define {name} {args}... + * | + * p */ + + /* Loop until reaching last argument. */ + do + { + p = skipwhite(p); + last = p; + p = skiptowhite(p); + } while (*p != NUL); + + p = vim_strchr(last, '='); + + /* :sign define {name} {args}... {last}= + * | | + * last p */ + if (p == NUL) + { + /* Expand last argument name (before equal sign). */ + xp->xp_pattern = last; + switch (cmd_idx) + { + case SIGNCMD_DEFINE: + expand_what = EXP_DEFINE; + break; + case SIGNCMD_PLACE: + expand_what = EXP_PLACE; + break; + case SIGNCMD_JUMP: + case SIGNCMD_UNPLACE: + expand_what = EXP_UNPLACE; + break; + default: + xp->xp_context = EXPAND_NOTHING; + } + } + else + { + /* Expand last argument value (after equal sign). */ + xp->xp_pattern = p + 1; + switch (cmd_idx) + { + case SIGNCMD_DEFINE: + if (STRNCMP(last, "texthl", p - last) == 0 || + STRNCMP(last, "linehl", p - last) == 0) + xp->xp_context = EXPAND_HIGHLIGHT; + else if (STRNCMP(last, "icon", p - last) == 0) + xp->xp_context = EXPAND_FILES; + else + xp->xp_context = EXPAND_NOTHING; + break; + case SIGNCMD_PLACE: + if (STRNCMP(last, "name", p - last) == 0) + expand_what = EXP_SIGN_NAMES; + else + xp->xp_context = EXPAND_NOTHING; + break; + default: + xp->xp_context = EXPAND_NOTHING; + } + } +} +#endif #endif #if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index a6e6feac6..3de873092 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3695,6 +3695,11 @@ set_one_cmd_context(xp, buff) set_context_in_cscope_cmd(xp, arg, ea.cmdidx); break; #endif +#ifdef FEAT_SIGNS + case CMD_sign: + set_context_in_sign_cmd(xp, arg); + break; +#endif #ifdef FEAT_LISTCMDS case CMD_bdelete: case CMD_bwipeout: @@ -5218,6 +5223,9 @@ static struct {EXPAND_MENUS, "menu"}, {EXPAND_SETTINGS, "option"}, {EXPAND_SHELLCMD, "shellcmd"}, +#if defined(FEAT_SIGNS) + {EXPAND_SIGN, "sign"}, +#endif {EXPAND_TAGS, "tag"}, {EXPAND_TAGS_LISTFILES, "tag_listfiles"}, {EXPAND_USER_VARS, "var"}, diff --git a/src/ex_getln.c b/src/ex_getln.c index f3bcc2bee..32635f814 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -325,7 +325,7 @@ getcmdline(firstc, count, indent) #endif #ifdef FEAT_DIGRAPHS - do_digraph(-1); /* init digraph typahead */ + do_digraph(-1); /* init digraph typeahead */ #endif /* @@ -4521,6 +4521,9 @@ ExpandFromContext(xp, pat, num_file, file, options) #ifdef FEAT_CSCOPE {EXPAND_CSCOPE, get_cscope_name, TRUE}, #endif +#ifdef FEAT_SIGNS + {EXPAND_SIGN, get_sign_name, TRUE}, +#endif #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ && (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE)) {EXPAND_LANGUAGE, get_lang_arg, TRUE}, diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro index b2c77cd17..315b6bb5e 100644 --- a/src/proto/ex_cmds.pro +++ b/src/proto/ex_cmds.pro @@ -40,7 +40,6 @@ void global_exe __ARGS((char_u *cmd)); int read_viminfo_sub_string __ARGS((vir_T *virp, int force)); void write_viminfo_sub_string __ARGS((FILE *fp)); void free_old_sub __ARGS((void)); -void free_signs __ARGS((void)); int prepare_tagpreview __ARGS((int undo_sync)); void ex_help __ARGS((exarg_T *eap)); char_u *check_help_lang __ARGS((char_u *arg)); @@ -56,5 +55,8 @@ int sign_get_attr __ARGS((int typenr, int line)); char_u *sign_get_text __ARGS((int typenr)); void *sign_get_image __ARGS((int typenr)); char_u *sign_typenr2name __ARGS((int typenr)); +void free_signs __ARGS((void)); +char_u *get_sign_name __ARGS((expand_T *xp, int idx)); +void set_context_in_sign_cmd __ARGS((expand_T *xp, char_u *arg)); void ex_drop __ARGS((exarg_T *eap)); /* vim: set ft=c : */ diff --git a/src/version.c b/src/version.c index b4e4120e3..8aa0729de 100644 --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 166, +/**/ 165, /**/ 164, @@ -709,6 +709,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname); #define EXPAND_USER_LIST 31 #define EXPAND_SHELLCMD 32 #define EXPAND_CSCOPE 33 +#define EXPAND_SIGN 34 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1 |