diff options
| -rw-r--r-- | runtime/doc/eval.txt | 2 | ||||
| -rw-r--r-- | src/nvim/eval.c | 4 | ||||
| -rw-r--r-- | src/nvim/globals.h | 27 | ||||
| -rw-r--r-- | src/nvim/main.c | 6 | ||||
| -rw-r--r-- | test/functional/core/startup_spec.lua | 96 | 
5 files changed, 120 insertions, 15 deletions
| diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 0a62b4f08b..24d704017f 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -8335,6 +8335,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");  } diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua new file mode 100644 index 0000000000..ae7f949e52 --- /dev/null +++ b/test/functional/core/startup_spec.lua @@ -0,0 +1,96 @@ +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 +local iswin = helpers.iswin + +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() +    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 \"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() +    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. +            ..[[, 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) + | 
