mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 7.4.1898
Problem: User commands don't support modifiers. Solution: Add the <mods> item. (Yegappan Lakshmanan, closes #829)
This commit is contained in:
@@ -1411,6 +1411,27 @@ The valid escape sequences are
|
|||||||
<bang> (See the '-bang' attribute) Expands to a ! if the
|
<bang> (See the '-bang' attribute) Expands to a ! if the
|
||||||
command was executed with a ! modifier, otherwise
|
command was executed with a ! modifier, otherwise
|
||||||
expands to nothing.
|
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>* *<register>*
|
||||||
<reg> (See the '-register' attribute) The optional register,
|
<reg> (See the '-register' attribute) The optional register,
|
||||||
if specified. Otherwise, expands to nothing. <register>
|
if specified. Otherwise, expands to nothing. <register>
|
||||||
|
110
src/ex_docmd.c
110
src/ex_docmd.c
@@ -6413,6 +6413,26 @@ uc_split_args(char_u *arg, size_t *lenp)
|
|||||||
return buf;
|
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.
|
* Check for a <> code in a user command.
|
||||||
* "code" points to the '<'. "len" the length of the <> (inclusive).
|
* "code" points to the '<'. "len" the length of the <> (inclusive).
|
||||||
@@ -6436,8 +6456,8 @@ uc_check_code(
|
|||||||
char_u *p = code + 1;
|
char_u *p = code + 1;
|
||||||
size_t l = len - 2;
|
size_t l = len - 2;
|
||||||
int quote = 0;
|
int quote = 0;
|
||||||
enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER,
|
enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS,
|
||||||
ct_LT, ct_NONE } type = ct_NONE;
|
ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE;
|
||||||
|
|
||||||
if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-')
|
if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-')
|
||||||
{
|
{
|
||||||
@@ -6463,6 +6483,8 @@ uc_check_code(
|
|||||||
type = ct_LT;
|
type = ct_LT;
|
||||||
else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
|
else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0)
|
||||||
type = ct_REGISTER;
|
type = ct_REGISTER;
|
||||||
|
else if (STRNICMP(p, "mods>", l) == 0)
|
||||||
|
type = ct_MODS;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -6586,6 +6608,90 @@ uc_check_code(
|
|||||||
break;
|
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:
|
case ct_REGISTER:
|
||||||
result = eap->regname ? 1 : 0;
|
result = eap->regname ? 1 : 0;
|
||||||
if (quote)
|
if (quote)
|
||||||
|
@@ -179,6 +179,7 @@ NEW_TESTS = test_arglist.res \
|
|||||||
test_perl.res \
|
test_perl.res \
|
||||||
test_quickfix.res \
|
test_quickfix.res \
|
||||||
test_syntax.res \
|
test_syntax.res \
|
||||||
|
test_usercommands.res \
|
||||||
test_viminfo.res \
|
test_viminfo.res \
|
||||||
test_viml.res \
|
test_viml.res \
|
||||||
test_visual.res \
|
test_visual.res \
|
||||||
|
48
src/testdir/test_usercommands.vim
Normal file
48
src/testdir/test_usercommands.vim
Normal file
@@ -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
|
@@ -753,6 +753,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1898,
|
||||||
/**/
|
/**/
|
||||||
1897,
|
1897,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user