我正在使用带有vim-golang插件的vim。这个插件附带a function called :Fmt,使用命令行可执行文件gofmt“重新格式化”源代码。
我想在每次保存文件时调用:Fmt函数,因此它会不断重新格式化。我认为应该使用autocmd指令来完成。但我有两个疑问:
所以这就是我到目前为止:
" I can set variables for go like this
autocmd FileType go setlocal noexpandtab shiftwidth=4 tabstop=4 softtabstop=4 nolist
" I can clean trailing spaces(conserving cursor position) on save like this
autocmd BufWritePre * kz|:%s/\s\+$//e|'z
" None of these worked:
autocmd BufWritePre,FileType go Fmt
autocmd BufWritePre,FileType go :Fmt
答案 0 :(得分:56)
缓冲区写入时不会触发FileType
事件; BufWritePre
是正确的,但您需要提供文件模式,例如*.go
:
autocmd BufWritePre *.go Fmt
唯一的缺点是,这会重复检测 go 文件类型。您可以通过挂钩FileType
事件来委派此事件,然后使用特殊的<buffer>
模式为每个Go缓冲区定义格式化autocmd:
autocmd FileType go autocmd BufWritePre <buffer> Fmt
这有一个缺点,即如果多次设置文件类型,您也将多次运行格式化。这可以通过自定义:augroup
来解决,但现在变得非常复杂。或者,如果您确定这是Go缓冲区的唯一BufWritePre
autocmd,则可以使用:autocmd! BufWritePre ...
(使用!
)。
答案 1 :(得分:2)
对于那些不使用插件的人,这应该有效:
autocmd FileType go autocmd BufWritePre <buffer> execute "normal! mz:mkview\<esc>:%!gofmt-safe\<esc>:loadview\<esc>`z"
将以下脚本添加到您的 PATH
中,这是必需的,否则如果存在任何语法错误,gofmt 将破坏文件。例如,如果您键入 :x
,这可能很危险。
gofmt-safe
#!/usr/bin/env bash
orig=$(mktemp)
fmt=$(mktemp)
cat > "$orig"
<"$orig" gofmt "$@" > "$fmt" 2>/dev/null
if [ $? -eq 0 ]; then
cat "$fmt"
else
cat "$orig"
fi
rm -f "$orig" "$fmt"
如果你想在没有这个脚本的情况下过着危险的生活,你可以在 %!gofmt-safe
行中用 %!gofmt
替换 autocmd
。这有利于向您显示 :w
上的语法错误。只要确保不要输入 :x
或 :wq
。
答案 2 :(得分:1)
如果你使用折叠,gofmt将这些折叠起来(它打开封闭的折叠,关闭打开的折叠)。 要保持折叠,请使用以下自动命令
autocmd FileType go autocmd BufWritePre <buffer> execute "normal! mz:mkview\<esc>:Fmt\<esc>:loadview\<esc>`z"
它使用z寄存器来标记光标位置,因为:mkview和:loadview(保存并恢复折叠)由于某种原因移动光标。