changeset 1868:954947a70580 v7.2.166

updated for version 7.2-166
author vimboss
date Wed, 29 Apr 2009 16:47:23 +0000
parents 5ea1f7516c2c
children 720a59d79bcd
files src/ex_cmds.c src/ex_docmd.c src/ex_getln.c src/proto/ex_cmds.pro src/version.c src/vim.h
diffstat 6 files changed, 240 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -6543,6 +6543,43 @@ static int	last_sign_typenr = MAX_TYPENR
 static void sign_list_defined __ARGS((sign_T *sp));
 static void sign_undefine __ARGS((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(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
  */
@@ -6556,35 +6593,14 @@ ex_sign(eap)
     sign_T	*sp;
     sign_T	*sp_prev;
     buf_T	*buf;
-    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
-#define SIGNCMD_LAST	6
-    };
 
     /* Parse the subcommand. */
     p = skiptowhite(arg);
-    if (*p != NUL)
-	*p++ = NUL;
-    for (idx = 0; ; ++idx)
-    {
-	if (idx == SIGNCMD_LAST)
-	{
-	    EMSG2(_("E160: Unknown sign command: %s"), arg);
-	    return;
-	}
-	if (STRCMP(arg, cmds[idx]) == 0)
-	    break;
+    idx = sign_cmd_idx(arg, p);
+    if (idx == SIGNCMD_LAST)
+    {
+	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)
--- 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"},
--- 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, fil
 #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},
--- 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, in
 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 : */
--- 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,
--- a/src/vim.h
+++ b/src/vim.h
@@ -709,6 +709,7 @@ extern char *(*dyn_libintl_textdomain)(c
 #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