📿
Vimの起動時に現在のリポジトリで直前に使ったファイルを開く
Vimには:oldfiles
というコマンド(およびv:oldfiles
という変数)があり、過去に開いたファイルを一覧することができます。
この番号は#<0
というフォーマットで選択することができ、例えば:edit
コマンドなどに渡すことができます。
これを利用し、Vim起動時にvim -c 'edit #<0'
と指定すれば、ファイルパスを指定せずとも直前に使ったファイルを開くことができます。
ただし、v:oldfiles
には「過去に開いたファイル」がすべて入っているため、直前の終了状況によっては、以下のようなファイルが対象になってしまうこともあります。
- 現在のディレクトリとは別リポジトリのファイル
-
.git/COMMIT_EDITMSG
などの.git
内のファイル - 以前編集したが、その後削除したファイル
- プラグインによって開かれた一時的なファイル
- ヘルプファイル
(状況にもよりますが)基本的にこれらは「直前のファイル」の対象にしたくありません。
ということで、oldfiles
をフィルタする関数を作成しました。
以下を設定ファイルに記載してください。
.vimrc or init.vim
" {{{ EditProjectMru()
function! EditProjectMru() abort
let cmd = 'git rev-parse --show-superproject-working-tree --show-toplevel 2>/dev/null | head -1'
let root = system(cmd)->trim()->expand()
" not in git project
if !isdirectory(root)
edit #<1
return
endif
" filter oldfiles
for file in v:oldfiles
let file = expand(file)
if file =~ root .. '/' && file !~ '\.git/' && filereadable(file)
execute 'edit' file
return
endif
endfor
endfunction
" remove function because it is only for `$ vim -c 'call EditProjectMru()'`
autocmd VimEnter * ++once delfunction! EditProjectMru
" }}}
これをvim -c 'call EditProjectMru()'
のように起動時に呼び出すことで、「現在のプロジェクトで最近使ったファイル」を開くことができます。
内部では、「現在のgitプロジェクト」かつ「.git/
内ではない」かつ「読み込み可能」なファイルを選択する条件を設定しています。
また、起動後に使用することはない想定なので、VimEnter
のタイミングで関数を削除しています。
これと:h restore-cursor
のテクニックを組み合わせると、直前のファイルを開いて編集に戻るのが楽になります。
毎回-c 'call EditProjectMru()'
を打ち込むのも億劫なので、エイリアスに登録しておくのがおすすめです。
git rootの検出は以下の記事でも使用しています。
Discussion
たぶんセッション使ったほうが直前の閉じた状態を楽に再現できる気がします