[vim/vim] Whitespace in the middle of the line can be removed when exiting into Normal mode with enabled 'autoindent' (Issue #19363)

4 views
Skip to first unread message

Evgeni Chasnovski

unread,
Feb 8, 2026, 2:07:15 PM (2 days ago) Feb 8
to vim/vim, Subscribed
echasnovski created an issue (vim/vim#19363)

Steps to reproduce

  1. Start vim --clean with the following config file:

    set nocompatible
    set autoindent
    inoremap <M-t> <Cmd>call setline('.', 'v  v')<CR><Cmd>call setpos('.', [0, line('.'), 2, 0])<CR>
  2. Start Insert mode with i and press <M-t>. It inserts v v with cursor after the first v.

  3. Exit into Normal mode with <Esc>. The line stays the same v v, which is expected.

  4. Start Insert mode on an empty line with cc (or o, or O) and press <M-t>. It still inserts v v with cursor after first v.

  5. Exit into Normal mode with <Esc> (or <C-o>). Line becomes vv.

This seems to be a by-product of the following documented behavior:

If you do not type anything on the new line except <BS> or CTRL-D and
then type <Esc>, CTRL-O or <CR>, the indent is deleted again

Expected behaviour

Whitespace in the middle of the line is not changed when exiting into Normal mode.

Version of Vim

9.1.2132

Environment

OS: EndeavourOS Linux x86_64, 6.18.7-arch1-1
Terminal: Ghostty 1.2.3-arch2
$TERM: xterm-ghostty
Shell: Nushell 0.110.0

Logs and stack traces


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19363@github.com>

Christian Brabandt

unread,
Feb 8, 2026, 3:46:13 PM (2 days ago) Feb 8
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#19363)

yes correct for the documentation change. I guess the obvious question is, why do you enable autoindent? I guess that is automatically enabled by Neovim?

Something like this would fix it:

diff --git a/src/edit.c b/src/edit.c
index 2392361fb..45c71cbcb 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -30,7 +30,7 @@ static void start_arrow_common(pos_T *end_insert_pos, int change);
 #ifdef FEAT_SPELL
 static void check_spell_redraw(void);
 #endif
-static void stop_insert(pos_T *end_insert_pos, int esc, int nomove);
+static void stop_insert(pos_T *end_insert_pos, int esc, int nomove, int doformat);
 static int  echeck_abbr(int);
 static void mb_replace_pop_ins(int cc);
 static void replace_flush(void);
@@ -39,7 +39,7 @@ static int del_char_after_col(int limit_col);
 static void ins_reg(void);
 static void ins_ctrl_g(void);
 static void ins_ctrl_hat(void);
-static int  ins_esc(long *count, int cmdchar, int nomove);
+static int  ins_esc(long *count, int cmdchar, int nomove, int doformat);
 #ifdef FEAT_RIGHTLEFT
 static void ins_ctrl_(void);
 #endif
@@ -159,6 +159,7 @@ edit(
     int                inserted_space = FALSE;     // just inserted a space
     int                replaceState = MODE_REPLACE;
     int                nomove = FALSE;             // don't move cursor on return
+    int                doformat = TRUE;
 #ifdef FEAT_JOB_CHANNEL
     int                cmdchar_todo = cmdchar;
 #endif
@@ -899,7 +900,7 @@ doESCkey:
            if (ins_at_eol && gchar_cursor() == NUL)
                o_lnum = curwin->w_cursor.lnum;

-           if (ins_esc(&count, cmdchar, nomove))
+           if (ins_esc(&count, cmdchar, nomove, doformat))
            {
                // When CTRL-C was typed got_int will be set, with the result
                // that the autocommands won't be executed. When mapped got_int
@@ -1133,6 +1134,7 @@ doESCkey:
        case K_SCRIPT_COMMAND:      // <ScriptCmd>command<CR>
            {
                do_cmdkey_command(c, 0);
+               doformat = FALSE;

 #ifdef FEAT_TERMINAL
                if (term_use_loop())
@@ -2439,7 +2441,7 @@ start_arrow_common(
     if (!arrow_used && end_change)     // something has been inserted
     {
        AppendToRedobuff(ESC_STR);
-       stop_insert(end_insert_pos, FALSE, FALSE);
+       stop_insert(end_insert_pos, FALSE, FALSE, TRUE);
        arrow_used = TRUE;      // this means we stopped the current insert
     }
 #ifdef FEAT_SPELL
@@ -2522,7 +2524,8 @@ stop_arrow(void)
 stop_insert(
     pos_T      *end_insert_pos,
     int                esc,                    // called by ins_esc()
-    int                nomove)                 // <c-\><c-o>, don't move cursor
+    int                nomove,                 // <c-\><c-o>, don't move cursor
+    int                doformat)               // do not reformat
 {
     int                cc;
     string_T   inserted;
@@ -2591,7 +2594,8 @@ stop_insert(
        // Do this when ESC was used or moving the cursor up/down.
        // Check for the old position still being valid, just in case the text
        // got changed unexpectedly.
-       if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
+       if (doformat && !nomove && did_ai &&
+               (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL
                        && curwin->w_cursor.lnum != end_insert_pos->lnum))
                && end_insert_pos->lnum <= curbuf->b_ml.ml_line_count)
        {
@@ -3726,7 +3730,8 @@ ins_ctrl_hat(void)
 ins_esc(
     long       *count,
     int                cmdchar,
-    int                nomove)     // don't move cursor
+    int                nomove,     // don't move cursor
+    int                doformat)   // don't reformat
 {
     int                temp;
     static int disabled_redraw = FALSE;
@@ -3781,7 +3786,7 @@ ins_esc(
            disabled_redraw = TRUE;
            return FALSE;       // repeat the insert
        }
-       stop_insert(&curwin->w_cursor, TRUE, nomove);
+       stop_insert(&curwin->w_cursor, TRUE, nomove, doformat);
        undisplay_dollar();
     }

Note: be aware of whitespace changes. This is copied pasted using my terminal, it won't include tab changes and probably won't apply directly using patch/git


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19363/3868234852@github.com>

Evgeni Chasnovski

unread,
Feb 8, 2026, 3:49:19 PM (2 days ago) Feb 8
to vim/vim, Subscribed
echasnovski left a comment (vim/vim#19363)

I guess the obvious question is, why do you enable autoindent? I guess that is automatically enabled by Neovim?

Yes, it is enabled by Neovim by default. But I also prefer the behavior of when it is on.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19363/3868240723@github.com>

Christian Brabandt

unread,
Feb 9, 2026, 2:42:37 PM (20 hours ago) Feb 9
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#19363)

yes, you could try the above patch.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19363/3873492581@github.com>

Evgeni Chasnovski

unread,
Feb 9, 2026, 2:57:23 PM (20 hours ago) Feb 9
to vim/vim, Subscribed
echasnovski left a comment (vim/vim#19363)

yes, you could try the above patch.

Yes, it seems to have fixed this particular issue. Do you prefer me creating a PR with this change? I can do that, but without much understanding of any line of code here :)


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/19363/3873525640@github.com>

Reply all
Reply to author
Forward
0 new messages