neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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:
Msrc/nvim/main.c | 32+++++++++++++++++++++++++++-----
Mtest/functional/core/startup_spec.lua | 20++++++++++++++++++++
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')