diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2017-12-03 03:38:58 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2018-06-04 02:07:39 +0200 |
commit | 51e817dc1be46947073529fa97bb07a6a8078dd4 (patch) | |
tree | 5d3d5067cbc45e9cb421318ee2e6610227f0eb8e | |
parent | fad748dfface98fa035747b7d2d4402228bae087 (diff) | |
download | rneovim-51e817dc1be46947073529fa97bb07a6a8078dd4.tar.gz rneovim-51e817dc1be46947073529fa97bb07a6a8078dd4.tar.bz2 rneovim-51e817dc1be46947073529fa97bb07a6a8078dd4.zip |
startup: stdin as text instead of commands
Treat stdin as text by default (so the "-" file is not needed):
echo foo | nvim
It works with file args (implemented in next commit), too:
echo foo | nvim file1.txt file2.txt
Why? Because:
- Execution of input is (1) almost always unintentional/confusing,
and (2) potentially destructive.
- Avoids the need for time-delayed warning. #7659
- The _common_ case is to open text in a buffer, not send commands.
Note:
- Not for Ex-mode (-es) because it is used by scripts. But maybe `-Es`?
- Not for --headless, because stdio may be a protocol stream and may be
used for any purpose by stdioopen().
To treat stdin as Normal-mode commands, use `-s -` instead:
echo ifoo | nvim -s -
Other alternatives:
- Replay a register. E.g. the following mostly works, except @q aborts
on any "beep" (e.g. if the cursor can't move).
nvim -c '%d q|norm @q' -
- Future: Let `:%source` work with unsaved buffer contents?
closes #2087
closes #7659
-rw-r--r-- | src/nvim/main.c | 26 | ||||
-rw-r--r-- | test/functional/core/startup_spec.lua | 64 |
2 files changed, 67 insertions, 23 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index 1616ba05f8..127f14de2d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -281,12 +281,6 @@ int main(int argc, char **argv) full_screen = true; - // When starting in Ex mode and commands come from a file, set Silent mode. - // is active input a terminal? - if (!headless_mode && exmode_active && !params.input_isatty) { - silent_mode = true; - } - /* * Set the default values for the options that use Rows and Columns. */ @@ -1097,7 +1091,7 @@ scripterror: mch_exit(2); } int error; - if (STRCMP(argv[0], "-") == 0) { + if (strequal(argv[0], "-")) { const int stdin_dup_fd = os_dup(STDIN_FILENO); #ifdef WIN32 // On Windows, replace the original stdin with the @@ -1212,6 +1206,21 @@ scripterror: set_vim_var_string(VV_SWAPCOMMAND, swcmd, -1); xfree(swcmd); } + + // Handle "foo | nvim". #6299 + if (!headless_mode + && !embedded_mode + && !parmp->input_isatty + && !exmode_active // `-es` was not given. + && scriptin[0] == NULL // `-s -` was not given. + ) { + if (parmp->edit_type == EDIT_NONE) { + parmp->edit_type = EDIT_STDIN; + } else if (parmp->edit_type != EDIT_STDIN) { + mainerr(err_too_many_args, "stdin"); + } + } + TIME_MSG("parsing arguments"); } @@ -1884,7 +1893,6 @@ static void usage(void) mch_msg(_("Usage:\n")); mch_msg(_(" nvim [options] [file ...] Edit file(s)\n")); - mch_msg(_(" nvim [options] - Read text from stdin\n")); mch_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n")); mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n")); mch_msg(_("\nOptions:\n")); @@ -1918,7 +1926,7 @@ static void usage(void) mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n")); mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n")); mch_msg(_(" --headless Don't start a user interface\n")); - mch_msg(_(" --listen <address> Start RPC server at this address\n")); + mch_msg(_(" --listen <address> Serve RPC API from this address\n")); #if !defined(UNIX) mch_msg(_(" --literal Don't expand wildcards\n")); #endif diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index ae7f949e52..0d4199ea6e 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -9,11 +9,13 @@ local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set local read_file = helpers.read_file local retry = helpers.retry +local sleep = helpers.sleep local iswin = helpers.iswin describe('startup', function() before_each(function() clear() + os.remove('Xtest_startup_ttyout') end) after_each(function() os.remove('Xtest_startup_ttyout') @@ -46,8 +48,8 @@ describe('startup', function() end -- Running in :terminal command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\" ]] - ..[[-c \"echo has('ttyin') has('ttyout')\""]] + ..nvim_set..[[\"]] + ..[[ -c \"echo has('ttyin') has('ttyout')\""]] ..[[, shellescape(v:progpath))]]) screen:expect([[ ^ | @@ -56,41 +58,75 @@ describe('startup', function() ]]) end) it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() - local screen = Screen.new(25, 5) - screen:attach() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\" ]] - ..[[-c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] - ..[[-c q | cat -v"]] -- Output to a pipe. + ..nvim_set..[[\"]] + ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] + ..[[ -c q | cat -v"]] -- Output to a pipe. ..[[, shellescape(v:progpath))]]) retry(nil, 3000, function() - screen:sleep(1) + sleep(1) eq('1\n0\n', -- stdin is a TTY, stdout is a pipe read_file('Xtest_startup_ttyout')) end) end) it('input from pipe: has("ttyin")==0 has("ttyout")==1', function() - local screen = Screen.new(25, 5) - screen:attach() if iswin() then command([[set shellcmdflag=/s\ /c shellxquote=\"]]) end -- Running in :terminal command([[exe printf("terminal echo foo | ]] -- Input from a pipe. ..[[%s -u NONE -i NONE --cmd \"]] - ..nvim_set..[[\" ]] - ..[[-c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] - ..[[-c q -- -"]] + ..nvim_set..[[\"]] + ..[[ -c \"call writefile([has('ttyin'), has('ttyout')], 'Xtest_startup_ttyout')\"]] + ..[[ -c q -- -"]] ..[[, shellescape(v:progpath))]]) retry(nil, 3000, function() - screen:sleep(1) + sleep(1) eq('0\n1\n', -- stdin is a pipe, stdout is a TTY read_file('Xtest_startup_ttyout')) end) end) + it('input from pipe (implicit) #7679', function() + local screen = Screen.new(25, 3) + screen:attach() + if iswin() then + command([[set shellcmdflag=/s\ /c shellxquote=\"]]) + end + -- Running in :terminal + command([[exe printf("terminal echo foo | ]] -- Input from a pipe. + ..[[%s -u NONE -i NONE --cmd \"]] + ..nvim_set..[[\"]] + ..[[ -c \"echo has('ttyin') has('ttyout')\""]] + ..[[, shellescape(v:progpath))]]) + screen:expect([[ + ^foo | + 0 1 | + | + ]]) + end) + it('input from pipe (implicit) + file args #7679', function() + local screen = Screen.new(25, 3) + screen:attach() + if iswin() then + command([[set shellcmdflag=/s\ /c shellxquote=\"]]) + end + command([[exe "terminal echo ohyeah | "]] -- Input from a pipe. + ..[[.shellescape(v:progpath)." -u NONE -i NONE --cmd \"]] + ..nvim_set..[[\"]] + ..[[ --cmd \"set shortmess+=I\"]] + ..[[ -c \"echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')\"]] + ..[[ -- test/functional/fixtures/shell-test.c]] + ..[[ test/functional/fixtures/tty-test.c]] + ..[["]]) + screen:expect([[ + ^ohyeah | + 0 1 bufs=3 | + | + ]]) + end) end) |