如何在vim中进行嵌套缩进?

如何在vim中进行嵌套缩进?

我想在 vim 中制作 if-fi 语句,其中iabbrev将“自动完成”if-fi子句:

 autocmd Filetype sh iabbrev if if<esc>ma<cr>ifi<esc>`ak

从而if生成:

if
fi

这是正确的 - 我不必fi在子句末尾输入。所以我可以继续。例如:

if pwd; then
    echo "bla bla"

fi

现在在下面echo,我想嵌套另一个语句,但是这一次,如果我输入if它会生成:

if pwd; then
    echo "bla bla"

    if
fi
fi

第二个(嵌套的)if-fi 打破了缩进。结局fi应该是这样的:

if pwd; then
    echo "bla bla"

    if
    fi
fi

所以第二个if-fi子句是内含第一个。但我不知道如何实现这一目标。我有

:set autoindent
:set smartindent

所以 vim 记住了 的缩进级别<cr>,这样我就可以通过一个退格键在嵌套中获得正确的缩进if-fi。但我不知道应该做什么键映射才能实现这一目标。那么我应该添加什么键映射.vimrc才能iabbrev在 vim 中生成正确的缩进级别?

答案1

我没有重现您遇到的确切问题,filetype=sh并且启用了缩进插件,它似乎正在重新感染以与我fi匹配。if

但我可以在您的缩写中看到一个问题,因为它使用<CR>正常模式移动到下一行,然后使用 ani插入fi部分。一方面,它指望下一行已经为空(否则它只会在fi已经存在的内容前面加上 。)它也可能会导致您的问题,因为插入新行通常不会触发自动缩进,因为插入新行(使用<CR>插入模式,或使用正常模式o命令)会。

我的建议是保持插入模式并使用<C-o>执行单个正常模式命令来设置标记并移动到它。 (看:help i_CTRL-O.)

这个缩写应该很好用:

iabbrev if if<C-o>ma<CR>fi<C-o>`a

请注意,这是在插入模式下发生的,因此它实际上是在插入新行,并且通常会尊重<CR>插入新行的时间。autoindent

如果要为每个文件类型设置缩写,通常应该将它们设置为本地缓冲区,因此如果您有其他缓冲区编辑不同类型的文件,它们将不会在那里应用。您可以通过<buffer>向命令添加修饰符来做到这一点:

iabbrev <buffer> if if<C-o>ma<cr>fi<C-o>`a

autocmd FileTye sh如果您愿意,您可以将其添加到 an 中。如果您使用 an autocmd,您通常希望将其保留在 an 内augroup,因此如果您再次获取 vimrc 文件,它不会重复自动命令并在每次文件类型匹配时多次运行它。

我通常的偏好是让 Vim ftplugin 机制为我处理这个问题。为此,只需创建一个名为 的文件~/.vim/after/ftplugin/sh.vim并将iabbrev <buffer> ...命令直接添加到其中。 (不要添加该autocmd部分。)Vim 会自动处理这些,每当检测到文件类型为 时sh,它就会自动获取所有这些脚本。这使得为​​特定文件类型获取许多规则变得更加简单。您也不会用所有特定于文件类型的规则污染您的 vimrc。最后,您无需担心使用自动命令和映射来转义这些长行。

相关内容