在Vim中,Tab键等同于4个空格,并且在花括号后自动缩进。

1423

如何让 vi-Vim 永远不使用制表符(将空格转换为制表符,很糟糕!),使 Tab 键等于 4 个空格,并在花括号块后自动缩进代码,就像 Emacs 一样?

另外,如何保存这些设置,以便我永远不必再次输入它们?

我看到了其他相关的问题,但似乎总是与我想要的有些不同。


3
相关链接:如何在Vim中将制表符替换为空格? 在 Vim Stack Exchange。 - kenorb
12个回答

2130

正如其他答案中指出的那样,现在首选的方法不是使用smartindent,而是在您的.vimrc中使用以下内容:

filetype plugin indent on
" show existing tab with 4 spaces width
set tabstop=4
" when indenting with '>', use 4 spaces width
set shiftwidth=4
" On pressing tab, insert 4 spaces
set expandtab

In your [.vimrc:][1] file:
set smartindent
set tabstop=4
set shiftwidth=4
set expandtab

The help files take a bit of time to get used to, but the more you read, the better Vim gets:

:help smartindent

Even better, you can embed these settings in your source for portability:

:help auto-setting

To see your current settings:

:set all

As graywh points out in the comments, smartindent has been replaced by cindent which "Works more cleverly", although still mainly for languages with C-like syntax:

:help C-indenting

4
如果您设置了"expandtab",则应该使用空格。您是否也设置了“set compatible”?这会产生各种副作用,包括将"expandtab"重置为其默认值"off"。 - Ken
66
抱歉,但smartindent已被cindent替代,它本身仅适用于C风格的语法。在vimrc中启用其中任何一个可能会在处理其他语言时引起问题。只需使用"filetype indent on"即可。 - graywh
2
我注意到当我按下 backspace 键时,wim 只会一次删除一个空格,这很烦人。有什么解决办法吗? - Fermat's Little Student
4
如果我启用了expandtab,是否还有办法在文本中输入制表符? - Daniele Segato
3
在插入模式下,可以使用 @DanieleSegato 建议的 <ctrl v><tab> 来插入制表符,即使 expandtab 选项开启也可以。原文链接:https://dev59.com/fm445IYBdhLWcg3wmLdd - Ken
显示剩余11条评论

279

如果您打开一个同时使用制表符和空格的文件,假设您已经

set expandtab ts=4 sw=4 ai

你可以使用以下方法将整个文件中的所有制表符替换为空格:

:%retab

11
如您不希望使用空格来替换制表符,请删掉"expandtab"这行代码。 - Eno
7
选项卡不是空格吗?;-) - Rob Wells
13
@Rob-Wells: 我将“whitespace”更改为“spaces”。现在你满意了吗?;-) - netjeff
你能解释一下第一行是什么意思吗? - anon
4
expandtab 用来确定是否将制表符扩展为空格。ts(tabstop)是文件中 <Tab> 字符计数的空格数。sw(shiftwidth)是(自动)缩进时每个步骤要使用的空格数。ai(autoindent)表示在开始新行时从当前行复制缩进。 - mcmacerson

93

获取特定文件类型的缩进最好的方法是在您的vimrc中使用filetype plugin indent on。例如,您可以在.vim/ftplugin/c.vim中指定set sw=4 sts=4 et,而无需将其应用于正在编辑的所有文件,并且其他非C类型语法也会正确缩进,甚至包括Lisp。


10
在我看来,比被标记为正确的答案更好。文件类型缩进“filetype indent on”优于“cindent”和“smartindent”。 - 0fnt

74

为了在大多数文件中使用4个空格的 tab,Makefile 中使用真正的 8 个字符宽度的 tab,以及在各种文件(包括 C/C++)中自动缩进,请将以下内容放入您的 ~/.vimrc 文件:

" Only do this part when compiled with support for autocommands.
if has("autocmd")
    " Use filetype detection and file-based automatic indenting.
    filetype plugin indent on

    " Use actual tab chars in Makefiles.
    autocmd FileType make set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab
endif

" For everything else, use a tab width of 4 space chars.
set tabstop=4       " The width of a TAB is set to 4.
                    " Still it is a \t. It is just that
                    " Vim will interpret it to be having
                    " a width of 4.
set shiftwidth=4    " Indents will have a width of 4.
set softtabstop=4   " Sets the number of columns for a TAB.
set expandtab       " Expand TABs to spaces.

1
为什么不需要else?在我看来,最后一行似乎在所有情况下都会覆盖特定于makefile的内容。 - lucidbrot
8
嗨 @lucidbrot,“autocmd FileType make”这条语句基本上告诉 vim 每当打开一个 Makefile 时使用哪些设置。而它下面的行是设置默认值。换句话说,当文件被打开时,“tabstop=8 ...”这些设置会在后面应用并覆盖初始化时应用的“tabstop=4 ...”设置。 - Shervin Emami
2
+1 使其可扩展。我选择这个,因为关于每个部分的注释允许我按照自己的方式设置事物(而不会破坏任何东西),因为我知道每件事情都在做什么。万岁! - bballdave025

66

在许多Linux系统(例如Ubuntu)上,默认情况下不存在.vimrc文件,因此建议您首先创建该文件。

不要使用位于主目录中的.viminfo文件。它用于不同的目的。

步骤1:进入您的主目录

cd ~

步骤2:创建文件

vim .vimrc

步骤3:添加上述配置

filetype plugin indent on
set tabstop=4
set shiftwidth=4
set expandtab

第三步:按下 Shift + ZZ 保存文件。


14
不要使用“Shift + ZZ”,它会创建.swp文件。请使用“wq”。 - shas
8
@shas: "ZZ" 等同于 ":x",与 ":wq" 相同,但仅在文件已更改时才保存...(Ctrl-Z 则是另一回事...) - Gert van den Berg
2
@shas,那完全不正确。如果您不想为编辑会话使用交换文件,则必须运行“vim -n <file>”。交换文件不是在保存时生成的;这基本上会破坏其目的,因为交换文件在恢复意外终止的编辑会话方面非常有用。 - Kaz
详细描述可以在这里找到。(https://vim.fandom.com/wiki/Converting_tabs_to_spaces) - Ramganesh

37

推荐的方式是使用基于文件类型的缩进,并仅在必要时使用smartindent和cindent。

将以下内容添加到您的.vimrc文件中:

set expandtab
set shiftwidth=2
set softtabstop=2
filetype plugin indent on

希望它能作为不同答案来帮助你。


18

编辑你的 ~/.vimrc 文件

$ vim ~/.vimrc

添加以下代码:

set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab

17

来自 VIM wiki:

:set tabstop=4
:set shiftwidth=4
:set expandtab

11
自动缩进基于当前语法模式。我知道如果您正在编辑Foo.java文件,那么输入“{”并按下Enter键会缩进以下行。
至于标签,有两个设置。在Vim中,键入冒号然后输入“set tabstop=4”,这将将制表符显示为四个空格。再次键入冒号,然后键入“set expandtab”,这将插入空格以替换制表符。
您可以将这些设置放在位于您主目录中的.vimrc(Windows上的_vimrc)文件中,因此您只需输入一次即可。

2
首先,在Vim中不要使用Tab键进行手动缩进。Vim在插入模式下有一对命令,用于手动增加或减少缩进量。这些命令是Ctrl-TCtrl-D。这些命令遵循tabstopshiftwidthexpandtab的值,并保持正确的空格和制表符混合(最大数量的制表符后跟任何必要数量的空格)。
其次,如果您使用自动缩进,这些手动缩进键不需要经常使用。
如果您觉得使用Ctrl-T而不是Tab不方便,可以重新映射它:
:imap <Tab> ^T

您可以将Shift-Tab重新映射为执行Ctrl-D反缩进操作:
:imap <S-Tab> ^D

这里的^T和^D是字面上的控制字符,可以通过Ctrl-VCtrl-T插入。

有了这个映射,您仍然可以使用Ctrl-VTab在缓冲区中输入字面上的制表符。请注意,即使:set expandtab打开,如果这样做,您也会得到未扩展的制表符。

使用:set smarttab也可以实现与<Tab>映射类似的效果,它还会导致行首的退格键行为更加智能。

smarttab模式下,当Tab不在行首使用时,它没有特殊含义。这与我上面将Tab映射为Ctrl-T不同,因为在任何一行(插入模式下)使用Ctrl-T都会增加该行的缩进。

其他有用的映射可能包括:

:map <Tab> >
:map <S-Tab> <

现在我们可以选择一些行,然后按Tab键将它们缩进。或者在命令模式下按两次Tab键,以增加其缩进量。
如果使用适当的缩进管理命令,则所有内容都由三个参数控制:shiftwidthtabstopexpandtabshiftwidth参数控制缩进大小;如果您想要四个空格缩进,请使用:set shiftwidth=4或缩写:set sw=4
如果只执行此操作,则将使用空格和制表符混合创建缩进,因为noexpandtab是默认设置。使用:set expandtab。这会导致您在缓冲区中键入的制表符字符扩展为空格,并且Vim管理的缩进只使用空格。
当打开expandtab并且通过所有正确的Vim机制管理缩进时,tabstop的值变得无关紧要。它控制文件中制表符出现的方式。如果您设置了set tabstop=8 expandtab,然后使用Ctrl-VTab在文件中插入一个硬制表符,它将像往常一样对齐到下一个基于8列的制表符位置。

所有的映射都应该使用非递归变量。映射go <C-t>可以使用该语法而不是字面值。最后,在正常模式下映射<Tab>也会映射<C-i>(它们是相同的字符),所以我不建议这样做(你会失去一个很棒的vim功能)。 - D. Ben Knoble
1
@D.BenKnoble 我不推荐这些做法;我自己使用 Ctrl-T、Ctrl-D 和 < >。这才是 Vim 的正确用法。习惯在其他编辑器中使用 Tab 键的人可能不喜欢这种方式,仅此而已。 - Kaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接