ぺんぎんさんのおうち

日記です。たまに日記じゃないこともあります。

Vimmer baby, vimmer baby

これは Harekaze Advent Calendar 2017 16日目の記事です.

Vimの話をします.

もちろん, これを読んでいる皆さんの中には "Vimってなぁに?" "わかりあえない人種" "聞いたことある!!" "これすき" などなど, 色々な方がいるかと思います.
この記事を読んで, Vimのことを全く知らない, 使ったことがない人が少しでも興味を持ってくれたり使い始めてくれると嬉しいです.
インストールの話からしていくと大変なので, 使い方, 主に僕がよく使うコマンドの紹介をしたいと思います.

これ書いたのAdventarに登録してすぐなんですが(1ヶ月くらい前かな?), その頃から大見得切ってVimの話をしますとかなんとか言ってました.
さぞ素晴らしいエントリなんだろうみたいな期待がもしかしたらあるかもしれません.
安心してください, クオリティに関して言えば最悪です(ハードルを下げたい).

ちょっとその前に

僕は3年半ほどVimを使っているので, 人並みには使えてると思っていますがvimrcに関しては全くの初心者です.
vimrc書いたりプラグイン入れてないとvimmerじゃないみたいな煽りを受けたのでちゃんと勉強します.


全く知らない人でも楽しめるようにするにはまず Insert mode と Command mode の話をしなきゃいけませんね..
ざっくり説明すると,
Insert mode が よくある普通のテキストエディタのように書き込んだり delete (back space?) で文字消したりできるモード
Command mode が コマンド叩いたりするモードです(保存とか, vim終了とか).

本当にざっくりしていますが, 今回はコマンド紹介の話なので, Insert mode についてはまた今度. (というか解説することある?)


Vimはじめ

早速始めます.

$ vim hoge.txt

vimをファイルを開くとデフォルトでcommand modeになっています.
Insert mode に入るには

i, o, a, I, O, A

をのどれかを入力してください.
使い始めの人がよく使用するのは i だと思いますが, 他の o や a, Shift + i, o, a などもかなり活躍します. これらについての解説は割愛します. 興味がある方は調べてみてください><


Command mode には escape を叩くか, Ctrl + c で戻れます.
デフォルトのキーボード設定だとescは遠いですよね.
Ctrl + c を使うと指が短い僕でも楽にCommand mode に戻れます.


次にカーソル移動.

h, j, k, l それぞれ 左, 下, 上, 右 への移動

ファイルに何も書き込まれていない状態だと変化がわからないと思うので, 何か適当に

hogehgoehogehogheohgoe
piyopiyoofeomoafhoafhorapnhpa
feamrioaaponropangrioa
ssssss
fooooooo

みたいに書き込んでおくといいかもしれません. 実際に h j k l でカーソルが動いているのがわかると思います.


ファイルの編集が終わったら, Command mode にもどって

:w

すれば保存

:wq

すれば保存して終了できます. 保存せずに終了しようとすると怒られちゃうので, 変更を加えたくない場合は

:q!

で保存せずに終了ができます.
vimの起動, モードの切り替え, カーソル移動, ファイルの保存 ができるようになれば十分です. これで君も今日からVimmerだ!!
ちょっと待って, 行番号がついてないやん??
こんなんじゃ(エラー出てもそこにカーソル持っていくの大変だし)商品になんないよ.

.vimrc書けばいいじゃんアゼルバイジャン.

$ echo "set number" >> ~/.vimrc

これで行番号が表示されるようになります.






ここまで基本的な使い方を解説してきました. ここから少し踏み込んでいきます.


undo redo

編集中, 間違えてしまった時に undo があると便利ですよね(Ctrl + Z).
vimにはちゃんとundoが機能としてついています. Command mode で

u

これだけ.
戻りすぎちゃってredo したいときは

Ctrl + r

でできます.
ただこれらは一回の起動での編集履歴しか記録されていないので, 例えば保存して終了してから開き直してもundoはできません.
少し編集してすぐ :wq 叩く癖をつけてしまうと大変です.


削除 ペースト

Insert modeで, ではなくCommand mode で 1文字消すには, 削除したい文字にカーソルを合わせて

x

文字単位ではなく, 行単位で削除したい時は

dd

削除ではなく, 行をコピーしたい場合もありますよね.
そんなときは

yy

次にペーストですが, これらのコマンドはクリップボードに記録されず, "ヤンクバッファ" と呼ばれるものに記録されます. (コピーの事をヤンクって呼ぶらしい)
つまり, Ctrl + v ではペーストできません.
ペーストには

p (or P)

を使います.
p はカーソルの次の位置に貼り付け, P はカーソル位置に貼り付けてくれます.
dコマンドは削除した上でヤンクするので, 1行丸ごと移動させたい時は便利ですね.


ヴィジュアルモード

Command mode で v を押すとヴィジュアルモードに切り替わります(もう一度vを押すと終了).
これはいわゆる範囲選択で, この状態でカーソル移動すると選択されている部分に色がついていきます.
適当な部分を選択して,

d

すると選択した部分を削除

y

すると選択した部分をコピー

もちろん p(P) でペーストできます.

部分的な削除, コピー

小見出し的にヴィジュアルモード的な匂いがしますね. でも違うんです.

コード等を書いてると,
{aaaa} [bbbb] (cccc) "foo" 'bar'
のような, 記号で囲まれた部分だけを削除(コピー)したい時ってありますよね.
そんな時, vim が便利なんです.

di%s (%s の部分は { [ ( " ' のいずれか)

もしくは

yi%s (%s の部分は { [ ( " ' のいずれか)

です.
d, y についてはもう説明しなくても大丈夫ですね.
先日, c92で購入した同人誌*1を読んで知ったのですが,

ci%s (%s の部分は { [ ( " ' のいずれか)

で, 削除した上でInsert modeに入れるそうです.

行移動 ページ送り

特定の行にカーソルを持っていきたいとき,

:数字

で指定した行に飛ぶことができます.
810行目にエラーが出てるよ!!と教えてもらっても, 1行ずつ巡って行くのは大変ですよね.

:810

するだけで810行目にジャンプできます.

1ページずつ

Ctrl + f

1ページ次へ

Ctrl + b

1ページ前へ

単語単位でカーソル移動

厳密には単語単位での移動ではないけれど(どう表現すれば?)

w

次の単語の位置へ

b

前の単語の位置へ

先頭, 末尾へ

ファイルの先頭や末尾に飛びたい時は

gg

先頭

G

末尾

検索 置換

検索

/search

/以降で指定した文字列を検索してくれます.
複数ヒットした場合は, n で次のヒット位置へ, N で前のヒット位置へ移動してくれます.

置換

変数名に変更があった時に, 一つ一つ参照していくのは大変です.
置換コマンドを使いましょう.

:s/置換したい文字/変更させたい文字

例えば, hogepiyo に変えたい時は

:s/hoge/piyo

とします. ただこのままだと, カーソルがある行のみ置換が行われるので,

:%s/hoge/piyo/gc

とすることで, 全ての hoge に対して1つずつ piyo に変更するかどうか[y/n]確認しながら置換ができます.

バイナリエディタとしてのVim

-b オプションをつけてファイルを開き,

:%!xxd

を叩くとバイナリエディタとして機能します.
変更を保存する時は

:%!xxd -r

します

シェルコマンドも使える!!

ls や pwd, file といったシェルコマンドはvimからでも叩けます.
Command modeで

:!コマンド

するだけ!!

vimを開いた状態でコンパイルしたりインタプリタ起動したりできます.

例えば僕がpython書いててたまにするのが,

:!python %

ファイル名をtypeしてもいいのですが, % と入力することで自分自身を指す(つまり編集中のファイル)ことができます.

エラーが出た時なんかは, 表示された行番号に飛んだり, もしくは原因となった変数名で検索して直しています.






いかがだったでしょうか,
"こんな機能あったのか!!" "これ知ってた!!" など, 楽しんでいただけましたか.
もしかすると少し複雑な内容になっていたかもしれません(というか読みやすさ大丈夫か?).
僕も最初のうちは慣れませんでしたが, 使っているうちに自然と使いこなせる(?)ようになってきました.

また, こんな便利な機能もあるんだぜ!!といったものがあれば教えてください.





おまけ

f:id:ushiromiya3:20171122030401p:plain

こんな風に1行に収まりきらなかったとき, 本来のカーソル移動を叩くと行単位で動いてしまうので目当ての部分にたどり着くのは大変ですね.
カーソル移動の h, j, k, l を叩く前に g を入力すると... やってみてください.

あとはカーソルを数字にあてて

Ctrl + a Ctrl + x

とか.

おまけ2

Emacsというものがあるみたいですね.
僕がVimを使うようになったのはこいつが原因です. あれがなければ今頃Emacs使っていたのではないでしょうか.
授業で写経する課題があり, ほぼ書き終えたいた段階でtypoしてundoしようと癖でCtrl+zしました. こういう時に限って分量多いのなんなんでしょうかね.
何が起こるかはやって確かめてみてください. 僕はそれが嫌でVimを使うようになりました.

*1 TomoriNao Vol.1 (Vim --魔法のカーソルを持つエディタ-- @fopen)