[Vim] プラグインを使わなくてもデフォルトの機能でできること


はじめに

昔はvimのプラグインをよく使用していました。
しかし、プラグインを入れるたびにそのプラグインのコマンドを覚える必要があり、その作業が段々面倒になってきました。
プラグインがないとできないことは当然あります。しかし、プラグインが使えない環境で作業をすることもあるので、最近はプラグインに頼るよりもVim自体の機能をもっと知ることに注力しています。
その結果、デフォルトの機能で色々できることが分かってきました。
共有の意味を込めて便利そうな機能を少しずつ記事にしていこうと思います。

起動オプション

2つのファイルを垂直分割して開く
vim -O file1 file2

コーディング中やコードを調査するときに便利な移動機能

個人的に便利だと思う移動機能。

キーバインド 挙動
% 対応する括弧に移動
[m (上方向に移動)関数を定義している箇所に移動する
]m (下方向に移動)関数を定義している箇所に移動する
m <任意のキー>
ex) ma
現在のカーソル箇所にマークをつける
` <マークをつけたキー>
ex) `a
マークをつけた場所に移動する
g, 最後に修正した場所への移動

grepで検索

Vimにもvimgrepと呼ばれるgrep機能が備わっています。

私はtaglistプラグインが使えない環境でメソッドの一覧をみたい時に下記のようにvimgrepをよく使います。

:vimgrep /public function/ % | cw

ちなみに%は現在開いているファイル名のことを指します。
vimにはレジスタ編集中のファイル名やヤンク(コピー)した文字列の情報などをためこむ収納庫のようなものがあり、%はファイル名が保存されています。
興味のある方は:regで確認してみてください。

vimgrepに関しては下記の記事が参考になると思います。
vimgrepとQuickfix知らないVimmerはちょっとこっち来い

Tabを活用する

vimコマンドはパイプで組み合わせて使うことが出来るので、
:tabnew | edit /home/xxx/xxx.txt
とeditコマンドで新しいタブでファイルをしたり、
:tabnew | b 1
新しいタブにバッファーに展開されているファイルを流し込んだりできます。

Tabの切り替えコマンドは沢山存在しますが、下記のコマンドで大体のことが代用できると思います。

キーバインド 挙動 Link
gt Tabを次のタブに切り替える http://vim-jp.org/vimdoc-ja/tabpage.html
{Tab番号}gt Tabを指定したTab番号のタブに切り替える

{Tab番号}gtを使うのならTab内にTab番号が表示されていたほうが分かりやすいかもしれませんね。
.vimrcファイルに下記のように設定するとTab番号が表示されます。
Tab番号 : [ファイル名] のフォーマットになるような設定です。

.vimrc
colo desert
" カレントタブをハイライト
hi TabLineSel ctermbg=1

" タブにフルパスでなく、ファイル名のみを表示する                                
set tabline=%!MyTabLine()

" 常にタブラインを表示                                                          
set showtabline=2

function! MyTabLine()
    let s = ''
    for i in range(tabpagenr('$'))
        " ラベルは MyTabLabel() で作成する
        let my_tab_label = '%{MyTabLabel(' . (i + 1) . ')}'
        " 強調表示グループの選択
        if i + 1 == tabpagenr()
            let s .= '%#TabLineSel#'
        else
            let s .= '%#TabLine#'
        endif
        " タブ番号 : [ファイル名] のフォーマットになるように設定
        let s .= (i + 1) . ':[' . my_tab_label .'] '
    endfor

    " 最後のタブページの後は TabLineFill で埋め、タブページ番号をリセットする
    let s .= '%#TabLineFill#%T'

    return s
endfunction                                                                     

function! MyTabLabel(n)
    let buflist = tabpagebuflist(a:n)
    let winnr = tabpagewinnr(a:n)
    return fnamemodify(bufname(buflist[winnr - 1]), ":t")
endfunction 

ファイルに書かれているファイルパスからそのファイルを開く

下記のようにファイルにパスが記載されているとします。

...
   $filepath = '/usr/local/log/error.log';
...

カーソルをパスの上に合わせて下記のコマンドを実行すると:e /usr/local/log/error.logなどしなくてもerror.logファイルを開くことができます。

キーバインド 挙動 Link
gf カレントウィンドウ上でファイルを開く http://vim-jp.org/vimdoc-ja/usr_22.html
<Ctrl>w gf 新しくタブを開いてファイルを開く http://vim-jp.org/vimdoc-ja/windows.html#CTRL-W_gf

ファイルをあるときの状態に戻す

ファイルを編集している時にuを連打してファイルを元の状態に戻した経験はありませんか?
Undoブランチを理解すればuをひたすら連打するよりももっとスマートにファイルを戻せます。
http://vim-jp.org/vimdoc-ja/undo.html#undo-branches
http://vim-jp.org/vimdoc-ja/usr_32.html
ファイルの編集中は書いたり消したりという作業を繰り返するのでUndoブランチの分岐点がたくさん出来ます。
u連打でもいいですが、

{N}回前のファイルを保存したときのテキスト状態に移動する
:earlier {N}f

など様々な戻し方を知っていると便利なこともあるので知っておいて損はないと思います。
ちなみに戻しすぎた場合は、

{N}回後のファイルを保存したときのテキスト状態に移動する
:later {N}f

で調整してください。

ディレクトリをツリー表示

Windowsのエクスプローラーの様にディレクトリをツリー表示させるのに
Vimのプラグインnerdtreeを使用している方は多いのではないかと思います。
標準のvimでも同じようなことが:edit .で出来ます。ちなみにこのように表示されます。

" ============================================================================
" Netrw Directory Listing                                        (netrw v109)
"   Sorted by      name
"   Sort sequence: [\/]$,\.h$,\.c$,\.cpp$,*,\.info$,\.swp$,\.o$\.obj$,\.bak$
"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:exec
" ============================================================================
../
./
check/
Makefile
autocmd.txt
change.txt
eval.txt~
filetype.txt~
help.txt.info
キーバインド 挙動
Enter ディレクトリを開く
-(マイナス) 親ディレクトリに移動
d ディレクトリを作成する
D ファイル / ディレクトリを削除する
R ファイル / ディレクトリをリネームする

などなど他にも機能がたくさんあります。
詳しくは下記を参照してください。
キーバンドのリファレンス : http://vim-jp.org/vimdoc-ja/pi_netrw.html#netrw-quickmap

標準のvimでもnerdtreeのようにディレクトリにブックマークをつけることも出来るので結構便利。

最近開いたファイルの一覧を表示する

:ol[dfiles]で最近開いたファイルの一覧を表示することが出来ます。

ファイルの一覧を表示する
:ol[dfiles]

ただし、oldfilesコマンドは最近開いたファイルの一覧を表示するだけです。
VimプラグインのMRUのように
過去に開いたファイルの一覧を表示 → 開きたいファイルを選択し移動
という事がしたいのであれば、:bro[wse]と組み合わせて下さい。

ファイルの一覧を表示->開きたいファイルを選択し移動
:bro[wse] ol[dfiles]

仕組みに興味のある方はhelpのリンクを貼っておきますので、読んでみてください。
viminfo : http://vim-jp.org/vimdoc-ja/usr_21.html#21.3
v:oldfiles変数 : http://vim-jp.org/vimdoc-ja/eval.html#v:oldfiles

外部コマンドを実行する

vimはファイルを開いた状態でも:![コマンド]で外部(OS)コマンドを実行することが出来ます。
私はPHPのファイルを編集する際、編集の合間でちょこちょこプログラムを実行しながらデバッグします。

phpファイルのlint処理
:!php -l %

こんな感じ。

あとファイルを編集する前にバックアップ取る時も外部コマンドを使っています。

ファイルのバックアップ作成
:!cp -pi % %.bk
ファイルのバックアップが作成できたか確認
:!ls -l %{,.bk}

///
2018-05-25追記
vim8.0で:terminalコマンド機能が追加されたのでそちらを使用してもよさそう。
https://vim-jp.org/vimdoc-ja/terminal.html

範囲選択と外部シェルを組み合わせる

下記の様にコマンドがファイル上に書かれているとします。

hoge.txt
grep -i 'INFO' dev.log

このコマンドをビジュアルモードで範囲選択し、!shと組み合わせることでそのコマンドを実行することができます。

vimコマンド

:'<,'> !sh

こうするとgrep -i 'INFO' dev.logが実行され、grep -i 'INFO' dev.logの行がコマンドの結果に置き換えられます。

終わりに

今後もちょこちょこ編集していきます。