commit 0c70fbf0d6393d7ba3e617619d7d469366633199
parent a331d187ba7591f2bbf0841194e96ba0900c1106
Author: Jan Edmund Lazo <jan.lazo@mail.utoronto.ca>
Date: Fri, 12 Dec 2025 23:34:07 -0500
vim-patch:8.2.4633: Visual range does not work before command modifiers
Problem: Visual range does not work before command modifiers.
Solution: Move Visual range to after command modifiers.
https://github.com/vim/vim/commit/c75bca3ee955ff36ece99a42041733ddea5f45a7
Co-authored-by: Bram Moolenaar <Bram@vim.org>
Diffstat:
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
@@ -2511,8 +2511,19 @@ 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 *cmd_start;
+ 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.
+ eap->cmd += 5;
+ cmd_start = eap->cmd;
+ has_visual_range = true;
+ }
+
// Repeat until no more command modifiers are found.
while (true) {
while (*eap->cmd == ' '
@@ -2750,6 +2761,16 @@ int parse_command_modifiers(exarg_T *eap, const char **errormsg, cmdmod_T *cmod,
break;
}
+ if (has_visual_range && 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.
+ memmove(cmd_start - 5, cmd_start, (size_t)(eap->cmd - cmd_start));
+ eap->cmd -= 5;
+ memmove(eap->cmd - 1, ":'<,'>", 6);
+ }
+
return OK;
}
diff --git a/test/old/testdir/test_source.vim b/test/old/testdir/test_source.vim
@@ -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