aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/main.c')
-rw-r--r--src/nvim/main.c855
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(&params);
- 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(&params, params.remote, params.server_addr, argc, argv);
+ remote_request(&params, 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(&params)) {
+ params.edit_type = EDIT_STDIN;
}
+ open_script_files(&params);
+
// 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(&params);
@@ -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) {