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.c133
1 files changed, 66 insertions, 67 deletions
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 30b6b6e86b..dc102f6f6d 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -6,7 +6,6 @@
#endif
#include <assert.h>
#include <limits.h>
-#include <msgpack/pack.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -37,13 +36,14 @@
#include "nvim/diff.h"
#include "nvim/drawline.h"
#include "nvim/drawscreen.h"
+#include "nvim/errors.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/userfunc.h"
#include "nvim/event/loop.h"
#include "nvim/event/multiqueue.h"
-#include "nvim/event/process.h"
+#include "nvim/event/proc.h"
#include "nvim/event/stream.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
@@ -154,7 +154,6 @@ void event_init(void)
loop_init(&main_loop, NULL);
resize_events = multiqueue_new_child(main_loop.events);
- input_init();
signal_init();
// mspgack-rpc initialization
channel_init();
@@ -175,7 +174,7 @@ bool event_teardown(void)
loop_poll_events(&main_loop, 0); // Drain thread_events, fast_events.
input_stop();
channel_teardown();
- process_teardown(&main_loop);
+ proc_teardown(&main_loop);
timer_teardown();
server_teardown();
signal_teardown();
@@ -267,7 +266,7 @@ int main(int argc, char **argv)
if (argc > 1 && STRICMP(argv[1], "-ll") == 0) {
if (argc == 2) {
- print_mainerr(err_arg_missing, argv[1]);
+ print_mainerr(err_arg_missing, argv[1], NULL);
exit(1);
}
nlua_run_script(argv, argc, 3);
@@ -333,12 +332,6 @@ int main(int argc, char **argv)
#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,
use_builtin_ui);
@@ -356,11 +349,16 @@ int main(int argc, char **argv)
ui_client_channel_id = rv;
}
+ // NORETURN: Start builtin UI client.
if (ui_client_channel_id) {
- time_finish();
ui_client_run(remote_ui); // NORETURN
}
assert(!ui_client_channel_id && !use_builtin_ui);
+ // Nvim server...
+
+ if (!server_init(params.listen_addr)) {
+ mainerr(IObuff, NULL, NULL);
+ }
TIME_MSG("expanding arguments");
@@ -545,10 +543,8 @@ int main(int argc, char **argv)
no_wait_return = true;
- //
// Create the requested number of windows and edit buffers in them.
// Also does recovery if "recoverymode" set.
- //
create_windows(&params);
TIME_MSG("opening buffers");
@@ -971,8 +967,8 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
os_exit(2);
}
- if (o.type == kObjectTypeDictionary) {
- rvobj.data.dictionary = o.data.dictionary;
+ if (o.type == kObjectTypeDict) {
+ rvobj.data.dict = o.data.dict;
} else {
fprintf(stderr, "vim._cs_remote returned unexpected value\n");
os_exit(2);
@@ -981,32 +977,32 @@ static void remote_request(mparm_T *params, int remote_args, char *server_addr,
TriState should_exit = kNone;
TriState tabbed = kNone;
- for (size_t i = 0; i < rvobj.data.dictionary.size; i++) {
- if (strequal(rvobj.data.dictionary.items[i].key.data, "errmsg")) {
- if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) {
+ for (size_t i = 0; i < rvobj.data.dict.size; i++) {
+ if (strequal(rvobj.data.dict.items[i].key.data, "errmsg")) {
+ if (rvobj.data.dict.items[i].value.type != kObjectTypeString) {
fprintf(stderr, "vim._cs_remote returned an unexpected type for 'errmsg'\n");
os_exit(2);
}
- fprintf(stderr, "%s\n", rvobj.data.dictionary.items[i].value.data.string.data);
+ fprintf(stderr, "%s\n", rvobj.data.dict.items[i].value.data.string.data);
os_exit(2);
- } else if (strequal(rvobj.data.dictionary.items[i].key.data, "result")) {
- if (rvobj.data.dictionary.items[i].value.type != kObjectTypeString) {
+ } else if (strequal(rvobj.data.dict.items[i].key.data, "result")) {
+ if (rvobj.data.dict.items[i].value.type != kObjectTypeString) {
fprintf(stderr, "vim._cs_remote returned an unexpected type for 'result'\n");
os_exit(2);
}
- printf("%s", rvobj.data.dictionary.items[i].value.data.string.data);
- } else if (strequal(rvobj.data.dictionary.items[i].key.data, "tabbed")) {
- if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) {
+ printf("%s", rvobj.data.dict.items[i].value.data.string.data);
+ } else if (strequal(rvobj.data.dict.items[i].key.data, "tabbed")) {
+ if (rvobj.data.dict.items[i].value.type != kObjectTypeBoolean) {
fprintf(stderr, "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 (strequal(rvobj.data.dictionary.items[i].key.data, "should_exit")) {
- if (rvobj.data.dictionary.items[i].value.type != kObjectTypeBoolean) {
+ tabbed = rvobj.data.dict.items[i].value.data.boolean ? kTrue : kFalse;
+ } else if (strequal(rvobj.data.dict.items[i].key.data, "should_exit")) {
+ if (rvobj.data.dict.items[i].value.type != kObjectTypeBoolean) {
fprintf(stderr, "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;
+ should_exit = rvobj.data.dict.items[i].value.data.boolean ? kTrue : kFalse;
}
}
if (should_exit == kNone || tabbed == kNone) {
@@ -1054,7 +1050,7 @@ static void command_line_scan(mparm_T *parmp)
// "+" or "+{number}" or "+/{pat}" or "+{command}" argument.
if (argv[0][0] == '+' && !had_minmin) {
if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
+ mainerr(err_extra_cmd, NULL, NULL);
}
argv_idx = -1; // skip to next argument
if (argv[0][1] == NUL) {
@@ -1075,7 +1071,7 @@ static void command_line_scan(mparm_T *parmp)
parmp->no_swap_file = true;
} else {
if (parmp->edit_type > EDIT_STDIN) {
- mainerr(err_too_many_args, argv[0]);
+ mainerr(err_too_many_args, argv[0], NULL);
}
parmp->had_stdin_file = true;
parmp->edit_type = EDIT_STDIN;
@@ -1100,23 +1096,13 @@ static void command_line_scan(mparm_T *parmp)
// set stdout to binary to avoid crlf in --api-info output
_setmode(STDOUT_FILENO, _O_BINARY);
#endif
- FileDescriptor fp;
- const int fof_ret = file_open_fd(&fp, STDOUT_FILENO,
- kFileWriteOnly);
- if (fof_ret != 0) {
- semsg(_("E5421: Failed to open stdin: %s"), os_strerror(fof_ret));
- }
String data = api_metadata_raw();
- const ptrdiff_t written_bytes = file_write(&fp, data.data, data.size);
+ const ptrdiff_t written_bytes = os_write(STDOUT_FILENO, data.data, data.size, false);
if (written_bytes < 0) {
- msgpack_file_write_error((int)written_bytes);
+ semsg(_("E5420: Failed to write to file: %s"), os_strerror((int)written_bytes));
}
- const int ff_ret = file_flush(&fp);
- if (ff_ret < 0) {
- msgpack_file_write_error(ff_ret);
- }
os_exit(0);
} else if (STRICMP(argv[0] + argv_idx, "headless") == 0) {
headless_mode = true;
@@ -1148,7 +1134,7 @@ static void command_line_scan(mparm_T *parmp)
nlua_disable_preload = true;
} else {
if (argv[0][argv_idx]) {
- mainerr(err_opt_unknown, argv[0]);
+ mainerr(err_opt_unknown, argv[0], NULL);
}
had_minmin = true;
}
@@ -1222,7 +1208,7 @@ static void command_line_scan(mparm_T *parmp)
break;
case 'q': // "-q" QuickFix mode
if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
+ mainerr(err_too_many_args, argv[0], NULL);
}
parmp->edit_type = EDIT_QF;
if (argv[0][argv_idx]) { // "-q{errorfile}"
@@ -1251,7 +1237,7 @@ static void command_line_scan(mparm_T *parmp)
break;
case 't': // "-t {tag}" or "-t{tag}" jump to tag
if (parmp->edit_type != EDIT_NONE) {
- mainerr(err_too_many_args, argv[0]);
+ mainerr(err_too_many_args, argv[0], NULL);
}
parmp->edit_type = EDIT_TAG;
if (argv[0][argv_idx]) { // "-t{tag}"
@@ -1285,7 +1271,7 @@ static void command_line_scan(mparm_T *parmp)
case 'c': // "-c{command}" or "-c {command}" exec command
if (argv[0][argv_idx] != NUL) {
if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
+ mainerr(err_extra_cmd, NULL, NULL);
}
parmp->commands[parmp->n_commands++] = argv[0] + argv_idx;
argv_idx = -1;
@@ -1302,19 +1288,19 @@ static void command_line_scan(mparm_T *parmp)
break;
default:
- mainerr(err_opt_unknown, argv[0]);
+ mainerr(err_opt_unknown, argv[0], NULL);
}
// Handle option arguments with argument.
if (want_argument) {
// Check for garbage immediately after the option letter.
if (argv[0][argv_idx] != NUL) {
- mainerr(err_opt_garbage, argv[0]);
+ mainerr(err_opt_garbage, argv[0], NULL);
}
argc--;
if (argc < 1 && c != 'S') { // -S has an optional argument
- mainerr(err_arg_missing, argv[0]);
+ mainerr(err_arg_missing, argv[0], NULL);
}
argv++;
argv_idx = -1;
@@ -1323,7 +1309,7 @@ static void command_line_scan(mparm_T *parmp)
case 'c': // "-c {command}" execute command
case 'S': // "-S {file}" execute Vim script
if (parmp->n_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
+ mainerr(err_extra_cmd, NULL, NULL);
}
if (c == 'S') {
char *a;
@@ -1354,7 +1340,7 @@ static void command_line_scan(mparm_T *parmp)
if (strequal(argv[-1], "--cmd")) {
// "--cmd {command}" execute command
if (parmp->n_pre_commands >= MAX_ARG_CMDS) {
- mainerr(err_extra_cmd, NULL);
+ mainerr(err_extra_cmd, NULL, NULL);
}
parmp->pre_commands[parmp->n_pre_commands++] = argv[0];
} else if (strequal(argv[-1], "--listen")) {
@@ -1436,7 +1422,7 @@ scripterror:
// Check for only one type of editing.
if (parmp->edit_type > EDIT_STDIN) {
- mainerr(err_too_many_args, argv[0]);
+ mainerr(err_too_many_args, argv[0], NULL);
}
parmp->edit_type = EDIT_FILE;
@@ -1444,6 +1430,17 @@ scripterror:
ga_grow(&global_alist.al_ga, 1);
char *p = xstrdup(argv[0]);
+ // On Windows expand "~\" or "~/" prefix in file names to profile directory.
+#ifdef MSWIN
+ if (*p == '~' && (p[1] == '\\' || p[1] == '/')) {
+ size_t size = strlen(os_homedir()) + strlen(p);
+ char *tilde_expanded = xmalloc(size);
+ snprintf(tilde_expanded, size, "%s%s", os_homedir(), p + 1);
+ xfree(p);
+ p = tilde_expanded;
+ }
+#endif
+
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);
@@ -1472,7 +1469,7 @@ scripterror:
}
if (embedded_mode && (silent_mode || parmp->luaf)) {
- mainerr(_("--embed conflicts with -es/-Es/-l"), NULL);
+ mainerr(_("--embed conflicts with -es/-Es/-l"), NULL, NULL);
}
// If there is a "+123" or "-c" command, set v:swapcommand to the first one.
@@ -1516,7 +1513,7 @@ static void init_startuptime(mparm_T *paramp)
}
for (int i = 1; i < paramp->argc - 1; i++) {
if (STRICMP(paramp->argv[i], "--startuptime") == 0) {
- time_init(paramp->argv[i + 1], is_embed ? "Embedded" : "Primary/TUI");
+ time_init(paramp->argv[i + 1], is_embed ? "Embedded" : "Primary (or UI client)");
time_start("--- NVIM STARTING ---");
break;
}
@@ -2135,28 +2132,30 @@ static int execute_env(char *env)
return OK;
}
-/// Prints the following then exits:
-/// - An error message `errstr`
-/// - A string `str` if not null
+/// Prints a message of the form "{msg1}: {msg2}: {msg3}", then exits with code 1.
///
-/// @param errstr string containing an error message
-/// @param str string to append to the primary error message, or NULL
-static void mainerr(const char *errstr, const char *str)
+/// @param msg1 error message
+/// @param msg2 extra message, or NULL
+/// @param msg3 extra message, or NULL
+static void mainerr(const char *msg1, const char *msg2, const char *msg3)
FUNC_ATTR_NORETURN
{
- print_mainerr(errstr, str);
+ print_mainerr(msg1, msg2, msg3);
os_exit(1);
}
-static void print_mainerr(const char *errstr, const char *str)
+static void print_mainerr(const char *msg1, const char *msg2, const char *msg3)
{
char *prgname = path_tail(argv0);
signal_stop(); // kill us with CTRL-C here, if you like
- fprintf(stderr, "%s: %s", prgname, _(errstr));
- if (str != NULL) {
- fprintf(stderr, ": \"%s\"", str);
+ fprintf(stderr, "%s: %s", prgname, _(msg1));
+ if (msg2 != NULL) {
+ fprintf(stderr, ": \"%s\"", msg2);
+ }
+ if (msg3 != NULL) {
+ fprintf(stderr, ": \"%s\"", msg3);
}
fprintf(stderr, _("\nMore info with \""));
fprintf(stderr, "%s -h\"\n", prgname);
@@ -2207,7 +2206,7 @@ static void usage(void)
printf(_(" --headless Don't start a user interface\n"));
printf(_(" --listen <address> Serve RPC API from this address\n"));
printf(_(" --remote[-subcommand] Execute commands remotely on a server\n"));
- printf(_(" --server <address> Specify RPC server to send commands to\n"));
+ printf(_(" --server <address> Connect to this Nvim server\n"));
printf(_(" --startuptime <file> Write startup timing messages to <file>\n"));
printf(_("\nSee \":help startup-options\" for all options.\n"));
}