You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vim中Bash脚本特殊语法自动缩进失效问题求助

解决Vim中Bash脚本:&&{结构的自动缩进问题

这个问题我之前也碰到过——Vim默认的bash缩进规则对if这类关键字后的块结构识别得很到位,但对:&&{这种用短路运算符连接的块就有点“迟钝”,只缩进第一行后就不管了。本质原因是Vim自带的sh.vim缩进脚本没有把:&&{识别为开启代码块的标记,所以后续行不会自动延续缩进。

下面给你几个可行的解决方案:

一、自定义缩进规则(无需插件)

不建议直接修改Vim自带的$VIMRUNTIME/indent/sh.vim,最好用Vim的after目录来扩展规则,这样升级Vim也不会覆盖你的配置。

  1. 先创建after缩进目录(如果不存在的话):
mkdir -p ~/.vim/after/indent
  1. 在该目录下新建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()
  1. 保存后重启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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:51:46