diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 694 |
1 files changed, 0 insertions, 694 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e7f4736613..8722c03204 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -67,10 +67,6 @@ #include "nvim/os/input.h" #include "nvim/os/time.h" -/* - * Struct to hold the sign properties. - */ -typedef struct sign sign_T; /// Case matching style to use for :substitute typedef enum { @@ -5521,21 +5517,6 @@ void ex_helptags(exarg_T *eap) } } -struct sign -{ - sign_T *sn_next; // next sign in list - int sn_typenr; // type number of sign - char_u *sn_name; // name of sign - char_u *sn_icon; // name of pixmap - char_u *sn_text; // text used instead of pixmap - int sn_line_hl; // highlight ID for line - int sn_text_hl; // highlight ID for text - int sn_num_hl; // highlight ID for line number -}; - -static sign_T *first_sign = NULL; -static int next_sign_typenr = 1; - /* * ":helpclose": Close one help window */ @@ -5549,681 +5530,6 @@ void ex_helpclose(exarg_T *eap) } } -static char *cmds[] = { - "define", -#define SIGNCMD_DEFINE 0 - "undefine", -#define SIGNCMD_UNDEFINE 1 - "list", -#define SIGNCMD_LIST 2 - "place", -#define SIGNCMD_PLACE 3 - "unplace", -#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( - char_u *begin_cmd, /* begin of sign subcmd */ - char_u *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(exarg_T *eap) -{ - char_u *arg = eap->arg; - char_u *p; - int idx; - sign_T *sp; - sign_T *sp_prev; - - // Parse the subcommand. - p = skiptowhite(arg); - idx = sign_cmd_idx(arg, p); - if (idx == SIGNCMD_LAST) { - EMSG2(_("E160: Unknown sign command: %s"), arg); - return; - } - arg = skipwhite(p); - - if (idx <= SIGNCMD_LIST) { - // Define, undefine or list signs. - if (idx == SIGNCMD_LIST && *arg == NUL) { - // ":sign list": list all defined signs - for (sp = first_sign; sp != NULL && !got_int; sp = sp->sn_next) { - sign_list_defined(sp); - } - } else if (*arg == NUL) { - EMSG(_("E156: Missing sign name")); - } else { - // Isolate the sign name. If it's a number skip leading zeroes, - // so that "099" and "99" are the same sign. But keep "0". - p = skiptowhite(arg); - if (*p != NUL) { - *p++ = NUL; - } - while (arg[0] == '0' && arg[1] != NUL) { - arg++; - } - - sp_prev = NULL; - for (sp = first_sign; sp != NULL; sp = sp->sn_next) { - if (STRCMP(sp->sn_name, arg) == 0) { - break; - } - sp_prev = sp; - } - if (idx == SIGNCMD_DEFINE) { - // ":sign define {name} ...": define a sign - if (sp == NULL) { - sign_T *lp; - int start = next_sign_typenr; - - // Allocate a new sign. - sp = xcalloc(1, sizeof(sign_T)); - - // Check that next_sign_typenr is not already being used. - // This only happens after wrapping around. Hopefully - // another one got deleted and we can use its number. - for (lp = first_sign; lp != NULL; ) { - if (lp->sn_typenr == next_sign_typenr) { - next_sign_typenr++; - if (next_sign_typenr == MAX_TYPENR) { - next_sign_typenr = 1; - } - if (next_sign_typenr == start) { - xfree(sp); - EMSG(_("E612: Too many signs defined")); - return; - } - lp = first_sign; // start all over - continue; - } - lp = lp->sn_next; - } - - sp->sn_typenr = next_sign_typenr; - if (++next_sign_typenr == MAX_TYPENR) { - next_sign_typenr = 1; // wrap around - } - - sp->sn_name = vim_strsave(arg); - - // add the new sign to the list of signs - if (sp_prev == NULL) { - first_sign = sp; - } else { - sp_prev->sn_next = sp; - } - } - - // set values for a defined sign. - for (;;) { - arg = skipwhite(p); - if (*arg == NUL) { - break; - } - p = skiptowhite_esc(arg); - if (STRNCMP(arg, "icon=", 5) == 0) { - arg += 5; - xfree(sp->sn_icon); - sp->sn_icon = vim_strnsave(arg, (int)(p - arg)); - backslash_halve(sp->sn_icon); - } else if (STRNCMP(arg, "text=", 5) == 0) { - char_u *s; - int cells; - int len; - - arg += 5; - for (s = arg; s + 1 < p; s++) { - if (*s == '\\') { - // Remove a backslash, so that it is possible - // to use a space. - STRMOVE(s, s + 1); - p--; - } - } - - // Count cells and check for non-printable chars - cells = 0; - for (s = arg; s < p; s += utfc_ptr2len(s)) { - if (!vim_isprintc(utf_ptr2char(s))) { - break; - } - cells += utf_ptr2cells(s); - } - // Currently must be one or two display cells - if (s != p || cells < 1 || cells > 2) { - *p = NUL; - EMSG2(_("E239: Invalid sign text: %s"), arg); - return; - } - - xfree(sp->sn_text); - // Allocate one byte more if we need to pad up - // with a space. - len = (int)(p - arg + ((cells == 1) ? 1 : 0)); - sp->sn_text = vim_strnsave(arg, len); - - if (cells == 1) { - STRCPY(sp->sn_text + len - 1, " "); - } - } else if (STRNCMP(arg, "linehl=", 7) == 0) { - arg += 7; - sp->sn_line_hl = syn_check_group(arg, (int)(p - arg)); - } else if (STRNCMP(arg, "texthl=", 7) == 0) { - arg += 7; - sp->sn_text_hl = syn_check_group(arg, (int)(p - arg)); - } else if (STRNCMP(arg, "numhl=", 6) == 0) { - arg += 6; - sp->sn_num_hl = syn_check_group(arg, (int)(p - arg)); - } else { - EMSG2(_(e_invarg2), arg); - return; - } - } - } else if (sp == NULL) { - EMSG2(_("E155: Unknown sign: %s"), arg); - } else if (idx == SIGNCMD_LIST) { - // ":sign list {name}" - sign_list_defined(sp); - } else { - // ":sign undefine {name}" - sign_undefine(sp, sp_prev); - } - } - } else { - int id = -1; - linenr_T lnum = -1; - char_u *sign_name = NULL; - char_u *arg1; - - if (*arg == NUL) { - if (idx == SIGNCMD_PLACE) { - // ":sign place": list placed signs in all buffers - sign_list_placed(NULL); - } else if (idx == SIGNCMD_UNPLACE) { - // ":sign unplace": remove placed sign at cursor - id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum); - if (id > 0) { - buf_delsign(curwin->w_buffer, id); - redraw_buf_line_later(curwin->w_buffer, curwin->w_cursor.lnum); - } else { - EMSG(_("E159: Missing sign number")); - } - } else { - EMSG(_(e_argreq)); - } - return; - } - - if (idx == SIGNCMD_UNPLACE && arg[0] == '*' && arg[1] == NUL) { - // ":sign unplace *": remove all placed signs - buf_delete_all_signs(); - return; - } - - // first arg could be placed sign id - arg1 = arg; - if (ascii_isdigit(*arg)) { - id = getdigits_int(&arg); - if (!ascii_iswhite(*arg) && *arg != NUL) { - id = -1; - arg = arg1; - } else { - arg = skipwhite(arg); - if (idx == SIGNCMD_UNPLACE && *arg == NUL) { - // ":sign unplace {id}": remove placed sign by number - FOR_ALL_BUFFERS(buf) { - if ((lnum = buf_delsign(buf, id)) != 0) { - redraw_buf_line_later(buf, lnum); - } - } - return; - } - } - } - - // Check for line={lnum} name={name} and file={fname} or buffer={nr}. - // Leave "arg" pointing to {fname}. - - buf_T *buf = NULL; - for (;;) { - if (STRNCMP(arg, "line=", 5) == 0) { - arg += 5; - lnum = atoi((char *)arg); - arg = skiptowhite(arg); - } else if (STRNCMP(arg, "*", 1) == 0 && idx == SIGNCMD_UNPLACE) { - if (id != -1) { - EMSG(_(e_invarg)); - return; - } - id = -2; - arg = skiptowhite(arg + 1); - } else if (STRNCMP(arg, "name=", 5) == 0) { - arg += 5; - sign_name = arg; - arg = skiptowhite(arg); - if (*arg != NUL) { - *arg++ = NUL; - } - while (sign_name[0] == '0' && sign_name[1] != NUL) { - sign_name++; - } - } else if (STRNCMP(arg, "file=", 5) == 0) { - arg += 5; - buf = buflist_findname(arg); - break; - } else if (STRNCMP(arg, "buffer=", 7) == 0) { - arg += 7; - buf = buflist_findnr(getdigits_int(&arg)); - if (*skipwhite(arg) != NUL) { - EMSG(_(e_trailing)); - } - break; - } else { - EMSG(_(e_invarg)); - return; - } - arg = skipwhite(arg); - } - - if (buf == NULL) { - EMSG2(_("E158: Invalid buffer name: %s"), arg); - } else if (id <= 0 && !(idx == SIGNCMD_UNPLACE && id == -2)) { - if (lnum >= 0 || sign_name != NULL) { - EMSG(_(e_invarg)); - } else { - // ":sign place file={fname}": list placed signs in one file - sign_list_placed(buf); - } - } else if (idx == SIGNCMD_JUMP) { - // ":sign jump {id} file={fname}" - if (lnum >= 0 || sign_name != NULL) { - EMSG(_(e_invarg)); - } else if ((lnum = buf_findsign(buf, id)) > 0) { - // goto a sign ... - if (buf_jump_open_win(buf) != NULL) { - // ... in a current window - curwin->w_cursor.lnum = lnum; - check_cursor_lnum(); - beginline(BL_WHITE); - } else { - // ... not currently in a window - if (buf->b_fname == NULL) { - EMSG(_("E934: Cannot jump to a buffer that does not have a name")); - return; - } - size_t cmdlen = STRLEN(buf->b_fname) + 24; - char *cmd = xmallocz(cmdlen); - snprintf(cmd, cmdlen, "e +%" PRId64 " %s", - (int64_t)lnum, buf->b_fname); - do_cmdline_cmd(cmd); - xfree(cmd); - } - - foldOpenCursor(); - } else { - EMSGN(_("E157: Invalid sign ID: %" PRId64), id); - } - } else if (idx == SIGNCMD_UNPLACE) { - if (lnum >= 0 || sign_name != NULL) { - EMSG(_(e_invarg)); - } else if (id == -2) { - // ":sign unplace * file={fname}" - redraw_buf_later(buf, NOT_VALID); - buf_delete_signs(buf); - } else { - // ":sign unplace {id} file={fname}" - lnum = buf_delsign(buf, id); - redraw_buf_line_later(buf, lnum); - } - } else if (sign_name != NULL) { - // idx == SIGNCMD_PLACE - for (sp = first_sign; sp != NULL; sp = sp->sn_next) { - if (STRCMP(sp->sn_name, sign_name) == 0) { - break; - } - } - if (sp == NULL) { - EMSG2(_("E155: Unknown sign: %s"), sign_name); - return; - } - if (lnum > 0) { - // ":sign place {id} line={lnum} name={name} file={fname}": - // place a sign - buf_addsign(buf, id, lnum, sp->sn_typenr); - } else { - // ":sign place {id} file={fname}": change sign type - lnum = buf_change_sign_type(buf, id, sp->sn_typenr); - } - if (lnum > 0) { - redraw_buf_line_later(buf, lnum); - } else { - EMSG2(_("E885: Not possible to change sign %s"), sign_name); - } - } else { - EMSG(_(e_invarg)); - } - } -} - -/* - * List one sign. - */ -static void sign_list_defined(sign_T *sp) -{ - smsg("sign %s", sp->sn_name); - if (sp->sn_icon != NULL) { - msg_puts(" icon="); - msg_outtrans(sp->sn_icon); - msg_puts(_(" (not supported)")); - } - if (sp->sn_text != NULL) { - msg_puts(" text="); - msg_outtrans(sp->sn_text); - } - if (sp->sn_line_hl > 0) { - msg_puts(" linehl="); - const char *const p = get_highlight_name_ext(NULL, - sp->sn_line_hl - 1, false); - if (p == NULL) { - msg_puts("NONE"); - } else { - msg_puts(p); - } - } - if (sp->sn_text_hl > 0) { - msg_puts(" texthl="); - const char *const p = get_highlight_name_ext(NULL, - sp->sn_text_hl - 1, false); - if (p == NULL) { - msg_puts("NONE"); - } else { - msg_puts(p); - } - } - if (sp->sn_num_hl > 0) { - msg_puts(" numhl="); - const char *const p = get_highlight_name_ext(NULL, - sp->sn_num_hl - 1, false); - if (p == NULL) { - msg_puts("NONE"); - } else { - msg_puts(p); - } - } -} - -/* - * Undefine a sign and free its memory. - */ -static void sign_undefine(sign_T *sp, sign_T *sp_prev) -{ - xfree(sp->sn_name); - xfree(sp->sn_icon); - xfree(sp->sn_text); - if (sp_prev == NULL) - first_sign = sp->sn_next; - else - sp_prev->sn_next = sp->sn_next; - xfree(sp); -} - -/// Gets highlighting attribute for sign "typenr" corresponding to "type". -int sign_get_attr(int typenr, SignType type) -{ - sign_T *sp; - int sign_hl = 0; - - for (sp = first_sign; sp != NULL; sp = sp->sn_next) { - if (sp->sn_typenr == typenr) { - switch (type) { - case SIGN_TEXT: - sign_hl = sp->sn_text_hl; - break; - case SIGN_LINEHL: - sign_hl = sp->sn_line_hl; - break; - case SIGN_NUMHL: - sign_hl = sp->sn_num_hl; - break; - default: - abort(); - } - if (sign_hl > 0) { - return syn_id2attr(sign_hl); - } - break; - } - } - return 0; -} - -/* - * Get text mark for sign "typenr". - * Returns NULL if there isn't one. - */ -char_u * sign_get_text(int typenr) -{ - sign_T *sp; - - for (sp = first_sign; sp != NULL; sp = sp->sn_next) - if (sp->sn_typenr == typenr) - return sp->sn_text; - return NULL; -} - - -/* - * Get the name of a sign by its typenr. - */ -char_u * sign_typenr2name(int typenr) -{ - sign_T *sp; - - for (sp = first_sign; sp != NULL; sp = sp->sn_next) - if (sp->sn_typenr == typenr) - return sp->sn_name; - return (char_u *)_("[Deleted]"); -} - -#if defined(EXITFREE) -/* - * Undefine/free all signs. - */ -void free_signs(void) -{ - while (first_sign != NULL) - sign_undefine(first_sign, NULL); -} -#endif - -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. -char_u * get_sign_name(expand_T *xp, int idx) -{ - switch (expand_what) - { - case EXP_SUBCMD: - return (char_u *)cmds[idx]; - case EXP_DEFINE: { - char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=", - 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 - 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; - default: - return NULL; - } -} - -/* - * 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; - 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 == NULL) { - // 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 - || STRNCMP(last, "numhl", 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; - } - } -} - /// Shows the effects of the :substitute command being typed ('inccommand'). /// If inccommand=split, shows a preview window and later restores the layout. static buf_T *show_sub(exarg_T *eap, pos_T old_cusr, |