aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-02-11 18:25:01 +0800
committerGitHub <noreply@github.com>2023-02-11 18:25:01 +0800
commit7d58de11f49c574a8a305e28e96b9ff810493012 (patch)
treea3fc6cd9cbb6e689d7f1bd1be776f493ee3802b8 /src
parent4be6c6cf0ddf5e31d4103cb5df06651ba6f4897b (diff)
downloadrneovim-7d58de11f49c574a8a305e28e96b9ff810493012.tar.gz
rneovim-7d58de11f49c574a8a305e28e96b9ff810493012.tar.bz2
rneovim-7d58de11f49c574a8a305e28e96b9ff810493012.zip
fix(rpc)!: preseve files when stdio channel is closed (#22137)
BREAKING CHANGE: Unsaved changes are now preserved rather than discarded when stdio channel is closed.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/event/process.c7
-rw-r--r--src/nvim/main.c18
-rw-r--r--src/nvim/msgpack_rpc/channel.c4
3 files changed, 22 insertions, 7 deletions
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 1a524a56ca..1219566e9b 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -422,7 +422,12 @@ static void exit_event(void **argv)
}
if (!exiting) {
- os_exit(status);
+ if (ui_client_channel_id) {
+ os_exit(status);
+ } else {
+ assert(status == 0); // Called from rpc_close(), which passes 0 as status.
+ preserve_exit(NULL);
+ }
}
}
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 4ee02b4e1b..f36730a8b3 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -674,6 +674,7 @@ void os_exit(int r)
void getout(int exitval)
FUNC_ATTR_NORETURN
{
+ assert(!ui_client_channel_id);
exiting = true;
// On error during Ex mode, exit with a non-zero code.
@@ -794,6 +795,7 @@ void getout(int exitval)
}
/// Preserve files, print contents of `errmsg`, and exit 1.
+/// @param errmsg If NULL, this function will not print anything.
///
/// May be called from deadly_signal().
void preserve_exit(const char *errmsg)
@@ -819,19 +821,21 @@ void preserve_exit(const char *errmsg)
// For TUI: exit alternate screen so that the error messages can be seen.
ui_client_stop();
}
- os_errmsg(errmsg);
- os_errmsg("\n");
+ if (errmsg != NULL) {
+ os_errmsg(errmsg);
+ os_errmsg("\n");
+ }
if (ui_client_channel_id) {
os_exit(1);
}
- 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) {
- os_errmsg("Vim: preserving files...\r\n");
- ui_flush();
+ if (errmsg != NULL) {
+ os_errmsg("Vim: preserving files...\r\n");
+ }
ml_sync_all(false, false, true); // preserve all swap files
break;
}
@@ -839,7 +843,9 @@ void preserve_exit(const char *errmsg)
ml_close_all(false); // close all memfiles, without deleting
- os_errmsg("Vim: Finished.\r\n");
+ if (errmsg != NULL) {
+ os_errmsg("Vim: Finished.\r\n");
+ }
getout(1);
}
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 34c8f89e3f..f8be0d4c8d 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -550,6 +550,10 @@ void rpc_close(Channel *channel)
if (channel->streamtype == kChannelStreamStdio
|| (channel->id == ui_client_channel_id && channel->streamtype != kChannelStreamProc)) {
+ if (channel->streamtype == kChannelStreamStdio) {
+ // Avoid hanging when there are no other UIs and a prompt is triggered on exit.
+ remote_ui_disconnect(channel->id);
+ }
exit_from_channel(0);
}
}