diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/ui_events.in.h | 3 | ||||
-rw-r--r-- | src/nvim/event/process.c | 1 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 4 | ||||
-rw-r--r-- | src/nvim/tui/tui.c | 16 | ||||
-rw-r--r-- | src/nvim/ui_client.h | 3 |
5 files changed, 24 insertions, 3 deletions
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index fc70215352..6ca5024a04 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -167,4 +167,7 @@ void msg_history_show(Array entries) FUNC_API_SINCE(6) FUNC_API_REMOTE_ONLY; void msg_history_clear(void) FUNC_API_SINCE(10) FUNC_API_REMOTE_ONLY; + +void error_exit(Integer status) + FUNC_API_SINCE(12); #endif // NVIM_API_UI_EVENTS_IN_H diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 95bf4d1c3b..00ba1334b0 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -423,6 +423,7 @@ static void exit_event(void **argv) if (!exiting) { if (ui_client_channel_id) { + ui_client_exit_status = status; os_exit(status); } else { assert(status == 0); // Called from rpc_close(), which passes 0 as status. diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 44610c81d8..0a0f7c244d 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -4591,7 +4591,9 @@ static void ex_cquit(exarg_T *eap) FUNC_ATTR_NORETURN { // this does not always pass on the exit code to the Manx compiler. why? - getout(eap->addr_count > 0 ? (int)eap->line2 : EXIT_FAILURE); + int status = eap->addr_count > 0 ? (int)eap->line2 : EXIT_FAILURE; + ui_call_error_exit(status); + getout(status); } /// Do preparations for "qall" and "wqall". diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 9fea6442a9..4097b770c9 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -145,6 +145,7 @@ struct TUIData { } unibi_ext; char *space_buf; bool stopped; + int seen_error_exit; int width; int height; bool rgb; @@ -162,6 +163,7 @@ void tui_start(TUIData **tui_p, int *width, int *height, char **term) tui->is_starting = true; tui->screenshot = NULL; tui->stopped = false; + tui->seen_error_exit = 0; tui->loop = &main_loop; kv_init(tui->invalid_regions); signal_watcher_init(tui->loop, &tui->winch_handle, tui); @@ -384,8 +386,13 @@ static void terminfo_stop(TUIData *tui) unibi_out_ext(tui, tui->unibi_ext.disable_extended_keys); // May restore old title before exiting alternate screen. tui_set_title(tui, (String)STRING_INIT); - // Exit alternate screen. - unibi_out(tui, unibi_exit_ca_mode); + // if nvim exited with nonzero status, without indicated this was an + // intentional exit (like `:1cquit`), it likely was an internal failure. + // Don't clobber the stderr error message in this case. + if (ui_client_exit_status == tui->seen_error_exit) { + // Exit alternate screen. + unibi_out(tui, unibi_exit_ca_mode); + } if (tui->cursor_color_changed) { unibi_out_ext(tui, tui->unibi_ext.reset_cursor_color); } @@ -443,6 +450,11 @@ static void tui_terminal_stop(TUIData *tui) terminfo_stop(tui); } +void tui_error_exit(TUIData *tui, Integer status) +{ + tui->seen_error_exit = (int)status; +} + void tui_stop(TUIData *tui) { tui_terminal_stop(tui); diff --git a/src/nvim/ui_client.h b/src/nvim/ui_client.h index 7e5f847039..05964422f3 100644 --- a/src/nvim/ui_client.h +++ b/src/nvim/ui_client.h @@ -23,6 +23,9 @@ EXTERN sattr_T *grid_line_buf_attr INIT(= NULL); // ID of the ui client channel. If zero, the client is not running. EXTERN uint64_t ui_client_channel_id INIT(= 0); +// exit status from embedded nvim process +EXTERN int ui_client_exit_status INIT(= 0); + // TODO(bfredl): the current structure for how tui and ui_client.c communicate is a bit awkward. // This will be restructured as part of The UI Devirtualization Project. |