diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-01-25 18:31:31 +0000 |
commit | 9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch) | |
tree | 607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/main.c | |
parent | 9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff) | |
parent | 3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff) | |
download | rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.gz rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.bz2 rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.zip |
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/main.c')
-rw-r--r-- | src/nvim/main.c | 855 |
1 files changed, 440 insertions, 415 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c index d06b475934..bbe877356d 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -3,47 +3,51 @@ #define EXTERN #include <assert.h> -#include <msgpack.h> +#include <limits.h> +#include <msgpack/pack.h> #include <stdbool.h> #include <stdint.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> +#include "auto/config.h" #include "nvim/arglist.h" #include "nvim/ascii.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" +#include "nvim/buffer_defs.h" #include "nvim/channel.h" -#include "nvim/charset.h" #include "nvim/decoration.h" #include "nvim/decoration_provider.h" #include "nvim/diff.h" #include "nvim/drawscreen.h" #include "nvim/eval.h" +#include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" +#include "nvim/event/multiqueue.h" +#include "nvim/event/stream.h" #include "nvim/ex_cmds.h" -#include "nvim/ex_cmds2.h" #include "nvim/ex_docmd.h" #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" +#include "nvim/getchar.h" +#include "nvim/gettext.h" +#include "nvim/globals.h" +#include "nvim/grid.h" #include "nvim/hashtab.h" #include "nvim/highlight.h" #include "nvim/highlight_group.h" -#include "nvim/iconv.h" -#include "nvim/if_cscope.h" -#include "nvim/insexpand.h" +#include "nvim/keycodes.h" +#include "nvim/locale.h" +#include "nvim/log.h" #include "nvim/lua/executor.h" +#include "nvim/macros.h" #include "nvim/main.h" -#include "nvim/mapping.h" -#include "nvim/ui_client.h" -#include "nvim/vim.h" -#ifdef HAVE_LOCALE_H -# include <locale.h> -#endif -#include "nvim/garray.h" -#include "nvim/grid.h" -#include "nvim/log.h" #include "nvim/mark.h" -#include "nvim/mbyte.h" +#include "nvim/memfile_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -52,32 +56,37 @@ #include "nvim/normal.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_defs.h" #include "nvim/optionstr.h" #include "nvim/os/fileio.h" #include "nvim/os/input.h" #include "nvim/os/os.h" -#include "nvim/os/os_defs.h" +#include "nvim/os/stdpaths_defs.h" #include "nvim/os/time.h" -#include "nvim/os_unix.h" #include "nvim/path.h" #include "nvim/popupmenu.h" +#include "nvim/pos.h" #include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/runtime.h" #include "nvim/shada.h" #include "nvim/sign.h" -#include "nvim/state.h" +#include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/syntax.h" +#include "nvim/terminal.h" +#include "nvim/types.h" #include "nvim/ui.h" +#include "nvim/ui_client.h" #include "nvim/ui_compositor.h" #include "nvim/version.h" +#include "nvim/vim.h" #include "nvim/window.h" -#ifdef WIN32 +#ifdef MSWIN # include "nvim/os/os_win_console.h" #endif +#include "nvim/api/extmark.h" #include "nvim/api/private/defs.h" -#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/ui.h" #include "nvim/event/loop.h" @@ -86,22 +95,22 @@ #include "nvim/msgpack_rpc/helpers.h" #include "nvim/msgpack_rpc/server.h" #include "nvim/os/signal.h" -#ifndef WIN32 -# include "nvim/os/pty_process_unix.h" -#endif -#include "nvim/api/extmark.h" // values for "window_layout" -#define WIN_HOR 1 // "-o" horizontally split windows -#define WIN_VER 2 // "-O" vertically split windows -#define WIN_TABS 3 // "-p" windows on tab pages +enum { + WIN_HOR = 1, // "-o" horizontally split windows + WIN_VER = 2, // "-O" vertically split windows + WIN_TABS = 3, // "-p" windows on tab pages +}; // Values for edit_type. -#define EDIT_NONE 0 // no edit type yet -#define EDIT_FILE 1 // file name argument[s] given, use argument list -#define EDIT_STDIN 2 // read file from stdin -#define EDIT_TAG 3 // tag name argument given, use tagname -#define EDIT_QF 4 // start in quickfix mode +enum { + EDIT_NONE = 0, // no edit type yet + EDIT_FILE = 1, // file name argument[s] given, use argument list + EDIT_STDIN = 2, // read file from stdin + EDIT_TAG = 3, // tag name argument given, use tagname + EDIT_QF = 4, // start in quickfix mode +}; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "main.c.generated.h" @@ -170,7 +179,7 @@ void early_init(mparm_T *paramp) runtime_init(); highlight_init(); -#ifdef WIN32 +#ifdef MSWIN OSVERSIONINFO ovi; ovi.dwOSVersionInfoSize = sizeof(ovi); GetVersionEx(&ovi); @@ -187,11 +196,11 @@ void early_init(mparm_T *paramp) init_locale(); #endif - // Allocate the first window and buffer. - // Can't do anything without it, exit when it fails. - if (!win_alloc_first()) { - os_exit(0); - } + // tabpage local options (p_ch) must be set before allocating first tabpage. + set_init_tablocal(); + + // Allocate the first tabpage, window and buffer. + win_alloc_first(); TIME_MSG("init first window"); alist_init(&global_alist); // Init the argument list to empty. @@ -212,13 +221,13 @@ void early_init(mparm_T *paramp) #ifdef MAKE_LIB int nvim_main(int argc, char **argv); // silence -Wmissing-prototypes int nvim_main(int argc, char **argv) -#elif defined(WIN32) +#elif defined(MSWIN) int wmain(int argc, wchar_t **argv_w) // multibyte args on Windows. #7060 #else int main(int argc, char **argv) #endif { -#if defined(WIN32) && !defined(MAKE_LIB) +#if defined(MSWIN) && !defined(MAKE_LIB) char **argv = xmalloc((size_t)argc * sizeof(char *)); for (int i = 0; i < argc; i++) { char *buf = NULL; @@ -230,10 +239,10 @@ int main(int argc, char **argv) argv0 = argv[0]; - char_u *fname = NULL; // file name from command line + char *fname = NULL; // file name from command line mparm_T params; // various parameters passed between // main() and other functions. - char_u *cwd = NULL; // current working dir on startup + char *cwd = NULL; // current working dir on startup time_init(); // Many variables are in `params` so that we can pass them around easily. @@ -267,8 +276,7 @@ int main(int argc, char **argv) // argument list "global_alist". command_line_scan(¶ms); - nlua_init(); - + nlua_init(argv, argc, params.lua_arg0); TIME_MSG("init lua interpreter"); if (embedded_mode) { @@ -278,9 +286,35 @@ int main(int argc, char **argv) } } - server_init(params.listen_addr); +#ifdef MSWIN + // on windows we use CONIN special file, thus we don't know this yet. + bool has_term = true; +#else + bool has_term = (stdin_isatty || stdout_isatty || stderr_isatty); +#endif + bool use_builtin_ui = (has_term && !headless_mode && !embedded_mode && !silent_mode); + + // don't bind the server yet, if we are using builtin ui. + // This will be done when nvim server has been forked from the ui process + if (!use_builtin_ui) { + server_init(params.listen_addr); + } + if (params.remote) { - remote_request(¶ms, params.remote, params.server_addr, argc, argv); + remote_request(¶ms, params.remote, params.server_addr, argc, argv, + use_builtin_ui); + } + + bool remote_ui = (ui_client_channel_id != 0); + + if (use_builtin_ui && !remote_ui) { + ui_client_forward_stdin = !stdin_isatty; + uint64_t rv = ui_client_start_server(params.argc, params.argv); + if (!rv) { + os_errmsg("Failed to start Nvim server!\n"); + getout(1); + } + ui_client_channel_id = rv; } if (GARGCOUNT > 0) { @@ -316,7 +350,7 @@ int main(int argc, char **argv) assert(p_ch >= 0 && Rows >= p_ch && Rows - p_ch <= INT_MAX); cmdline_row = (int)(Rows - p_ch); msg_row = cmdline_row; - screenalloc(); // allocate screen buffers + default_grid_alloc(); // allocate screen buffers set_init_2(headless_mode); TIME_MSG("inits 2"); @@ -331,57 +365,57 @@ int main(int argc, char **argv) debug_break_level = params.use_debug_break_level; // Read ex-commands if invoked with "-es". - if (!params.input_isatty && !params.input_neverscript - && silent_mode && exmode_active) { - input_start(STDIN_FILENO); + if (!stdin_isatty && !params.input_istext && silent_mode && exmode_active) { + input_start(); + } + + if (ui_client_channel_id) { + ui_client_run(remote_ui); // NORETURN } // Wait for UIs to set up Nvim or show early messages // and prompts (--cmd, swapfile dialog, …). bool use_remote_ui = (embedded_mode && !headless_mode); - bool use_builtin_ui = (!headless_mode && !embedded_mode && !silent_mode); - if (use_remote_ui || use_builtin_ui) { + if (use_remote_ui) { TIME_MSG("waiting for UI"); - if (use_remote_ui) { - remote_ui_wait_for_attach(); - } else { - ui_builtin_start(); - } + remote_ui_wait_for_attach(); TIME_MSG("done waiting for UI"); - - // prepare screen now, so external UIs can display messages - starting = NO_BUFFERS; - screenclear(); - TIME_MSG("init screen for UI"); + firstwin->w_prev_height = firstwin->w_height; // may have changed } - if (ui_client_channel_id) { - ui_client_init(ui_client_channel_id); - ui_client_execute(ui_client_channel_id); - abort(); // unreachable + // prepare screen now + starting = NO_BUFFERS; + screenclear(); + win_new_screensize(); + TIME_MSG("clear screen"); + + // Handle "foo | nvim". EDIT_FILE may be overwritten now. #6299 + if (edit_stdin(¶ms)) { + params.edit_type = EDIT_STDIN; } + open_script_files(¶ms); + // Default mappings (incl. menus) Error err = ERROR_INIT; - Object o = nlua_exec(STATIC_CSTR_AS_STRING("return vim._init_default_mappings()"), - (Array)ARRAY_DICT_INIT, &err); + Object o = NLUA_EXEC_STATIC("return vim._init_default_mappings()", + (Array)ARRAY_DICT_INIT, &err); assert(!ERROR_SET(&err)); api_clear_error(&err); assert(o.type == kObjectTypeNil); api_free_object(o); + TIME_MSG("init default mappings"); init_default_autocmds(); TIME_MSG("init default autocommands"); - bool vimrc_none = params.use_vimrc != NULL && strequal(params.use_vimrc, "NONE"); + bool vimrc_none = strequal(params.use_vimrc, "NONE"); // Reset 'loadplugins' for "-u NONE" before "--cmd" arguments. // Allows for setting 'loadplugins' there. - if (vimrc_none) { - // When using --clean we still want to load plugins - p_lpl = params.clean; - } + // For --clean we still want to load plugins. + p_lpl = vimrc_none ? params.clean : p_lpl; // Execute --cmd arguments. exe_pre_commands(¶ms); @@ -434,10 +468,8 @@ int main(int argc, char **argv) p_ut = 1; } - // // Read in registers, history etc, from the ShaDa file. // This is where v:oldfiles gets filled. - // if (*p_shada != NUL) { shada_read_everything(NULL, false, true); TIME_MSG("reading ShaDa"); @@ -470,20 +502,13 @@ int main(int argc, char **argv) // 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 || stdin_fd >= 0) && !recoverymode) { + if (params.edit_type == EDIT_STDIN && !recoverymode) { read_stdin(); } setmouse(); // may start using the mouse - if (exmode_active || use_remote_ui || use_builtin_ui) { - // Don't clear the screen when starting in Ex mode, or when a UI might have - // displayed messages. - redraw_later(curwin, VALID); - } else { - screenclear(); // clear screen - TIME_MSG("clearing screen"); - } + redraw_later(curwin, UPD_VALID); no_wait_return = true; @@ -508,7 +533,7 @@ int main(int argc, char **argv) // When started with "-q errorfile" jump to first error now. if (params.edit_type == EDIT_QF) { - qf_jump(NULL, 0, 0, FALSE); + qf_jump(NULL, 0, 0, false); TIME_MSG("jump to first error"); } @@ -520,7 +545,9 @@ int main(int argc, char **argv) if (params.diff_mode) { // set options in each window for "nvim -d". FOR_ALL_WINDOWS_IN_TAB(wp, curtab) { - diff_win_options(wp, TRUE); + if (!wp->w_arg_idx_invalid) { + diff_win_options(wp, true); + } } } @@ -529,7 +556,7 @@ int main(int argc, char **argv) // Need to jump to the tag before executing the '-c command'. // Makes "vim -c '/return' -t main" work. - handle_tag((char_u *)params.tagname); + handle_tag(params.tagname); // Execute any "+", "-c" and "-S" arguments. if (params.n_commands > 0) { @@ -539,7 +566,7 @@ int main(int argc, char **argv) starting = 0; RedrawingDisabled = 0; - redraw_all_later(NOT_VALID); + redraw_all_later(UPD_NOT_VALID); no_wait_return = false; // 'autochdir' has been postponed. @@ -553,6 +580,13 @@ int main(int argc, char **argv) TIME_MSG("UIEnter autocommands"); } +#ifdef MSWIN + if (use_builtin_ui) { + os_icon_init(); + } + os_title_save(); +#endif + // Adjust default register name for "unnamed" in 'clipboard'. Can only be // done after the clipboard is available and all initial commands that may // modify the 'clipboard' setting have run; i.e. just before entering the @@ -578,13 +612,19 @@ int main(int argc, char **argv) (void)eval_has_provider("clipboard"); } + if (params.luaf != NULL) { + bool lua_ok = nlua_exec_file(params.luaf); + TIME_MSG("executing Lua -l script"); + getout(lua_ok ? 0 : 1); + } + TIME_MSG("before starting main loop"); ILOG("starting main loop"); // Main loop: never returns. normal_enter(false, false); -#if defined(WIN32) && !defined(MAKE_LIB) +#if defined(MSWIN) && !defined(MAKE_LIB) xfree(argv); #endif return 0; @@ -595,15 +635,19 @@ void os_exit(int r) { exiting = true; - ui_flush(); - ui_call_stop(); - ml_close_all(true); // remove all memfiles + if (ui_client_channel_id) { + ui_client_stop(); + } else { + ui_flush(); + ui_call_stop(); + ml_close_all(true); // remove all memfiles + } if (!event_teardown() && r == 0) { r = 1; // Exit with error if main_loop did not teardown gracefully. } - if (input_global_fd() >= 0) { - stream_set_blocking(input_global_fd(), true); // normalize stream (#2598) + if (used_stdin) { + stream_set_blocking(STDIN_FILENO, true); // normalize stream (#2598) } ILOG("Nvim exit: %d", r); @@ -621,9 +665,8 @@ void getout(int exitval) { exiting = true; - // When running in Ex mode an error causes us to exit with a non-zero exit - // code. POSIX requires this, although it's not 100% clear from the - // standard. + // On error during Ex mode, exit with a non-zero code. + // POSIX requires this, although it's not 100% clear from the standard. if (exmode_active) { exitval += ex_exitval; } @@ -713,8 +756,9 @@ void getout(int exitval) if (did_emsg) { // give the user a chance to read the (error) message - no_wait_return = FALSE; - wait_return(FALSE); + no_wait_return = false; + // TODO(justinmk): this may call getout(0), clobbering exitval... + wait_return(false); } // Position the cursor again, the autocommands may have moved it @@ -722,21 +766,25 @@ void getout(int exitval) // Apply 'titleold'. if (p_title && *p_titleold != NUL) { - ui_call_set_title(cstr_as_string((char *)p_titleold)); + ui_call_set_title(cstr_as_string(p_titleold)); } - cs_end(); if (garbage_collect_at_exit) { garbage_collect(false); } +#ifdef MSWIN + // Restore Windows console icon before exiting. + os_icon_set(NULL, NULL); + os_title_reset(); +#endif + os_exit(exitval); } -/// Preserve files and exit. -/// @note IObuff must contain a message. -/// @note This may be called from deadly_signal() in a signal handler, avoid -/// unsafe functions, such as allocating memory. +/// Preserve files, print contents of `IObuff`, and exit 1. +/// +/// May be called from deadly_signal(). void preserve_exit(void) FUNC_ATTR_NORETURN { @@ -745,9 +793,9 @@ void preserve_exit(void) // Prevent repeated calls into this method. if (really_exiting) { - if (input_global_fd() >= 0) { + if (used_stdin) { // normalize stream (#2598) - stream_set_blocking(input_global_fd(), true); + stream_set_blocking(STDIN_FILENO, true); } exit(2); } @@ -755,15 +803,15 @@ void preserve_exit(void) really_exiting = true; // Ignore SIGHUP while we are already exiting. #9274 signal_reject_deadly(); - mch_errmsg(IObuff); - mch_errmsg("\n"); + os_errmsg(IObuff); + os_errmsg("\n"); ui_flush(); ml_close_notmod(); // close all not-modified buffers FOR_ALL_BUFFERS(buf) { if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) { - mch_errmsg("Vim: preserving files...\r\n"); + os_errmsg("Vim: preserving files...\r\n"); ui_flush(); ml_sync_all(false, false, true); // preserve all swap files break; @@ -772,7 +820,7 @@ void preserve_exit(void) ml_close_all(false); // close all memfiles, without deleting - mch_errmsg("Vim: Finished.\r\n"); + os_errmsg("Vim: Finished.\r\n"); getout(1); } @@ -801,30 +849,6 @@ static int get_number_arg(const char *p, int *idx, int def) return def; } -#if defined(HAVE_LOCALE_H) -/// Setup to use the current locale (for ctype() and many other things). -static void init_locale(void) -{ - setlocale(LC_ALL, ""); - -# ifdef LC_NUMERIC - // Make sure strtod() uses a decimal point, not a comma. - setlocale(LC_NUMERIC, "C"); -# endif - - char localepath[MAXPATHL] = { 0 }; - snprintf(localepath, sizeof(localepath), "%s", get_vim_var_str(VV_PROGPATH)); - char *tail = path_tail_with_sep(localepath); - *tail = NUL; - tail = path_tail(localepath); - xstrlcpy(tail, "share/locale", - sizeof(localepath) - (size_t)(tail - localepath)); - bindtextdomain(PROJECT_NAME, localepath); - textdomain(PROJECT_NAME); - TIME_MSG("locale set"); -} -#endif - static uint64_t server_connect(char *server_addr, const char **errmsg) { if (server_addr == NULL) { @@ -845,16 +869,25 @@ static uint64_t server_connect(char *server_addr, const char **errmsg) /// Handle remote subcommands static void remote_request(mparm_T *params, int remote_args, char *server_addr, int argc, - char **argv) + char **argv, bool ui_only) { + bool is_ui = strequal(argv[remote_args], "--remote-ui"); + if (ui_only && !is_ui) { + // TODO(bfredl): this implies always starting the TUI. + // if we be smart we could delay this past should_exit + return; + } + const char *connect_error = NULL; uint64_t chan = server_connect(server_addr, &connect_error); Object rvobj = OBJECT_INIT; - if (strequal(argv[remote_args], "--remote-ui-test")) { + if (is_ui) { if (!chan) { - emsg(connect_error); - exit(1); + os_errmsg("Remote ui failed to start: "); + os_errmsg(connect_error); + os_errmsg("\n"); + os_exit(1); } ui_client_channel_id = chan; @@ -878,15 +911,15 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, Object o = nlua_exec(s, a, &err); api_free_array(a); if (ERROR_SET(&err)) { - mch_errmsg(err.msg); - mch_errmsg("\n"); + os_errmsg(err.msg); + os_errmsg("\n"); os_exit(2); } if (o.type == kObjectTypeDictionary) { rvobj.data.dictionary = o.data.dictionary; } else { - mch_errmsg("vim._cs_remote returned unexpected value\n"); + os_errmsg("vim._cs_remote returned unexpected value\n"); os_exit(2); } @@ -896,28 +929,28 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, for (size_t i = 0; i < rvobj.data.dictionary.size; i++) { if (strcmp(rvobj.data.dictionary.items[i].key.data, "errmsg") == 0) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) { - mch_errmsg("vim._cs_remote returned an unexpected type for 'errmsg'\n"); + os_errmsg("vim._cs_remote returned an unexpected type for 'errmsg'\n"); os_exit(2); } - mch_errmsg(rvobj.data.dictionary.items[i].value.data.string.data); - mch_errmsg("\n"); + os_errmsg(rvobj.data.dictionary.items[i].value.data.string.data); + os_errmsg("\n"); os_exit(2); } else if (strcmp(rvobj.data.dictionary.items[i].key.data, "tabbed") == 0) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) { - mch_errmsg("vim._cs_remote returned an unexpected type for 'tabbed'\n"); + os_errmsg("vim._cs_remote returned an unexpected type for 'tabbed'\n"); os_exit(2); } tabbed = rvobj.data.dictionary.items[i].value.data.boolean ? kTrue : kFalse; } else if (strcmp(rvobj.data.dictionary.items[i].key.data, "should_exit") == 0) { if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) { - mch_errmsg("vim._cs_remote returned an unexpected type for 'should_exit'\n"); + os_errmsg("vim._cs_remote returned an unexpected type for 'should_exit'\n"); os_exit(2); } should_exit = rvobj.data.dictionary.items[i].value.data.boolean ? kTrue : kFalse; } } if (should_exit == kNone || tabbed == kNone) { - mch_errmsg("vim._cs_remote didn't return a value for should_exit or tabbed, bailing\n"); + os_errmsg("vim._cs_remote didn't return a value for should_exit or tabbed, bailing\n"); os_exit(2); } api_free_object(o); @@ -933,14 +966,14 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr, /// Decides whether text (as opposed to commands) will be read from stdin. /// @see EDIT_STDIN -static bool edit_stdin(bool explicit, mparm_T *parmp) +static bool edit_stdin(mparm_T *parmp) { bool implicit = !headless_mode - && !embedded_mode - && (!exmode_active || parmp->input_neverscript) - && !parmp->input_isatty - && scriptin[0] == NULL; // `-s -` was not given. - return explicit || implicit; + && !(embedded_mode && stdin_fd <= 0) + && (!exmode_active || parmp->input_istext) + && !stdin_isatty + && parmp->scriptin == NULL; // `-s -` was not given. + return parmp->had_stdin_file || implicit; } /// Scan the command line arguments. @@ -949,7 +982,6 @@ static void command_line_scan(mparm_T *parmp) int argc = parmp->argc; char **argv = parmp->argv; int argv_idx; // index in argv[n][] - bool had_stdin_file = false; // found explicit "-" argument bool had_minmin = false; // found "--" argument int want_argument; // option argument with argument long n; @@ -969,9 +1001,9 @@ static void command_line_scan(mparm_T *parmp) } else { parmp->commands[parmp->n_commands++] = &(argv[0][1]); } - - // Optional argument. } else if (argv[0][0] == '-' && !had_minmin) { + // Optional argument. + want_argument = false; char c = argv[0][argv_idx++]; switch (c) { @@ -981,17 +1013,15 @@ static void command_line_scan(mparm_T *parmp) silent_mode = true; parmp->no_swap_file = true; } else { - if (parmp->edit_type != EDIT_NONE - && parmp->edit_type != EDIT_FILE - && parmp->edit_type != EDIT_STDIN) { + if (parmp->edit_type > EDIT_STDIN) { mainerr(err_too_many_args, argv[0]); } - had_stdin_file = true; + parmp->had_stdin_file = true; parmp->edit_type = EDIT_STDIN; } argv_idx = -1; // skip to next argument break; - case '-': // "--" don't take any more option arguments + case '-': // "--" No more option arguments. // "--help" give help message // "--version" give version message // "--noplugin[s]" skip plugins @@ -1052,7 +1082,7 @@ static void command_line_scan(mparm_T *parmp) } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { parmp->use_vimrc = "NONE"; parmp->clean = true; - set_option_value("shadafile", 0L, "NONE", 0); + set_option_value_give_err("shadafile", 0L, "NONE", 0); } else if (STRNICMP(argv[0] + argv_idx, "luamod-dev", 9) == 0) { nlua_disable_preload = true; } else { @@ -1066,7 +1096,7 @@ static void command_line_scan(mparm_T *parmp) } break; case 'A': // "-A" start in Arabic mode. - set_option_value("arabic", 1L, NULL, 0); + set_option_value_give_err("arabic", 1L, NULL, 0); break; case 'b': // "-b" binary mode. // Needs to be effective before expanding file names, because @@ -1087,7 +1117,7 @@ static void command_line_scan(mparm_T *parmp) break; case 'E': // "-E" Ex mode exmode_active = true; - parmp->input_neverscript = true; + parmp->input_istext = true; break; case 'f': // "-f" GUI: run in foreground. break; @@ -1097,11 +1127,7 @@ static void command_line_scan(mparm_T *parmp) os_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; + set_option_value_give_err("rl", 1L, NULL, 0); break; case 'M': // "-M" no changes or writing of files reset_modifiable(); @@ -1181,15 +1207,15 @@ static void command_line_scan(mparm_T *parmp) // 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]); + set_option_value_give_err("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 - if (ascii_isdigit(((char_u *)argv[0])[argv_idx])) { + if (ascii_isdigit((argv[0])[argv_idx])) { n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value("window", n, NULL, 0); + set_option_value_give_err("window", n, NULL, 0); break; } want_argument = true; @@ -1207,6 +1233,7 @@ static void command_line_scan(mparm_T *parmp) FALLTHROUGH; case 'S': // "-S {file}" execute Vim script case 'i': // "-i {shada}" use for ShaDa file + case 'l': // "-l {file}" Lua mode case 'u': // "-u {vimrc}" vim inits file case 'U': // "-U {gvimrc}" gvim inits file case 'W': // "-W {scriptout}" overwrite @@ -1252,7 +1279,7 @@ static void command_line_scan(mparm_T *parmp) a = argv[0]; } - size_t s_size = STRLEN(a) + 9; + size_t s_size = strlen(a) + 9; char *s = xmalloc(s_size); snprintf(s, s_size, "so %s", a); parmp->cmds_tofree[parmp->n_commands] = true; @@ -1284,41 +1311,37 @@ static void command_line_scan(mparm_T *parmp) break; case 'i': // "-i {shada}" use for shada - set_option_value("shadafile", 0L, argv[0], 0); + set_option_value_give_err("shadafile", 0L, argv[0], 0); break; - case 's': { // "-s {scriptin}" read from script file - if (scriptin[0] != NULL) { + case 'l': // "-l" Lua script: args after "-l". + headless_mode = true; + silent_mode = true; + p_verbose = 1; + parmp->no_swap_file = true; + parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE"; + if (p_shadafile == NULL || *p_shadafile == NUL) { + set_option_value_give_err("shadafile", 0L, "NONE", 0); + } + parmp->luaf = argv[0]; + argc--; + if (argc > 0) { // Lua args after "-l <file>". + parmp->lua_arg0 = parmp->argc - argc; + argc = 0; + } + break; + + case 's': // "-s {scriptin}" read from script file + if (parmp->scriptin != NULL) { scripterror: - vim_snprintf((char *)IObuff, IOSIZE, + vim_snprintf(IObuff, IOSIZE, _("Attempt to open script file again: \"%s %s\"\n"), argv[-1], argv[0]); - mch_errmsg((const char *)IObuff); - os_exit(2); - } - int error; - if (strequal(argv[0], "-")) { - const int stdin_dup_fd = os_dup(STDIN_FILENO); -#ifdef WIN32 - // Replace the original stdin with the console input handle. - os_replace_stdin_to_conin(); -#endif - FileDescriptor *const stdin_dup = file_open_fd_new(&error, stdin_dup_fd, - kFileReadOnly|kFileNonBlocking); - assert(stdin_dup != NULL); - scriptin[0] = stdin_dup; - } else if ((scriptin[0] = - file_open_new(&error, argv[0], kFileReadOnly|kFileNonBlocking, - 0)) == NULL) { - vim_snprintf((char *)IObuff, IOSIZE, - _("Cannot open for reading: \"%s\": %s\n"), - argv[0], os_strerror(error)); - mch_errmsg((const char *)IObuff); + os_errmsg(IObuff); os_exit(2); } - save_typebuf(); + parmp->scriptin = argv[0]; break; - } case 't': // "-t {tag}" parmp->tagname = argv[0]; @@ -1331,35 +1354,27 @@ scripterror: case 'w': // "-w {nr}" 'window' value // "-w {scriptout}" append to script file - if (ascii_isdigit(*((char_u *)argv[0]))) { + if (ascii_isdigit(*(argv[0]))) { argv_idx = 0; n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value("window", n, NULL, 0); + set_option_value_give_err("window", n, NULL, 0); argv_idx = -1; break; } FALLTHROUGH; case 'W': // "-W {scriptout}" overwrite script file - if (scriptout != NULL) { + if (parmp->scriptout != NULL) { goto scripterror; } - if ((scriptout = os_fopen(argv[0], c == 'w' ? APPENDBIN : WRITEBIN)) - == NULL) { - mch_errmsg(_("Cannot open for script output: \"")); - mch_errmsg(argv[0]); - mch_errmsg("\"\n"); - os_exit(2); - } - break; + parmp->scriptout = argv[0]; + parmp->scriptout_append = (c == 'w'); } } } 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 - && parmp->edit_type != EDIT_STDIN) { + if (parmp->edit_type > EDIT_STDIN) { mainerr(err_too_many_args, argv[0]); } parmp->edit_type = EDIT_FILE; @@ -1368,8 +1383,8 @@ scripterror: ga_grow(&global_alist.al_ga, 1); char *p = xstrdup(argv[0]); - if (parmp->diff_mode && os_isdir((char_u *)p) && GARGCOUNT > 0 - && !os_isdir((char_u *)alist_name(&GARGLIST[0]))) { + if (parmp->diff_mode && os_isdir(p) && GARGCOUNT > 0 + && !os_isdir(alist_name(&GARGLIST[0]))) { char *r = concat_fnames(p, path_tail(alist_name(&GARGLIST[0])), true); xfree(p); p = r; @@ -1380,7 +1395,7 @@ scripterror: path_fix_case(p); #endif - int alist_fnum_flag = edit_stdin(had_stdin_file, parmp) + int alist_fnum_flag = edit_stdin(parmp) ? 1 // add buffer nr after exp. : 2; // add buffer number now and use curbuf alist_add(&global_alist, p, alist_fnum_flag); @@ -1395,31 +1410,25 @@ scripterror: } } - if (embedded_mode && silent_mode) { - mainerr(_("--embed conflicts with -es/-Es"), NULL); + if (embedded_mode && (silent_mode || parmp->luaf)) { + mainerr(_("--embed conflicts with -es/-Es/-l"), NULL); } // 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; + const size_t swcmd_len = strlen(parmp->commands[0]) + 3; char *const swcmd = xmalloc(swcmd_len); snprintf(swcmd, swcmd_len, ":%s\r", parmp->commands[0]); set_vim_var_string(VV_SWAPCOMMAND, swcmd, -1); xfree(swcmd); } - // Handle "foo | nvim". EDIT_FILE may be overwritten now. #6299 - if (edit_stdin(had_stdin_file, parmp)) { - parmp->edit_type = EDIT_STDIN; - } - TIME_MSG("parsing arguments"); } -/* - * Many variables are in "params" so that we can pass them to invoked - * functions without a lot of arguments. "argc" and "argv" are also - * copied, so that they can be changed. */ +// Many variables are in "params" so that we can pass them to invoked +// functions without a lot of arguments. "argc" and "argv" are also +// copied, so that they can be changed. static void init_params(mparm_T *paramp, int argc, char **argv) { CLEAR_POINTER(paramp); @@ -1430,6 +1439,8 @@ static void init_params(mparm_T *paramp, int argc, char **argv) paramp->listen_addr = NULL; paramp->server_addr = NULL; paramp->remote = 0; + paramp->luaf = NULL; + paramp->lua_arg0 = -1; } /// Initialize global startuptime file if "--startuptime" passed as an argument. @@ -1442,25 +1453,13 @@ static void init_startuptime(mparm_T *paramp) break; } } - - starttime = time(NULL); } static void check_and_set_isatty(mparm_T *paramp) { - stdin_isatty - = paramp->input_isatty = os_isatty(STDIN_FILENO); - stdout_isatty - = paramp->output_isatty = os_isatty(STDOUT_FILENO); - paramp->err_isatty = os_isatty(STDERR_FILENO); -#ifndef WIN32 - int tty_fd = paramp->input_isatty - ? STDIN_FILENO - : (paramp->output_isatty - ? STDOUT_FILENO - : (paramp->err_isatty ? STDERR_FILENO : -1)); - pty_process_save_termios(tty_fd); -#endif + stdin_isatty = os_isatty(STDIN_FILENO); + stdout_isatty = os_isatty(STDOUT_FILENO); + stderr_isatty = os_isatty(STDERR_FILENO); TIME_MSG("window checked"); } @@ -1478,7 +1477,7 @@ static void init_path(const char *exename) set_vim_var_string(VV_PROGPATH, exepath, -1); set_vim_var_string(VV_PROGNAME, path_tail(exename), -1); -#ifdef WIN32 +#ifdef MSWIN // Append the process start directory to $PATH, so that ":!foo" finds tools // shipped with Windows package. This also mimics SearchPath(). os_setenv_append_path(exepath); @@ -1486,14 +1485,12 @@ 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) +static char *get_fname(mparm_T *parmp, char *cwd) { - return (char_u *)alist_name(&GARGLIST[0]); + return alist_name(&GARGLIST[0]); } -/* - * Decide about window layout for diff mode after reading vimrc. - */ +// Decide about window layout for diff mode after reading vimrc. static void set_window_layout(mparm_T *paramp) { if (paramp->diff_mode && paramp->window_layout == 0) { @@ -1505,18 +1502,16 @@ static void set_window_layout(mparm_T *paramp) } } -/* - * "-q errorfile": Load the error file now. - * If the error file can't be read, exit before doing anything else. - */ +// "-q errorfile": Load the error file now. +// If the error file can't be read, exit before doing anything else. static void handle_quickfix(mparm_T *paramp) { if (paramp->edit_type == EDIT_QF) { if (paramp->use_ef != NULL) { set_string_option_direct("ef", -1, paramp->use_ef, OPT_FREE, SID_CARG); } - vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef); - if (qf_init(NULL, (char *)p_ef, p_efm, true, (char *)IObuff, (char *)p_menc) < 0) { + vim_snprintf(IObuff, IOSIZE, "cfile %s", p_ef); + if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) { msg_putchar('\n'); os_exit(3); } @@ -1524,17 +1519,15 @@ static void handle_quickfix(mparm_T *paramp) } } -/* - * Need to jump to the tag before executing the '-c command'. - * Makes "vim -c '/return' -t main" work. - */ -static void handle_tag(char_u *tagname) +// Need to jump to the tag before executing the '-c command'. +// Makes "vim -c '/return' -t main" work. +static void handle_tag(char *tagname) { if (tagname != NULL) { swap_exists_did_quit = false; - vim_snprintf((char *)IObuff, IOSIZE, "ta %s", tagname); - do_cmdline_cmd((char *)IObuff); + vim_snprintf(IObuff, IOSIZE, "ta %s", tagname); + do_cmdline_cmd(IObuff); TIME_MSG("jumping to tag"); // If the user doesn't want to edit the file then we quit here. @@ -1566,18 +1559,46 @@ static void read_stdin(void) check_swap_exists_action(); } -/* - * Create the requested number of windows and edit buffers in them. - * Also does recovery if "recoverymode" set. - */ +static void open_script_files(mparm_T *parmp) +{ + if (parmp->scriptin) { + int error; + if (strequal(parmp->scriptin, "-")) { + FileDescriptor *stdin_dup = file_open_stdin(); + scriptin[0] = stdin_dup; + } else { + scriptin[0] = file_open_new(&error, parmp->scriptin, + kFileReadOnly|kFileNonBlocking, 0); + if (scriptin[0] == NULL) { + vim_snprintf((char *)IObuff, IOSIZE, + _("Cannot open for reading: \"%s\": %s\n"), + parmp->scriptin, os_strerror(error)); + os_errmsg(IObuff); + os_exit(2); + } + } + save_typebuf(); + } + + if (parmp->scriptout) { + scriptout = os_fopen(parmp->scriptout, parmp->scriptout_append ? APPENDBIN : WRITEBIN); + if (scriptout == NULL) { + os_errmsg(_("Cannot open for script output: \"")); + os_errmsg(parmp->scriptout); + os_errmsg("\"\n"); + os_exit(2); + } + } +} + +// Create the requested number of windows and edit buffers in them. +// Also does recovery if "recoverymode" set. static void create_windows(mparm_T *parmp) { int dorewind; int done = 0; - /* - * Create the number of windows that was requested. - */ + // Create the number of windows that was requested. if (parmp->window_count == -1) { // was not set parmp->window_count = 1; } @@ -1638,7 +1659,7 @@ static void create_windows(mparm_T *parmp) } curwin = curwin->w_next; } - dorewind = FALSE; + dorewind = false; curbuf = curwin->w_buffer; if (curbuf->b_ml.ml_mfp == NULL) { // Set 'foldlevel' to 'foldlevelstart' if it's not negative.. @@ -1647,15 +1668,15 @@ static void create_windows(mparm_T *parmp) } // When getting the ATTENTION prompt here, use a dialog. swap_exists_action = SEA_DIALOG; - set_buflisted(TRUE); + set_buflisted(true); // create memfile, read file - (void)open_buffer(FALSE, NULL, 0); + (void)open_buffer(false, NULL, 0); if (swap_exists_action == SEA_QUIT) { if (got_int || only_one_window()) { // abort selected or quit and only one window - did_emsg = FALSE; // avoid hit-enter prompt + did_emsg = false; // avoid hit-enter prompt getout(1); } // We can't close the window, it would disturb what @@ -1667,7 +1688,7 @@ static void create_windows(mparm_T *parmp) } else { handle_swap_exists(NULL); } - dorewind = TRUE; // start again + dorewind = true; // start again } os_breakcheck(); if (got_int) { @@ -1688,7 +1709,7 @@ static void create_windows(mparm_T *parmp) /// If opened more than one window, start editing files in the other /// windows. make_windows() has already opened the windows. -static void edit_buffers(mparm_T *parmp, char_u *cwd) +static void edit_buffers(mparm_T *parmp, char *cwd) { int arg_idx; // index in argument list int i; @@ -1696,9 +1717,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) win_T *win; char *p_shm_save = NULL; - /* - * Don't execute Win/Buf Enter/Leave autocommands here - */ + // Don't execute Win/Buf Enter/Leave autocommands here autocmd_no_enter++; autocmd_no_leave++; @@ -1709,9 +1728,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) } arg_idx = 1; - for (i = 1; i < parmp->window_count; ++i) { + for (i = 1; i < parmp->window_count; i++) { if (cwd != NULL) { - os_chdir((char *)cwd); + os_chdir(cwd); } // When w_arg_idx is -1 remove the window (see create_windows()). if (curwin->w_arg_idx == -1) { @@ -1733,9 +1752,9 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) if (i == 1) { char buf[100]; - p_shm_save = xstrdup((char *)p_shm); + p_shm_save = xstrdup(p_shm); snprintf(buf, sizeof(buf), "F%s", p_shm); - set_option_value("shm", 0L, buf, 0); + set_option_value_give_err("shm", 0L, buf, 0); } } else { if (curwin->w_next == NULL) { // just checking @@ -1760,7 +1779,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) // abort or quit selected if (got_int || only_one_window()) { // abort selected and only one window - did_emsg = FALSE; // avoid hit-enter prompt + did_emsg = false; // avoid hit-enter prompt getout(1); } win_close(curwin, true, false); @@ -1779,7 +1798,7 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) } if (p_shm_save != NULL) { - set_option_value("shm", 0L, p_shm_save, 0); + set_option_value_give_err("shm", 0L, p_shm_save, 0); xfree(p_shm_save); } @@ -1807,41 +1826,37 @@ static void edit_buffers(mparm_T *parmp, char_u *cwd) } } -/* - * Execute the commands from --cmd arguments "cmds[cnt]". - */ +// Execute the commands from --cmd arguments "cmds[cnt]". static void exe_pre_commands(mparm_T *parmp) { char **cmds = parmp->pre_commands; int cnt = parmp->n_pre_commands; int i; - if (cnt > 0) { - curwin->w_cursor.lnum = 0; // just in case.. - estack_push(ETYPE_ARGS, _("pre-vimrc command line"), 0); - current_sctx.sc_sid = SID_CMDARG; - for (i = 0; i < cnt; i++) { - do_cmdline_cmd(cmds[i]); - } - estack_pop(); - current_sctx.sc_sid = 0; - TIME_MSG("--cmd commands"); + if (cnt <= 0) { + return; } + + curwin->w_cursor.lnum = 0; // just in case.. + estack_push(ETYPE_ARGS, _("pre-vimrc command line"), 0); + current_sctx.sc_sid = SID_CMDARG; + for (i = 0; i < cnt; i++) { + do_cmdline_cmd(cmds[i]); + } + estack_pop(); + current_sctx.sc_sid = 0; + TIME_MSG("--cmd commands"); } -/* - * Execute "+", "-c" and "-S" arguments. - */ +// Execute "+", "-c" and "-S" arguments. static void exe_commands(mparm_T *parmp) { int i; - /* - * We start commands on line 0, make "vim +/pat file" match a - * pattern on line 1. But don't move the cursor when an autocommand - * with g`" was used. - */ - msg_scroll = TRUE; + // We start commands on line 0, make "vim +/pat file" match a + // pattern on line 1. But don't move the cursor when an autocommand + // with g`" was used. + msg_scroll = true; if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) { curwin->w_cursor.lnum = 0; } @@ -1861,12 +1876,12 @@ static void exe_commands(mparm_T *parmp) } if (!exmode_active) { - msg_scroll = FALSE; + msg_scroll = false; } // When started with "-q errorfile" jump to first error again. if (parmp->edit_type == EDIT_QF) { - qf_jump(NULL, 0, 0, FALSE); + qf_jump(NULL, 0, 0, false); } TIME_MSG("executing command arguments"); } @@ -1936,12 +1951,12 @@ static bool do_user_initialization(void) return do_exrc; } - char_u *init_lua_path = (char_u *)stdpaths_user_conf_subpath("init.lua"); - char_u *user_vimrc = (char_u *)stdpaths_user_conf_subpath("init.vim"); + char *init_lua_path = stdpaths_user_conf_subpath("init.lua"); + char *user_vimrc = stdpaths_user_conf_subpath("init.vim"); // init.lua if (os_path_exists(init_lua_path) - && do_source((char *)init_lua_path, true, DOSO_VIMRC)) { + && do_source(init_lua_path, true, DOSO_VIMRC)) { if (os_path_exists(user_vimrc)) { semsg(_("E5422: Conflicting configs: \"%s\" \"%s\""), init_lua_path, user_vimrc); @@ -1949,15 +1964,16 @@ static bool do_user_initialization(void) xfree(user_vimrc); xfree(init_lua_path); - return false; + do_exrc = p_exrc; + return do_exrc; } xfree(init_lua_path); // init.vim - if (do_source((char *)user_vimrc, true, DOSO_VIMRC) != FAIL) { + if (do_source(user_vimrc, true, DOSO_VIMRC) != FAIL) { do_exrc = p_exrc; if (do_exrc) { - do_exrc = (path_full_compare(VIMRC_FILE, (char *)user_vimrc, false, true) != kEqualFiles); + do_exrc = (path_full_compare(VIMRC_FILE, user_vimrc, false, true) != kEqualFiles); } xfree(user_vimrc); return do_exrc; @@ -2001,6 +2017,41 @@ static bool do_user_initialization(void) return do_exrc; } +// Read initialization commands from ".nvim.lua", ".nvimrc", or ".exrc" in +// current directory. This is only done if the 'exrc' option is set. +// Only do this if VIMRC_FILE is not the same as vimrc file sourced in +// do_user_initialization. +static void do_exrc_initialization(void) +{ + char *str; + + if (os_path_exists(VIMRC_LUA_FILE)) { + str = nlua_read_secure(VIMRC_LUA_FILE); + if (str != NULL) { + Error err = ERROR_INIT; + nlua_exec(cstr_as_string(str), (Array)ARRAY_DICT_INIT, &err); + xfree(str); + if (ERROR_SET(&err)) { + semsg("Error detected while processing %s:", VIMRC_LUA_FILE); + semsg_multiline(err.msg); + api_clear_error(&err); + } + } + } else if (os_path_exists(VIMRC_FILE)) { + str = nlua_read_secure(VIMRC_FILE); + if (str != NULL) { + do_source_str(str, VIMRC_FILE); + xfree(str); + } + } else if (os_path_exists(EXRC_FILE)) { + str = nlua_read_secure(EXRC_FILE); + if (str != NULL) { + do_source_str(str, EXRC_FILE); + xfree(str); + } + } +} + /// Source startup scripts static void source_startup_scripts(const mparm_T *const parmp) FUNC_ATTR_NONNULL_ALL @@ -2019,35 +2070,8 @@ static void source_startup_scripts(const mparm_T *const parmp) do_system_initialization(); if (do_user_initialization()) { - // Read initialization commands from ".vimrc" or ".exrc" in current - // directory. This is only done if the 'exrc' option is set. - // Because of security reasons we disallow shell and write commands - // now, except for unix if the file is owned by the user or 'secure' - // option has been reset in environment of global "exrc" or "vimrc". - // Only do this if VIMRC_FILE is not the same as vimrc file sourced in - // do_user_initialization. -#if defined(UNIX) - // If vimrc file is not owned by user, set 'secure' mode. - if (!os_file_owned(VIMRC_FILE)) // NOLINT(readability/braces) -#endif - secure = p_secure; - - if (do_source(VIMRC_FILE, true, DOSO_VIMRC) == FAIL) { -#if defined(UNIX) - // if ".exrc" is not owned by user set 'secure' mode - if (!os_file_owned(EXRC_FILE)) { - secure = p_secure; - } else { - secure = 0; - } -#endif - (void)do_source(EXRC_FILE, false, DOSO_NONE); - } + do_exrc_initialization(); } - if (secure == 2) { - need_wait_return = true; - } - secure = 0; } TIME_MSG("sourcing vimrc file(s)"); } @@ -2062,19 +2086,20 @@ static int execute_env(char *env) FUNC_ATTR_NONNULL_ALL { const char *initstr = os_getenv(env); - if (initstr != NULL) { - estack_push(ETYPE_ENV, env, 0); - const sctx_T save_current_sctx = current_sctx; - current_sctx.sc_sid = SID_ENV; - current_sctx.sc_seq = 0; - current_sctx.sc_lnum = 0; - do_cmdline_cmd((char *)initstr); - - estack_pop(); - current_sctx = save_current_sctx; - return OK; - } - return FAIL; + if (initstr == NULL) { + return FAIL; + } + + estack_push(ETYPE_ENV, env, 0); + const sctx_T save_current_sctx = current_sctx; + current_sctx.sc_sid = SID_ENV; + current_sctx.sc_seq = 0; + current_sctx.sc_lnum = 0; + do_cmdline_cmd((char *)initstr); + + estack_pop(); + current_sctx = save_current_sctx; + return OK; } /// Prints the following then exits: @@ -2090,17 +2115,17 @@ static void mainerr(const char *errstr, const char *str) signal_stop(); // kill us with CTRL-C here, if you like - mch_errmsg(prgname); - mch_errmsg(": "); - mch_errmsg(_(errstr)); + os_errmsg(prgname); + os_errmsg(": "); + os_errmsg(_(errstr)); if (str != NULL) { - mch_errmsg(": \""); - mch_errmsg(str); - mch_errmsg("\""); + os_errmsg(": \""); + os_errmsg((char *)str); + os_errmsg("\""); } - mch_errmsg(_("\nMore info with \"")); - mch_errmsg(prgname); - mch_errmsg(" -h\"\n"); + os_errmsg(_("\nMore info with \"")); + os_errmsg(prgname); + os_errmsg(" -h\"\n"); os_exit(1); } @@ -2109,8 +2134,8 @@ static void mainerr(const char *errstr, const char *str) static void version(void) { // TODO(bfred): not like this? - nlua_init(); - info_message = true; // use mch_msg(), not mch_errmsg() + nlua_init(NULL, 0, -1); + info_message = true; // use os_msg(), not os_errmsg() list_version(); msg_putchar('\n'); msg_didout = false; @@ -2121,53 +2146,53 @@ static void usage(void) { signal_stop(); // kill us with CTRL-C here, if you like - mch_msg(_("Usage:\n")); - mch_msg(_(" nvim [options] [file ...] Edit file(s)\n")); - mch_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n")); - mch_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n")); - mch_msg(_("\nOptions:\n")); - mch_msg(_(" -- Only file names after this\n")); - mch_msg(_(" + Start at end of file\n")); - mch_msg(_(" --cmd <cmd> Execute <cmd> before any config\n")); - mch_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n")); - mch_msg("\n"); - mch_msg(_(" -b Binary mode\n")); - mch_msg(_(" -d Diff mode\n")); - mch_msg(_(" -e, -E Ex mode\n")); - mch_msg(_(" -es, -Es Silent (batch) mode\n")); - mch_msg(_(" -h, --help Print this help message\n")); - mch_msg(_(" -i <shada> Use this shada file\n")); - mch_msg(_(" -m Modifications (writing files) not allowed\n")); - mch_msg(_(" -M Modifications in text not allowed\n")); - mch_msg(_(" -n No swap file, use memory only\n")); - mch_msg(_(" -o[N] Open N windows (default: one per file)\n")); - mch_msg(_(" -O[N] Open N vertical windows (default: one per file)\n")); - mch_msg(_(" -p[N] Open N tab pages (default: one per file)\n")); - mch_msg(_(" -r, -L List swap files\n")); - mch_msg(_(" -r <file> Recover edit state for this file\n")); - mch_msg(_(" -R Read-only mode\n")); - mch_msg(_(" -S <session> Source <session> after loading the first file\n")); - mch_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n")); - mch_msg(_(" -u <config> Use this config file\n")); - mch_msg(_(" -v, --version Print version information\n")); - mch_msg(_(" -V[N][file] Verbose [level][file]\n")); - mch_msg("\n"); - mch_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n")); - mch_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n")); - mch_msg(_(" --headless Don't start a user interface\n")); - mch_msg(_(" --listen <address> Serve RPC API from this address\n")); - mch_msg(_(" --noplugin Don't load plugins\n")); - mch_msg(_(" --remote[-subcommand] Execute commands remotely on a server\n")); - mch_msg(_(" --server <address> Specify RPC server to send commands to\n")); - mch_msg(_(" --startuptime <file> Write startup timing messages to <file>\n")); - mch_msg(_("\nSee \":help startup-options\" for all options.\n")); + os_msg(_("Usage:\n")); + os_msg(_(" nvim [options] [file ...] Edit file(s)\n")); + os_msg(_(" nvim [options] -t <tag> Edit file where tag is defined\n")); + os_msg(_(" nvim [options] -q [errorfile] Edit file with first error\n")); + os_msg(_("\nOptions:\n")); + os_msg(_(" -- Only file names after this\n")); + os_msg(_(" + Start at end of file\n")); + os_msg(_(" --cmd <cmd> Execute <cmd> before any config\n")); + os_msg(_(" +<cmd>, -c <cmd> Execute <cmd> after config and first file\n")); + os_msg(_(" -l <script> [args...] Execute Lua <script> (with optional args)\n")); + os_msg("\n"); + os_msg(_(" -b Binary mode\n")); + os_msg(_(" -d Diff mode\n")); + os_msg(_(" -e, -E Ex mode\n")); + os_msg(_(" -es, -Es Silent (batch) mode\n")); + os_msg(_(" -h, --help Print this help message\n")); + os_msg(_(" -i <shada> Use this shada file\n")); + os_msg(_(" -m Modifications (writing files) not allowed\n")); + os_msg(_(" -M Modifications in text not allowed\n")); + os_msg(_(" -n No swap file, use memory only\n")); + os_msg(_(" -o[N] Open N windows (default: one per file)\n")); + os_msg(_(" -O[N] Open N vertical windows (default: one per file)\n")); + os_msg(_(" -p[N] Open N tab pages (default: one per file)\n")); + os_msg(_(" -r, -L List swap files\n")); + os_msg(_(" -r <file> Recover edit state for this file\n")); + os_msg(_(" -R Read-only mode\n")); + os_msg(_(" -S <session> Source <session> after loading the first file\n")); + os_msg(_(" -s <scriptin> Read Normal mode commands from <scriptin>\n")); + os_msg(_(" -u <config> Use this config file\n")); + os_msg(_(" -v, --version Print version information\n")); + os_msg(_(" -V[N][file] Verbose [level][file]\n")); + os_msg("\n"); + os_msg(_(" --api-info Write msgpack-encoded API metadata to stdout\n")); + os_msg(_(" --clean \"Factory defaults\" (skip user config and plugins, shada)\n")); + os_msg(_(" --embed Use stdin/stdout as a msgpack-rpc channel\n")); + os_msg(_(" --headless Don't start a user interface\n")); + os_msg(_(" --listen <address> Serve RPC API from this address\n")); + os_msg(_(" --noplugin Don't load plugins\n")); + os_msg(_(" --remote[-subcommand] Execute commands remotely on a server\n")); + os_msg(_(" --server <address> Specify RPC server to send commands to\n")); + os_msg(_(" --startuptime <file> Write startup timing messages to <file>\n")); + os_msg(_("\nSee \":help startup-options\" for all options.\n")); } -/* - * Check the result of the ATTENTION dialog: - * When "Quit" selected, exit Vim. - * When "Recover" selected, recover the file. - */ +// Check the result of the ATTENTION dialog: +// When "Quit" selected, exit Vim. +// When "Recover" selected, recover the file. static void check_swap_exists_action(void) { if (swap_exists_action == SEA_QUIT) { |