From a1f562b044fb85d5bed589c5312f30e99d02bbeb Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Dec 2017 01:31:34 +0100 Subject: doc/man: brevity, clarity --- man/nvim.1 | 88 +++++++++++++++++++++++++++----------------------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/man/nvim.1 b/man/nvim.1 index 12f342247e..7872f932d5 100644 --- a/man/nvim.1 +++ b/man/nvim.1 @@ -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 @@ -81,16 +81,11 @@ Ex mode. See .Ic :help Ex-mode . .It Fl E -Improved Ex mode. +Ex mode, improved. 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 +Ex mode, silent. .It Fl d Diff mode. Show the difference between two to four files, similar to @@ -99,12 +94,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 +107,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 +142,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 +165,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 +183,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 +222,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 +234,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 +255,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 +278,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 +325,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 +356,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" -- cgit From 488f6ecddad186f4859196b64b5c494e07715ca7 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Dec 2017 04:44:46 +0100 Subject: lint --- src/nvim/main.c | 88 +++++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 8b0d3bb2cc..d74bc1a407 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -421,20 +421,22 @@ int main(int argc, char **argv) * Clear screen now, so file message will not be cleared. */ starting = NO_BUFFERS; - no_wait_return = FALSE; - if (!exmode_active) - msg_scroll = FALSE; + no_wait_return = false; + if (!exmode_active) { + msg_scroll = false; + } - /* - * If "-" argument given: Read file from stdin. - * Do this before starting Raw mode, because it may change things that the - * writing end of the pipe doesn't like, e.g., in case stdin and stderr - * are the same terminal: "cat | vim -". - * Using autocommands here may cause trouble... - */ - if (params.edit_type == EDIT_STDIN && !recoverymode) + // Read file from stdin: + // - If "-" argument was given as a file arg. + // - If stdin is a pipe and "-es"/"-Es"/"-s -" were not given. + // + // Do this before starting Raw mode, because it may change things that the + // writing end of the pipe doesn't like, e.g., in case stdin and stderr + // are the same terminal: "cat | vim -". + // Using autocommands here may cause trouble... + if (params.edit_type == EDIT_STDIN && !recoverymode) { read_stdin(); - + } if (reading_input && (need_wait_return || msg_didany)) { // Since at this point there's no UI instance running yet, error messages @@ -691,9 +693,7 @@ static int get_number_arg(const char *p, int *idx, int def) } #if defined(HAVE_LOCALE_H) -/* - * Setup to use the current locale (for ctype() and many other things). - */ +/// Setup to use the current locale (for ctype() and many other things). static void init_locale(void) { setlocale(LC_ALL, ""); @@ -724,7 +724,6 @@ static void init_locale(void) } #endif - /// Scan the command line arguments. static void command_line_scan(mparm_T *parmp) { @@ -1156,27 +1155,23 @@ scripterror: } } - } - /* - * File name argument. - */ - else { - argv_idx = -1; /* skip to next argument */ + } else { // File name argument. + argv_idx = -1; // skip to next argument - /* Check for only one type of editing. */ - if (parmp->edit_type != EDIT_NONE && parmp->edit_type != EDIT_FILE) + // Check for only one type of editing. + if (parmp->edit_type != EDIT_NONE && parmp->edit_type != EDIT_FILE) { mainerr(err_too_many_args, argv[0]); + } parmp->edit_type = EDIT_FILE; - /* Add the file to the global argument list. */ + // Add the file to the global argument list. ga_grow(&global_alist.al_ga, 1); p = vim_strsave((char_u *)argv[0]); if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 && !os_isdir(alist_name(&GARGLIST[0]))) { - char_u *r; - - r = (char_u *)concat_fnames((char *)p, (char *)path_tail(alist_name(&GARGLIST[0])), TRUE); + char_u *r = (char_u *)concat_fnames((char *)p, + (char *)path_tail(alist_name(&GARGLIST[0])), true); xfree(p); p = r; } @@ -1188,28 +1183,23 @@ scripterror: alist_add(&global_alist, p, #if !defined(UNIX) - parmp->literal ? 2 : 0 /* add buffer nr after exp. */ + parmp->literal ? 2 : 0 // add buffer nr after exp. #else - 2 /* add buffer number now and use curbuf */ + 2 // add buffer number now and use curbuf #endif - ); - + ); } - /* - * If there are no more letters after the current "-", go to next - * argument. argv_idx is set to -1 when the current argument is to be - * skipped. - */ + // If there are no more letters after the current "-", go to next argument. + // argv_idx is set to -1 when the current argument is to be skipped. if (argv_idx <= 0 || argv[0][argv_idx] == NUL) { - --argc; - ++argv; + argc--; + argv++; argv_idx = 1; } } - /* If there is a "+123" or "-c" command, set v:swapcommand to the first - * one. */ + // If there is a "+123" or "-c" command, set v:swapcommand to the first one. if (parmp->n_commands > 0) { const size_t swcmd_len = STRLEN(parmp->commands[0]) + 3; char *const swcmd = xmalloc(swcmd_len); @@ -1441,16 +1431,14 @@ static void check_tty(mparm_T *parmp) */ static void read_stdin(void) { - int i; - - /* When getting the ATTENTION prompt here, use a dialog */ + // When getting the ATTENTION prompt here, use a dialog. swap_exists_action = SEA_DIALOG; - no_wait_return = TRUE; - i = msg_didany; - set_buflisted(TRUE); - (void)open_buffer(TRUE, NULL, 0); /* create memfile and read file */ - no_wait_return = FALSE; - msg_didany = i; + no_wait_return = true; + int save_msg_didany = msg_didany; + set_buflisted(true); + (void)open_buffer(true, NULL, 0); // create memfile and read file + no_wait_return = false; + msg_didany = save_msg_didany; TIME_MSG("reading stdin"); check_swap_exists_action(); } -- cgit From fad748dfface98fa035747b7d2d4402228bae087 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Dec 2017 02:44:22 +0100 Subject: main.c: remove check_tty(), delayed warning This code was essentially dead because this condition: (!parmp->err_isatty && (!parmp->output_isatty || !parmp->input_isatty)) is almost never true. ref #7659 --- src/nvim/main.c | 45 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index d74bc1a407..1616ba05f8 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -280,7 +280,12 @@ int main(int argc, char **argv) setbuf(stdout, NULL); full_screen = true; - check_tty(¶ms); + + // 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. @@ -1392,43 +1397,7 @@ static void handle_tag(char_u *tagname) } } -// Print a warning if stdout is not a terminal. -// When starting in Ex mode and commands come from a file, set Silent mode. -static void check_tty(mparm_T *parmp) -{ - if (headless_mode) { - return; - } - - // is active input a terminal? - if (exmode_active) { - if (!parmp->input_isatty) { - silent_mode = true; - } - } else if (parmp->want_full_screen && (!parmp->err_isatty - && (!parmp->output_isatty || !parmp->input_isatty))) { - - if (!parmp->output_isatty) { - mch_errmsg(_("Vim: Warning: Output is not to a terminal\n")); - } - - if (!parmp->input_isatty) { - mch_errmsg(_("Vim: Warning: Input is not from a terminal\n")); - } - - ui_flush(); - - if (scriptin[0] == NULL) { - os_delay(2000L, true); - } - - TIME_MSG("Warning delay"); - } -} - -/* - * Read text from stdin. - */ +/// Read text from stdin. static void read_stdin(void) { // When getting the ATTENTION prompt here, use a dialog. -- cgit From 51e817dc1be46947073529fa97bb07a6a8078dd4 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 3 Dec 2017 03:38:58 +0100 Subject: 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 --- src/nvim/main.c | 26 +++++++++----- 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 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
Start RPC server at this address\n")); + mch_msg(_(" --listen
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) -- cgit From 905d4d78fc4a702613b694d4ece984b69f5f2481 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 23 May 2018 10:54:09 +0200 Subject: startup: stdin-text with file args --- src/nvim/main.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 127f14de2d..268297aa7d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -723,6 +723,17 @@ static void init_locale(void) } #endif +/// Decides whether text (as opposed to commands) will be read from stdin. +/// @see EDIT_STDIN +static bool edit_stdin(mparm_T *parmp) +{ + return !headless_mode + && !embedded_mode + && !exmode_active // `-es` was not given. + && !parmp->input_isatty + && scriptin[0] == NULL; // `-s -` was not given. +} + /// Scan the command line arguments. static void command_line_scan(mparm_T *parmp) { @@ -1180,13 +1191,13 @@ scripterror: path_fix_case(p); #endif - alist_add(&global_alist, p, + int alist_fnum_flag = edit_stdin(parmp) + ? 1 // add buffer nr after exp. + : 2; // add buffer number now and use curbuf #if !defined(UNIX) - parmp->literal ? 2 : 0 // add buffer nr after exp. -#else - 2 // add buffer number now and use curbuf + alist_fnum_flag = parmp->literal ? alist_fnum_flag : 0; #endif - ); + alist_add(&global_alist, p, alist_fnum_flag); } // If there are no more letters after the current "-", go to next argument. @@ -1208,17 +1219,8 @@ scripterror: } // 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"); - } + if (edit_stdin(parmp)) { + parmp->edit_type = EDIT_STDIN; } TIME_MSG("parsing arguments"); -- cgit From 4b70ebe0130d746a471cd2772483979c68ee6744 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 23 May 2018 02:28:31 +0200 Subject: startup: stdin-text with -E, -Es (improved Ex-mode) Special-case for -E/-Es (as opposed to -e/-es). -es/-Es is the only mode that really allows N/Vim to work as a batch script engine. Adding a new flag (say `-x`) would involve a lot of churn: -es/-Es is implemented by checking `exmode_active` in numerous places. This commit does not change -es because some scripts use it. But scripts are unlikely to use -Es because it is not functionally different from -es. Also, both -es and -Es were broken in Nvim for years and no one mentioned it... --- src/nvim/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 268297aa7d..19e96c4b6a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -729,7 +729,7 @@ static bool edit_stdin(mparm_T *parmp) { return !headless_mode && !embedded_mode - && !exmode_active // `-es` was not given. + && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es. && !parmp->input_isatty && scriptin[0] == NULL; // `-s -` was not given. } -- cgit From d00ef758c3a644759064565cdc7fc219ece0df3a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 24 May 2018 11:51:35 +0200 Subject: lint --- src/nvim/event/rstream.c | 2 +- src/nvim/globals.h | 231 +++++++++++++--------------- src/nvim/main.c | 387 ++++++++++++++++++++++++----------------------- src/nvim/message.c | 5 +- src/nvim/os/input.c | 5 +- 5 files changed, 308 insertions(+), 322 deletions(-) diff --git a/src/nvim/event/rstream.c b/src/nvim/event/rstream.c index 2fbe7f6773..6812b342bf 100644 --- a/src/nvim/event/rstream.c +++ b/src/nvim/event/rstream.c @@ -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, diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 2860817f79..eefe7b4bf5 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -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); - -/* - * "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. - */ +/// 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. 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,50 @@ 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. +/// 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 */ - -EXTERN int redo_VIsual_busy INIT(= FALSE); -/* TRUE when redoing Visual */ +/// TRUE when redoing Visual. +EXTERN int redo_VIsual_busy INIT(= false); -/* - * 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 +706,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 +1136,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. diff --git a/src/nvim/main.c b/src/nvim/main.c index 19e96c4b6a..c2cd87bb39 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -281,14 +281,13 @@ int main(int argc, char **argv) full_screen = true; - /* - * Set the default values for the options that use Rows and Columns. - */ + // Set the default values for the options that use Rows and Columns. win_init_size(); // Set the 'diff' option now, so that it can be checked for in a vimrc // file. There is no buffer yet though. - if (params.diff_mode) - diff_win_options(firstwin, FALSE); + if (params.diff_mode) { + diff_win_options(firstwin, false); + } assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX); cmdline_row = (int)(Rows - p_ch); @@ -297,13 +296,13 @@ int main(int argc, char **argv) set_init_2(headless_mode); TIME_MSG("inits 2"); - msg_scroll = TRUE; - no_wait_return = TRUE; + msg_scroll = true; + no_wait_return = true; - init_highlight(TRUE, FALSE); /* set the default highlight groups */ + init_highlight(true, false); // Default highlight groups. TIME_MSG("init highlight"); - /* Set the break level after the terminal is initialized. */ + // Set the break level after the terminal is initialized. debug_break_level = params.use_debug_break_level; bool reading_input = !headless_mode @@ -340,18 +339,18 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. - if (params.use_vimrc != NULL && strcmp(params.use_vimrc, "NONE") == 0) { + if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { p_lpl = false; } - /* Execute --cmd arguments. */ + // Execute --cmd arguments. exe_pre_commands(¶ms); - /* Source startup scripts. */ + // Source startup scripts. source_startup_scripts(¶ms); // If using the runtime (-u is not NONE), enable syntax & filetype plugins. - if (params.use_vimrc == NULL || strcmp(params.use_vimrc, "NONE") != 0) { + if (params.use_vimrc == NULL || !strequal(params.use_vimrc, "NONE")) { // Does ":filetype plugin indent on". filetype_maybe_enable(); // Sources syntax/syntax.vim, which calls `:filetype on`. @@ -425,9 +424,9 @@ int main(int argc, char **argv) msg_scroll = false; } - // Read file from stdin: - // - If "-" argument was given as a file arg. - // - If stdin is a pipe and "-es"/"-Es"/"-s -" were not given. + // Read file (text, not commands) from stdin if: + // - stdin is not a tty + // - and -e/-es was not given // // Do this before starting Raw mode, because it may change things that the // writing end of the pipe doesn't like, e.g., in case stdin and stderr @@ -438,16 +437,15 @@ int main(int argc, char **argv) } if (reading_input && (need_wait_return || msg_didany)) { - // Since at this point there's no UI instance running yet, error messages - // would have been printed to stdout. Before starting (which can result in - // a alternate screen buffer being shown) we need confirmation that the - // user has seen the messages and that is done with a call to wait_return. + // Because there's no UI yet, error messages would have been printed to + // stdout. Before starting we need confirmation that the user has seen the + // messages and that is done with a call to wait_return. TIME_MSG("waiting for return"); - wait_return(TRUE); + wait_return(true); } if (!headless_mode) { - // Stop reading from input stream, the UI layer will take over now. + // Stop reading from input stream. UI (if any) will take over. input_stop(); ui_builtin_start(); } @@ -455,15 +453,14 @@ int main(int argc, char **argv) setmouse(); // may start using the mouse ui_reset_scroll_region(); // In case Rows changed - // Don't clear the screen when starting in Ex mode, unless using the GUI. if (exmode_active) - must_redraw = CLEAR; + must_redraw = CLEAR; // Don't clear the screen when starting in Ex mode. else { - screenclear(); /* clear screen */ + screenclear(); // clear screen TIME_MSG("clearing screen"); } - no_wait_return = TRUE; + no_wait_return = true; /* * Create the requested number of windows and edit buffers in them. @@ -738,56 +735,54 @@ static bool edit_stdin(mparm_T *parmp) static void command_line_scan(mparm_T *parmp) { int argc = parmp->argc; - char **argv = parmp->argv; - int argv_idx; /* index in argv[n][] */ - int had_minmin = FALSE; /* found "--" argument */ - int want_argument; /* option argument with argument */ + char **argv = parmp->argv; + int argv_idx; // index in argv[n][] + int had_minmin = false; // found "--" argument + int want_argument; // option argument with argument int c; - char_u *p = NULL; + char_u *p = NULL; long n; - --argc; - ++argv; - argv_idx = 1; /* active option letter is argv[0][argv_idx] */ + argc--; + argv++; + argv_idx = 1; // active option letter is argv[0][argv_idx] while (argc > 0) { - /* - * "+" or "+{number}" or "+/{pat}" or "+{command}" argument. - */ + // "+" or "+{number}" or "+/{pat}" or "+{command}" argument. if (argv[0][0] == '+' && !had_minmin) { - if (parmp->n_commands >= MAX_ARG_CMDS) + if (parmp->n_commands >= MAX_ARG_CMDS) { mainerr(err_extra_cmd, NULL); - argv_idx = -1; /* skip to next argument */ - if (argv[0][1] == NUL) + } + argv_idx = -1; // skip to next argument + if (argv[0][1] == NUL) { parmp->commands[parmp->n_commands++] = "$"; - else + } else { parmp->commands[parmp->n_commands++] = &(argv[0][1]); - } - /* - * Optional argument. - */ - else if (argv[0][0] == '-' && !had_minmin) { - want_argument = FALSE; + } + + // Optional argument. + } else if (argv[0][0] == '-' && !had_minmin) { + want_argument = false; c = argv[0][argv_idx++]; switch (c) { - case NUL: /* "vim -" read from stdin */ + case NUL: { // "nvim -" read from stdin if (exmode_active) { - // "ex -" silent mode - silent_mode = TRUE; + // "nvim -e -" silent mode + silent_mode = true; } else { if (parmp->edit_type != EDIT_NONE) { mainerr(err_too_many_args, argv[0]); } parmp->edit_type = EDIT_STDIN; } - argv_idx = -1; /* skip to next argument */ + argv_idx = -1; // skip to next argument break; - - case '-': /* "--" don't take any more option arguments */ - /* "--help" give help message */ - /* "--version" give version message */ - /* "--literal" take files literally */ - /* "--noplugin[s]" skip plugins */ - /* "--cmd " execute cmd before vimrc */ + } + case '-': { // "--" don't take any more option arguments + // "--help" give help message + // "--version" give version message + // "--literal" take files literally + // "--noplugin[s]" skip plugins + // "--cmd " execute cmd before vimrc if (STRICMP(argv[0] + argv_idx, "help") == 0) { usage(); mch_exit(0); @@ -831,25 +826,26 @@ static void command_line_scan(mparm_T *parmp) argv_idx += 6; } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) { #if !defined(UNIX) - parmp->literal = TRUE; + parmp->literal = true; #endif - } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) - p_lpl = FALSE; - else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) { - want_argument = TRUE; + } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) { + p_lpl = false; + } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) { + want_argument = true; argv_idx += 3; } else if (STRNICMP(argv[0] + argv_idx, "startuptime", 11) == 0) { - want_argument = TRUE; + want_argument = true; argv_idx += 11; } else { if (argv[0][argv_idx]) mainerr(err_opt_unknown, argv[0]); - had_minmin = TRUE; + had_minmin = true; + } + if (!want_argument) { + argv_idx = -1; // skip to next argument } - if (!want_argument) - argv_idx = -1; /* skip to next argument */ break; - + } case 'A': { // "-A" start in Arabic mode. set_option_value("arabic", 1L, NULL, 0); break; @@ -863,168 +859,176 @@ static void command_line_scan(mparm_T *parmp) break; } - case 'e': /* "-e" Ex mode */ + case 'D': { // "-D" Debugging + parmp->use_debug_break_level = 9999; + break; + } + case 'd': { // "-d" 'diff' + parmp->diff_mode = true; + break; + } + case 'e': { // "-e" Ex mode exmode_active = EXMODE_NORMAL; break; - - case 'E': /* "-E" Improved Ex mode */ + } + case 'E': { // "-E" Improved Ex mode exmode_active = EXMODE_VIM; break; - - case 'f': /* "-f" GUI: run in foreground. */ + } + case 'f': { // "-f" GUI: run in foreground. break; - + } case 'F': { // "-F" start in Farsi mode: rl + fkmap set. p_fkmap = true; set_option_value("rl", 1L, NULL, 0); break; } - - case 'h': /* "-h" give help message */ + case 'h': { // "-h" give help message usage(); mch_exit(0); - + } case 'H': { // "-H" start in Hebrew mode: rl + hkmap set. p_hkmap = true; set_option_value("rl", 1L, NULL, 0); break; } - case 'l': { // "-l" lisp mode, 'lisp' and 'showmatch' on. set_option_value("lisp", 1L, NULL, 0); p_sm = true; break; } - - case 'M': /* "-M" no changes or writing of files */ + case 'M': { // "-M" no changes or writing of files reset_modifiable(); - /* FALLTHROUGH */ - - case 'm': /* "-m" no writing of files */ - p_write = FALSE; + // FALLTHROUGH + } + case 'm': { // "-m" no writing of files + p_write = false; break; + } - case 'N': // "-N" Nocompatible - case 'X': // "-X" Do not connect to X server + case 'N': // "-N" Nocompatible + case 'X': // "-X" Do not connect to X server // No-op break; - case 'n': /* "-n" no swap file */ - parmp->no_swap_file = TRUE; + case 'n': { // "-n" no swap file + parmp->no_swap_file = true; break; - - case 'p': // "-p[N]" open N tab pages + } + case 'p': { // "-p[N]" open N tab pages // default is 0: open window for each file parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); parmp->window_layout = WIN_TABS; break; - - case 'o': /* "-o[N]" open N horizontal split windows */ - /* default is 0: open window for each file */ + } + case 'o': { // "-o[N]" open N horizontal split windows + // default is 0: open window for each file parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); parmp->window_layout = WIN_HOR; break; - - case 'O': /* "-O[N]" open N vertical split windows */ - /* default is 0: open window for each file */ + } + case 'O': { // "-O[N]" open N vertical split windows + // default is 0: open window for each file parmp->window_count = get_number_arg(argv[0], &argv_idx, 0); parmp->window_layout = WIN_VER; break; - - case 'q': /* "-q" QuickFix mode */ - if (parmp->edit_type != EDIT_NONE) + } + case 'q': { // "-q" QuickFix mode + if (parmp->edit_type != EDIT_NONE) { mainerr(err_too_many_args, argv[0]); + } parmp->edit_type = EDIT_QF; - if (argv[0][argv_idx]) { /* "-q{errorfile}" */ + if (argv[0][argv_idx]) { // "-q{errorfile}" parmp->use_ef = (char_u *)argv[0] + argv_idx; argv_idx = -1; - } else if (argc > 1) /* "-q {errorfile}" */ - want_argument = TRUE; + } else if (argc > 1) { // "-q {errorfile}" + want_argument = true; + } break; - - case 'R': /* "-R" readonly mode */ - readonlymode = TRUE; - curbuf->b_p_ro = TRUE; - p_uc = 10000; /* don't update very often */ + } + case 'R': { // "-R" readonly mode + readonlymode = true; + curbuf->b_p_ro = true; + p_uc = 10000; // don't update very often break; - - case 'r': /* "-r" recovery mode */ - case 'L': /* "-L" recovery mode */ + } + case 'r': // "-r" recovery mode + case 'L': { // "-L" recovery mode recoverymode = 1; break; - - case 's': - if (exmode_active) { // "-es" silent (batch) mode + } + case 's': { + if (exmode_active) { // "-es" silent (batch) Ex-mode silent_mode = true; } else { // "-s {scriptin}" read from script file want_argument = true; } break; - - case 't': /* "-t {tag}" or "-t{tag}" jump to tag */ - if (parmp->edit_type != EDIT_NONE) + } + case 't': { // "-t {tag}" or "-t{tag}" jump to tag + if (parmp->edit_type != EDIT_NONE) { mainerr(err_too_many_args, argv[0]); + } parmp->edit_type = EDIT_TAG; - if (argv[0][argv_idx]) { /* "-t{tag}" */ + if (argv[0][argv_idx]) { // "-t{tag}" parmp->tagname = (char_u *)argv[0] + argv_idx; argv_idx = -1; - } else /* "-t {tag}" */ - want_argument = TRUE; - break; - - case 'D': /* "-D" Debugging */ - parmp->use_debug_break_level = 9999; - break; - case 'd': /* "-d" 'diff' */ - parmp->diff_mode = TRUE; + } else { // "-t {tag}" + want_argument = true; + } break; - case 'v': + } + case 'v': { version(); mch_exit(0); - case 'V': /* "-V{N}" Verbose level */ - /* default is 10: a little bit verbose */ + } + case 'V': { // "-V{N}" Verbose level + // default is 10: a little bit verbose p_verbose = get_number_arg(argv[0], &argv_idx, 10); if (argv[0][argv_idx] != NUL) { set_option_value("verbosefile", 0L, argv[0] + argv_idx, 0); argv_idx = (int)STRLEN(argv[0]); } break; - - case 'w': /* "-w{number}" set window height */ - /* "-w {scriptout}" write to script */ + } + case 'w': { // "-w{number}" set window height + // "-w {scriptout}" write to script if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) { n = get_number_arg(argv[0], &argv_idx, 10); set_option_value("window", n, NULL, 0); break; } - want_argument = TRUE; + want_argument = true; break; - - case 'Z': /* "-Z" restricted mode */ - restricted = TRUE; + } + case 'Z': { // "-Z" restricted mode + restricted = true; break; + } - case 'c': /* "-c{command}" or "-c {command}" execute - command */ + case 'c': { // "-c{command}" or "-c {command}" exec command if (argv[0][argv_idx] != NUL) { - if (parmp->n_commands >= MAX_ARG_CMDS) + if (parmp->n_commands >= MAX_ARG_CMDS) { mainerr(err_extra_cmd, NULL); - parmp->commands[parmp->n_commands++] = argv[0] - + argv_idx; + } + parmp->commands[parmp->n_commands++] = argv[0] + argv_idx; argv_idx = -1; break; } - /*FALLTHROUGH*/ - case 'S': /* "-S {file}" execute Vim script */ - case 'i': /* "-i {shada}" use for ShaDa file */ - case 'u': /* "-u {vimrc}" vim inits file */ - case 'U': /* "-U {gvimrc}" gvim inits file */ - case 'W': /* "-W {scriptout}" overwrite */ - want_argument = TRUE; + // FALLTHROUGH + } + case 'S': // "-S {file}" execute Vim script + case 'i': // "-i {shada}" use for ShaDa file + case 'u': // "-u {vimrc}" vim inits file + case 'U': // "-U {gvimrc}" gvim inits file + case 'W': { // "-W {scriptout}" overwrite + want_argument = true; break; + } - default: + default: { mainerr(err_opt_unknown, argv[0]); + } } // Handle option arguments with argument. @@ -1034,43 +1038,45 @@ static void command_line_scan(mparm_T *parmp) mainerr(err_opt_garbage, argv[0]); } - --argc; - if (argc < 1 && c != 'S') /* -S has an optional argument */ + argc--; + if (argc < 1 && c != 'S') { // -S has an optional argument mainerr(err_arg_missing, argv[0]); - ++argv; + } + argv++; argv_idx = -1; switch (c) { - case 'c': /* "-c {command}" execute command */ - case 'S': /* "-S {file}" execute Vim script */ - if (parmp->n_commands >= MAX_ARG_CMDS) + case 'c': // "-c {command}" execute command + case 'S': { // "-S {file}" execute Vim script + if (parmp->n_commands >= MAX_ARG_CMDS) { mainerr(err_extra_cmd, NULL); + } if (c == 'S') { - char *a; + char *a; - if (argc < 1) - /* "-S" without argument: use default session file - * name. */ + if (argc < 1) { + // "-S" without argument: use default session file name. a = SESSION_FILE; - else if (argv[0][0] == '-') { - /* "-S" followed by another option: use default - * session file name. */ + } else if (argv[0][0] == '-') { + // "-S" followed by another option: use default session file. a = SESSION_FILE; ++argc; --argv; } else { a = argv[0]; } - char *s = xmalloc(STRLEN(a) + 4); - sprintf(s, "so %s", a); - parmp->cmds_tofree[parmp->n_commands] = TRUE; + size_t s_size = STRLEN(a) + 4; + char *s = xmalloc(s_size); + snprintf(s, s_size, "so %s", a); + parmp->cmds_tofree[parmp->n_commands] = true; parmp->commands[parmp->n_commands++] = s; } else { parmp->commands[parmp->n_commands++] = argv[0]; } break; + } - case '-': + case '-': { if (strequal(argv[-1], "--cmd")) { // "--cmd {command}" execute command if (parmp->n_pre_commands >= MAX_ARG_CMDS) { @@ -1083,16 +1089,19 @@ static void command_line_scan(mparm_T *parmp) } // "--startuptime " already handled break; + } - case 'q': /* "-q {errorfile}" QuickFix mode */ + case 'q': { // "-q {errorfile}" QuickFix mode parmp->use_ef = (char_u *)argv[0]; break; + } - case 'i': /* "-i {shada}" use for shada */ + case 'i': { // "-i {shada}" use for shada used_shada_file = argv[0]; break; + } - case 's': /* "-s {scriptin}" read from script file */ + case 's': { // "-s {scriptin}" read from script file if (scriptin[0] != NULL) { scripterror: vim_snprintf((char *)IObuff, IOSIZE, @@ -1105,8 +1114,7 @@ scripterror: if (strequal(argv[0], "-")) { const int stdin_dup_fd = os_dup(STDIN_FILENO); #ifdef WIN32 - // On Windows, replace the original stdin with the - // console input handle. + // Replace the original stdin with the console input handle. close(STDIN_FILENO); const HANDLE conin_handle = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, @@ -1129,20 +1137,22 @@ scripterror: } save_typebuf(); break; + } - case 't': /* "-t {tag}" */ + case 't': { // "-t {tag}" parmp->tagname = (char_u *)argv[0]; break; - - case 'u': /* "-u {vimrc}" vim inits file */ + } + case 'u': { // "-u {vimrc}" vim inits file parmp->use_vimrc = argv[0]; break; - - case 'U': /* "-U {gvimrc}" gvim inits file */ + } + case 'U': { // "-U {gvimrc}" gvim inits file break; + } - case 'w': /* "-w {nr}" 'window' value */ - /* "-w {scriptout}" append to script file */ + case 'w': { // "-w {nr}" 'window' value + // "-w {scriptout}" append to script file if (ascii_isdigit(*((char_u *)argv[0]))) { argv_idx = 0; n = get_number_arg(argv[0], &argv_idx, 10); @@ -1150,10 +1160,12 @@ scripterror: argv_idx = -1; break; } - /*FALLTHROUGH*/ - case 'W': /* "-W {scriptout}" overwrite script file */ - if (scriptout != NULL) + // FALLTHROUGH + } + case 'W': { // "-W {scriptout}" overwrite script file + if (scriptout != NULL) { goto scripterror; + } if ((scriptout = mch_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN)) == NULL) { mch_errmsg(_("Cannot open for script output: \"")); @@ -1162,7 +1174,7 @@ scripterror: mch_exit(2); } break; - + } } } } else { // File name argument. @@ -1759,14 +1771,15 @@ static bool do_user_initialization(void) static void source_startup_scripts(const mparm_T *const parmp) FUNC_ATTR_NONNULL_ALL { - // If -u argument given, use only the initializations from that file and - // nothing else. + // If -u given, use only the initializations from that file and nothing else. if (parmp->use_vimrc != NULL) { - if (strcmp(parmp->use_vimrc, "NONE") == 0 - || strcmp(parmp->use_vimrc, "NORC") == 0) { + if (strequal(parmp->use_vimrc, "NONE") + || strequal(parmp->use_vimrc, "NORC")) { + // Do nothing. } else { - if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK) + if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK) { EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc); + } } } else if (!silent_mode) { #ifdef SYS_VIMRC_FILE diff --git a/src/nvim/message.c b/src/nvim/message.c index 7ca82c2878..63accaaa23 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -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(); diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 405500767d..69caa6aaf3 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -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. +/// File (set at startup) used to read user-input (or commands for -e/-es). int input_global_fd(void) { return global_fd; @@ -438,8 +438,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(); } -- cgit From 787ae1b38bb388e2ee236e89091e87932fd0efb3 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 26 May 2018 17:18:52 +0200 Subject: startup: silent-mode is not `full_screen` silent-mode (AKA batch-mode, -es/-Es) by definition should not behave like a UI. There are still some places that check `full_screen` to decide behavior, e.g. msg_start(). Future: maybe eliminate `full_screen`, check `ui_active()` instead? --- src/nvim/main.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index c2cd87bb39..f4b21d712c 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -97,7 +97,6 @@ typedef struct { char_u *tagname; // tag from -t argument char_u *use_ef; // 'errorfile' from -q argument - int want_full_screen; bool input_isatty; // stdin is a terminal bool output_isatty; // stdout is a terminal bool err_isatty; // stderr is a terminal @@ -271,15 +270,9 @@ int main(int argc, char **argv) /* Don't redraw until much later. */ ++RedrawingDisabled; - /* - * When listing swap file names, don't do cursor positioning et. al. - */ - if (recoverymode && fname == NULL) - params.want_full_screen = FALSE; - setbuf(stdout, NULL); - full_screen = true; + full_screen = !silent_mode; // Set the default values for the options that use Rows and Columns. win_init_size(); @@ -1247,7 +1240,6 @@ static void init_params(mparm_T *paramp, int argc, char **argv) memset(paramp, 0, sizeof(*paramp)); paramp->argc = argc; paramp->argv = argv; - paramp->want_full_screen = true; paramp->use_debug_break_level = -1; paramp->window_count = -1; paramp->listen_addr = NULL; -- cgit From 63058fb5b05a1293dd50851af46f33fc15110829 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 27 May 2018 03:41:02 +0200 Subject: startup: fix -es/-Es so they are actually silent silent-mode (-es/-Es) has been broken for years. The workaround up to now was to include --headless. But --headless is not equivalent because it prints all messages, not the limited subset defined by silent-mode. --- src/nvim/globals.h | 4 ---- src/nvim/main.c | 44 ++++++++++++++++++++--------------- src/nvim/os/input.c | 13 +++++++---- test/functional/core/startup_spec.lua | 31 +++++++++++++++++++++++- 4 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/nvim/globals.h b/src/nvim/globals.h index eefe7b4bf5..51bc3f1289 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -580,10 +580,6 @@ EXTERN int sandbox INIT(= 0); /// 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); - /// Start position of active Visual selection. EXTERN pos_T VIsual; /// Whether Visual mode is active. diff --git a/src/nvim/main.c b/src/nvim/main.c index f4b21d712c..5d3e3ff083 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -158,6 +158,7 @@ void event_init(void) bool event_teardown(void) { if (!main_loop.events) { + input_stop(); return true; } @@ -298,17 +299,18 @@ int main(int argc, char **argv) // Set the break level after the terminal is initialized. debug_break_level = params.use_debug_break_level; + bool reading_excmds = exmode_active == EXMODE_NORMAL; bool reading_input = !headless_mode && (params.input_isatty || params.output_isatty || params.err_isatty); - if (reading_input) { + if (reading_input || reading_excmds) { // One of the startup commands (arguments, sourced scripts or plugins) may // prompt the user, so start reading from a tty now. int fd = fileno(stdin); - if (!params.input_isatty || params.edit_type == EDIT_STDIN) { - // Use stderr or stdout since stdin is not a tty and/or could be used to - // read the "-" file (eg: cat file | nvim -) + if (!reading_excmds + && (!params.input_isatty || params.edit_type == EDIT_STDIN)) { + // Use stderr or stdout since stdin is being used to read commands. fd = params.err_isatty ? fileno(stderr) : fileno(stdout); } input_start(fd); @@ -332,7 +334,9 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. - if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { + if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE") + // && !silent_mode // XXX: avoid hang with "nvim -es -u NONE". + ) { p_lpl = false; } @@ -369,17 +373,21 @@ int main(int argc, char **argv) mch_exit(0); } - // Set a few option defaults after reading vimrc files: - // 'title' and 'icon', Unix: 'shellpipe' and 'shellredir'. + // Set a few option defaults after reading vimrc files: 'title', 'icon', + // 'shellpipe', 'shellredir'. set_init_3(); TIME_MSG("inits 3"); - /* - * "-n" argument: Disable swap file by setting 'updatecount' to 0. - * Note that this overrides anything from a vimrc file. - */ - if (params.no_swap_file) + // "-n" argument: Disable swap file by setting 'updatecount' to 0. + // Note that this overrides anything from a vimrc file. + if (params.no_swap_file) { p_uc = 0; + } + + // XXX: Minimize 'updatetime' for -es/-Es. #7679 + if (silent_mode) { + p_ut = 1; + } if (curwin->w_p_rl && p_altkeymap) { p_hkmap = FALSE; /* Reset the Hebrew keymap mode */ @@ -437,18 +445,17 @@ int main(int argc, char **argv) wait_return(true); } - if (!headless_mode) { - // Stop reading from input stream. UI (if any) will take over. - input_stop(); + if (!headless_mode && !silent_mode) { + input_stop(); // Stop reading from input stream. UI will take over. ui_builtin_start(); } setmouse(); // may start using the mouse ui_reset_scroll_region(); // In case Rows changed - if (exmode_active) + if (exmode_active) { must_redraw = CLEAR; // Don't clear the screen when starting in Ex mode. - else { + } else { screenclear(); // clear screen TIME_MSG("clearing screen"); } @@ -1769,7 +1776,7 @@ static void source_startup_scripts(const mparm_T *const parmp) || strequal(parmp->use_vimrc, "NORC")) { // Do nothing. } else { - if (do_source((char_u *)parmp->use_vimrc, FALSE, DOSO_NONE) != OK) { + if (do_source((char_u *)parmp->use_vimrc, false, DOSO_NONE) != OK) { EMSG2(_("E282: Cannot read from \"%s\""), parmp->use_vimrc); } } @@ -1810,7 +1817,6 @@ static void source_startup_scripts(const mparm_T *const parmp) } secure = 0; } - did_source_startup_scripts = true; TIME_MSG("sourcing vimrc file(s)"); } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index 69caa6aaf3..a2d1a7bace 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -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) { + // Input drained and eventloop drained: exit silent/batch-mode (-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)); diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 0d4199ea6e..b8af5de664 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -109,13 +109,14 @@ describe('startup', function() ]]) end) it('input from pipe (implicit) + file args #7679', function() + if helpers.pending_win32(pending) then return end 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 \"]] + ..[[.shellescape(v:progpath)." -n -u NONE -i NONE --cmd \"]] ..nvim_set..[[\"]] ..[[ --cmd \"set shortmess+=I\"]] ..[[ -c \"echo has('ttyin') has('ttyout') 'bufs='.bufnr('$')\"]] @@ -128,5 +129,33 @@ describe('startup', function() | ]]) 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 + -- + if not iswin() then + 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)) + end + + + -- + -- -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) -- cgit From 4211255c755513aa91d4a9277b69b557fc6658ee Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 28 May 2018 07:09:55 +0200 Subject: startup: allow explicit "-" file arg with --headless --- src/nvim/main.c | 23 +++++++++++++++-------- src/nvim/os/input.c | 2 +- test/functional/core/startup_spec.lua | 34 +++++++++++----------------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 5d3e3ff083..79d5d40a8a 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -722,13 +722,14 @@ static void init_locale(void) /// Decides whether text (as opposed to commands) will be read from stdin. /// @see EDIT_STDIN -static bool edit_stdin(mparm_T *parmp) +static bool edit_stdin(bool explicit, mparm_T *parmp) { - return !headless_mode + bool implicit = !headless_mode && !embedded_mode && exmode_active != EXMODE_NORMAL // -E/-Es but not -e/-es. && !parmp->input_isatty && scriptin[0] == NULL; // `-s -` was not given. + return explicit || implicit; } /// Scan the command line arguments. @@ -737,7 +738,8 @@ static void command_line_scan(mparm_T *parmp) int argc = parmp->argc; char **argv = parmp->argv; int argv_idx; // index in argv[n][] - int had_minmin = false; // found "--" argument + bool had_stdin_file = false; // found explicit "-" argument + bool had_minmin = false; // found "--" argument int want_argument; // option argument with argument int c; char_u *p = NULL; @@ -769,9 +771,12 @@ static void command_line_scan(mparm_T *parmp) // "nvim -e -" silent mode silent_mode = true; } else { - if (parmp->edit_type != EDIT_NONE) { + if (parmp->edit_type != EDIT_NONE + && parmp->edit_type != EDIT_FILE + && parmp->edit_type != EDIT_STDIN) { mainerr(err_too_many_args, argv[0]); } + had_stdin_file = true; parmp->edit_type = EDIT_STDIN; } argv_idx = -1; // skip to next argument @@ -1181,7 +1186,9 @@ scripterror: argv_idx = -1; // skip to next argument // Check for only one type of editing. - if (parmp->edit_type != EDIT_NONE && parmp->edit_type != EDIT_FILE) { + if (parmp->edit_type != EDIT_NONE + && parmp->edit_type != EDIT_FILE + && parmp->edit_type != EDIT_STDIN) { mainerr(err_too_many_args, argv[0]); } parmp->edit_type = EDIT_FILE; @@ -1203,7 +1210,7 @@ scripterror: path_fix_case(p); #endif - int alist_fnum_flag = edit_stdin(parmp) + int alist_fnum_flag = edit_stdin(had_stdin_file, parmp) ? 1 // add buffer nr after exp. : 2; // add buffer number now and use curbuf #if !defined(UNIX) @@ -1230,8 +1237,8 @@ scripterror: xfree(swcmd); } - // Handle "foo | nvim". #6299 - if (edit_stdin(parmp)) { + // Handle "foo | nvim". EDIT_FILE may be overwritten now. #6299 + if (edit_stdin(had_stdin_file, parmp)) { parmp->edit_type = EDIT_STDIN; } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index a2d1a7bace..c999396a6a 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -109,7 +109,7 @@ 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) { - // Input drained and eventloop drained: exit silent/batch-mode (-es). + // Drained input and eventloop: exit silent/batch-mode (-es/-Es). read_error_exit(); } diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index b8af5de664..4223e55d90 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -109,25 +109,16 @@ describe('startup', function() ]]) end) it('input from pipe (implicit) + file args #7679', function() - if helpers.pending_win32(pending) then return end - 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)." -n -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 | - | - ]]) + 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('stdin with -es, -Es #7679', function() @@ -137,15 +128,12 @@ describe('startup', function() -- -- -Es: read stdin as text -- - if not iswin() then eq('partylikeits1999\n', funcs.system({nvim_prog, '-n', '-u', 'NONE', '-i', 'NONE', '-Es', '+.print', 'test/functional/fixtures/tty-test.c' }, - { 'partylikeits1999' })) + { 'partylikeits1999', '' })) eq(inputstr, funcs.system({nvim_prog, '-i', 'NONE', '-Es', '+%print', '-' }, input)) - end - -- -- -es: read stdin as ex-commands -- cgit From 1f300e08b8c0c35b2f3d79506ae9817cd8591624 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 29 May 2018 07:22:15 +0200 Subject: win/startup: remove --literal Fixes 2 failing tests in startup_spec.lua. The Windows-only `--literal` option complicates support of "stdin-as-text + file-args" (#7679). Could work around it, but it's not worth the trouble: - users have a reasonable (and englightening) alternative: nvim +"n *" - "always literal" is more consistent/predictable - avoids platform-specific special-case Unrelated changes: - Replace fileno(stdxx) with STDXX_FILENO for consistency (not motivated by any observed technical reason). --- man/nvim.1 | 11 ++++---- runtime/doc/starting.txt | 11 +------- runtime/doc/vim_diff.txt | 4 +++ src/nvim/main.c | 53 ++++++++--------------------------- src/nvim/os/input.c | 2 +- test/functional/core/startup_spec.lua | 4 +-- 6 files changed, 24 insertions(+), 61 deletions(-) diff --git a/man/nvim.1 b/man/nvim.1 index 7872f932d5..75c037946a 100644 --- a/man/nvim.1 +++ b/man/nvim.1 @@ -73,19 +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 -Ex mode, improved. +Ex mode, improved. Reads stdin as text. See .Ic :help gQ . .It Fl es -Ex mode, silent. +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 diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt index db3eb757c0..5ff9e0b5dc 100644 --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -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 diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 04d78da45a..ceae8eba8c 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -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 diff --git a/src/nvim/main.c b/src/nvim/main.c index 79d5d40a8a..1828d6e6a7 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -105,9 +105,6 @@ typedef struct { int window_count; // number of windows to use int window_layout; // 0, WIN_HOR, WIN_VER or WIN_TABS -#if !defined(UNIX) - int literal; // don't expand file names -#endif int diff_mode; // start with 'diff' set char *listen_addr; // --listen {address} @@ -299,15 +296,18 @@ int main(int argc, char **argv) // Set the break level after the terminal is initialized. debug_break_level = params.use_debug_break_level; - bool reading_excmds = exmode_active == EXMODE_NORMAL; + // + // Read user-input if any TTY is connected. + // Read ex-commands if invoked with "-es". + // bool reading_input = !headless_mode && (params.input_isatty || params.output_isatty || params.err_isatty); - + bool reading_excmds = exmode_active == EXMODE_NORMAL; if (reading_input || reading_excmds) { // One of the startup commands (arguments, sourced scripts or plugins) may // prompt the user, so start reading from a tty now. - int fd = fileno(stdin); + int fd = STDIN_FILENO; if (!reading_excmds && (!params.input_isatty || params.edit_type == EDIT_STDIN)) { // Use stderr or stdout since stdin is being used to read commands. @@ -334,9 +334,7 @@ int main(int argc, char **argv) // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. - if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE") - // && !silent_mode // XXX: avoid hang with "nvim -es -u NONE". - ) { + if (params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE")) { p_lpl = false; } @@ -785,7 +783,6 @@ static void command_line_scan(mparm_T *parmp) case '-': { // "--" don't take any more option arguments // "--help" give help message // "--version" give version message - // "--literal" take files literally // "--noplugin[s]" skip plugins // "--cmd " execute cmd before vimrc if (STRICMP(argv[0] + argv_idx, "help") == 0) { @@ -830,9 +827,7 @@ static void command_line_scan(mparm_T *parmp) want_argument = true; argv_idx += 6; } else if (STRNICMP(argv[0] + argv_idx, "literal", 7) == 0) { -#if !defined(UNIX) - parmp->literal = true; -#endif + // Do nothing: file args are always literal. #7679 } else if (STRNICMP(argv[0] + argv_idx, "noplugin", 8) == 0) { p_lpl = false; } else if (STRNICMP(argv[0] + argv_idx, "cmd", 3) == 0) { @@ -1213,9 +1208,6 @@ scripterror: int alist_fnum_flag = edit_stdin(had_stdin_file, parmp) ? 1 // add buffer nr after exp. : 2; // add buffer number now and use curbuf -#if !defined(UNIX) - alist_fnum_flag = parmp->literal ? alist_fnum_flag : 0; -#endif alist_add(&global_alist, p, alist_fnum_flag); } @@ -1276,10 +1268,10 @@ static void init_startuptime(mparm_T *paramp) static void check_and_set_isatty(mparm_T *paramp) { stdin_isatty - = paramp->input_isatty = os_isatty(fileno(stdin)); + = paramp->input_isatty = os_isatty(STDIN_FILENO); stdout_isatty - = paramp->output_isatty = os_isatty(fileno(stdout)); - paramp->err_isatty = os_isatty(fileno(stderr)); + = paramp->output_isatty = os_isatty(STDOUT_FILENO); + paramp->err_isatty = os_isatty(STDERR_FILENO); #ifndef WIN32 int tty_fd = paramp->input_isatty ? STDIN_FILENO @@ -1315,26 +1307,6 @@ static void init_path(const char *exename) /// Get filename from command line, if any. static char_u *get_fname(mparm_T *parmp, char_u *cwd) { -#if !defined(UNIX) - /* - * Expand wildcards in file names. - */ - if (!parmp->literal) { - cwd = xmalloc(MAXPATHL); - if (cwd != NULL) { - os_dirname(cwd, MAXPATHL); - } - // Temporarily add '(' and ')' to 'isfname'. These are valid - // filename characters but are excluded from 'isfname' to make - // "gf" work on a file name in parenthesis (e.g.: see vim.h). - do_cmdline_cmd(":set isf+=(,)"); - alist_expand(NULL, 0); - do_cmdline_cmd(":set isf&"); - if (cwd != NULL) { - os_chdir((char *)cwd); - } - } -#endif return alist_name(&GARGLIST[0]); } @@ -1947,9 +1919,6 @@ static void usage(void) 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
Serve RPC API from this address\n")); -#if !defined(UNIX) - mch_msg(_(" --literal Don't expand wildcards\n")); -#endif mch_msg(_(" --noplugin Don't load plugins\n")); mch_msg(_(" --startuptime Write startup timing messages to \n")); mch_msg(_("\nSee \":help startup-options\" for all options.\n")); diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index c999396a6a..dd44df2c3c 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -50,7 +50,7 @@ void input_init(void) input_buffer = rbuffer_new(INPUT_BUFFER_SIZE + MAX_KEY_CODE_LEN); } -/// File (set at startup) used to read user-input (or commands for -e/-es). +/// This is the global stream of user-input (or Ex-commands for "-es"). int input_global_fd(void) { return global_fd; diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index 4223e55d90..d15faaf0a9 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -108,7 +108,7 @@ describe('startup', function() | ]]) end) - it('input from pipe (implicit) + file args #7679', function() + 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', @@ -121,7 +121,7 @@ describe('startup', function() { 'ohyeah', '' })) end) - it('stdin with -es, -Es #7679', function() + it('stdin with -es/-Es #7679', function() local input = { 'append', 'line1', 'line2', '.', '%print', '' } local inputstr = table.concat(input, '\n') -- cgit From d8c7ff13352d7182826b5716ff3b6a66df241231 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 30 May 2018 07:21:45 +0200 Subject: cleanup, test interactive -E --- src/nvim/main.c | 17 +++++++++-------- src/nvim/os/input.c | 6 +++--- test/functional/core/startup_spec.lua | 13 +++++++++++++ test/functional/helpers.lua | 8 ++++++++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/nvim/main.c b/src/nvim/main.c index 1828d6e6a7..e1a01fdba6 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -300,15 +300,16 @@ int main(int argc, char **argv) // Read user-input if any TTY is connected. // Read ex-commands if invoked with "-es". // - bool reading_input = !headless_mode - && (params.input_isatty || params.output_isatty - || params.err_isatty); - bool reading_excmds = exmode_active == EXMODE_NORMAL; - if (reading_input || reading_excmds) { + bool reading_tty = !headless_mode + && (params.input_isatty || params.output_isatty + || params.err_isatty); + bool reading_excmds = !params.input_isatty && silent_mode + && exmode_active == EXMODE_NORMAL; + if (reading_tty || reading_excmds) { // One of the startup commands (arguments, sourced scripts or plugins) may // prompt the user, so start reading from a tty now. int fd = STDIN_FILENO; - if (!reading_excmds + if (!silent_mode && (!params.input_isatty || params.edit_type == EDIT_STDIN)) { // Use stderr or stdout since stdin is being used to read commands. fd = params.err_isatty ? fileno(stderr) : fileno(stdout); @@ -435,7 +436,7 @@ int main(int argc, char **argv) read_stdin(); } - if (reading_input && (need_wait_return || msg_didany)) { + if (reading_tty && (need_wait_return || msg_didany)) { // Because there's no UI yet, error messages would have been printed to // stdout. Before starting we need confirmation that the user has seen the // messages and that is done with a call to wait_return. @@ -444,7 +445,7 @@ int main(int argc, char **argv) } if (!headless_mode && !silent_mode) { - input_stop(); // Stop reading from input stream. UI will take over. + input_stop(); // Stop reading input, let the UI take over. ui_builtin_start(); } diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index dd44df2c3c..599487c345 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -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); } -/// This is the global stream of user-input (or Ex-commands for "-es"). +/// Global TTY (or pipe for "-es") input stream, before UI starts. int input_global_fd(void) { return global_fd; @@ -109,7 +109,7 @@ 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 input and eventloop: exit silent/batch-mode (-es/-Es). + // Drained eventloop & initial input; exit silent/batch-mode (-es/-Es). read_error_exit(); } diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index d15faaf0a9..f1f96ba626 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -4,6 +4,7 @@ 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 @@ -121,6 +122,18 @@ describe('startup', function() { 'ohyeah', '' })) end) + it('-e/-E interactive #7679', function() + clear('-E') + local screen = Screen.new(25, 3) + screen:attach() + feed("put ='from -E'") + screen:expect([[ + | + from -E | + :^ | + ]]) + end) + it('stdin with -es/-Es #7679', function() local input = { 'append', 'line1', 'line2', '.', '%print', '' } local inputstr = table.concat(input, '\n') diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 9895281773..a6d2764187 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -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 -- cgit