標籤:

在 vim 中使用 git 的一些經驗

相比與自身就提供 git 操作集成的現代的編輯器,例如 atom、vscode,vim 本身做為一個單純的編輯器並沒有提供任何 git 相關支持,慶幸的是依賴 vim 強大的擴展能力,我們可以做的更多,甚至更好。 本文將介紹一些常見的 git 相關插件,以及提升效率的小技巧,供大家參考。

側邊欄插件

vim-gitgutter 應該算是最常用的 git 側邊欄插件了。

其中比較常用的一個命令是在修改塊之間進行切換,默認的快捷鍵映射如下:

nmap [c <Plug>GitGutterPrevHunknnmap ]c <Plug>GitGutterNextHunkn

狀態欄插件

比較流行的狀態欄插件例如 vim-airline 都有提供 git 相關的支持。

為了可以避免 git 命令調用導致的將近 200ms 打開延遲,我個人用的是自己弄的一段非同步腳本 https://github.com/chemzqm/vimrc/blob/master/statusline.vim#L50,它所調用的 git-status 命令是一段輸出 informativegitprompt 信息的 node 腳本,它可以幫我更全面的了解整個項目的當前狀態。

有一點需要額外注意,vim 里沒有 project 概念,但是有 CWD (當前工作目錄) 的概念,多數狀態欄的 git 狀態都是針對當前緩存區的 CWD 所在項目而言的, 所以如果你在 vim 內直接切換到別的項目文件,就會發現狀態欄並沒有改變,一種解決辦法是讓 vim 在切換緩衝區後自動切換 CWD (可通過 lcd 或者 tcd 避免全局切換),這種辦法的一個問題在於你從非 git 文件切到 git 目錄下文件再切回時如何對 CWD 進行處理?另一種辦法就是使用當前文件所在項目所謂 git 命令的根路徑。

vim-airline 同時有提供當前緩衝區 git 塊狀態的的提示(如上圖所示),通過一段 vim 代碼我們也能輕易實現該功能:

function! MyStatusGitChanges() abortn let gutter = get(b:, gitgutter, {})n if empty(gutter) | return | endifn let summary = gutter[summary]n if summary[0] == 0 && summary[1] == 0 && summary[2] == 0n return n endifn return +.summary[0]. ~.summary[1]. -.summary[2]. nendfunctionn

git 命令集成

你可以直接使用 ! 命令來執行命令行命令,然而這種方式多數情況體驗並不理想,結果就是促生了堪稱 vim 最受歡迎插件之一的 vim-fugitive, 其強大之處可以從以下文章的視頻中略知一二:

Fugitive.vim - working with the git index

Fugitive.vim - a complement to command line git

因為不太滿意 fugitive 的性能和擴展性,我也曾實現了一個封裝 git 命令的插件,vim-easygit, 遺憾的是目前該插件部分功能依然缺失,而且 windows 的支持不足。

Denite 插件

denite.nvim 是一個主要基於 python3 的為不同列表提供通用介面的插件。開發者可以擴展不同的 source,每個 source 都可以有獨立的排序配置等選項,以及多個不同的 action 操作,用戶可以便捷的對一個或者多個列表項同時進行指定操作。

denite-git 主要實現了 gitlog 和 gitstatus 兩個 source,通過 Denite gitlog 命令, 開發者不僅可以方便的瀏覽某個文件(或整個項目)的歷史提交記錄,還可以直觀的進行 diff,reset 等操作。通過 Denite gitstatus 命令, 開發者可以便捷的對 git 緩衝區內文件進行不同操作,以下是視頻演示:

asciinema.org/a/104395

asciinema.org/a/104410

快速提交、推送代碼

提交代碼和推送代碼是我日常最常用到的兩個命令,所以我做了兩個映射:

nnoremap gca :Gcommit -a -v<CR> " 需安裝 fugitive 或者 vim-easygitnnnoremap gp :Nrun git push<CR>n

其中的 Nrun 是我自定義的一個打開下方 terminal (僅 neovim 支持)執行命令然後自動關閉的非同步命令(推送同時可繼續其它工作), 完整代碼如下:

command! -complete=file -nargs=* Nrun :call s:Terminal(<q-args>)nnfunction! s:Terminal(cmd)n execute belowright 5newn set winfixheightn call termopen(a:cmd, {n on_exit: function(s:OnExit),n buffer_nr: bufnr(%),n })n call setbufvar(%, is_autorun, 1)n execute wincmd pnendfunctionnnfunction! s:OnExit(job_id, status, event) dictn if a:status == 0n execute silent! bd! .self.buffer_nrn endifnendfunctionn

視頻演示:

asciinema.org/a/110134

最後

本文僅是粗略的介紹了一些常見 git 插件,vim 社區還有更多的插件提供大家選擇。

Happy vimming


推薦閱讀:

Vim Tips #3: Vim 命令的模式
Vim 新人學習路線, 小技巧
想用 vim 寫 python,python-mode 幫你搞定[視頻]
SpaceVim release v0.6.0

TAG:Vim |