diff options
| -rw-r--r-- | src/nvim/ex_getln.c | 17 | ||||
| -rw-r--r-- | test/functional/ui/cmdline_highlight_spec.lua | 42 | 
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() | 
