mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.0.0151,3,4 #7389
vim-patch:8.0.0151 Problem: To pass buffer content to system() and systemlist() one has to first create a string or list. Solution: Allow passing a buffer number. (LemonBoy, closes vim/vim#1240)12c4492dd3
vim-patch:8.0.0153 Problem: system() test fails on MS-Windows. Solution: Deal when extra space and CR.9d9c356517
vim-patch:8.0.0154 Problem: system() test fails on OS/X. Solution: Deal with leading spaces.31f19ce0a0
This commit is contained in:
parent
de0a9548f7
commit
f8f7f9d5f5
@ -7645,6 +7645,9 @@ system({cmd} [, {input}]) *system()* *E677*
|
||||
|writefile()| does with {binary} set to "b" (i.e. with
|
||||
a newline between each list item, and newlines inside list
|
||||
items converted to NULs).
|
||||
When {input} is given and is a valid buffer id, the content of
|
||||
the buffer is written to the file line by line, each line
|
||||
terminated by a NL (and NUL where the text has NL).
|
||||
*E5677*
|
||||
Note: system() cannot write to or read from backgrounded ("&")
|
||||
shell commands, e.g.: >
|
||||
|
@ -17482,24 +17482,24 @@ write_list_error:
|
||||
|
||||
/// Saves a typval_T as a string.
|
||||
///
|
||||
/// For lists, replaces NLs with NUL and separates items with NLs.
|
||||
/// For lists or buffers, replaces NLs with NUL and separates items with NLs.
|
||||
///
|
||||
/// @param[in] tv A value to store as a string.
|
||||
/// @param[out] len The length of the resulting string or -1 on error.
|
||||
/// @param[in] tv Value to store as a string.
|
||||
/// @param[out] len Length of the resulting string or -1 on error.
|
||||
/// @param[in] endnl If true, the output will end in a newline (if a list).
|
||||
/// @returns an allocated string if `tv` represents a VimL string, list, or
|
||||
/// number; NULL otherwise.
|
||||
static char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
|
||||
FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
*len = 0;
|
||||
if (tv->v_type == VAR_UNKNOWN) {
|
||||
*len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// For types other than list, let tv_get_string_buf_chk() get the value or
|
||||
// For other types, let tv_get_string_buf_chk() get the value or
|
||||
// print an error.
|
||||
if (tv->v_type != VAR_LIST) {
|
||||
if (tv->v_type != VAR_LIST && tv->v_type != VAR_NUMBER) {
|
||||
const char *ret = tv_get_string_chk(tv);
|
||||
if (ret && (*len = strlen(ret))) {
|
||||
return xmemdupz(ret, (size_t)(*len));
|
||||
@ -17509,8 +17509,40 @@ static char *save_tv_as_string(typval_T *tv, ptrdiff_t *const len, bool endnl)
|
||||
}
|
||||
}
|
||||
|
||||
if (tv->v_type == VAR_NUMBER) { // Treat number as a buffer-id.
|
||||
buf_T *buf = buflist_findnr(tv->vval.v_number);
|
||||
if (buf) {
|
||||
for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
|
||||
for (char_u *p = ml_get_buf(buf, lnum, false); *p != NUL; p++) {
|
||||
*len += 1;
|
||||
}
|
||||
*len += 1;
|
||||
}
|
||||
} else {
|
||||
EMSGN(_(e_nobufnr), tv->vval.v_number);
|
||||
*len = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ret = xmalloc(*len + 1);
|
||||
char *end = ret;
|
||||
for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++) {
|
||||
for (char_u *p = ml_get_buf(buf, lnum, false); *p != NUL; p++) {
|
||||
*end++ = (*p == '\n') ? NUL : *p;
|
||||
}
|
||||
*end++ = '\n';
|
||||
}
|
||||
*end = NUL;
|
||||
*len = end - ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert(tv->v_type == VAR_LIST);
|
||||
// Pre-calculate the resulting length.
|
||||
*len = 0;
|
||||
list_T *list = tv->vval.v_list;
|
||||
TV_LIST_ITER_CONST(list, li, {
|
||||
*len += strlen(tv_get_string(TV_LIST_ITEM_TV(li))) + 1;
|
||||
|
@ -88,6 +88,7 @@ NEW_TESTS ?= \
|
||||
test_startup_utf8.res \
|
||||
test_substitute.res \
|
||||
test_syntax.res \
|
||||
test_system.res \
|
||||
test_tabpage.res \
|
||||
test_textobjects.res \
|
||||
test_timers.res \
|
||||
|
48
src/nvim/testdir/test_system.vim
Normal file
48
src/nvim/testdir/test_system.vim
Normal file
@ -0,0 +1,48 @@
|
||||
" Tests for system() and systemlist()
|
||||
|
||||
function! Test_System()
|
||||
if !executable('echo') || !executable('cat') || !executable('wc')
|
||||
return
|
||||
endif
|
||||
let out = system('echo 123')
|
||||
" On Windows we may get a trailing space.
|
||||
if out != "123 \n"
|
||||
call assert_equal("123\n", out)
|
||||
endif
|
||||
|
||||
let out = systemlist('echo 123')
|
||||
" On Windows we may get a trailing space and CR.
|
||||
if out != ["123 \r"]
|
||||
call assert_equal(['123'], out)
|
||||
endif
|
||||
|
||||
call assert_equal('123', system('cat', '123'))
|
||||
call assert_equal(['123'], systemlist('cat', '123'))
|
||||
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
|
||||
|
||||
new Xdummy
|
||||
call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
|
||||
let out = system('wc -l', bufnr('%'))
|
||||
" On OS/X we get leading spaces
|
||||
let out = substitute(out, '^ *', '', '')
|
||||
call assert_equal("3\n", out)
|
||||
|
||||
let out = systemlist('wc -l', bufnr('%'))
|
||||
" On Windows we may get a trailing CR.
|
||||
if out != ["3\r"]
|
||||
" On OS/X we get leading spaces
|
||||
if type(out) == v:t_list
|
||||
let out[0] = substitute(out[0], '^ *', '', '')
|
||||
endif
|
||||
call assert_equal(['3'], out)
|
||||
endif
|
||||
|
||||
let out = systemlist('cat', bufnr('%'))
|
||||
" On Windows we may get a trailing CR.
|
||||
if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"]
|
||||
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
|
||||
endif
|
||||
bwipe!
|
||||
|
||||
call assert_fails('call system("wc -l", 99999)', 'E86:')
|
||||
endfunction
|
@ -1281,10 +1281,10 @@ static const int included_patches[] = {
|
||||
157,
|
||||
156,
|
||||
155,
|
||||
// 154,
|
||||
// 153,
|
||||
154,
|
||||
153,
|
||||
152,
|
||||
// 151,
|
||||
151,
|
||||
150,
|
||||
149,
|
||||
148,
|
||||
|
@ -5,6 +5,7 @@ local eq, call, clear, eval, feed_command, feed, nvim =
|
||||
helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command,
|
||||
helpers.feed, helpers.nvim
|
||||
local command = helpers.command
|
||||
local exc_exec = helpers.exc_exec
|
||||
local iswin = helpers.iswin
|
||||
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
@ -274,9 +275,12 @@ describe('system()', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('input passed as Number', function()
|
||||
it('stringifies the input', function()
|
||||
eq('1', eval('system("cat", 1)'))
|
||||
describe('Number input', function()
|
||||
it('is treated as a buffer id', function()
|
||||
command("put ='text in buffer 1'")
|
||||
eq('\ntext in buffer 1\n', eval('system("cat", 1)'))
|
||||
eq('Vim(echo):E86: Buffer 42 does not exist',
|
||||
exc_exec('echo system("cat", 42)'))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user