Vimを学ぶ際のおすすめの流れ
はじめに
vim 操作が使えるようになるとコーディング速度が上がります。
また、Linux などを使う際に半強制的に vi 操作を行わなければならない場合がありますが、それに余裕を持って対応できます。
学習コストが高いため一朝一夕で身につくものではありませんが、身についた際のメリットが非常に大きいです。
個人的には vim 操作は全エンジニアができるべきではないかと思っています。
ここでは、vim を知っているけど使っていない人が vim を習得するまでのおすすめの流れを紹介します。
1:最初の一歩:拡張機能を使おう
VScodeを使っている人は vim 拡張機能を入れましょう
https://scrapbox.io/files/62eb8b039de94c0023b17412.png
他のエディタや IDE を使っている人も、それぞれにある vim 拡張を導入しましょう。
ただ、vim 操作習得のために最も優れているのは vscode の拡張機能だと思います。(他のものはあまり触っていないので何とも言えませんが)
導入が完了したら、まず初めにモードについて学びましょう。
vim には normal モード、insert モード、visual モード、command モードがあります
normal モードでは、多くの場合カーソル移動を行います。例えば、h j k l で 左下上右 にカーソルが移動します。
insert モードでは、通常のファイル編集です。文字を直接入力することができます。
visual モードでは、文字を選択することができます。主にコピーするときに使います。
command モードでは、コマンドを実行することができます。: や / でコマンドモードになるのですが、最初はファイルの保存や閉じることだけに使うことになるでしょう。
まずは適当なファイルで操作感を知るといいでしょう。
各モードへの変更方法は基本的に以下のものになります。
table:ノーマルモードへ
esc ノーマルモードへ
table:インサートモードへ
o 現在の行の下に改行してインサートモード
a カーソルの右にインサートモード
i カーソルの左にインサートモード
table:ビジュアルモードへ
v ビジュアルモードへ
V 行選択ビジュアルモードへ
<Ctrl-v> 矩形選択ビジュアルモードへ
table: コマンドモードへ
:{command name} コマンドを書き込みエンターで実行
/{word} word を検索
変なキーを選択したとしても esc を連打していると何もない通常の normal モードになるので、
困ったら esc を連打と覚えておきましょう。
最低限
移動の h j k l gg G w b f t
削除の d
コピー&ペーストである y p
/ による検索、 :w :q
などは知っておきましょう。
vim 操作をたくさん覚えるにはエディタ特有のショートカットは極力使わないようにしましょう
また、すべてのコマンドを覚えようとはしないほうが良いでしょう。
膨大な量ですし、すべてを等しい割合で使用するわけではないので自分にとって使えると思うコマンドを優先しましょう。
2:キーバインドをカスタマイズする
vim 操作を使い続けるといずれデフォルトのキーバインドでは満足できなくなるでしょう。
(もし、まだ満不満がわからないのであればカスタマイズには早いでしょう。)
通常キーバインドを変更するには「.vimrc」というファイルを作成し、使用します。
これは本家 vim の設定ファイルを示すもので、Unixだと /home/{name}/ 直下に、Windows だと C:\Users\{name}\ 直下に配置するのが基本です。({name} はユーザー名を表す文字列)
これは エディタの拡張機能によっては使用できませんが、vscode では不完全ではありつつも使用できます。
.vimrc ファイルを作成すると中身に
inoremap jj <Esc>
と書いて保存します。
本家 vim は起動時自動で ユーザー直下の .vimrc を読み込みます。
なので、本家 vim を使っている人はすでに insertモードで jj を押すと normal モードに移行するようになっているはずです
vscodeの場合は settings.json に以下を書き込むと読み込むようになるでしょう。
code:settings.json
"vim.vimrc.enable": true,
"vim.vimrc.path": "C:\\Users\\(ユーザー名)\\.vimrc",
しかし、恐らく jj では esc にはならないでしょう。vscode の拡張機能では insert モードの機能はすべて vscode の管理下に置かれているので insertモードのキーバインドの変更はできないのです。
.vimrc でのキーバインド変更方法
基本的に「どのモード」でマッピングするのか、「何」を打つと「何」になるのかを書きます
設定例は以下のようになります。
map hoge fuga これですべてのモードで hoge を押すと fuga に変換されます。
nmap hoge fuga で normal モード限定
vmap hoge fuga で visual モード限定
imap hoge fuga で insert モード限定
omap hoge fuga で コマンド打ち込み中限定
などになります。
また、nnoremap, vnoremap など nore を入れると非再帰的なマッピングになり、再帰的な動作が起こりません。
imap j jjとすると jjjjjjj... というように無限ループになりますが、inoremap を使うことで防止できます。
特殊なマッピング
<Esc>や<Space>などの通常のキーではないものがありますが、それらは各自調べてください。
追加で <Leader> という特殊な 仮想キーのようなものがあり、それを使ってマッピングすることができます。
.vimrc には let mapleader = "\<Space>" と書けば <Leader> に <Space>が割り当てられます。
3:本家Vim(もしくはNeoVim)を使う
いずれエディタの拡張機能だけでは限界がきます。
拡張機能は元あるエディタを拡張する機能であり、vim としては不完全なものです。
vim の特徴の一つである プラグイン も導入できないことがほとんどです。
もっと自分好みにしたいと思えるようになったら本家の vim をインストールして使用しましょう。
ただ、プラグインがない状態だとエディタとしてはかなり厳しいので、自分の好みに合うように設定していく必要があります。
プラグインには色々なものがあり、カーソル移動を強化するものやファイル検索するもの、構文解析から色付けを行うものなど、様々なものが存在しています。
それらを自分で調べて見つけ、自分好みのエディタとして完全にカスタマイズすることができるようになります。
本家 vim は昔書いた記事で Vimを始める がありますが、筆者の今のおすすめは NeoVim です。 おまけ
mapping 設定例
code:mapping.vim
let mapleader = "\<Space>"
inoremap jj <Esc>
tnoremap jj <C-\><C-n>
nnoremap s <Nop>
nnoremap sw s
nnoremap <S-s> s
nnoremap ss :<C-u>sp<CR>
nnoremap sv :<C-u>vs<CR>
nnoremap sq :<C-u>q<CR>
nnoremap s<S-q> :<C-u>bd<CR>
nnoremap sj <C-w>j
nnoremap sk <C-w>k
nnoremap sl <C-w>l
nnoremap sh <C-w>h
nnoremap s<S-j> <C-w>J
nnoremap s<S-k> <C-w>K
nnoremap s<S-l> <C-w>L
nnoremap s<S-h> <C-w>H
nnoremap s> <C-w>>
nnoremap s< <C-w><
nnoremap s+ <C-w>+
nnoremap s- <C-w>-
nnoremap s= <C-w>=
nnoremap s_ <C-w>_
nnoremap <Leader>L gt
nnoremap <Leader>H g<S-t>
nnoremap <Leader>< :tabm -1<CR>
nnoremap <Leader>> :tabm +1<CR>
noremap <Left> <Nop>
noremap <Down> <Nop>
noremap <Up> <Nop>
noremap <Right> <Nop>
noremap <A-l> $
noremap <A-h> 0
noremap <C-j> +
noremap <C-k> -
inoremap <C-k> <C-o>k
noremap + <C-a>
noremap - <C-x>
nnoremap <Leader>re :%s;\<<C-R><C-W>\>;g<Left><Left>;
inoremap <C-l> <Del>
nnoremap <Leader>q :bd<CR>
nnoremap <Leader>w :w<CR>
nnoremap <Leader>d "_d
nnoremap <Leader>c "_c
nnoremap <Leader>yw "_diwP
onoremap 8 i(
onoremap 2 i"
onoremap 7 i'
onoremap @ i`
onoremap [ i[
onoremap { i{