diff src/ex_cmds.c @ 15330:a6330a49e036 v8.1.0673

patch 8.1.0673: functionality for signs is spread out over several files commit https://github.com/vim/vim/commit/bbea47075cc4e7826e9f8c203e4272ba023ed7b0 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 1 13:20:31 2019 +0100 patch 8.1.0673: functionality for signs is spread out over several files Problem: Functionality for signs is spread out over several files. Solution: Move most of the sign functionality into sign.c. (Yegappan Lakshmanan, closes #3751)
author Bram Moolenaar <Bram@vim.org>
date Tue, 01 Jan 2019 13:30:09 +0100
parents c6c306c5027f
children 273649cad196
line wrap: on
line diff
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -7579,1252 +7579,6 @@ ex_helptags(exarg_T *eap)
     }
 }
 
-#if defined(FEAT_SIGNS) || defined(PROTO)
-
-/*
- * Struct to hold the sign properties.
- */
-typedef struct sign sign_T;
-
-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 */
-# ifdef FEAT_SIGN_ICONS
-    void	*sn_image;	/* icon image */
-# endif
-    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 */
-};
-
-static sign_T	*first_sign = NULL;
-static int	next_sign_typenr = 1;
-
-static void sign_list_defined(sign_T *sp);
-static void sign_undefine(sign_T *sp, sign_T *sp_prev);
-
-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)
-{
-    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 = (sign_T *)alloc_clear_id((unsigned)sizeof(sign_T),
-						aid_sign_define_by_name);
-	if (sp == NULL)
-	    return FAIL;
-
-	// 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)
-		{
-		    vim_free(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);
-	if (sp->sn_name == NULL)  // out of memory
-	{
-	    vim_free(sp);
-	    return FAIL;
-	}
-
-	// 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)
-    {
-	vim_free(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;
-	    }
-# ifdef FEAT_MBYTE
-	// Count cells and check for non-printable chars
-	if (has_mbyte)
-	{
-	    cells = 0;
-	    for (s = text; s < endp; s += (*mb_ptr2len)(s))
-	    {
-		if (!vim_isprintc((*mb_ptr2char)(s)))
-		    break;
-		cells += (*mb_ptr2cells)(s);
-	    }
-	}
-	else
-# endif
-	{
-	    for (s = text; s < endp; ++s)
-		if (!vim_isprintc(*s))
-		    break;
-	    cells = (int)(s - text);
-	}
-	// Currently must be one or two display cells
-	if (s != endp || cells < 1 || cells > 2)
-	{
-	    EMSG2(_("E239: Invalid sign text: %s"), text);
-	    return FAIL;
-	}
-
-	vim_free(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 (sp->sn_text != NULL && 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));
-
-    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)
-	update_debug_sign(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;
-    }
-
-    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;
-    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
-	{
-	    EMSG2(_(e_invarg2), arg);
-	    failed = TRUE;
-	    break;
-	}
-    }
-
-    if (!failed)
-	sign_define_by_name(sign_name, icon, linehl, text, texthl);
-
-    vim_free(icon);
-    vim_free(text);
-    vim_free(linehl);
-    vim_free(texthl);
-}
-
-/*
- * :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
-	char_u	*cmd;
-
-	if (buf->b_fname == NULL)
-	{
-	    EMSG(_("E934: Cannot jump to a buffer that does not have a name"));
-	    return;
-	}
-	cmd = alloc((unsigned)STRLEN(buf->b_fname) + 25);
-	if (cmd == NULL)
-	    return;
-	sprintf((char *)cmd, "e +%ld %s", (long)lnum, buf->b_fname);
-	do_cmdline_cmd(cmd);
-	vim_free(cmd);
-    }
-# ifdef FEAT_FOLDING
-    foldOpenCursor();
-# endif
-}
-
-/*
- * 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 (VIM_ISDIGIT(*arg))
-    {
-	*signid = getdigits(&arg);
-	if (!VIM_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((int)getdigits(&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;
-    buf_T	*buf = NULL;
-
-    // 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);
-
-	    vim_free(name);
-	    return;
-	}
-    }
-    else
-    {
-	int		id = -1;
-	linenr_T	lnum = -1;
-	char_u		*sign_name = NULL;
-	char_u		*group = NULL;
-	int		prio = SIGN_DEF_PRIO;
-
-	// 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;
-
-    dict_add_string(retdict, "name", (char_u *)sp->sn_name);
-    if (sp->sn_icon != NULL)
-	dict_add_string(retdict, "icon", (char_u *)sp->sn_icon);
-    if (sp->sn_text != NULL)
-	dict_add_string(retdict, "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";
-	dict_add_string(retdict, "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";
-	dict_add_string(retdict, "texthl", (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 = dict_alloc_id(aid_sign_getlist)) == NULL)
-	    return;
-	if (list_append_dict(retlist, dict) == FAIL)
-	    return;
-	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 = dict_alloc_id(aid_sign_getplaced_dict)) == NULL)
-	return;
-    list_append_dict(retlist, d);
-
-    dict_add_number(d, "bufnr", (long)buf->b_fnum);
-
-    if ((l = list_alloc_id(aid_sign_getplaced_list)) == NULL)
-	return;
-    dict_add_list(d, "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)
-		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);
-	}
-    }
-}
-
-# if defined(FEAT_SIGN_ICONS) || defined(PROTO)
-/*
- * Allocate the icons.  Called when the GUI has started.  Allows defining
- * signs before it starts.
- */
-    void
-sign_gui_started(void)
-{
-    sign_T	*sp;
-
-    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
-	if (sp->sn_icon != NULL)
-	    sp->sn_image = gui_mch_register_sign(sp->sn_icon);
-}
-# endif
-
-/*
- * List one sign.
- */
-    static void
-sign_list_defined(sign_T *sp)
-{
-    char_u	*p;
-
-    smsg((char_u *)"sign %s", sp->sn_name);
-    if (sp->sn_icon != NULL)
-    {
-	MSG_PUTS(" icon=");
-	msg_outtrans(sp->sn_icon);
-# ifdef FEAT_SIGN_ICONS
-	if (sp->sn_image == NULL)
-	    MSG_PUTS(_(" (NOT FOUND)"));
-# else
-	MSG_PUTS(_(" (not supported)"));
-# endif
-    }
-    if (sp->sn_text != NULL)
-    {
-	MSG_PUTS(" text=");
-	msg_outtrans(sp->sn_text);
-    }
-    if (sp->sn_line_hl > 0)
-    {
-	MSG_PUTS(" linehl=");
-	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=");
-	p = get_highlight_name_ext(NULL, sp->sn_text_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)
-{
-    vim_free(sp->sn_name);
-    vim_free(sp->sn_icon);
-# ifdef FEAT_SIGN_ICONS
-    if (sp->sn_image != NULL)
-    {
-	out_flush();
-	gui_mch_destroy_sign(sp->sn_image);
-    }
-# endif
-    vim_free(sp->sn_text);
-    if (sp_prev == NULL)
-	first_sign = sp->sn_next;
-    else
-	sp_prev->sn_next = sp->sn_next;
-    vim_free(sp);
-}
-
-/*
- * Get highlighting attribute for sign "typenr".
- * If "line" is TRUE: line highl, if FALSE: text highl.
- */
-    int
-sign_get_attr(int typenr, int line)
-{
-    sign_T	*sp;
-
-    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
-	if (sp->sn_typenr == typenr)
-	{
-	    if (line)
-	    {
-		if (sp->sn_line_hl > 0)
-		    return syn_id2attr(sp->sn_line_hl);
-	    }
-	    else
-	    {
-		if (sp->sn_text_hl > 0)
-		    return syn_id2attr(sp->sn_text_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;
-}
-
-# if defined(FEAT_SIGN_ICONS) || defined(PROTO)
-    void *
-sign_get_image(
-    int		typenr)		/* the attribute which may have a sign */
-{
-    sign_T	*sp;
-
-    for (sp = first_sign; sp != NULL; sp = sp->sn_next)
-	if (sp->sn_typenr == typenr)
-	    return sp->sn_image;
-    return NULL;
-}
-# endif
-
-/*
- * 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);
-}
-
-# 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.
- */
-    char_u *
-get_sign_name(expand_T *xp UNUSED, 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=", "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 */
-	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(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)
-		    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
-
 /*
  * Make the user happy.
  */