From 61f166ec409b7621fcc42e4da40d6ccb19973749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20M=C3=BCller?= Date: Sun, 8 Mar 2026 16:58:14 -0700 Subject: [PATCH] fix(textformat): don't swallow "space" with auto-formatting enabled (#38181) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vim-patch:9.2.0124: auto-format may swallow white space Problem: With auto paragraph formatting enabled, when a user makes an attempt to add a new word before the end of a line and with the following space bringing the line width over 'textwidth', the space ends up just getting swallowed by the editor. Solution: Detect such a constellation and do not auto-format in that case (Daniel Müller). closes: vim/vim#19593 https://github.com/vim/vim/commit/24fd6980457a942d58c2fe74b945d951081bf8ab --- src/nvim/textformat.c | 16 ++++++++++++++++ test/old/testdir/test_textformat.vim | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index a0f14e2d9d..b20a2bbd3f 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -646,6 +646,22 @@ void auto_format(bool trailblank, bool prev_line) curwin->w_cursor = pos; } + // Also skip formatting when the user just typed whitespace in the + // middle of the line. Reformatting would join all paragraph lines and + // re-wrap, consuming the space at the line break point via + // OPENLINE_DELSPACES. By deferring, the next non-whitespace character + // will be inserted adjacent to the space, keeping it protected from + // being consumed at a line break. auto_format() will then reformat + // properly on the next keystroke. + if (*old != NUL && !trailblank && !wasatend && pos.col > 0 + && (State & MODE_INSERT)) { + char *line = get_cursor_line_ptr(); + if (WHITECHAR(line[pos.col - 1])) { + curwin->w_cursor = pos; + return; + } + } + // With the 'c' flag in 'formatoptions' and 't' missing: only format // comments. if (has_format_option(FO_WRAP_COMS) && !has_format_option(FO_WRAP) diff --git a/test/old/testdir/test_textformat.vim b/test/old/testdir/test_textformat.vim index 1d1c0e8b3a..31c2012136 100644 --- a/test/old/testdir/test_textformat.vim +++ b/test/old/testdir/test_textformat.vim @@ -1158,6 +1158,32 @@ func Test_fo_a_w() %bw! endfunc +" Test that auto-format ('a' flag) preserves spaces typed in the middle of a line +func Test_fo_a_midline_space() + new + let lines = [ + \ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa it but', + \ 'Lorem Ipsum is simply dummy text of the printing and typesetting dasddd', + \ 'industry.', + \ ] + call setline(1, lines) + set fo=ta tw=70 + + " Prevent INPUT_BUFLEN batching so auto_format runs between keystrokes + autocmd InsertCharPre * " nothing + + " Position at 't' of 'it' (col 68) and type space then Z + call cursor(1, 68) + call feedkeys("a Z\", 'xt') + + " The space between 'it' and 'Z' must be preserved + call assert_match('it Z', getline(1)) + + autocmd! InsertCharPre + set fo& tw& + bw! +endfunc + " Test for formatting lines using gq in visual mode func Test_visual_gq_format() new