mirror of
https://github.com/neovim/neovim.git
synced 2025-09-20 10:18:18 +00:00
Merge #5975 from jamessan/execute-with-attrs
execute: Correctly capture output with highlight attributes
This commit is contained in:
@@ -2455,15 +2455,6 @@ static void redir_write(char_u *str, int maxlen)
|
|||||||
return;
|
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. */
|
/* Don't do anything for displaying prompts and the like. */
|
||||||
if (redir_off)
|
if (redir_off)
|
||||||
return;
|
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 the string doesn't start with CR or NL, go to msg_col */
|
||||||
if (*s != '\n' && *s != '\r') {
|
if (*s != '\n' && *s != '\r') {
|
||||||
while (cur_col < msg_col) {
|
while (cur_col < msg_col) {
|
||||||
|
if (capture_ga) {
|
||||||
|
ga_concat_len(capture_ga, " ", 1);
|
||||||
|
}
|
||||||
if (redir_reg) {
|
if (redir_reg) {
|
||||||
write_reg_contents(redir_reg, (char_u *)" ", 1, true);
|
write_reg_contents(redir_reg, (char_u *)" ", 1, true);
|
||||||
} else if (redir_vname) {
|
} else if (redir_vname) {
|
||||||
@@ -2490,8 +2484,11 @@ static void redir_write(char_u *str, int maxlen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redir_reg) {
|
|
||||||
size_t len = maxlen == -1 ? STRLEN(s) : (size_t)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) {
|
||||||
write_reg_contents(redir_reg, s, len, true);
|
write_reg_contents(redir_reg, s, len, true);
|
||||||
}
|
}
|
||||||
if (redir_vname) {
|
if (redir_vname) {
|
||||||
@@ -2500,7 +2497,7 @@ static void redir_write(char_u *str, int maxlen)
|
|||||||
|
|
||||||
/* Write and adjust the current column. */
|
/* Write and adjust the current column. */
|
||||||
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) {
|
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)
|
if (redir_fd != NULL)
|
||||||
putc(*s, redir_fd);
|
putc(*s, redir_fd);
|
||||||
if (verbose_fd != NULL)
|
if (verbose_fd != NULL)
|
||||||
|
@@ -8,6 +8,7 @@ local exc_exec = helpers.exc_exec
|
|||||||
local funcs = helpers.funcs
|
local funcs = helpers.funcs
|
||||||
local Screen = require('test.functional.ui.screen')
|
local Screen = require('test.functional.ui.screen')
|
||||||
local command = helpers.command
|
local command = helpers.command
|
||||||
|
local feed = helpers.feed
|
||||||
|
|
||||||
describe('execute()', function()
|
describe('execute()', function()
|
||||||
before_each(clear)
|
before_each(clear)
|
||||||
@@ -21,7 +22,11 @@ describe('execute()', function()
|
|||||||
eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'}))
|
eq("\nfoo\nbar", funcs.execute({'echo "foo"', 'echo "bar"'}))
|
||||||
end)
|
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([[
|
source([[
|
||||||
function! g:Foo()
|
function! g:Foo()
|
||||||
let a = ''
|
let a = ''
|
||||||
@@ -33,14 +38,39 @@ describe('execute()', function()
|
|||||||
function! g:Bar()
|
function! g:Bar()
|
||||||
let a = ''
|
let a = ''
|
||||||
redir => a
|
redir => a
|
||||||
|
silent echon "bar1"
|
||||||
call g:Foo()
|
call g:Foo()
|
||||||
|
silent echon "bar2"
|
||||||
redir END
|
redir END
|
||||||
|
silent echon "bar3"
|
||||||
return a
|
return a
|
||||||
endfunction
|
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)
|
end)
|
||||||
|
|
||||||
it('captures a transformed string', function()
|
it('captures a transformed string', function()
|
||||||
@@ -69,6 +99,25 @@ describe('execute()', function()
|
|||||||
eq('Vim:E729: using Funcref as a String', ret)
|
eq('Vim:E729: using Funcref as a String', ret)
|
||||||
end)
|
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.
|
-- This matches Vim behavior.
|
||||||
it('does not capture shell-command output', function()
|
it('does not capture shell-command output', function()
|
||||||
eq('\n:!echo "foo"\13\n', funcs.execute('!echo "foo"'))
|
eq('\n:!echo "foo"\13\n', funcs.execute('!echo "foo"'))
|
||||||
|
Reference in New Issue
Block a user