From 860ecd705588470b52094b7036c016b2af15f8c9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 23 Oct 2017 01:50:26 +0200 Subject: [PATCH 1/3] vim-patch:8.0.0096: has('ttyin'), has('ttyout') Nvim note: intentionally did not include `--ttyfail` since its purpose is not clear. (And it isn't used in any Vim test files/scripts). --- Problem: When the input or output is not a tty Vim appears to hang. Solution: Add the --ttyfail argument. Also add the "ttyin" and "ttyout" features to be able to check in Vim script. https://github.com/vim/vim/commit/2cab0e191055a8145ccd46cd52869fbb9798b971 --- runtime/doc/eval.txt | 2 ++ src/nvim/eval.c | 4 ++++ src/nvim/globals.h | 27 ++++++++++++++------------- src/nvim/main.c | 6 ++++-- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 300bdd061e..271adc833d 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -8317,6 +8317,8 @@ termresponse Compiled with support for |t_RV| and |v:termresponse|. textobjects Compiled with support for |text-objects|. timers Compiled with |timer_start()| support. title Compiled with window title support |'title'|. +ttyin input is a terminal (tty) +ttyout output is a terminal (tty) unix Unix version of Vim. unnamedplus Compiled with support for "unnamedplus" in 'clipboard' user_commands User-defined commands. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c7cb51ac29..9752851d4e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10672,6 +10672,10 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) n = has_nvim_version(name + 5); } else if (STRICMP(name, "vim_starting") == 0) { n = (starting != 0); + } else if (STRICMP(name, "ttyin") == 0) { + n = stdin_isatty; + } else if (STRICMP(name, "ttyout") == 0) { + n = stdout_isatty; } else if (STRICMP(name, "multi_byte_encoding") == 0) { n = has_mbyte != 0; #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 0f3e132bc0..8f804ff888 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -564,21 +564,22 @@ EXTERN int ru_col; /* column for ruler */ EXTERN int ru_wid; /* 'rulerfmt' width of ruler when non-zero */ EXTERN int sc_col; /* column for shown command */ -/* - * When starting or exiting some things are done differently (e.g. screen - * updating). - */ +// +// When starting or exiting some things are done differently (e.g. screen +// updating). +// + +// First NO_SCREEN, then NO_BUFFERS, then 0 when startup finished. EXTERN int starting INIT(= NO_SCREEN); -/* first NO_SCREEN, then NO_BUFFERS and then - * set to 0 when starting up finished */ -EXTERN int exiting INIT(= FALSE); -/* TRUE when planning to exit Vim. Might - * still keep on running if there is a changed - * buffer. */ -// volatile because it is used in signal handler deathtrap(). +// true when planning to exit. Might keep running if there is a changed buffer. +EXTERN int exiting INIT(= false); +// is stdin a terminal? +EXTERN int stdin_isatty INIT(= true); +// is stdout a terminal? +EXTERN int stdout_isatty INIT(= true); +// true when doing full-screen output, otherwise only writing some messages. +// volatile because it is used in a signal handler. EXTERN volatile int full_screen INIT(= false); -// TRUE when doing full-screen output -// otherwise only writing some messages EXTERN int restricted INIT(= FALSE); // TRUE when started in restricted mode (-Z) diff --git a/src/nvim/main.c b/src/nvim/main.c index ea7a58bda3..93afe11f3a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1240,8 +1240,10 @@ static void init_startuptime(mparm_T *paramp) static void check_and_set_isatty(mparm_T *paramp) { - paramp->input_isatty = os_isatty(fileno(stdin)); - paramp->output_isatty = os_isatty(fileno(stdout)); + stdin_isatty + = paramp->input_isatty = os_isatty(fileno(stdin)); + stdout_isatty + = paramp->output_isatty = os_isatty(fileno(stdout)); paramp->err_isatty = os_isatty(fileno(stderr)); TIME_MSG("window checked"); } From 68bef0a57de3c376406a0391c9ccd4099f7a0328 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 31 Oct 2017 13:28:16 +0100 Subject: [PATCH 2/3] test: has("ttyin"), has("ttyout") --- test/functional/core/startup_spec.lua | 89 +++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 test/functional/core/startup_spec.lua diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua new file mode 100644 index 0000000000..08b59db627 --- /dev/null +++ b/test/functional/core/startup_spec.lua @@ -0,0 +1,89 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') + +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local funcs = helpers.funcs +local nvim_prog = helpers.nvim_prog +local nvim_set = helpers.nvim_set +local read_file = helpers.read_file +local retry = helpers.retry + +describe('startup', function() + before_each(function() + clear() + end) + after_each(function() + os.remove('Xtest_startup_ttyout') + end) + + it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function() + -- system() puts a pipe at both ends. + local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', + '--cmd', nvim_set, + '-c', [[echo has('ttyin') has('ttyout')]], + '+q' }) + eq('0 0', out) + end) + it('with --embed: has("ttyin")==0 has("ttyout")==0', function() + local screen = Screen.new(25, 3) + -- Remote UI connected by --embed. + screen:attach() + command([[echo has('ttyin') has('ttyout')]]) + screen:expect([[ + ^ | + ~ | + 0 0 | + ]]) + end) + it('in a TTY: has("ttyin")==1 has("ttyout")==1', function() + local screen = Screen.new(25, 3) + screen:attach() + -- Running in :terminal + command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]] + ..nvim_set..[[\" ]] + ..[[-c \"echo has('ttyin') has('ttyout')\""]] + ..[[, shellescape(v:progpath))]]) + screen:expect([[ + ^ | + 1 1 | + | + ]]) + end) + it('output to pipe: has("ttyin")==1 has("ttyout")==0', function() + local screen = Screen.new(25, 5) + screen:attach() + -- 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. + ..[[, shellescape(v:progpath))]]) + retry(nil, 3000, function() + screen: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 -- -"]] + ..[[, shellescape(v:progpath))]]) + retry(nil, 3000, function() + screen:sleep(1) + eq('0\n1\n', -- stdin is a pipe, stdout is a TTY + read_file('Xtest_startup_ttyout')) + end) + end) +end) + From 54cac3033f2c6e27c677681e8ca6d21e3fd9fc0a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 2 Nov 2017 11:10:25 +0100 Subject: [PATCH 3/3] test: startup_spec: cmd.exe escaping --- test/functional/core/startup_spec.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 08b59db627..ae7f949e52 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -9,6 +9,7 @@ local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set local read_file = helpers.read_file local retry = helpers.retry +local iswin = helpers.iswin describe('startup', function() before_each(function() @@ -40,6 +41,9 @@ describe('startup', function() it('in a TTY: has("ttyin")==1 has("ttyout")==1', 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 %s -u NONE -i NONE --cmd \"]] ..nvim_set..[[\" ]] @@ -54,6 +58,9 @@ describe('startup', function() 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..[[\" ]]