aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r--src/nvim/ex_cmds.c1150
1 files changed, 0 insertions, 1150 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 212aeb4c27..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,1137 +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;
-}
-
-/*
- * Find a sign by name. Also returns pointer to the previous sign.
- */
- static sign_T *
-sign_find(char_u *name, sign_T **sp_prev)
-{
- sign_T *sp;
-
- if (sp_prev != NULL)
- *sp_prev = NULL;
- for (sp = first_sign; sp != NULL; sp = sp->sn_next)
- {
- if (STRCMP(sp->sn_name, name) == 0)
- break;
- if (sp_prev != NULL)
- *sp_prev = sp;
- }
-
- return sp;
-}
-
-/*
- * Define a new sign or update an existing sign
- */
-int sign_define_by_name(
- char_u *name,
- char_u *icon,
- char_u *linehl,
- char_u *text,
- char_u *texthl,
- char_u *numhl
-)
-{
- sign_T *sp_prev;
- sign_T *sp;
-
- sp = sign_find(name, &sp_prev);
- 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 FAIL;
- }
- 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(name);
-
- // 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.
- if (icon != NULL)
- {
- xfree(sp->sn_icon);
- sp->sn_icon = vim_strsave(icon);
- backslash_halve(sp->sn_icon);
-# ifdef FEAT_SIGN_ICONS
- if (gui.in_use)
- {
- out_flush();
- if (sp->sn_image != NULL)
- gui_mch_destroy_sign(sp->sn_image);
- sp->sn_image = gui_mch_register_sign(sp->sn_icon);
- }
-# endif
- }
-
- if (text != NULL)
- {
- char_u *s;
- char_u *endp;
- int cells;
- int len;
-
- endp = text + (int)STRLEN(text);
- for (s = text; s + 1 < endp; ++s) {
- if (*s == '\\')
- {
- // Remove a backslash, so that it is possible
- // to use a space.
- STRMOVE(s, s + 1);
- --endp;
- }
- }
- // Count cells and check for non-printable chars
- cells = 0;
- for (s = text; s < endp; s += (*mb_ptr2len)(s)) {
- if (!vim_isprintc(utf_ptr2char(s))) {
- break;
- }
- cells += utf_ptr2cells(s);
- }
- // Currently must be one or two display cells
- if (s != endp || cells < 1 || cells > 2) {
- EMSG2(_("E239: Invalid sign text: %s"), text);
- return FAIL;
- }
-
- xfree(sp->sn_text);
- // Allocate one byte more if we need to pad up
- // with a space.
- len = (int)(endp - text + ((cells == 1) ? 1 : 0));
- sp->sn_text = vim_strnsave(text, len);
-
- if (cells == 1)
- STRCPY(sp->sn_text + len - 1, " ");
- }
-
- if (linehl != NULL)
- sp->sn_line_hl = syn_check_group(linehl, (int)STRLEN(linehl));
-
- if (texthl != NULL)
- sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl));
-
- if (numhl != NULL)
- sp->sn_num_hl = syn_check_group(numhl, (int)STRLEN(numhl));
-
- return OK;
-}
-
-/*
- * Free the sign specified by 'name'.
- */
- int
-sign_undefine_by_name(char_u *name)
-{
- sign_T *sp_prev;
- sign_T *sp;
-
- sp = sign_find(name, &sp_prev);
- if (sp == NULL)
- {
- EMSG2(_("E155: Unknown sign: %s"), name);
- return FAIL;
- }
- sign_undefine(sp, sp_prev);
-
- return OK;
-}
-
-/*
- * List the signs matching 'name'
- */
- static void
-sign_list_by_name(char_u *name)
-{
- sign_T *sp;
-
- sp = sign_find(name, NULL);
- if (sp != NULL)
- sign_list_defined(sp);
- else
- EMSG2(_("E155: Unknown sign: %s"), name);
-}
-
-/*
- * Place a sign at the specifed file location or update a sign.
- */
-int sign_place(
- int *sign_id,
- char_u *sign_group,
- char_u *sign_name,
- buf_T *buf,
- linenr_T lnum,
- int prio
-)
-{
- sign_T *sp;
-
- // Check for reserved character '*' in group name
- if (sign_group != NULL && (*sign_group == '*' || *sign_group == '\0')) {
- return FAIL;
- }
-
- 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 FAIL;
- }
- if (*sign_id == 0)
- {
- *sign_id = sign_group_get_next_signid(buf, sign_group);
- }
-
- if (lnum > 0) {
- // ":sign place {id} line={lnum} name={name} file={fname}":
- // place a sign
- buf_addsign(buf, *sign_id, sign_group, prio, lnum, sp->sn_typenr);
- } else {
- // ":sign place {id} file={fname}": change sign type
- lnum = buf_change_sign_type(buf, *sign_id, sign_group, sp->sn_typenr);
- }
- if (lnum > 0) {
- redraw_buf_line_later(buf, lnum);
- } else {
- EMSG2(_("E885: Not possible to change sign %s"), sign_name);
- return FAIL;
- }
-
- return OK;
-}
-
-/*
- * Unplace the specified sign
- */
- int
-sign_unplace(int sign_id, char_u *sign_group, buf_T *buf, linenr_T atlnum)
-{
- if (buf->b_signlist == NULL) { // No signs in the buffer
- return OK;
- }
- if (sign_id == 0)
- {
- // Delete all the signs in the specified buffer
- redraw_buf_later(buf, NOT_VALID);
- buf_delete_signs(buf, sign_group);
- } else {
- linenr_T lnum;
-
- // Delete only the specified signs
- lnum = buf_delsign(buf, atlnum, sign_id, sign_group);
- if (lnum == 0) {
- return FAIL;
- update_debug_sign(buf, lnum);
- }
- redraw_buf_line_later(buf, lnum);
- }
-
- return OK;
-}
-
-/*
- * Unplace the sign at the current cursor line.
- */
-static void sign_unplace_at_cursor(char_u *groupname)
-{
- int id = -1;
-
- id = buf_findsign_id(curwin->w_buffer, curwin->w_cursor.lnum, groupname);
- if (id > 0) {
- sign_unplace(id, groupname, curwin->w_buffer, curwin->w_cursor.lnum);
- } else {
- EMSG(_("E159: Missing sign number"));
- }
-}
-
-/*
- * sign define command
- * ":sign define {name} ..."
- */
-static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
-{
- char_u *arg;
- char_u *p = cmdline;
- char_u *icon = NULL;
- char_u *text = NULL;
- char_u *linehl = NULL;
- char_u *texthl = NULL;
- char_u *numhl = NULL;
- int failed = FALSE;
-
- // 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;
- icon = vim_strnsave(arg, (int)(p - arg));
- } else if (STRNCMP(arg, "text=", 5) == 0) {
- arg += 5;
- text = vim_strnsave(arg, (int)(p - arg));
- } else if (STRNCMP(arg, "linehl=", 7) == 0) {
- arg += 7;
- linehl = vim_strnsave(arg, (int)(p - arg));
- } else if (STRNCMP(arg, "texthl=", 7) == 0) {
- arg += 7;
- texthl = vim_strnsave(arg, (int)(p - arg));
- } else if (STRNCMP(arg, "numhl=", 6) == 0) {
- arg += 6;
- numhl = vim_strnsave(arg, (int)(p - arg));
- } else {
- EMSG2(_(e_invarg2), arg);
- failed = TRUE;
- break;
- }
- }
-
- if (!failed) {
- sign_define_by_name(sign_name, icon, linehl, text, texthl, numhl);
- }
-
- xfree(icon);
- xfree(text);
- xfree(linehl);
- xfree(texthl);
- xfree(numhl);
-}
-
-/*
- * :sign place command
- */
-static void sign_place_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group,
- int prio
- )
-{
- if (id <= 0)
- {
- // List signs placed in a file/buffer
- // :sign place file={fname}
- // :sign place group={group} file={fname}
- // :sign place group=* file={fname}
- // :sign place buffer={nr}
- // :sign place group={group} buffer={nr}
- // :sign place group=* buffer={nr}
- // :sign place
- // :sign place group={group}
- // :sign place group=*
- if (lnum >= 0 || sign_name != NULL ||
- (group != NULL && *group == '\0')) {
- EMSG(_(e_invarg));
- } else {
- sign_list_placed(buf, group);
- }
- } else {
- // Place a new sign
- if (sign_name == NULL || buf == NULL ||
- (group != NULL && *group == '\0')) {
- EMSG(_(e_invarg));
- return;
- }
-
- sign_place(&id, group, sign_name, buf, lnum, prio);
- }
-}
-
-/*
- * :sign unplace command
- */
-static void sign_unplace_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
-)
-{
- if (lnum >= 0 || sign_name != NULL || (group != NULL && *group == '\0')) {
- EMSG(_(e_invarg));
- return;
- }
-
- if (id == -2)
- {
- if (buf != NULL) {
- // :sign unplace * file={fname}
- // :sign unplace * group={group} file={fname}
- // :sign unplace * group=* file={fname}
- // :sign unplace * buffer={nr}
- // :sign unplace * group={group} buffer={nr}
- // :sign unplace * group=* buffer={nr}
- sign_unplace(0, group, buf, 0);
- } else {
- // :sign unplace *
- // :sign unplace * group={group}
- // :sign unplace * group=*
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_signlist != NULL) {
- buf_delete_signs(buf, group);
- }
- }
- }
- } else {
- if (buf != NULL) {
- // :sign unplace {id} file={fname}
- // :sign unplace {id} group={group} file={fname}
- // :sign unplace {id} group=* file={fname}
- // :sign unplace {id} buffer={nr}
- // :sign unplace {id} group={group} buffer={nr}
- // :sign unplace {id} group=* buffer={nr}
- sign_unplace(id, group, buf, 0);
- } else {
- if (id == -1)
- {
- // :sign unplace group={group}
- // :sign unplace group=*
- sign_unplace_at_cursor(group);
- } else {
- // :sign unplace {id}
- // :sign unplace {id} group={group}
- // :sign unplace {id} group=*
- FOR_ALL_BUFFERS(buf) {
- sign_unplace(id, group, buf, 0);
- }
- }
- }
- }
-}
-
-/*
- * Jump to a placed sign
- * :sign jump {id} file={fname}
- * :sign jump {id} buffer={nr}
- * :sign jump {id} group={group} file={fname}
- * :sign jump {id} group={group} buffer={nr}
- */
-static void sign_jump_cmd(
- buf_T *buf,
- linenr_T lnum,
- char_u *sign_name,
- int id,
- char_u *group
- )
-{
- if (buf == NULL && sign_name == NULL && group == NULL && id == -1) {
- EMSG(_(e_argreq));
- return;
- }
-
- if (buf == NULL || (group != NULL && *group == '\0') ||
- lnum >= 0 || sign_name != NULL) {
- // File or buffer is not specified or an empty group is used
- // or a line number or a sign name is specified.
- EMSG(_(e_invarg));
- return;
- }
-
- if ((lnum = buf_findsign(buf, id, group)) <= 0) {
- EMSGN(_("E157: Invalid sign ID: %ld"), id);
- return;
- }
-
- // 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();
-}
-
-/*
- * Parse the command line arguments for the ":sign place", ":sign unplace" and
- * ":sign jump" commands.
- * The supported arguments are: line={lnum} name={name} group={group}
- * priority={prio} and file={fname} or buffer={nr}.
- */
-static int parse_sign_cmd_args(
- int cmd,
- char_u *arg,
- char_u **sign_name,
- int *signid,
- char_u **group,
- int *prio,
- buf_T **buf,
- linenr_T *lnum
-)
-{
- char_u *arg1;
- char_u *name;
- char_u *filename = NULL;
-
- // first arg could be placed sign id
- arg1 = arg;
- if (ascii_isdigit(*arg)) {
- *signid = getdigits_int(&arg);
- if (!ascii_iswhite(*arg) && *arg != NUL) {
- *signid = -1;
- arg = arg1;
- } else {
- arg = skipwhite(arg);
- }
- }
-
- while (*arg != NUL) {
- if (STRNCMP(arg, "line=", 5) == 0) {
- arg += 5;
- *lnum = atoi((char *)arg);
- arg = skiptowhite(arg);
- } else if (STRNCMP(arg, "*", 1) == 0 && cmd == SIGNCMD_UNPLACE) {
- if (*signid != -1) {
- EMSG(_(e_invarg));
- return FAIL;
- }
- *signid = -2;
- arg = skiptowhite(arg + 1);
- } else if (STRNCMP(arg, "name=", 5) == 0) {
- arg += 5;
- name = arg;
- arg = skiptowhite(arg);
- if (*arg != NUL) {
- *arg++ = NUL;
- }
- while (name[0] == '0' && name[1] != NUL) {
- ++name;
- }
- *sign_name = name;
- } else if (STRNCMP(arg, "group=", 6) == 0) {
- arg += 6;
- *group = arg;
- arg = skiptowhite(arg);
- if (*arg != NUL) {
- *arg++ = NUL;
- }
- } else if (STRNCMP(arg, "priority=", 9) == 0) {
- arg += 9;
- *prio = atoi((char *)arg);
- arg = skiptowhite(arg);
- } else if (STRNCMP(arg, "file=", 5) == 0) {
- arg += 5;
- filename = arg;
- *buf = buflist_findname_exp(arg);
- break;
- } else if (STRNCMP(arg, "buffer=", 7) == 0) {
- arg += 7;
- filename = arg;
- *buf = buflist_findnr(getdigits_int(&arg));
- if (*skipwhite(arg) != NUL) {
- EMSG(_(e_trailing));
- }
- break;
- } else {
- EMSG(_(e_invarg));
- return FAIL;
- }
- arg = skipwhite(arg);
- }
-
- if (filename != NULL && *buf == NULL) {
- EMSG2(_("E158: Invalid buffer name: %s"), filename);
- return FAIL;
- }
-
- return OK;
-}
-
-/*
- * ":sign" command
- */
-void ex_sign(exarg_T *eap)
-{
- char_u *arg = eap->arg;
- char_u *p;
- int idx;
- sign_T *sp;
-
- // 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 {
- char_u *name;
-
- // 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++;
- }
- name = vim_strsave(arg);
-
- if (idx == SIGNCMD_DEFINE) {
- sign_define_cmd(name, p);
- } else if (idx == SIGNCMD_LIST) {
- // ":sign list {name}"
- sign_list_by_name(name);
- } else {
- // ":sign undefine {name}"
- sign_undefine_by_name(name);
- }
-
- xfree(name);
- return;
- }
- } else {
- int id = -1;
- linenr_T lnum = -1;
- char_u *sign_name = NULL;
- char_u *group = NULL;
- int prio = SIGN_DEF_PRIO;
- buf_T *buf = NULL;
-
- // Parse command line arguments
- if (parse_sign_cmd_args(idx, arg, &sign_name, &id, &group, &prio,
- &buf, &lnum) == FAIL)
- return;
-
- if (idx == SIGNCMD_PLACE) {
- sign_place_cmd(buf, lnum, sign_name, id, group, prio);
- } else if (idx == SIGNCMD_UNPLACE) {
- sign_unplace_cmd(buf, lnum, sign_name, id, group);
- } else if (idx == SIGNCMD_JUMP) {
- sign_jump_cmd(buf, lnum, sign_name, id, group);
- }
- }
-}
-
-/*
- * Return information about a specified sign
- */
-static void sign_getinfo(sign_T *sp, dict_T *retdict)
-{
- char_u *p;
-
- tv_dict_add_str(retdict, S_LEN("name"), (char_u *)sp->sn_name);
- if (sp->sn_icon != NULL) {
- tv_dict_add_str(retdict, S_LEN("icon"), (char_u *)sp->sn_icon);
- }
- if (sp->sn_text != NULL) {
- tv_dict_add_str(retdict, S_LEN("text"), (char_u *)sp->sn_text);
- }
- if (sp->sn_line_hl > 0) {
- p = get_highlight_name_ext(NULL, sp->sn_line_hl - 1, FALSE);
- if (p == NULL) {
- p = (char_u *)"NONE";
- }
- tv_dict_add_str(retdict, S_LEN("linehl"), (char_u *)p);
- }
- if (sp->sn_text_hl > 0) {
- p = get_highlight_name_ext(NULL, sp->sn_text_hl - 1, FALSE);
- if (p == NULL) {
- p = (char_u *)"NONE";
- }
- tv_dict_add_str(retdict, S_LEN("texthl"), (char_u *)p);
- }
- if (sp->sn_num_hl > 0) {
- p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE);
- if (p == NULL) {
- p = (char_u *)"NONE";
- }
- tv_dict_add_str(retdict, S_LEN("numhl"), (char_u *)p);
- }
-}
-
-/*
- * If 'name' is NULL, return a list of all the defined signs.
- * Otherwise, return information about the specified sign.
- */
-void sign_getlist(char_u *name, list_T *retlist)
-{
- sign_T *sp = first_sign;
- dict_T *dict;
-
- if (name != NULL) {
- sp = sign_find(name, NULL);
- if (sp == NULL) {
- return;
- }
- }
-
- for (; sp != NULL && !got_int; sp = sp->sn_next) {
- if ((dict = tv_dict_alloc()) == NULL) {
- return;
- }
- tv_list_append_dict(retlist, dict);
- sign_getinfo(sp, dict);
-
- if (name != NULL) { // handle only the specified sign
- break;
- }
- }
-}
-
-/*
- * Return information about all the signs placed in a buffer
- */
-static void sign_get_placed_in_buf(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- char_u *sign_group,
- list_T *retlist)
-{
- dict_T *d;
- list_T *l;
- signlist_T *sign;
- dict_T *sdict;
-
- if ((d = tv_dict_alloc()) == NULL) {
- return;
- }
- tv_list_append_dict(retlist, d);
-
- tv_dict_add_nr(d, S_LEN("bufnr"), (long)buf->b_fnum);
-
- if ((l = tv_list_alloc(kListLenMayKnow)) == NULL) {
- return;
- }
- tv_dict_add_list(d, S_LEN("signs"), l);
-
- FOR_ALL_SIGNS_IN_BUF(buf, sign) {
- if (!sign_in_group(sign, sign_group)) {
- continue;
- }
- if ((lnum == 0 && sign_id == 0) ||
- (sign_id == 0 && lnum == sign->lnum) ||
- (lnum == 0 && sign_id == sign->id) ||
- (lnum == sign->lnum && sign_id == sign->id)) {
- if ((sdict = sign_get_info(sign)) != NULL) {
- tv_list_append_dict(l, sdict);
- }
- }
- }
-}
-
-/*
- * Get a list of signs placed in buffer 'buf'. If 'num' is non-zero, return the
- * sign placed at the line number. If 'lnum' is zero, return all the signs
- * placed in 'buf'. If 'buf' is NULL, return signs placed in all the buffers.
- */
-void sign_get_placed(
- buf_T *buf,
- linenr_T lnum,
- int sign_id,
- char_u *sign_group,
- list_T *retlist)
-{
- if (buf != NULL) {
- sign_get_placed_in_buf(buf, lnum, sign_id, sign_group, retlist);
- } else {
- FOR_ALL_BUFFERS(buf) {
- if (buf->b_signlist != NULL) {
- sign_get_placed_in_buf(buf, 0, sign_id, sign_group, retlist);
- }
- }
- }
-}
-
-/*
- * 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]");
-}
-
-/*
- * Undefine/free all signs.
- */
-void free_signs(void)
-{
- while (first_sign != NULL)
- sign_undefine(first_sign, NULL);
-}
-
-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=", "group=", "priority=", "file=",
- "buffer=", NULL };
- return (char_u *)place_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;
- 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,