在vim中,有哪些设置可以抵消smartindent拒绝缩进shell脚本中#注释的影响?

29

我最近开始使用vim 7(以前是vim 6)和smartindent设置。大多数情况下,它运作良好,尽管我习惯于在左花括号后键入一个制表符,但这几乎是适得其反。

但是,有一种疯狂的行为。在编辑shell脚本时,我尝试在当前缩进级别创建注释,但smartindent不会理睬它。它坚持认为注释必须在0级(无缩进)上。更糟糕的是,它会破坏shift-right('>>'和类似的操作),使它们无法正常工作。这是公然的不服从,我想知道如何修复它的最佳方法?

(我也不喜欢smartindent对在if之后缩进then的想法。)

首选解决方案将节省我手动敲击键盘-我懒惰了。一种选择是“在编辑shell脚本时关闭smartindent(其他情况下保留开启)”。另一种选择是提供指南,告诉我如何找到smartindent的控制脚本以及要编辑哪些内容来更改我不喜欢的特征。最后一个选项(我不需要关于如何执行它的建议-只是提示这是恢复理智的最佳或唯一方法)是将smartindent设置为未设置。

我看过了与之有关的问题“(PHP and) annoying vim unindent rules”,尽管其中提到的cindent和相关条目可能确实是答案的一部分,但这并没有直接提供给我答案。


1
这里有一个很好的答案:https://dev59.com/snVC5IYBdhLWcg3ww0Hr - Dan
7个回答

11

找到缩进文件(例如,在我的系统上为/usr/share/vim/vim71/indent/sh.vim)

这一行看起来是问题所在:

setlocal indentkeys-=:,0#

也许你可以在你的 .vimrc 文件中修复它,或者手动加载一个自定义的缩进文件。

编辑:看起来比我想象的要复杂,但也许在缩进文件中有一些特定设置需要修复。

第二次编辑:看起来我完全错了,请查看:

输入#后恢复缩进

或者

如何配置vim在编辑时不将注释放在行首


正确的指针方向。有一个README.txt文件,其中还提供了一些指针 - 特别是':help indent-expression',它又指向在线手册的30.3节。但那个文件是我需要破解、修改、反对或替换的文件。谢谢! - Jonathan Leffler
Heh...发现 smartindent 会将 # 放在 C 预处理器指令的开头。我可能会通过创建 ~/.vim/indent/sh.vim 包含 ':let b:did_indent = 1' 来取消 shell 规则。我也会跟随你添加的第二个编辑链接。 - Jonathan Leffler

3
在你的.vimrc文件中添加以下行:
filetype indent on
(它将根据文件类型设置正确的缩进模式)

3

我曾经也遇到过同样的问题,直到意识到如果在vimrc中设置了"filetype indent on",那么autoindent和smartindent都是不必要的。'filetype indent on'会使用你的vim目录下的indent/sh.vim(或其他语言)文件来确定缩进规则,而autoindent和smartindent都可能对其产生干扰。

虽然我没有测试过sh,但当我使用这种方法时,perl突然开始表现正常了。

另外一点:Juan提供的重定向解决方案“在键入#后恢复缩进”并不是一个好的解决方法 - 尽管它可以在一个情况下(输入代码)修正问题,但它并不能改变编辑器认为应该如何缩进,所以重新缩进(visual =或normal ==)将把它推回左边。


3

在搜索了一些选项后,包括使用':set cindent'代替':set smartindent',我最终决定只使用':set autoindent'。可能有办法让这个工具完全按照我的意愿运行,但是它已经够麻烦的了,我不想再去折腾。在过去的20多年中,我一直用autoindent很好地完成工作,而由smartindent提供的额外功能并不能弥补我认为它的错误行为所带来的负面影响。

感谢您的协助,Juan。信不信由你,它确实帮了我很大的忙。

在跟进此事时,我还发现了另外几个很棒的命令:

>i}
>a}

这些命令可以右移代码块。 'i' 版本将缩进主体而非闭合大括号(我个人偏好的风格), 'a' 版本将闭合大括号缩进(在工作中必需的版本)。

此外,您可以在执行shell命令时对 '%' 应用限定符:

:make %:r.o

这将在当前文件名的“根”目录(即“%:r”)上运行make,然后是“.o”。换句话说,如果我正在编辑somefile.c,则会执行make somefile.o


很高兴能帮忙。谢谢你关于移动块的提示。我经常移动块,但是以前都是通过可视化选择文本并使用右移(>>)操作符来实现的。 - Juan
我曾经在带有打开或关闭大括号的行上使用'>%'来移动所有内容。我也会使用'>%<<%<<'来将块的主体向右移动,然后取消两个大括号的缩进。但是这些新命令似乎可以在块的中间工作,这很不错。 - Jonathan Leffler

2

之前的答案建议使用:

:inoremap # X^H#

非常好。这是VIM文档在“:help smartindent”中建议的答案。请注意,使用CTRL-V CTRL-H输入^H。下面是文档中相关部分。

    When typing '#' as the first character in a new line, the indent for
    that line is removed, the '#' is put in the first column.  The indent
    is restored for the next line.  If you don't want this, use this
    mapping: ":inoremap # X^H#", where ^H is entered with CTRL-V CTRL-H.
    When using the ">>" command, lines starting with '#' are not shifted
    right.

谢谢您发布这篇文章!由于存在许多特殊字符,这并不是最容易搜索的技巧。 - Bonlenfum

1

1
我在我的 .vimrc 文件中有以下行,但我没有观察到问题。
set smartindent
inoremap # X^H#

我曾经在这两行代码后面加上了set autoindent,但似乎没有任何效果。


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