commit 30dae87de4c6d6c8bda9657e22e187634cfa12a8
parent a8dad46e1c3034765e479bae53094398f458dfa8
Author: Cameron Ring <cameron@cs.stanford.edu>
Date: Wed, 20 Aug 2025 20:34:49 -0700
fix(startup): file buf is lost if stdin is empty and "-" is last #35402
Problem:
Running `echo dummy | nvim file1 file2` closes the file1 buffer if
file1 doesn't exist.
Solution:
Logic changed in 43e8ec9 such that stdin buffer may now be created *after*
file args. Handle that case.
Diffstat:
2 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/src/nvim/main.c b/src/nvim/main.c
@@ -1623,15 +1623,37 @@ static void read_stdin(void)
swap_exists_action = SEA_DIALOG;
no_wait_return = true;
bool save_msg_didany = msg_didany;
+ buf_T *prev_buf = NULL;
+
+ if (curbuf->b_ffname) {
+ // curbuf is already opened for a file, create a new buffer for stdin. #35269
+ buf_T *newbuf = buflist_new(NULL, NULL, 0, 0);
+ if (newbuf == NULL) {
+ semsg("Failed to create buffer for stdin");
+ return;
+ }
+
+ // remember the current buffer so we can go back to it
+ prev_buf = curbuf;
+ set_curbuf(newbuf, 0, false);
+ }
+
set_buflisted(true);
// Create memfile and read from stdin.
open_buffer(true, NULL, 0);
- if (buf_is_empty(curbuf) && curbuf->b_next != NULL) {
- // stdin was empty, go to buffer 2 (e.g. "echo file1 | xargs nvim"). #8561
- do_cmdline_cmd("silent! bnext");
- // Delete the empty stdin buffer.
- do_cmdline_cmd("bwipeout 1");
+ if (buf_is_empty(curbuf)) {
+ // stdin was empty so we should wipe it (e.g. "echo file1 | xargs nvim"). #8561
+ // stdin buffer may be first or last ("echo foo | nvim file1 -"). #35269
+ if ((curbuf->b_next != NULL) || (curbuf->b_prev != NULL)) {
+ do_bufdel(DOBUF_WIPE, NULL, 0, 0, 0, 1);
+ }
+ }
+
+ // we had to switch buffers to load stdin, switch back
+ if (prev_buf) {
+ set_curbuf(prev_buf, 0, false);
}
+
no_wait_return = false;
msg_didany = save_msg_didany;
TIME_MSG("reading stdin");
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
@@ -534,6 +534,26 @@ describe('startup', function()
)
end)
+ it('if stdin is empty and - is last: selects buffer 1, deletes buffer 3 #35269', function()
+ eq(
+ '\r\n 1 %a "file1" line 0\r\n 2 #h "file2" line 1',
+ fn.system({
+ nvim_prog,
+ '-n',
+ '-u',
+ 'NONE',
+ '-i',
+ 'NONE',
+ '--headless',
+ '+ls!',
+ '+qall!',
+ 'file1',
+ 'file2',
+ '-',
+ }, { '' })
+ )
+ end)
+
it('stdin with -es/-Es #7679', function()
local input = { 'append', 'line1', 'line2', '.', '%print', '' }
local inputstr = table.concat(input, '\n')