Vim自动缩进与换行

47

如何让vim将光标放在新行开始的花括号内,即使用|表示光标位置:

class {
  |
}

目前使用我的设置只会做这些

class {
|}

我在我的 .vimrc 文件中写了这个: set autoindent shiftwidth=2 tabstop=2 noexpandtab

基本上,我只想要和普通的 IDE 一样缩进。

更新:

我找到了如何使用 inoremap { {<CR>}<Esc>O 来实现这个功能。

6个回答

27

我使用的是Ubuntu 12.04版本,但在我的Home目录下没有找到vimrc文件。全局的vimrc文件位于/etc/vim/vimrc
在这个文件中几乎什么都没有,因此我在/etc/vim/vimrc文件末尾添加了以下三行代码就可以了:

set autoindent
set cindent
inoremap { {<CR>}<up><end><CR>
当您下次键入 { 时,它将被更改为组合键 {、Enter、}、up、end、Enter。 cindentautoindent 将添加所需数量的制表符。
P.S. 我不擅长调整vim,因此某些解释可能不太准确。 这是我认为它的工作方式。

我在最后一行添加了一个"<Tab>",以使它将中间行缩进一步。即inoremap { {<CR>}<up><end><CR><Tab> - Skurpi

24
我发现 delimitMate 正是你所描述的,并可以自动插入结束符}。请注意,您需要通过添加let delimitMate_expand_cr=1到您的配置文件中来告诉delimitMate扩展换行符。
从我的观察来看,这正是在 TextMate 和 SublimeText 中发现的行为。

针对 delimitMate + neocomplcache 用户的 FYI:如果您使用默认的 neocomplcache .vimrc 设置,则需要调整 <CR> 映射以适应两个插件。更多信息请参见此处。我的 .vimrc 现在有 imap <expr> <CR> pumvisible() ? neocomplcache#smart_close_popup() : '<Plug>delimitMateCR',两个插件都按照我想要的方式工作。 - bknoles
4
最近delimitMateexpand_cr_1功能出现了问题。取而代之的是,你可以使用imap <expr> <CR> pumvisible() ? "\<c-y>" : "<Plug>delimitMateCR" - Yuriy Nemtsov

14

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

imap <C-Return> <CR><CR><C-o>k<Tab>
假设autoindentsmartindent都已正确设置,那么在大括号之间键入Ctrl + Return将把光标放在您想要的位置。

1
有没有办法将它映射到回车键呢?我已经习惯了使用 Eclipse,只需按下回车键即可。 - Zen
还有没有什么方法可以将此功能集成到特定语言的缩进文件中? - Zen
我认为将这样的功能映射到常规返回键意味着将其变成一个真正的函数,并且每次按下该键都要进行至少两个RegExp测试。这似乎有点过度杀伐。而且,我担心我还不够高级。不过对于缩进文件,我给+1。 - romainl
3
这里有一个稍微变化过的版本,更适用于重新映射 <Tab> 的插件:imap <C-Return> <CR><CR><C-o>k<C-t> - Jedidiah Hurt
谢谢,实际上我昨天找到了另一个:imap <C-Return> <CR><CR><C-o>k<S-s>,其中 <S-s> 从正确的缩进级别开始插入。此外,我认为使用 inoremap 应该可以防止副作用。 - romainl
首先,并非所有终端都能正确发送<C-Return>。您可能需要进行一些配置:https://dev59.com/fGQo5IYBdhLWcg3wDbwJ#42461580其次,另一个替代方案可以使用O,这将最小化光标移动:imap <C-CR> <CR><C-o><S-o> - Hielke Walinga

12

autoindent指的是它将当前缩进级别延续到后续行上。要根据语法进行缩进,您需要同时指定类似于smartindentcindent的标志。


缩进不是问题,我只想在按下回车键时自动插入正确缩进的换行符。 - Zen
我有点困惑。你现在是不是处于插入模式之外?如果你按下 i 然后再按下 Return,你能得到你想要的行为吗? - Justin Spahr-Summers
是的,我正在插入模式中,我想要的是当我在 { 后按下回车键时,vim会将我放在一个新行中,在闭合 } 中,基本上是我问题中的第一个块。 - Zen

3

我在我的.vimrc文件中写了这个。

inoremap <expr> <CR> InsertMapForEnter()
function! InsertMapForEnter()
    if pumvisible()
        return "\<C-y>"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,1) == '}'
        return "\<CR>\<Esc>O"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,2) == '</'
        return "\<CR>\<Esc>O"
    else
        return "\<CR>"
    endif
endfunction

上面的代码首先检查是否使用Enter完成代码完成确认,如果没有,则在输入Enter时缩进{|}。此外,它还提供了HTML标签自动缩进。
对于您的问题:
class {|}

按下Enter键,您将获得以下结果。

class {
    |
}

<html>|<html>

按下Enter键,你会得到结果。
<html>
    |
</html>

1
在文件底部,我使用了以下内容:
# vim: ts=2 sw=2 sts=2 sr noet st ai si

例如 Dockerfile
FROM centos-7
RUN ...
CMD ...

# vim: ts=2 sw=2 sts=2 sr noet st ai si

如果您想仅保留缩进,请使用# vim: st ai si

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