Bram Moolenaar wrote:

> Dominique Pelle wrote:
>
>> The ":sign" command currently has no command line
>> completion.  Attached patch (against Vim-7.2.148)
>> adds command line completion for this command.
>>
>> A few examples:
>>
>>   :sign <CTRL-D>
>>   define  jump  list  place  undefine  unplace

...snip...

> Thanks for the patch.  A few comments.
>
> ":sign un" would be handled like ":sign undefine", even though it's
> ambigious.  The new sign_cmd_idx() function needs to check that when not
> doing completion there is a full word match.
>
> In Vim code we don't use "const".  It's usually more work than it's
> worth.
>
> Can you update the patch for this?

Thanks for noticing the bug.  I have synched with Vim-7.2.160
and updated the patch:
- removed const as requested
- changed sign_cmd_idx() to perform full word match (it needed
  to do full word match wherever it's used)
- fixed another bug in sign_cmd_idx() (crash with ":sign f").

Regards
-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Index: src/ex_getln.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/ex_getln.c,v
retrieving revision 1.99
diff -c -r1.99 ex_getln.c
*** src/ex_getln.c	22 Apr 2009 11:52:19 -0000	1.99
--- src/ex_getln.c	22 Apr 2009 19:14:34 -0000
***************
*** 325,331 ****
  #endif
  
  #ifdef FEAT_DIGRAPHS
!     do_digraph(-1);		/* init digraph typahead */
  #endif
  
      /*
--- 325,331 ----
  #endif
  
  #ifdef FEAT_DIGRAPHS
!     do_digraph(-1);		/* init digraph typeahead */
  #endif
  
      /*
***************
*** 4521,4526 ****
--- 4521,4529 ----
  #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},
Index: src/ex_docmd.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/ex_docmd.c,v
retrieving revision 1.171
diff -c -r1.171 ex_docmd.c
*** src/ex_docmd.c	22 Apr 2009 14:24:37 -0000	1.171
--- src/ex_docmd.c	22 Apr 2009 19:14:39 -0000
***************
*** 3695,3700 ****
--- 3695,3705 ----
  	    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:
***************
*** 5217,5222 ****
--- 5222,5230 ----
      {EXPAND_MAPPINGS, "mapping"},
      {EXPAND_MENUS, "menu"},
      {EXPAND_SETTINGS, "option"},
+ #if defined(FEAT_SIGNS)
+     {EXPAND_SIGN, "sign"},
+ #endif
      {EXPAND_SHELLCMD, "shellcmd"},
      {EXPAND_TAGS, "tag"},
      {EXPAND_TAGS_LISTFILES, "tag_listfiles"},
Index: src/ex_cmds.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/ex_cmds.c,v
retrieving revision 1.121
diff -c -r1.121 ex_cmds.c
*** src/ex_cmds.c	24 Feb 2009 03:30:14 -0000	1.121
--- src/ex_cmds.c	22 Apr 2009 19:14:42 -0000
***************
*** 6543,6562 ****
  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[] = {
  			"define",
  #define SIGNCMD_DEFINE	0
  			"undefine",
--- 6543,6549 ----
  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",
***************
*** 6569,6590 ****
  #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;
      }
      arg = skipwhite(p);
  
--- 6556,6605 ----
  #define SIGNCMD_UNPLACE	4
  			"jump",
  #define SIGNCMD_JUMP	5
+ 			NULL
  #define SIGNCMD_LAST	6
! };
! 
! /*
!  * Find index of a ":sign" subcmd from its name
!  */
!     static int
! sign_cmd_idx(begin_cmd, end_cmd)
!     char	*begin_cmd;	/* begin of sign subcmd */
!     char	*end_cmd;	/* end of (and beyond) 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);
!     idx = sign_cmd_idx(arg, p);
!     if (idx == SIGNCMD_LAST)
      {
! 	EMSG2(_("E160: Unknown sign command: %s"), arg);
! 	return;
      }
      arg = skipwhite(p);
  
***************
*** 7110,7115 ****
--- 7125,7309 ----
  }
  #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;
+ 
+     /* 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 */
+     char_u *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)
Index: src/vim.h
===================================================================
RCS file: /cvsroot/vim/vim7/src/vim.h,v
retrieving revision 1.103
diff -c -r1.103 vim.h
*** src/vim.h	18 Mar 2009 11:52:22 -0000	1.103
--- src/vim.h	22 Apr 2009 19:14:45 -0000
***************
*** 709,714 ****
--- 709,715 ----
  #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
Index: src/proto/ex_cmds.pro
===================================================================
RCS file: /cvsroot/vim/vim7/src/proto/ex_cmds.pro,v
retrieving revision 1.15
diff -c -r1.15 ex_cmds.pro
*** src/proto/ex_cmds.pro	24 Feb 2009 03:30:04 -0000	1.15
--- src/proto/ex_cmds.pro	22 Apr 2009 19:14:45 -0000
***************
*** 56,60 ****
--- 56,62 ----
  char_u *sign_get_text __ARGS((int typenr));
  void *sign_get_image __ARGS((int typenr));
  char_u *sign_typenr2name __ARGS((int typenr));
+ void set_context_in_sign_cmd __ARGS((expand_T *xp, char_u *arg));
+ char_u *get_sign_name __ARGS((expand_T *xp, int idx));
  void ex_drop __ARGS((exarg_T *eap));
  /* vim: set ft=c : */
Index: runtime/doc/todo.txt
===================================================================
RCS file: /cvsroot/vim/vim7/runtime/doc/todo.txt,v
retrieving revision 1.275
diff -c -r1.275 todo.txt
*** runtime/doc/todo.txt	9 Aug 2008 17:53:58 -0000	1.275
--- runtime/doc/todo.txt	22 Apr 2009 19:14:48 -0000
***************
*** 2132,2138 ****
      words.
  8   Add more command line completion for :syntax.
  8   Add more command line completion for :highlight.
- 8   Add more command line completion for :sign.
  7   Should find a better way to parse the :syntax and :highlight commands.
      Use tables or lists that can be shared by parsing for execution and
      completion?
--- 2132,2137 ----

Raspunde prin e-mail lui