]> granicus.if.org Git - vim/commitdiff
patch 7.4.1898 v7.4.1898
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Jun 2016 20:08:55 +0000 (22:08 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Jun 2016 20:08:55 +0000 (22:08 +0200)
Problem:    User commands don't support modifiers.
Solution:   Add the <mods> item. (Yegappan Lakshmanan, closes #829)

runtime/doc/map.txt
src/ex_docmd.c
src/testdir/Make_all.mak
src/testdir/test_usercommands.vim [new file with mode: 0644]
src/version.c

index 3fd22f6ae01384ea3c2c063c5fc86cf41077d909..21858e09966a934b82f35b0aae54fd3ae0fd756f 100644 (file)
@@ -1411,6 +1411,27 @@ The valid escape sequences are
        <bang>  (See the '-bang' attribute) Expands to a ! if the
                command was executed with a ! modifier, otherwise
                expands to nothing.
+                                               *<mods>*
+       <mods>  The command modifiers, if specified. Otherwise, expands to
+               nothing. Supported modifiers are |aboveleft|, |belowright|,
+               |botright|, |browse|, |confirm|, |hide|, |keepalt|,
+               |keepjumps|, |keepmarks|, |keeppatterns|, |lockmarks|,
+               |noswapfile|, |silent|, |tab|, |topleft|, |verbose|, and
+               |vertical|.
+               Examples: >
+                   command! -nargs=+ -complete=file MyEdit
+                               \ for f in expand(<q-args>, 0, 1) |
+                               \ exe '<mods> split ' . f |
+                               \ endfor
+
+                   function! SpecialEdit(files, mods)
+                       for f in expand(a:files, 0, 1)
+                           exe a:mods . ' split ' . f
+                       endfor
+                   endfunction
+                   command! -nargs=+ -complete=file Sedit
+                               \ call SpecialEdit(<q-args>, <q-mods>)
+<
                                                *<reg>* *<register>*
        <reg>   (See the '-register' attribute) The optional register,
                if specified.  Otherwise, expands to nothing.  <register>
index 368c2e9853c894ddff8e316c2d75580be434b6ff..4f501aa45448748931a89b0fe6c2a61672189ce2 100644 (file)
@@ -6413,6 +6413,26 @@ uc_split_args(char_u *arg, size_t *lenp)
     return buf;
 }
 
+    static size_t
+add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods)
+{
+    size_t result;
+
+    result = STRLEN(mod_str);
+    if (*multi_mods)
+       result += 1;
+    if (buf != NULL)
+    {
+       if (*multi_mods)
+           STRCAT(buf, " ");
+       STRCAT(buf, mod_str);
+    }
+
+    *multi_mods = 1;
+
+    return result;
+}
+
 /*
  * Check for a <> code in a user command.
  * "code" points to the '<'.  "len" the length of the <> (inclusive).
@@ -6436,8 +6456,8 @@ uc_check_code(
     char_u     *p = code + 1;
     size_t     l = len - 2;
     int                quote = 0;
-    enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER,
-       ct_LT, ct_NONE } type = ct_NONE;
+    enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS,
+       ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE;
 
     if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-')
     {
@@ -6463,6 +6483,8 @@ uc_check_code(
        type = ct_LT;
     else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
        type = ct_REGISTER;
+    else if (STRNICMP(p, "mods>", l) == 0)
+       type = ct_MODS;
 
     switch (type)
     {
@@ -6586,6 +6608,90 @@ uc_check_code(
        break;
     }
 
+    case ct_MODS:
+    {
+       int multi_mods = 0;
+       typedef struct {
+           int *varp;
+           char *name;
+       } mod_entry_T;
+       static mod_entry_T mod_entries[] = {
+#ifdef FEAT_BROWSE_CMD
+           {&cmdmod.browse, "browse"},
+#endif
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+           {&cmdmod.confirm, "confirm"},
+#endif
+           {&cmdmod.hide, "hide"},
+           {&cmdmod.keepalt, "keepalt"},
+           {&cmdmod.keepjumps, "keepjumps"},
+           {&cmdmod.keepmarks, "keepmarks"},
+           {&cmdmod.keeppatterns, "keeppatterns"},
+           {&cmdmod.lockmarks, "lockmarks"},
+           {&cmdmod.noswapfile, "noswapfile"},
+           {NULL, NULL}
+       };
+       int i;
+
+       result = quote ? 2 : 0;
+       if (buf != NULL)
+       {
+           if (quote)
+               *buf++ = '"';
+           *buf = '\0';
+       }
+
+#ifdef FEAT_WINDOWS
+       /* :aboveleft and :leftabove */
+       if (cmdmod.split & WSP_ABOVE)
+           result += add_cmd_modifier(buf, "aboveleft", &multi_mods);
+       /* :belowright and :rightbelow */
+       if (cmdmod.split & WSP_BELOW)
+           result += add_cmd_modifier(buf, "belowright", &multi_mods);
+       /* :botright */
+       if (cmdmod.split & WSP_BOT)
+           result += add_cmd_modifier(buf, "botright", &multi_mods);
+#endif
+
+       /* the modifiers that are simple flags */
+       for (i = 0; mod_entries[i].varp != NULL; ++i)
+           if (*mod_entries[i].varp)
+               result += add_cmd_modifier(buf, mod_entries[i].name,
+                                                                &multi_mods);
+
+       /* TODO: How to support :noautocmd? */
+#ifdef HAVE_SANDBOX
+       /* TODO: How to support :sandbox?*/
+#endif
+       /* :silent */
+       if (msg_silent > 0)
+           result += add_cmd_modifier(buf,
+                   emsg_silent > 0 ? "silent!" : "silent", &multi_mods);
+#ifdef FEAT_WINDOWS
+       /* :tab */
+       if (cmdmod.tab > 0)
+           result += add_cmd_modifier(buf, "tab", &multi_mods);
+       /* :topleft */
+       if (cmdmod.split & WSP_TOP)
+           result += add_cmd_modifier(buf, "topleft", &multi_mods);
+#endif
+       /* TODO: How to support :unsilent?*/
+       /* :verbose */
+       if (p_verbose > 0)
+           result += add_cmd_modifier(buf, "verbose", &multi_mods);
+#ifdef FEAT_WINDOWS
+       /* :vertical */
+       if (cmdmod.split & WSP_VERT)
+           result += add_cmd_modifier(buf, "vertical", &multi_mods);
+#endif
+       if (quote && buf != NULL)
+       {
+           buf += result - 2;
+           *buf = '"';
+       }
+       break;
+    }
+
     case ct_REGISTER:
        result = eap->regname ? 1 : 0;
        if (quote)
index 0e4ab7f523dbb64792b8eabe606fd773a62bb174..59fff145f0e0913e5d391013e391513ffceaba6a 100644 (file)
@@ -179,6 +179,7 @@ NEW_TESTS = test_arglist.res \
            test_perl.res \
            test_quickfix.res \
            test_syntax.res \
+           test_usercommands.res \
            test_viminfo.res \
            test_viml.res \
            test_visual.res \
diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim
new file mode 100644 (file)
index 0000000..a3c5b95
--- /dev/null
@@ -0,0 +1,48 @@
+" Tests for user defined commands
+
+" Test for <mods> in user defined commands
+function Test_cmdmods()
+  let g:mods = ''
+
+  command! -nargs=* MyCmd let g:mods .= '<mods> '
+
+  MyCmd
+  aboveleft MyCmd
+  belowright MyCmd
+  botright MyCmd
+  browse MyCmd
+  confirm MyCmd
+  hide MyCmd
+  keepalt MyCmd
+  keepjumps MyCmd
+  keepmarks MyCmd
+  keeppatterns MyCmd
+  lockmarks MyCmd
+  noswapfile MyCmd
+  silent MyCmd
+  tab MyCmd
+  topleft MyCmd
+  verbose MyCmd
+  vertical MyCmd
+
+  aboveleft belowright botright browse confirm hide keepalt keepjumps
+             \ keepmarks keeppatterns lockmarks noswapfile silent tab
+             \ topleft verbose vertical MyCmd
+
+  call assert_equal(' aboveleft belowright botright browse confirm ' .
+      \ 'hide keepalt keepjumps keepmarks keeppatterns lockmarks ' .
+      \ 'noswapfile silent tab topleft verbose vertical aboveleft ' .
+      \ 'belowright botright browse confirm hide keepalt keepjumps ' .
+      \ 'keepmarks keeppatterns lockmarks noswapfile silent tab topleft ' .
+      \ 'verbose vertical ', g:mods)
+
+  let g:mods = ''
+  command! -nargs=* MyQCmd let g:mods .= '<q-mods> '
+
+  vertical MyQCmd
+  call assert_equal('"vertical" ', g:mods)
+
+  delcommand MyCmd
+  delcommand MyQCmd
+  unlet g:mods
+endfunction
index 6e8b0c70a625a930d46173de9c5b23400898261b..b909cd67eecf9ce12f8a87837ec254d49abc5df4 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1898,
 /**/
     1897,
 /**/