为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
白板的微信 2021-06-24 18:03:14
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 | Fmtend如果我弄明白了最后一点,我想我有一个解决方案。
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

我认为这几乎就在那里,完成了你的要求,但我看到它正在删除一个撤消点(我认为这是预期的undojoin):


function! GoFmt()

    try                

        exe "undojoin"

        exe "Fmt"

    catch              

    endtry

endfunction

au FileType go au BufWritePre <buffer> call GoFmt()

编辑

根据 MattyW 的回答,我想起了另一个选择:


au FileType go au BufWritePre <buffer> %!gofmt

:%!<some command>在缓冲区上执行一个 shell 命令,所以我在将它写入文件之前执行它。而且,它会将光标放在文件顶部......


查看完整回答
反对 回复 2021-06-28
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

这是我的做法。它似乎在读/写 autocmds 和绑定到一个键上都运行良好。它将光标放回并且不包括撤消中的文件顶部事件。


function! GoFormatBuffer()

    if &modifiable == 1

        let l:curw=winsaveview()

        let l:tmpname=tempname()

        call writefile(getline(1,'$'), l:tmpname)

        call system("gofmt " . l:tmpname ." > /dev/null 2>&1")

        if v:shell_error == 0

            try | silent undojoin | catch | endtry

            silent %!gofmt -tabwidth=4

        endif

        call delete(l:tmpname)

        call winrestview(l:curw)

    endif

endfunction

我检查可修改,因为我使用 vim 作为我的寻呼机。


查看完整回答
反对 回复 2021-06-28
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

我试图使用@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()

  " Save cursor/view info.

  let view = winsaveview()


  " 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.


  " Copy the file to a temp file and attempt to run gofmt on it

  let TempFile = tempname()

  let SaveModified = &modified

  exe 'w ' . TempFile

  let &modified = SaveModified

  silent exe '! ' . g:gofmt_command . ' ' . TempFile

  call delete(TempFile)


  if v:shell_error

    " Execute Fmt to populate the location window

    silent Fmt

  else

    " Now that we know Fmt will succeed we can now run Fmt with its undo

    " joined to the previous edit in the current buffer

    try                

      silent undojoin | silent Fmt

    catch              

    endtry

  endif

  " Restore the saved cursor/view info.

  call winrestview(view)

endfunction

command! GoFmt call GoFmt()


查看完整回答
反对 回复 2021-06-28
  • 3 回答
  • 0 关注
  • 242 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信