fix(textformat): don't swallow "space" with auto-formatting enabled (#38181)

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

24fd698045
This commit is contained in:
Daniel Müller
2026-03-08 16:58:14 -07:00
committed by GitHub
parent 9a9b9c581c
commit 61f166ec40
2 changed files with 42 additions and 0 deletions

View File

@@ -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)

View File

@@ -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\<Esc>", '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