aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/main.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/main.c
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-usermarks.tar.gz
rneovim-usermarks.tar.bz2
rneovim-usermarks.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
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 =