mirror of
https://github.com/neovim/neovim.git
synced 2026-08-25 16:41:52 +00:00
Merge pull request #36934 from janlazo/vim-8.2.4633
vim-patch:8.2.{4633,4636,4637,4763,5092},9.0.0025
This commit is contained in:
@@ -2511,8 +2511,23 @@ static char *ex_range_without_command(exarg_T *eap)
|
||||
/// @return FAIL when the command is not to be executed.
|
||||
int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod, bool skip_only)
|
||||
{
|
||||
char *orig_cmd = eap->cmd;
|
||||
char *cmd_start = NULL;
|
||||
bool use_plus_cmd = false;
|
||||
bool has_visual_range = false;
|
||||
CLEAR_POINTER(cmod);
|
||||
|
||||
if (strncmp(eap->cmd, "'<,'>", 5) == 0) {
|
||||
// The automatically inserted Visual area range is skipped, so that
|
||||
// typing ":cmdmod cmd" in Visual mode works without having to move the
|
||||
// range to after the modififiers. The command will be
|
||||
// "'<,'>cmdmod cmd", parse "cmdmod cmd" and then put back "'<,'>"
|
||||
// before "cmd" below.
|
||||
eap->cmd += 5;
|
||||
cmd_start = eap->cmd;
|
||||
has_visual_range = true;
|
||||
}
|
||||
|
||||
// Repeat until no more command modifiers are found.
|
||||
while (true) {
|
||||
while (*eap->cmd == ' '
|
||||
@@ -2521,14 +2536,16 @@ int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod,
|
||||
eap->cmd++;
|
||||
}
|
||||
|
||||
// in ex mode, an empty line works like :+
|
||||
// in ex mode, an empty command (after modifiers) works like :+
|
||||
if (*eap->cmd == NUL && exmode_active
|
||||
&& getline_equal(eap->ea_getline, eap->cookie, getexline)
|
||||
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
|
||||
eap->cmd = exmode_plus;
|
||||
use_plus_cmd = true;
|
||||
if (!skip_only) {
|
||||
ex_pressedreturn = true;
|
||||
}
|
||||
break; // no modifiers following
|
||||
}
|
||||
|
||||
// ignore comment and empty lines
|
||||
@@ -2750,6 +2767,39 @@ int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod,
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_visual_range) {
|
||||
if (eap->cmd > cmd_start) {
|
||||
// Move the '<,'> range to after the modifiers and insert a colon.
|
||||
// Since the modifiers have been parsed put the colon on top of the
|
||||
// space: "'<,'>mod cmd" -> "mod:'<,'>cmd
|
||||
// Put eap->cmd after the colon.
|
||||
if (use_plus_cmd) {
|
||||
size_t len = strlen(cmd_start);
|
||||
|
||||
// Special case: empty command uses "+":
|
||||
// "'<,'>mods" -> "mods *+
|
||||
// Use "*" instead of "'<,'>" to avoid the command getting
|
||||
// longer, in case is was allocated.
|
||||
memmove(orig_cmd, cmd_start, len);
|
||||
xmemcpyz(orig_cmd + len, S_LEN(" *+"));
|
||||
} else {
|
||||
memmove(cmd_start - 5, cmd_start, (size_t)(eap->cmd - cmd_start));
|
||||
eap->cmd -= 5;
|
||||
memmove(eap->cmd - 1, ":'<,'>", 6);
|
||||
}
|
||||
} else {
|
||||
// No modifiers, move the pointer back.
|
||||
// Special case: change empty command to "+".
|
||||
if (use_plus_cmd) {
|
||||
eap->cmd = "'<,'>+";
|
||||
} else {
|
||||
eap->cmd = orig_cmd;
|
||||
}
|
||||
}
|
||||
} else if (use_plus_cmd) {
|
||||
eap->cmd = exmode_plus;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -2561,6 +2561,14 @@ func Test_cmdwin_insert_mode_close()
|
||||
call assert_equal(1, winnr('$'))
|
||||
endfunc
|
||||
|
||||
func Test_cmdwin_ex_mode_with_modifier()
|
||||
" this was accessing memory after allocated text in Ex mode
|
||||
new
|
||||
call setline(1, ['some', 'text', 'lines'])
|
||||
silent! call feedkeys("gQnormal vq:atopleft\<C-V>\<CR>\<CR>", 'xt')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" test that ";" works to find a match at the start of the first line
|
||||
func Test_zero_line_search()
|
||||
new
|
||||
|
||||
@@ -287,6 +287,18 @@ func Test_ex_mode_large_indent()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" This was accessing illegal memory when using "+" for eap->cmd.
|
||||
func Test_empty_command_visual_mode()
|
||||
let lines =<< trim END
|
||||
r<sfile>
|
||||
0norm0V:
|
||||
:qall!
|
||||
END
|
||||
call writefile(lines, 'Xexmodescript')
|
||||
call assert_equal(1, RunVim([], [], '-u NONE -e -s -S Xexmodescript'))
|
||||
|
||||
call delete('Xexmodescript')
|
||||
endfunc
|
||||
|
||||
" Testing implicit print command
|
||||
func Test_implicit_print()
|
||||
|
||||
@@ -577,6 +577,13 @@ func Test_source_buffer_vim9()
|
||||
call assert_equal(#{pi: 3.12, e: 2.71828}, g:Math)
|
||||
call assert_equal(['vim', 'nano'], g:Editors)
|
||||
|
||||
" '<,'> range before the cmd modifier works
|
||||
unlet g:Math
|
||||
unlet g:Editors
|
||||
exe "normal 6GV4j:vim9cmd source\<CR>"
|
||||
call assert_equal(['vim', 'nano'], g:Editors)
|
||||
unlet g:Editors
|
||||
|
||||
" test for using try/catch
|
||||
%d _
|
||||
let lines =<< trim END
|
||||
|
||||
Reference in New Issue
Block a user