簡體   English   中英

Golang Formatter和Vim-如何銷毀歷史記錄?

[英]Golang Formatter and Vim - How to destroy history record?

Go(Golang)編程語言隨附一個名為go fmt的工具。 它是一個代碼格式化程序,可以自動格式化代碼(對齊,字母排序,制表,空格,成語...)。 真的很棒

所以我發現了這個小的自動命令,每次在緩沖區中保存到文件時都會在Vim中使用它。 au FileType go au BufWritePre <buffer> Fmt是Go vim插件隨附的函數。

這確實很棒,但是有1個問題。 每次格式化程序寫入緩沖區時,它都會在撤消/重做歷史記錄中創建一個跳轉。 嘗試撤消/重做更改時,這非常痛苦,因為每個第二次更改都是格式化程序(使光標跳至第1行)。

所以我想知道,觸發Fmt后,是否有任何方法可以放棄撤消/重做歷史中的最新更改?

編輯:好的,到目前為止,我有: au FileType go au BufWritePre <buffer> undojoin | Fmt au FileType go au BufWritePre <buffer> undojoin | Fmtau FileType go au BufWritePre <buffer> undojoin | Fmt不是很好。 根據:h undojoin ,撤消后不允許進行undojoin。 確實,在撤消后嘗試執行:w時,它會引發錯誤。

因此,我該如何實現以下偽代碼:

if lastAction != undo then
    au FileType go au BufWritePre <buffer> undojoin | Fmt
end

如果我弄清楚這最后一點,我想我有解決辦法。

我認為這幾乎undojoin您的要求,但是我看到它正在刪除一個撤消點(我認為這是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命令,因此在將其寫入文件之前先執行它。 而且,它將光標放在文件的頂部...

這是我的努力。 它與讀/寫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作為尋呼機。

我的.vimrc中只有這個:

au BufWritePost *.go !gofmt -w %

保存時自動在文件上運行gofmt。 它實際上並沒有在緩沖區中重新格式化,因此不會中斷我正在查看的內容,但是它在磁盤上的格式正確,因此所有簽入的格式都正確。 如果您想查看格式正確的代碼,則可以執行:e

也不對我的撤銷/重做歷史做任何事情

我試圖使用@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()

您可以從默認存儲庫安裝vim插件。 另外,這里也有病原體友好的鏡子:

https://github.com/jnwhiteh/vim-golang

然后,您可以使用:Fmt命令安全地執行go fmt!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM