Vim中Bash脚本特殊语法自动缩进失效问题求助
解决Vim中Bash脚本
:&&{结构的自动缩进问题 这个问题我之前也碰到过——Vim默认的bash缩进规则对if这类关键字后的块结构识别得很到位,但对:&&{这种用短路运算符连接的块就有点“迟钝”,只缩进第一行后就不管了。本质原因是Vim自带的sh.vim缩进脚本没有把:&&{识别为开启代码块的标记,所以后续行不会自动延续缩进。
下面给你几个可行的解决方案:
一、自定义缩进规则(无需插件)
不建议直接修改Vim自带的$VIMRUNTIME/indent/sh.vim,最好用Vim的after目录来扩展规则,这样升级Vim也不会覆盖你的配置。
- 先创建
after缩进目录(如果不存在的话):
mkdir -p ~/.vim/after/indent
- 在该目录下新建
sh.vim文件,写入以下内容:
function! shIndent() let current_line = getline(v:lnum) let prev_line = getline(v:lnum - 1) " 识别`:&&{`(含空格变体,比如`: && {`)的起始块 if current_line =~# '^\s*:\s*&&\s*{' return cindent(v:lnum) endif " 处理块内的行:如果上一行是块起始或块内行,增加缩进 if prev_line =~# ':\s*&&\s*{' || (prev_line =~# '^\s*echo\|^\s*#' && indent(v:lnum - 1) > 0) return indent(v:lnum - 1) + &shiftwidth endif " 处理块结束的`}`:匹配对应起始块后减少缩进 if current_line =~# '^\s*}' let line_num = v:lnum - 1 while line_num > 0 let check_line = getline(line_num) if check_line =~# ':\s*&&\s*{' return indent(line_num) endif let line_num -= 1 endwhile endif " 其他情况沿用默认缩进规则 return cindent(v:lnum) endfunction setlocal indentexpr=shIndent()
- 保存后重启Vim,再执行
gg=G就能让:&&{结构的代码正常缩进了。
二、使用第三方bash缩进插件
如果不想自己写脚本,可以用专门的bash缩进插件,比如vim-bash-indent。这类插件会更全面地识别bash的各种语法结构,包括短路运算符、管道后的块等边缘场景,配置起来也省心——只需要通过Vim-Plug、Pathogen等插件管理器安装后,就能自动替换默认的缩进规则。
三、临时应急技巧
如果只是偶尔碰到这种情况,不想改配置,可以在:&&{后面加个注释标记块起始,比如:
#!/bin/bash :&&{ # block start echo 1 echo 2 }
Vim的默认缩进脚本会把注释后的块当成需要缩进的结构,也能临时解决问题。
内容的提问来源于stack exchange,提问作者Gerald Schade
相关产品推荐
相关产品推荐

