diff options
author | Luuk van Baal <luukvbaal@gmail.com> | 2025-03-13 13:47:48 +0100 |
---|---|---|
committer | Christian Clason <ch.clason+github@icloud.com> | 2025-03-15 12:09:22 +0100 |
commit | a70ad5cdb6de024f2efd1885107cb89c135515e3 (patch) | |
tree | c2061886b8a488244f500e1114b3dc4762ec3ebd | |
parent | 98c1355e2f2236bcbad7f8f513d3c11237040293 (diff) | |
download | rneovim-a70ad5cdb6de024f2efd1885107cb89c135515e3.tar.gz rneovim-a70ad5cdb6de024f2efd1885107cb89c135515e3.tar.bz2 rneovim-a70ad5cdb6de024f2efd1885107cb89c135515e3.zip |
fix(cmdline): ext_cmdline block events for conditionals
Problem: No block events emitted with ext_cmdline for :if, :while, :try etc.
Solution: Emit cmdline block events; store the indent level of the
previous cmdline and whether a block event was emitted.
-rw-r--r-- | src/nvim/ex_docmd.c | 27 | ||||
-rw-r--r-- | test/functional/ui/cmdline_spec.lua | 53 |
2 files changed, 70 insertions, 10 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 3b78092daf..af93db9956 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -406,6 +406,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) bool msg_didout_before_start = false; int count = 0; // line number count bool did_inc = false; // incremented RedrawingDisabled + int block_indent = -1; // indent for ext_cmdline block event int retval = OK; cstack_T cstack = { // conditional stack .cs_idx = -1, @@ -573,16 +574,18 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) // 2. If no line given, get an allocated line with fgetline(). if (next_cmdline == NULL) { - // Need to set msg_didout for the first line after an ":if", - // otherwise the ":if" will be overwritten. - if (count == 1 && getline_equal(fgetline, cookie, getexline)) { - msg_didout = true; - } - if (fgetline == NULL - || (next_cmdline = fgetline(':', cookie, - cstack.cs_idx < - 0 ? 0 : (cstack.cs_idx + 1) * 2, - true)) == NULL) { + int indent = cstack.cs_idx < 0 ? 0 : (cstack.cs_idx + 1) * 2; + if (count >= 1 && getline_equal(fgetline, cookie, getexline)) { + if (ui_has(kUICmdline)) { + ui_ext_cmdline_block_append((size_t)MAX(0, block_indent), last_cmdline); + block_indent = indent; + } else if (count == 1) { + // Need to set msg_didout for the first line after an ":if", + // otherwise the ":if" will be overwritten. + msg_didout = true; + } + } + if (fgetline == NULL || (next_cmdline = fgetline(':', cookie, indent, true)) == NULL) { // Don't call wait_return() for aborted command line. The NULL // returned for the end of a sourced file or executed function // doesn't do this. @@ -939,6 +942,10 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) } } + if (block_indent >= 0) { + ui_ext_cmdline_block_leave(); + } + did_endif = false; // in case do_cmdline used recursively do_cmdline_end(); diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index ce7c9596bb..cb9d978a0f 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -865,6 +865,59 @@ local function test_cmdline(linegrid) }, }) end) + + it('works with conditionals', function() + local s1 = [[ + ^ | + {1:~ }|*3 + | + ]] + screen:expect(s1) + feed(':if 1<CR>') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { '' } }, + firstc = ':', + indent = 2, + pos = 0, + }, + }, + cmdline_block = { { { 'if 1' } } }, + }) + feed(':let x = 1<CR>') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { '' } }, + firstc = ':', + indent = 2, + pos = 0, + }, + }, + cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + }) + feed(':endif') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { ':endif' } }, + firstc = ':', + indent = 2, + pos = 6, + }, + }, + cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + }) + feed('<CR>') + screen:expect({ + grid = s1, + cmdline = { { abort = false } }, + }) + end) end -- the representation of cmdline and cmdline_block contents changed with ext_linegrid |