aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ex_getln.c17
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua42
2 files changed, 43 insertions, 16 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index e10a485f76..c23d6089a3 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -166,6 +166,12 @@ static int hisnum[HIST_COUNT] = {0, 0, 0, 0, 0};
/* identifying (unique) number of newest history entry */
static int hislen = 0; /* actual length of history tables */
+/// Flag for command_line_handle_key to ignore <C-c>
+///
+/// Used if it was received while processing highlight function in order for
+/// user interrupting highlight function to not interrupt command-line.
+static bool getln_interrupted_highlight = false;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ex_getln.c.generated.h"
@@ -1026,8 +1032,11 @@ static int command_line_handle_key(CommandLineState *s)
case ESC: // get here if p_wc != ESC or when ESC typed twice
case Ctrl_C:
// In exmode it doesn't make sense to return. Except when
- // ":normal" runs out of characters.
- if (exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0)) {
+ // ":normal" runs out of characters. Also when highlight callback is active
+ // <C-c> should interrupt only it.
+ if ((exmode_active && (ex_normal_busy == 0 || typebuf.tb_len > 0))
+ || (getln_interrupted_highlight && s->c == Ctrl_C)) {
+ getln_interrupted_highlight = false;
return command_line_not_changed(s);
}
@@ -2278,6 +2287,7 @@ static bool color_cmdline(void)
//
// Also using try_start() because error messages may overwrite typed
// command-line which is not expected.
+ getln_interrupted_highlight = false;
try_start();
err_errmsg = N_("E5407: Callback has thrown an exception: %s");
const int saved_msg_col = msg_col;
@@ -2285,6 +2295,9 @@ static bool color_cmdline(void)
const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv);
msg_silent--;
msg_col = saved_msg_col;
+ if (got_int) {
+ getln_interrupted_highlight = true;
+ }
if (try_end(&err) || !cbcall_ret) {
goto color_cmdline_error;
}
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index dbabf65b68..671490e668 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -10,6 +10,13 @@ local source = helpers.source
local screen
+-- Bug in input() handling: {REDRAW} will erase the whole prompt up until
+-- user types something. It exists in Vim as well, so using `h<BS>` as
+-- a workaround.
+local function redraw_input()
+ feed('{REDRAW}h<BS>')
+end
+
before_each(function()
clear()
screen = Screen.new(40, 8)
@@ -214,10 +221,7 @@ describe('Command-line coloring', function()
{EOB:~ }|
:echo {RBP1:(}{RBP2:(}42{RBP2:)}^ |
]])
- -- Bug in input() handling: {REDRAW} will erase the whole prompt up until
- -- user types something. It exists in Vim as well, so using `h<BS>` as
- -- a workaround.
- feed('{REDRAW}h<BS>')
+ redraw_input()
screen:expect([[
|
{EOB:~ }|
@@ -364,24 +368,33 @@ describe('Command-line coloring', function()
: |
{ERR:E5407: Callback has thrown an exception:}|
{ERR: Keyboard interrupt} |
- ^ |
+ :echo 42^ |
]])
- if true then return pending('<C-c> should only cancel callback, not input()') end
- feed('{REDRAW}')
- screen:snapshot_util()
- feed('<CR>')
- eq('echo 42', meths.get_var('out'))
+ redraw_input()
screen:expect([[
- ^ |
+ |
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- Type :quit<Enter> to exit Nvim |
+ :echo 42^ |
]])
- start_prompt('echo 42<CR>')
+ feed('\n')
+ screen:expect([[
+ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ ^:echo 42 |
+ ]])
+ feed('\n')
+ eq('echo 42', meths.get_var('out'))
+ feed('<C-c>')
screen:expect([[
^ |
{EOB:~ }|
@@ -390,7 +403,7 @@ describe('Command-line coloring', function()
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
- 42 |
+ Type :quit<Enter> to exit Nvim |
]])
end)
it('works fine with NUL, NL, CR', function()
@@ -420,3 +433,4 @@ describe('Ex commands coloring support', function()
end)
-- TODO Specifically test for coloring in cmdline and expr modes
+-- TODO Check using highlighted input() from inside highlighted input()