Hi,
On Sat, May 21, 2016 at 1:12 PM, Yegappan Lakshmanan
<[email protected]> wrote:
> On Fri, May 20, 2016 at 9:17 AM, Bram Moolenaar <[email protected]>
> wrote:
>>
>>
>> Justin Keyes wrote:
>>
>> >
>> > ```
>> > Doesn't work for :diffsplit, :diffpatch, :execute and :normal.
>> > ```
>> >
>> > But it doesn't mention user commands. It would avoid a lot of redundant
>> > commands, and add flexibility, if `:tab` supported user commands.
>> >
>> > Steps to reproduce:
>> >
>> > ```
>> > :command! -nargs=1 Foo split <args>
>> > :tab Foo bar
>> > ```
>> >
>> > - Expected behavior: opens a new buffer named "bar" in a new tab
>> > - Actual behavior: opens a new buffer named "bar" in a new split window
>>
>> OK, but this will cause trouble if the user command has several Ex
>> commands, then we don't know where to apply the modifier. E.g. when
>> temporarily opening a scratch bufffer.
>>
>> We could make the modifiers available in <> form, so that the user
>> command can apply them where needed. Possibly just <mods>, to pass on
>> all modifiers.
>
>
> The attached patch adds support for the <mods> user command escape
> sequence.
>
Updated the patch to also support "<q-mods>".
- Yegappan
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt
index 3fd22f6..360f4da 100644
--- a/runtime/doc/map.txt
+++ b/runtime/doc/map.txt
@@ -1411,6 +1411,13 @@ 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'.
*<reg>* *<register>*
<reg> (See the '-register' attribute) The optional register,
if specified. Otherwise, expands to nothing. <register>
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index e5de379..42ddc4d 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -6412,6 +6412,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).
@@ -6435,8 +6455,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] == '-')
{
@@ -6462,6 +6482,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)
{
@@ -6585,6 +6607,112 @@ uc_check_code(
break;
}
+ case ct_MODS:
+ {
+ int multi_mods = 0;
+
+ 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
+
+#ifdef FEAT_BROWSE_CMD
+ /* :browse */
+ if (cmdmod.browse)
+ result += add_cmd_modifier(buf, "browse", &multi_mods);
+#endif
+
+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
+ /* :confirm */
+ if (cmdmod.confirm)
+ result += add_cmd_modifier(buf, "confirm", &multi_mods);
+#endif
+
+ /* :hide */
+ if (cmdmod.hide)
+ result += add_cmd_modifier(buf, "hide", &multi_mods);
+
+ /* :keepalt */
+ if (cmdmod.keepalt)
+ result += add_cmd_modifier(buf, "keepalt", &multi_mods);
+
+ /* :keepjumps */
+ if (cmdmod.keepjumps)
+ result += add_cmd_modifier(buf, "keepjumps", &multi_mods);
+
+ /* :keepmarks */
+ if (cmdmod.keepmarks)
+ result += add_cmd_modifier(buf, "keepmarks", &multi_mods);
+
+ /* :keeppatterns */
+ if (cmdmod.keeppatterns)
+ result += add_cmd_modifier(buf, "keeppatterns", &multi_mods);
+
+ /* :lockmarks */
+ if (cmdmod.lockmarks)
+ result += add_cmd_modifier(buf, "lockmarks", &multi_mods);
+
+ /* TODO: How to support :noautocmd? */
+
+ /* :noswapfile */
+ if (cmdmod.noswapfile)
+ result += add_cmd_modifier(buf, "noswapfile", &multi_mods);
+
+#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)
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 0e4ab7f..635f23c 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -179,6 +179,7 @@ NEW_TESTS = test_arglist.res \
test_perl.res \
test_quickfix.res \
test_syntax.res \
+ test_usrcmds.res \
test_viminfo.res \
test_viml.res \
test_visual.res \
diff --git a/src/testdir/test_usrcmds.vim b/src/testdir/test_usrcmds.vim
new file mode 100644
index 0000000..a3c5b95
--- /dev/null
+++ b/src/testdir/test_usrcmds.vim
@@ -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