Merge #7679 'startup: treat stdin as text instead of commands'

This commit is contained in:
Justin M. Keyes 2018-06-10 15:10:59 +02:00 committed by GitHub
commit b8363283fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 552 additions and 567 deletions

View File

@ -1,4 +1,4 @@
.Dd January 28, 2016
.Dd December 17, 2017
.Dt NVIM 1
.Os
.Sh NAME
@ -25,7 +25,7 @@ To enter commands in
type a colon
.Pq Sq \&:
which is also used in this manual to denote commands.
For more information, consult the online help system with the
For more information, consult the online help with the
.Ic :help
command.
.Bl -tag -width Fl
@ -73,24 +73,18 @@ See
Interpret all further arguments as files.
Can be used to edit files starting with a hyphen
.Pq Sq - .
.It Fl -literal
Interpret filenames literally, that is, do not expand wildcards.
Has no effect on Unix-like systems, where the shell expands wildcards.
.It Fl e
Ex mode.
Ex mode. Reads stdin as Ex commands.
See
.Ic :help Ex-mode .
.It Fl E
Improved Ex mode.
Ex mode, improved. Reads stdin as text.
See
.Ic :help gQ .
.It Fl s
Silent mode.
Only takes effect if
.Fl e
or
.Fl E
is specified before it.
.It Fl es
Silent (batch) mode. Reads stdin as Ex commands.
.It Fl Es
Silent (batch) mode. Reads stdin as text.
.It Fl d
Diff mode.
Show the difference between two to four files, similar to
@ -99,12 +93,12 @@ See
.Ic :help diff .
.It Fl R
Read-only mode.
Sets the option 'readonly'.
Sets the 'readonly' option.
Implies
.Fl n .
Buffers can still be edited, but cannot be written to disk if already
associated with a file.
To overwrite a file, add an exclamation mark to the needed Ex command, such as
To overwrite a file, add an exclamation mark to the relevant Ex command, such as
.Ic :w! .
See
.Ic :help 'readonly' .
@ -112,37 +106,31 @@ See
Restricted mode.
Disable commands that make use of an external shell.
.It Fl m
Disable file modifications.
Unsets the option 'write'.
Resets the 'write' option, to disable file modifications.
Writing to a file is disabled, but buffers can still be modified.
.It Fl M
Disable file and buffer modifications.
Unsets the options 'write' and 'modifiable'.
Note that these options can be set to re-enable making modifications.
Resets the 'write' and 'modifiable' options, to disable file and buffer
modifications.
.It Fl b
Binary mode.
See
.Ic :help edit-binary .
.It Fl l
Lisp mode.
Sets the options 'lisp' and 'showmatch'.
Sets the 'lisp' and 'showmatch' options.
.It Fl A
Arabic mode.
Sets the option 'arabic'.
.It Fl F
Farsi mode.
Sets the options 'fkmap' and 'rightleft'.
Sets the 'arabic' option.
.It Fl H
Hebrew mode.
Sets the options 'hkmap' and 'rightleft'.
Sets the 'hkmap' and 'rightleft' options.
.It Fl V Ns Oo Ar N Oc Ns Op Ar file
Verbose mode.
Print messages about which files are being sourced and for reading and
writing a ShaDa file.
.Ar N
is the value for the 'verbose' option; defaults to
.Cm 10
if omitted.
is the 'verbose' level; defaults to
.Cm 10.
If
.Ar file
is specified, append messages to
@ -153,9 +141,9 @@ Debugging mode.
Started when executing the first command from a script.
.It Fl n
Disable the use of swap files.
Sets the option 'updatecount' to
Sets the 'updatecount' option to
.Cm 0 .
Can be useful for editing file(s) on a slow medium.
Can be useful for editing files on a slow medium.
.It Fl r Op Ar file
Recovery mode.
If
@ -176,13 +164,13 @@ Alias for
.It Fl u Ar vimrc
Use
.Ar vimrc
instead of the default of
instead of the default
.Pa ~/.config/nvim/init.vim .
If
.Ar vimrc
is
.Cm NORC ,
do not load any initialization files (excluding plugins),
do not load any initialization files (except plugins),
and do not attempt to parse environment variables.
If
.Ar vimrc
@ -194,7 +182,7 @@ See
.It Fl i Ar shada
Use
.Ar shada
instead of the default of
instead of the default
.Pa ~/.local/share/nvim/shada/main.shada .
If
.Ar shada
@ -233,7 +221,6 @@ For the first file, position the cursor on line
If
.Ar linenum
is omitted, position the cursor on the last line of the file.
Note that
.Cm +5
and
.Cm -c 5
@ -246,8 +233,7 @@ For the first file, position the cursor on the first occurrence of
.Ar pattern .
If
.Ar pattern
is omitted, the most recently used search pattern is used (if there is one).
Note that
is omitted, the most recent search pattern is used (if any).
.Cm +/foo
and
.Cm -c /foo
@ -268,10 +254,9 @@ Up to 10 instances of
or
.Cm +
can be used.
Note that
.Qq Cm +set si
.Qq Cm +foo
and
.Cm -c \(dqset si\(dq
.Cm -c \(dqfoo\(dq
are equivalent.
.It Fl -cmd Ar command
Like
@ -292,9 +277,9 @@ cannot start with a hyphen
.Pq Sq - .
If
.Ar session
is omitted, then
.Pa Session.vim ,
if found, is used.
is omitted then
.Pa Session.vim
is used, if found.
See
.Ic :help session-file .
.It Fl s Ar scriptin
@ -339,24 +324,24 @@ Print version information and exit.
.Sh ENVIRONMENT
.Bl -tag -width Fl
.It Ev VIM
Used to locate various user files, such as init.vim.
Used to locate user files, such as init.vim.
System-dependent, see :help $VIM.
.It Ev VIMRUNTIME
Used to locate runtime files, such as online documentation and
syntax highlighting definitions.
Used to locate runtime files (documentation, syntax highlighting, etc.).
.It Ev XDG_CONFIG_HOME
Path to the user-local configuration directory, see
.Sx FILES .
Defaults to
.Pa ~/.config
if not set.
.Pa ~/.config .
See :help xdg.
.It Ev XDG_DATA_HOME
Like
.Ev XDG_CONFIG_HOME ,
but used to store data not generally edited by the user,
namely swap, backup, and ShaDa files.
Defaults to
.Pa ~/.local/share
if not set.
.Pa ~/.local/share .
See :help xdg.
.It Ev VIMINIT
Ex commands to be executed at startup.
For example, the command to quit is
@ -370,9 +355,11 @@ to
See
.Ic :help VIMINIT .
.It Ev SHELL
Used to set the 'shell' option, which determines the shell used by the
.Ic :terminal
command.
Used to initialize the 'shell' option, which decides the default shell used by
features like
.Ic :terminal ,
.Ic :! , and
.Ic system() .
.El
.Sh FILES
.Bl -tag -width "~/.config/nvim/init.vim"

View File

@ -22,8 +22,7 @@ More generally, Vim is started with:
Option arguments and file name arguments can be mixed, and any number of them
can be given. However, watch out for options that take an argument.
Exactly one out of the following five items may be used to choose how to
start editing:
The following items may be used to choose how to start editing:
*-file* *---*
filename One or more file names. The first one will be the current
@ -34,7 +33,6 @@ filename One or more file names. The first one will be the current
nvim -- -filename
< All arguments after the "--" will be interpreted as file names,
no other options or "+command" argument can follow.
For behavior of quotes on MS-Windows, see |win32-quotes|.
*--*
- This argument can mean two things, depending on whether Ex
@ -104,13 +102,6 @@ argument.
(Only available when compiled with the |+startuptime|
feature).
*--literal*
--literal Take file names literally, don't expand wildcards. Not needed
for Unix, because Vim always takes file names literally (the
shell expands wildcards).
Applies to all the names, also the ones that come before this
argument.
*-+*
+[num] The cursor will be positioned on line "num" for the first
file being edited. If "num" is missing, the cursor will be

View File

@ -440,6 +440,10 @@ Other compile-time features:
Emacs tags support
X11 integration (see |x11-selection|)
Startup:
--literal (file args are always literal; to expand wildcards on Windows, use
|:n| e.g. `nvim +"n *"`)
Nvim does not have a built-in GUI and hence the following aliases have been
removed: gvim, gex, gview, rgvim, rgview

View File

@ -115,7 +115,7 @@ static void read_cb(uv_stream_t *uvstream, ssize_t cnt, const uv_buf_t *buf)
if (cnt == UV_ENOBUFS || cnt == 0) {
return;
} else if (cnt == UV_EOF && uvstream->type == UV_TTY) {
// The TTY driver might signal TTY without closing the stream
// The TTY driver might signal EOF without closing the stream
invoke_read_cb(stream, 0, true);
} else {
DLOG("Closing Stream (%p): %s (%s)", stream,

View File

@ -290,13 +290,11 @@ EXTERN int vgetc_busy INIT(= 0); /* when inside vgetc() then > 0 */
EXTERN int didset_vim INIT(= FALSE); /* did set $VIM ourselves */
EXTERN int didset_vimruntime INIT(= FALSE); /* idem for $VIMRUNTIME */
/*
* Lines left before a "more" message. Ex mode needs to be able to reset this
* after you type something.
*/
EXTERN int lines_left INIT(= -1); /* lines left for listing */
EXTERN int msg_no_more INIT(= FALSE); /* don't use more prompt, truncate
messages */
/// Lines left before a "more" message. Ex mode needs to be able to reset this
/// after you type something.
EXTERN int lines_left INIT(= -1); // lines left for listing
EXTERN int msg_no_more INIT(= false); // don't use more prompt, truncate
// messages
EXTERN char_u *sourcing_name INIT( = NULL); /* name of error message source */
EXTERN linenr_T sourcing_lnum INIT(= 0); /* line number of the source file */
@ -307,88 +305,71 @@ EXTERN int debug_did_msg INIT(= false); // did "debug mode" message
EXTERN int debug_tick INIT(= 0); // breakpoint change count
EXTERN int debug_backtrace_level INIT(= 0); // breakpoint backtrace level
/* Values for "do_profiling". */
#define PROF_NONE 0 /* profiling not started */
#define PROF_YES 1 /* profiling busy */
#define PROF_PAUSED 2 /* profiling paused */
EXTERN int do_profiling INIT(= PROF_NONE); /* PROF_ values */
// Values for "do_profiling".
#define PROF_NONE 0 ///< profiling not started
#define PROF_YES 1 ///< profiling busy
#define PROF_PAUSED 2 ///< profiling paused
EXTERN int do_profiling INIT(= PROF_NONE); ///< PROF_ values
/*
* The exception currently being thrown. Used to pass an exception to
* a different cstack. Also used for discarding an exception before it is
* caught or made pending.
*/
/// Exception currently being thrown. Used to pass an exception to a different
/// cstack. Also used for discarding an exception before it is caught or made
/// pending.
EXTERN except_T *current_exception;
/*
* need_rethrow: set to TRUE when a throw that cannot be handled in do_cmdline()
* must be propagated to the cstack of the previously called do_cmdline().
*/
EXTERN int need_rethrow INIT(= FALSE);
/// Set when a throw that cannot be handled in do_cmdline() must be propagated
/// to the cstack of the previously called do_cmdline().
EXTERN int need_rethrow INIT(= false);
/*
* check_cstack: set to TRUE when a ":finish" or ":return" that cannot be
* handled in do_cmdline() must be propagated to the cstack of the previously
* called do_cmdline().
*/
EXTERN int check_cstack INIT(= FALSE);
/// Set when a ":finish" or ":return" that cannot be handled in do_cmdline()
/// must be propagated to the cstack of the previously called do_cmdline().
EXTERN int check_cstack INIT(= false);
/*
* Number of nested try conditionals (across function calls and ":source"
* commands).
*/
/// Number of nested try conditionals (across function calls and ":source"
/// commands).
EXTERN int trylevel INIT(= 0);
/*
* When "force_abort" is TRUE, always skip commands after an error message,
* even after the outermost ":endif", ":endwhile" or ":endfor" or for a
* function without the "abort" flag. It is set to TRUE when "trylevel" is
* non-zero (and ":silent!" was not used) or an exception is being thrown at
* the time an error is detected. It is set to FALSE when "trylevel" gets
* zero again and there was no error or interrupt or throw.
*/
EXTERN int force_abort INIT(= FALSE);
/// When "force_abort" is TRUE, always skip commands after an error message,
/// even after the outermost ":endif", ":endwhile" or ":endfor" or for a
/// function without the "abort" flag. It is set to TRUE when "trylevel" is
/// non-zero (and ":silent!" was not used) or an exception is being thrown at
/// the time an error is detected. It is set to FALSE when "trylevel" gets
/// zero again and there was no error or interrupt or throw.
EXTERN int force_abort INIT(= false);
/*
* "msg_list" points to a variable in the stack of do_cmdline() which keeps
* the list of arguments of several emsg() calls, one of which is to be
* converted to an error exception immediately after the failing command
* returns. The message to be used for the exception value is pointed to by
* the "throw_msg" field of the first element in the list. It is usually the
* same as the "msg" field of that element, but can be identical to the "msg"
* field of a later list element, when the "emsg_severe" flag was set when the
* emsg() call was made.
*/
/// "msg_list" points to a variable in the stack of do_cmdline() which keeps
/// the list of arguments of several emsg() calls, one of which is to be
/// converted to an error exception immediately after the failing command
/// returns. The message to be used for the exception value is pointed to by
/// the "throw_msg" field of the first element in the list. It is usually the
/// same as the "msg" field of that element, but can be identical to the "msg"
/// field of a later list element, when the "emsg_severe" flag was set when the
/// emsg() call was made.
EXTERN struct msglist **msg_list INIT(= NULL);
/*
* suppress_errthrow: When TRUE, don't convert an error to an exception. Used
* when displaying the interrupt message or reporting an exception that is still
* uncaught at the top level (which has already been discarded then). Also used
* for the error message when no exception can be thrown.
*/
EXTERN int suppress_errthrow INIT(= FALSE);
/// When set, don't convert an error to an exception. Used when displaying the
/// interrupt message or reporting an exception that is still uncaught at the
/// top level (which has already been discarded then). Also used for the error
/// message when no exception can be thrown.
EXTERN int suppress_errthrow INIT(= false);
/*
* The stack of all caught and not finished exceptions. The exception on the
* top of the stack is the one got by evaluation of v:exception. The complete
* stack of all caught and pending exceptions is embedded in the various
* cstacks; the pending exceptions, however, are not on the caught stack.
*/
/// The stack of all caught and not finished exceptions. The exception on the
/// top of the stack is the one got by evaluation of v:exception. The complete
/// stack of all caught and pending exceptions is embedded in the various
/// cstacks; the pending exceptions, however, are not on the caught stack.
EXTERN except_T *caught_stack INIT(= NULL);
/*
* Garbage collection can only take place when we are sure there are no Lists
* or Dictionaries being used internally. This is flagged with
* "may_garbage_collect" when we are at the toplevel.
* "want_garbage_collect" is set by the garbagecollect() function, which means
* we do garbage collection before waiting for a char at the toplevel.
* "garbage_collect_at_exit" indicates garbagecollect(1) was called.
*/
EXTERN int may_garbage_collect INIT(= FALSE);
EXTERN int want_garbage_collect INIT(= FALSE);
EXTERN int garbage_collect_at_exit INIT(= FALSE);
///
/// Garbage collection can only take place when we are sure there are no Lists
/// or Dictionaries being used internally. This is flagged with
/// "may_garbage_collect" when we are at the toplevel.
/// "want_garbage_collect" is set by the garbagecollect() function, which means
/// we do garbage collection before waiting for a char at the toplevel.
/// "garbage_collect_at_exit" indicates garbagecollect(1) was called.
///
EXTERN int may_garbage_collect INIT(= false);
EXTERN int want_garbage_collect INIT(= false);
EXTERN int garbage_collect_at_exit INIT(= false);
// Special values for current_SID.
#define SID_MODELINE -1 // when using a modeline
@ -574,57 +555,46 @@ EXTERN int stdout_isatty INIT(= true);
// volatile because it is used in a signal handler.
EXTERN volatile int full_screen INIT(= false);
EXTERN int restricted INIT(= FALSE);
// TRUE when started in restricted mode (-Z)
EXTERN int secure INIT(= FALSE);
/* non-zero when only "safe" commands are
* allowed, e.g. when sourcing .exrc or .vimrc
* in current directory */
// When started in restricted mode (-Z).
EXTERN int restricted INIT(= false);
/// Non-zero when only "safe" commands are allowed, e.g. when sourcing .exrc or
/// .vimrc in current directory.
EXTERN int secure INIT(= false);
/// Non-zero when changing text and jumping to another window/buffer is not
/// allowed.
EXTERN int textlock INIT(= 0);
/* non-zero when changing text and jumping to
* another window or buffer is not allowed */
/// Non-zero when the current buffer can't be changed. Used for FileChangedRO.
EXTERN int curbuf_lock INIT(= 0);
/* non-zero when the current buffer can't be
* changed. Used for FileChangedRO. */
/// Non-zero when no buffer name can be changed, no buffer can be deleted and
/// current directory can't be changed. Used for SwapExists et al.
EXTERN int allbuf_lock INIT(= 0);
/* non-zero when no buffer name can be
* changed, no buffer can be deleted and
* current directory can't be changed.
* Used for SwapExists et al. */
/// Non-zero when evaluating an expression in a "sandbox". Several things are
/// not allowed then.
EXTERN int sandbox INIT(= 0);
/* Non-zero when evaluating an expression in a
* "sandbox". Several things are not allowed
* then. */
EXTERN int silent_mode INIT(= FALSE);
/* set to TRUE when "-s" commandline argument
* used for ex */
/// Batch-mode: "-es" or "-Es" commandline argument was given.
EXTERN int silent_mode INIT(= false);
// Set to true when sourcing of startup scripts (init.vim) is done.
// Used for options that cannot be changed after startup scripts.
EXTERN bool did_source_startup_scripts INIT(= false);
EXTERN pos_T VIsual; /* start position of active Visual selection */
EXTERN int VIsual_active INIT(= FALSE);
/* whether Visual mode is active */
EXTERN int VIsual_select INIT(= FALSE);
/* whether Select mode is active */
/// Start position of active Visual selection.
EXTERN pos_T VIsual;
/// Whether Visual mode is active.
EXTERN int VIsual_active INIT(= false);
/// Whether Select mode is active.
EXTERN int VIsual_select INIT(= false);
/// Whether to restart the selection after a Select-mode mapping or menu.
EXTERN int VIsual_reselect;
/* whether to restart the selection after a
* Select mode mapping or menu */
/// Type of Visual mode.
EXTERN int VIsual_mode INIT(= 'v');
/* type of Visual mode */
/// TRUE when redoing Visual.
EXTERN int redo_VIsual_busy INIT(= false);
EXTERN int redo_VIsual_busy INIT(= FALSE);
/* TRUE when redoing Visual */
/*
* When pasting text with the middle mouse button in visual mode with
* restart_edit set, remember where it started so we can set Insstart.
*/
/// When pasting text with the middle mouse button in visual mode with
/// restart_edit set, remember where it started so we can set Insstart.
EXTERN pos_T where_paste_started;
/*
@ -732,25 +702,23 @@ EXTERN int (*iconvctl)(iconv_t cd, int request, void *argument);
EXTERN int* (*iconv_errno)(void);
# endif
/*
* "State" is the main state of Vim.
* There are other variables that modify the state:
* "Visual_mode" When State is NORMAL or INSERT.
* "finish_op" When State is NORMAL, after typing the operator and before
* typing the motion command.
*/
EXTERN int State INIT(= NORMAL); /* This is the current state of the
* command interpreter. */
/// "State" is the main state of Vim.
/// There are other variables that modify the state:
/// Visual_mode: When State is NORMAL or INSERT.
/// finish_op : When State is NORMAL, after typing the operator and
/// before typing the motion command.
EXTERN int State INIT(= NORMAL); // This is the current state of the
// command interpreter.
EXTERN bool finish_op INIT(= false); // true while an operator is pending
EXTERN long opcount INIT(= 0); // count for pending operator
// Ex Mode (Q) state
EXTERN int exmode_active INIT(= 0); // zero, EXMODE_NORMAL or EXMODE_VIM
EXTERN int ex_no_reprint INIT(= false); // no need to print after z or p
EXTERN int exmode_active INIT(= 0); // Zero, EXMODE_NORMAL or EXMODE_VIM.
EXTERN int ex_no_reprint INIT(=false); // No need to print after z or p.
EXTERN int Recording INIT(= FALSE); /* TRUE when recording into a reg. */
EXTERN int Exec_reg INIT(= FALSE); /* TRUE when executing a register */
EXTERN int Recording INIT(= false); // TRUE when recording into a reg.
EXTERN int Exec_reg INIT(= false); // TRUE when executing a register.
EXTERN int no_mapping INIT(= false); // currently no mapping allowed
EXTERN int no_zero_mapping INIT(= 0); // mapping zero not allowed
@ -1164,10 +1132,9 @@ EXTERN FILE *time_fd INIT(= NULL); /* where to write startup timing */
EXTERN int ignored;
EXTERN char *ignoredp;
// If a msgpack-rpc channel should be started over stdin/stdout
// Start a msgpack-rpc channel over stdin/stdout.
EXTERN bool embedded_mode INIT(= false);
// Dont try to start an user interface
// or read/write to stdio (unless embedding)
// Do not start a UI nor read/write to stdio (unless embedding).
EXTERN bool headless_mode INIT(= false);
/// Used to track the status of external functions.

File diff suppressed because it is too large Load Diff

View File

@ -2076,8 +2076,9 @@ static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr)
}
}
// Returns TRUE when messages should be printed to stdout/stderr, which
// happens when no UIs are attached and nvim is not being embedded
// Returns TRUE when messages should be printed to stdout/stderr:
// - "batch mode" ("silent mode", -es/-Es)
// - no UI and not embedded
int msg_use_printf(void)
{
return !embedded_mode && !ui_active();

View File

@ -34,7 +34,7 @@ typedef enum {
kInputEof
} InbufPollResult;
static Stream read_stream = {.closed = true};
static Stream read_stream = { .closed = true }; // Input before UI starts.
static RBuffer *input_buffer = NULL;
static bool input_eof = false;
static int global_fd = -1;
@ -50,7 +50,7 @@ void input_init(void)
input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN);
}
/// Gets the file from which input was gathered at startup.
/// Global TTY (or pipe for "-es") input stream, before UI starts.
int input_global_fd(void)
{
return global_fd;
@ -64,7 +64,7 @@ void input_start(int fd)
global_fd = fd;
rstream_init_fd(&main_loop, &read_stream, fd, READ_BUFFER_SIZE);
rstream_start(&read_stream, read_cb, NULL);
rstream_start(&read_stream, input_read_cb, NULL);
}
void input_stop(void)
@ -108,6 +108,11 @@ int os_inchar(uint8_t *buf, int maxlen, int ms, int tb_change_cnt)
}
} else {
if ((result = inbuf_poll((int)p_ut)) == kInputNone) {
if (read_stream.closed && silent_mode) {
// Drained eventloop & initial input; exit silent/batch-mode (-es/-Es).
read_error_exit();
}
if (trigger_cursorhold() && !typebuf_changed(tb_change_cnt)) {
create_cursorhold_event();
} else {
@ -376,11 +381,11 @@ static InbufPollResult inbuf_poll(int ms)
return input_eof ? kInputEof : kInputNone;
}
static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
bool at_eof)
static void input_read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
bool at_eof)
{
if (at_eof) {
input_eof = true;
input_done();
}
assert(rbuffer_space(input_buffer) >= rbuffer_size(buf));
@ -438,8 +443,9 @@ static bool input_ready(void)
// Exit because of an input read error.
static void read_error_exit(void)
{
if (silent_mode) /* Normal way to exit for "ex -s" */
if (silent_mode) { // Normal way to exit for "nvim -es".
getout(0);
}
STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
preserve_exit();
}

View File

@ -4,16 +4,19 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
local feed = helpers.feed
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 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 +49,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,25 +59,40 @@ 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)
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()
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=\"]])
@ -82,15 +100,63 @@ describe('startup', function()
-- 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 \"echo has('ttyin') has('ttyout')\""]]
..[[, 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)
screen:expect([[
^foo |
0 1 |
|
]])
end)
it('input from pipe + file args #7679', function()
eq('ohyeah\r\n0 0 bufs=3',
funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '--headless',
'+.print',
"+echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')",
'+qall!',
'-',
'test/functional/fixtures/tty-test.c',
'test/functional/fixtures/shell-test.c',
},
{ 'ohyeah', '' }))
end)
it('-e/-E interactive #7679', function()
clear('-E')
local screen = Screen.new(25, 3)
screen:attach()
feed("put ='from -E'<CR>")
screen:expect([[
|
from -E |
:^ |
]])
end)
it('stdin with -es/-Es #7679', function()
local input = { 'append', 'line1', 'line2', '.', '%print', '' }
local inputstr = table.concat(input, '\n')
--
-- -Es: read stdin as text
--
eq('partylikeits1999\n',
funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-Es', '+.print', 'test/functional/fixtures/tty-test.c' },
{ 'partylikeits1999', '' }))
eq(inputstr,
funcs.system({nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' },
input))
--
-- -es: read stdin as ex-commands
--
eq(' encoding=utf-8\n',
funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-es', 'test/functional/fixtures/tty-test.c' },
{ 'set encoding', '' }))
eq('line1\nline2\n',
funcs.system({nvim_prog, '-i', 'NONE', '-es', '-' },
input))
end)
end)

View File

@ -316,6 +316,14 @@ local function retry(max, max_ms, fn)
end
end
-- Starts a new global Nvim session.
-- Parameters are interpreted as startup args, OR a map with these keys:
-- args: Merged with the default `nvim_argv` set.
-- env : Defines the environment of the new session.
--
-- Example:
-- clear('-e')
-- clear({args={'-e'}, env={TERM=term}})
local function clear(...)
local args = {unpack(nvim_argv)}
local new_args