Golang Formatter 和 Vim - 如何销毁历史记录?

Go(Golang)编程语言附带了一个名为go fmt. 它是一个代码格式化程序,可以自动格式化您的代码(对齐、字母排序、制表符、间距、习语......)。它真的很棒。


所以我发现了这个在 Vim 中使用它的小自动命令,每次将缓冲区保存到文件时。 au FileType go au BufWritePre <buffer> Fmt fmt 是 Go vim 插件自带的功能。


这真的很棒,但它有 1 个问题。每次格式化程序写入缓冲区时,它都会在撤消/重做历史记录中创建一个跳转。尝试撤消/重做更改时会变得非常痛苦,因为每第二次更改都是格式化程序(使光标跳转到第 1 行)。


所以我想知道,有没有办法在触发后丢弃撤消/重做历史记录中的最新更改Fmt?


编辑: 好的,到目前为止我有: au FileType go au BufWritePre <buffer> undojoin | Fmt 但它还不是很好。根据:h undojoin,撤消后不允许撤消加入。果然,当我尝试:w撤消后,它会触发错误。


那么我如何实现这样的伪代码:


if lastAction != undo then

    au FileType go au BufWritePre <buffer> undojoin | Fmt

end

如果我弄明白了最后一点,我想我有一个解决方案。


白板的微信
浏览 243回答 3
3回答

叮当猫咪

我认为这几乎就在那里,完成了你的要求,但我看到它正在删除一个撤消点(我认为这是预期的undojoin):function! GoFmt()&nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; exe "undojoin"&nbsp; &nbsp; &nbsp; &nbsp; exe "Fmt"&nbsp; &nbsp; catch&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; endtryendfunctionau FileType go au BufWritePre <buffer> call GoFmt()编辑根据 MattyW 的回答,我想起了另一个选择:au FileType go au BufWritePre <buffer> %!gofmt:%!<some command>在缓冲区上执行一个 shell 命令,所以我在将它写入文件之前执行它。而且,它会将光标放在文件顶部......

蓝山帝景

这是我的做法。它似乎在读/写 autocmds 和绑定到一个键上都运行良好。它将光标放回并且不包括撤消中的文件顶部事件。function! GoFormatBuffer()&nbsp; &nbsp; if &modifiable == 1&nbsp; &nbsp; &nbsp; &nbsp; let l:curw=winsaveview()&nbsp; &nbsp; &nbsp; &nbsp; let l:tmpname=tempname()&nbsp; &nbsp; &nbsp; &nbsp; call writefile(getline(1,'$'), l:tmpname)&nbsp; &nbsp; &nbsp; &nbsp; call system("gofmt " . l:tmpname ." > /dev/null 2>&1")&nbsp; &nbsp; &nbsp; &nbsp; if v:shell_error == 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try | silent undojoin | catch | endtry&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; silent %!gofmt -tabwidth=4&nbsp; &nbsp; &nbsp; &nbsp; endif&nbsp; &nbsp; &nbsp; &nbsp; call delete(l:tmpname)&nbsp; &nbsp; &nbsp; &nbsp; call winrestview(l:curw)&nbsp; &nbsp; endifendfunction我检查可修改,因为我使用 vim 作为我的寻呼机。

杨__羊羊

我试图使用@pepper_chino 的答案,但遇到了一些问题,如果 fmt 错误,那么 vim 会在运行之前撤消最后一次更改GoFmt。我以一种漫长而稍微复杂的方式解决了这个问题:" Fmt calls 'go fmt' to convert the file to go's format standards. This being" run often makes the undo buffer long and difficult to use. This function" wraps the Fmt function causing it to join the format with the last action." This has to have a try/catch since you can't undojoin if the previous" command was itself an undo.function! GoFmt()&nbsp; " Save cursor/view info.&nbsp; let view = winsaveview()&nbsp; " Check if Fmt will succeed or not. If it will fail run again to populate location window. If it succeeds then we call it with an undojoin.&nbsp; " Copy the file to a temp file and attempt to run gofmt on it&nbsp; let TempFile = tempname()&nbsp; let SaveModified = &modified&nbsp; exe 'w ' . TempFile&nbsp; let &modified = SaveModified&nbsp; silent exe '! ' . g:gofmt_command . ' ' . TempFile&nbsp; call delete(TempFile)&nbsp; if v:shell_error&nbsp; &nbsp; " Execute Fmt to populate the location window&nbsp; &nbsp; silent Fmt&nbsp; else&nbsp; &nbsp; " Now that we know Fmt will succeed we can now run Fmt with its undo&nbsp; &nbsp; " joined to the previous edit in the current buffer&nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; silent undojoin | silent Fmt&nbsp; &nbsp; catch&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; endtry&nbsp; endif&nbsp; " Restore the saved cursor/view info.&nbsp; call winrestview(view)endfunctioncommand! GoFmt call GoFmt()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go