Vim 正常模式将制表符显示为 1 个字符宽,不与左边距对齐

Vim normal mode shows tabs as 1 char wide, not aligned to left margin

这是我的光标在正常模式下的最左边。

这是它在插入模式下的样子。

我有以下文件类型设置

au BufNewFile,BufRead *.py
     \ set tabstop=4 |
     \ set softtabstop=4 |
     \ set shiftwidth=4 |
     \ set textwidth=79 |
     \ set expandtab |
     \ set autoindent |
     \ set fileformat=unix |

 au BufNewFile,BufRead *.js, *.html, *.css
     \ set tabstop=2 |
     \ set softtabstop=2 |
     \ set shiftwidth=2 |

 au BufNewFile,BufRead *.go
     \ set tabstop=4 |
     \ set softtabstop=4 |
     \ set shiftwidth=4 |
     \ set noexpandtab |
     \ set smarttab

This typically happens with .go files as I guess I have noexpandtab. But the cursor not going to column-0 in normal mode freaks me out.

您看到的是正常的 Vim 行为。在以 <Tab> 字符开头的行上,光标 显示在 字符上;由于制表符占用多个(默认为 8)个屏幕单元格,Vim 将光标放在字符的末尾(对于双倍宽度的字符,Vim 也将字符加倍,但 8 个字符宽的光标在 正常模式 下可能看起来很糟糕,并且在终端技术上可能不可行)。在 插入模式 中,光标位于字符之间,因此您可以将光标定位在选项卡之前(例如使用 gI)和之后(I)。

补救措施

最好接受这种行为;如果您真的受不了,这里有一些可以改变行为的选项。不幸的是,每个都有警告和缺点:

  • :set list 一起,Vim 将光标置于前面,如您所愿。但是您也会看到 whitespace 突出显示。您可以 fiddle 使用 'listchars' 选项来减少视觉噪音,但这样您就会失去这个有用的功能。
  • 使用 :set virtualedit=all,您可以将光标定位在选项卡内的任意位置。从中间开始编辑会将制表符分成 space 前后。此外,您可以将光标定位在物理文本后面的任何位置。
  • 使用 :autocmds,您可以在读取缓冲区时将制表符转换为 spaces,然后再写入。 (参见 :help retab-example