mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.1898
Problem: User commands don't support modifiers.
Solution: Add the <mods> item. (Yegappan Lakshmanan, closes vim/vim#829)
63a60ded3f
This commit is contained in:
parent
4d253b4df5
commit
8a7b15cf35
@ -1406,6 +1406,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>
|
||||
|
@ -5154,6 +5154,24 @@ static char_u *uc_split_args(char_u *arg, size_t *lenp)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static size_t add_cmd_modifier(char_u *buf, char *mod_str, bool *multi_mods)
|
||||
{
|
||||
size_t result = STRLEN(mod_str);
|
||||
if (*multi_mods) {
|
||||
result++;
|
||||
}
|
||||
|
||||
if (buf != NULL) {
|
||||
if (*multi_mods) {
|
||||
STRCAT(buf, " ");
|
||||
}
|
||||
STRCAT(buf, mod_str);
|
||||
}
|
||||
|
||||
*multi_mods = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a <> code in a user command.
|
||||
* "code" points to the '<'. "len" the length of the <> (inclusive).
|
||||
@ -5178,8 +5196,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] == '-') {
|
||||
quote = (*p == 'q' || *p == 'Q') ? 1 : 2;
|
||||
@ -5187,23 +5205,26 @@ uc_check_code (
|
||||
l -= 2;
|
||||
}
|
||||
|
||||
++l;
|
||||
if (l <= 1)
|
||||
l++;
|
||||
if (l <= 1) {
|
||||
type = ct_NONE;
|
||||
else if (STRNICMP(p, "args>", l) == 0)
|
||||
} else if (STRNICMP(p, "args>", l) == 0) {
|
||||
type = ct_ARGS;
|
||||
else if (STRNICMP(p, "bang>", l) == 0)
|
||||
} else if (STRNICMP(p, "bang>", l) == 0) {
|
||||
type = ct_BANG;
|
||||
else if (STRNICMP(p, "count>", l) == 0)
|
||||
} else if (STRNICMP(p, "count>", l) == 0) {
|
||||
type = ct_COUNT;
|
||||
else if (STRNICMP(p, "line1>", l) == 0)
|
||||
} else if (STRNICMP(p, "line1>", l) == 0) {
|
||||
type = ct_LINE1;
|
||||
else if (STRNICMP(p, "line2>", l) == 0)
|
||||
} else if (STRNICMP(p, "line2>", l) == 0) {
|
||||
type = ct_LINE2;
|
||||
else if (STRNICMP(p, "lt>", l) == 0)
|
||||
} else if (STRNICMP(p, "lt>", l) == 0) {
|
||||
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;
|
||||
} else if (STRNICMP(p, "mods>", l) == 0) {
|
||||
type = ct_MODS;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ct_ARGS:
|
||||
@ -5311,6 +5332,87 @@ uc_check_code (
|
||||
break;
|
||||
}
|
||||
|
||||
case ct_MODS:
|
||||
{
|
||||
result = quote ? 2 : 0;
|
||||
if (buf != NULL) {
|
||||
if (quote) {
|
||||
*buf++ = '"';
|
||||
}
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
bool multi_mods = false;
|
||||
|
||||
// :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);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
bool *set;
|
||||
char *name;
|
||||
} mod_entry_T;
|
||||
static mod_entry_T mod_entries[] = {
|
||||
{ &cmdmod.browse, "browse" },
|
||||
{ (bool *)&cmdmod.confirm, "confirm" },
|
||||
{ (bool *)&cmdmod.hide, "hide" },
|
||||
{ (bool *)&cmdmod.keepalt, "keepalt" },
|
||||
{ (bool *)&cmdmod.keepjumps, "keepjumps" },
|
||||
{ (bool *)&cmdmod.keepmarks, "keepmarks" },
|
||||
{ (bool *)&cmdmod.keeppatterns, "keeppatterns" },
|
||||
{ (bool *)&cmdmod.lockmarks, "lockmarks" },
|
||||
{ &cmdmod.noswapfile, "noswapfile" }
|
||||
};
|
||||
// the modifiers that are simple flags
|
||||
for (size_t i = 0; i < ARRAY_SIZE(mod_entries); i++) {
|
||||
if (*mod_entries[i].set) {
|
||||
result += add_cmd_modifier(buf, mod_entries[i].name, &multi_mods);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(vim): How to support :noautocmd?
|
||||
// TODO(vim): How to support :sandbox
|
||||
|
||||
// :silent
|
||||
if (msg_silent > 0) {
|
||||
result += add_cmd_modifier(buf, emsg_silent > 0 ? "silent!" : "silent",
|
||||
&multi_mods);
|
||||
}
|
||||
// :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);
|
||||
}
|
||||
|
||||
// TODO(vim): How to support :unsilent
|
||||
|
||||
// :verbose
|
||||
if (p_verbose > 0) {
|
||||
result += add_cmd_modifier(buf, "verbose", &multi_mods);
|
||||
}
|
||||
// :vertical
|
||||
if (cmdmod.split & WSP_VERT) {
|
||||
result += add_cmd_modifier(buf, "vertical", &multi_mods);
|
||||
}
|
||||
if (quote && buf != NULL) {
|
||||
buf += result - 2;
|
||||
*buf = '"';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ct_REGISTER:
|
||||
result = eap->regname ? 1 : 0;
|
||||
if (quote)
|
||||
|
@ -36,6 +36,7 @@ NEW_TESTS = \
|
||||
test_help_tagjump.res \
|
||||
test_langmap.res \
|
||||
test_syntax.res \
|
||||
test_usercommands.res \
|
||||
test_timers.res \
|
||||
test_viml.res \
|
||||
test_visual.res \
|
||||
|
46
src/nvim/testdir/test_usercommands.vim
Normal file
46
src/nvim/testdir/test_usercommands.vim
Normal file
@ -0,0 +1,46 @@
|
||||
" 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
|
@ -378,7 +378,7 @@ static int included_patches[] = {
|
||||
// 1901 NA
|
||||
// 1900,
|
||||
// 1899 NA
|
||||
// 1898,
|
||||
1898,
|
||||
// 1897,
|
||||
// 1896,
|
||||
// 1895,
|
||||
|
Loading…
Reference in New Issue
Block a user