I would like to propose a new v: variable that makes any command
modifiers specified to the current user-command available to the
scripts as a string. This I think is very useful to create
user-defined commands that are more "flush" with the built-in commands
and in general work as a newbie would expect. Currently any modifiers
specified before a user-defined command are ignored. From the source,
I noticed that they are actually processed but there is no way to
expose them to the scripts, so there is no way to take advantage of
them.

As one use case, let us say you create a replacement for a built-in
command to enhance the functionality, but as a result, you loose the
ability to recognize modifiers. I.e., you can say "vert diffsplit" or
"confirm q" but you can't say "vert DiffSplit" or "confirm Q".

As another use case, plugins have to create multiple variants of a
user-defined command, to different modifiers, or global variables (as
settings) that can't change for each command. While these are useful
by themselves, in most cases they are trying to solve the inability to
read modifiers from the script.

As a first cut approach, I tried this below change and it seems to
work nicely. One big drawback with this simplistic change is that the
same string that user specified is exposed, so if required, the burden
to parse falls on the script (especially that Vim allows typing
partial command, as long as it is unambiguous). However, it is still
useful for most cases when the modifiers will be literally passed down
to one of the built-in commands that the script executes, something
like this:

command! UDC call UDC()
func! UDC()
  .
  .
  exec v:cmdmodifiers 'split' s:windowName
  .
  .
endfunc

Ideally, the internal "cmdmod" is exposed such a way that the
individual flags are accessible, or we can even try to expose each one
of the flags as a separate v: variable (which should be easier
compared to the former), but I will leave this discussion to the
exerts (in which case the below change can still serve as a
prototype). I am not too comfortable programming in c, so please
excuse me if I missed any obvious things.

After applying the patch, try commands like this to see it in action:

-----------------
:command! T echo v:cmdmodifiers
:vert T
vert
:vert confirm T
vert confirm
:echo v:cmdmodifiers

:T

:let v:cmdmodifiers = 'vert'
:T
vert
:echo v:cmdmodifiers
vert
:keepjumps T
keepjumps
:echo v:cmdmodifiers

-----------------


Index: C:/src/vim7mods/src/ex_docmd.c
===================================================================
--- C:/src/vim7mods/src/ex_docmd.c      (revision 1617)
+++ C:/src/vim7mods/src/ex_docmd.c      (working copy)
@@ -530,6 +530,9 @@
 static int     store_loop_line __ARGS((garray_T *gap, char_u *line));
 static void    free_cmdlines __ARGS((garray_T *gap));

+void set_cmd_modifiers(char *string, int len);
+void clear_cmd_modifiers();
+
 /* Struct to save a few things while debugging.  Used in do_cmdline() only. */
 struct dbg_stuff
 {
@@ -1685,6 +1688,8 @@
 #endif
     cmdmod_T           save_cmdmod;
     int                        ni;                     /* set when Not 
Implemented */
+    char_u             *modifiers_start = NULL;
+    char_u             *modifiers_end = NULL;

     vim_memset(&ea, 0, sizeof(ea));
     ea.line1 = 1;
@@ -1748,6 +1753,8 @@
  * 2. handle command modifiers.
  */
        p = ea.cmd;
+       if (modifiers_start == NULL)
+           modifiers_start = p;
        if (VIM_ISDIGIT(*ea.cmd))
            p = skipwhite(skipdigits(ea.cmd));
        switch (*p)
@@ -1913,6 +1920,7 @@
        }
        break;
     }
+    modifiers_end = p;

 #ifdef FEAT_EVAL
     ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
@@ -2615,7 +2623,15 @@
        /*
         * Execute a user-defined command.
         */
+       if (modifiers_start != modifiers_end)
+       {
+           set_cmd_modifiers(modifiers_start, (modifiers_end - 
modifiers_start));
+       }
        do_ucmd(&ea);
+       if (modifiers_start != modifiers_end)
+       {
+           clear_cmd_modifiers();
+       }
     }
     else
 #endif
Index: C:/src/vim7mods/src/eval.c
===================================================================
--- C:/src/vim7mods/src/eval.c  (revision 1617)
+++ C:/src/vim7mods/src/eval.c  (working copy)
@@ -355,6 +355,7 @@
     {VV_NAME("operator",        VAR_STRING), VV_RO},
     {VV_NAME("searchforward",   VAR_NUMBER), 0},
     {VV_NAME("oldfiles",        VAR_LIST), 0},
+    {VV_NAME("cmdmodifiers",    VAR_STRING), 0},
 };

 /* shorthand */
@@ -22748,4 +22749,19 @@
     return ret;
 }

+void
+set_cmd_modifiers(string, len)
+    char_u     *string;
+    int                len;
+{
+    vimvars[VV_CMDMODIFIERS].vv_str = vim_strnsave(string, len);
+}
+
+void
+clear_cmd_modifiers()
+{
+    clear_tv(&vimvars[VV_CMDMODIFIERS].vv_tv);
+}
+
+
 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */
Index: C:/src/vim7mods/src/vim.h
===================================================================
--- C:/src/vim7mods/src/vim.h   (revision 1617)
+++ C:/src/vim7mods/src/vim.h   (working copy)
@@ -1746,7 +1746,8 @@
 #define VV_OP          52
 #define VV_SEARCHFORWARD 53
 #define VV_OLDFILES    54
-#define VV_LEN         55      /* number of v: vars */
+#define VV_CMDMODIFIERS        55
+#define VV_LEN         56      /* number of v: vars */

 #ifdef FEAT_CLIPBOARD

Bram, if  you like the patch, could you please include it in Vim?

-- 
Thanks,
Hari

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

Raspunde prin e-mail lui