diff options
| -rw-r--r-- | src/nvim/message.c | 19 | ||||
| -rw-r--r-- | test/functional/eval/execute_spec.lua | 55 | 
2 files changed, 60 insertions, 14 deletions
| diff --git a/src/nvim/message.c b/src/nvim/message.c index 91dd042777..6104adf2c7 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -2455,15 +2455,6 @@ static void redir_write(char_u *str, int maxlen)      return;    } -  // Append output for execute(). -  if (capture_ga) { -    size_t len = 0; -    while (str[len] && (maxlen < 0 ? 1 : (len < (size_t)maxlen))) { -      len++; -    } -    ga_concat_len(capture_ga, (const char *)str, len); -  } -    /* Don't do anything for displaying prompts and the like. */    if (redir_off)      return; @@ -2476,6 +2467,9 @@ static void redir_write(char_u *str, int maxlen)      /* If the string doesn't start with CR or NL, go to msg_col */      if (*s != '\n' && *s != '\r') {        while (cur_col < msg_col) { +        if (capture_ga) { +          ga_concat_len(capture_ga, " ", 1); +        }          if (redir_reg) {            write_reg_contents(redir_reg, (char_u *)" ", 1, true);          } else if (redir_vname) { @@ -2490,8 +2484,11 @@ static void redir_write(char_u *str, int maxlen)        }      } +    size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen; +    if (capture_ga) { +      ga_concat_len(capture_ga, (const char *)str, len); +    }      if (redir_reg) { -      size_t len = maxlen == -1 ? STRLEN(s) : (size_t)maxlen;        write_reg_contents(redir_reg, s, len, true);      }      if (redir_vname) { @@ -2500,7 +2497,7 @@ static void redir_write(char_u *str, int maxlen)      /* Write and adjust the current column. */      while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) { -      if (!redir_reg && !redir_vname) +      if (!redir_reg && !redir_vname && !capture_ga)          if (redir_fd != NULL)            putc(*s, redir_fd);        if (verbose_fd != NULL) diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua index cc9b61b842..91966ed3dd 100644 --- a/test/functional/eval/execute_spec.lua +++ b/test/functional/eval/execute_spec.lua @@ -8,6 +8,7 @@ local exc_exec = helpers.exc_exec  local funcs = helpers.funcs  local Screen = require('test.functional.ui.screen')  local command = helpers.command +local feed = helpers.feed  describe('execute()', function()    before_each(clear) @@ -21,7 +22,11 @@ describe('execute()', function()      eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'}))    end) -  it('supports nested redirection', function() +  it('supports nested execute("execute(...)")', function() +    eq('42', funcs.execute([[echon execute("echon execute('echon 42')")]])) +  end) + +  it('supports nested :redir to a variable', function()      source([[      function! g:Foo()        let a = '' @@ -33,14 +38,39 @@ describe('execute()', function()      function! g:Bar()        let a = ''        redir => a +      silent echon "bar1"        call g:Foo() +      silent echon "bar2"        redir END +      silent echon "bar3"        return a      endfunction      ]]) -    eq('foo', funcs.execute('call g:Bar()')) +    eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()')) +  end) -    eq('42', funcs.execute([[echon execute("echon execute('echon 42')")]])) +  it('supports nested :redir to a register', function() +    source([[ +    let @a = '' +    function! g:Foo() +      redir @a>> +      silent echon "foo" +      redir END +      return @a +    endfunction +    function! g:Bar() +      redir @a>> +      silent echon "bar1" +      call g:Foo() +      silent echon "bar2" +      redir END +      silent echon "bar3" +      return @a +    endfunction +    ]]) +    eq('top1bar1foobar2bar3', funcs.execute('echon "top1"|call g:Bar()')) +    -- :redir itself doesn't nest, so the redirection ends in g:Foo +    eq('bar1foo', eval('@a'))    end)    it('captures a transformed string', function() @@ -69,6 +99,25 @@ describe('execute()', function()      eq('Vim:E729: using Funcref as a String', ret)    end) +  it('captures output with highlights', function() +    eq('\nErrorMsg       xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', +       eval('execute("hi ErrorMsg")')) +  end) + +  it('does not corrupt the command display #5422', function() +    local screen = Screen.new(70, 5) +    screen:attach() +    feed(':echo execute("hi ErrorMsg")<CR>') +    screen:expect([[ +      ~                                                                     | +      ~                                                                     | +      :echo execute("hi ErrorMsg")                                          | +      ErrorMsg       xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red         | +      Press ENTER or type command to continue^                               | +    ]]) +    feed('<CR>') +  end) +    -- This matches Vim behavior.    it('does not capture shell-command output', function()      eq('\n:!echo "foo"\13\n', funcs.execute('!echo "foo"')) | 
