自分の知らなかったVim標準操作たち
※この記事はVim駅伝の記事です。 前回の記事はAIエージェントのお供にNeovimはいかが? ― コードビューアーとしてのNeovim入門でした。
みなさんはVim標準のキーマップは使いこなしてますよね?
まさか使いこなしていないのにプラグイン作ってるなんてないですよね?
うん?なんか痛いな…グエブーメラン刺さってる
…というのはいいとして、正直標準を使いこなせていない気がしたので自分で調べて記事にしてみました。 ちなみに書いた基準は最近まで私が知らなかったものです。
知識がある方が見たら泡吹いて倒れるレベルで基本的なものを会得してませんが書いていきます。
Normal
Normalモードの操作は、単一で動作するコマンド、オペレーター、モーションに分けられます。 それぞれに分けて書いていきます。これでも単一で動作するコマンドがとんでもなく大量にあります。
単一で動作するコマンド
-
a…iだと左からだけどaだと右から。append。 -
I/A…行の先頭/末尾からInsertに入る。さっきの左/右のノリで覚えられそう。 -
O…上の行からInsertに。oの逆。 -
V/Ctrl+v…行/ブロックのvisual。visualではないV-LINEとV-BLOCKという専用モードがあるっぽい。 -
U…行単位でundoする。複数のundoを一気にできる。ただ一度行を離れると効かない。 -
r…一文字だけreplaceする。例えばdd[c].vimでruと叩くとdd[u].vimになる。 -
R…専用モードに入って抜けるまでreplaceし続ける。普通のキーボードのInsertキーみたいな挙動。 -
.…なんでもリピートできる。一つの命令セットで一つぐらいな感じっぽい?(ex.daw実行、Insert入って抜けるまで) -
?…後方検索。前方検索の/は知っていた。ちなみに下書き段階では逆に認識していた。危なかった… -
*/#…カーソル位置の単語を完全後方検索。#は前方。完全は単語の境界も含めという意味? -
g*/g#…カーソル位置単語を部分後方検索。もちろんg#は前方。 -
:s…操作というかコマンドだけど。いつもはファイル全体で:%sと叩いていたが:sは知らなかった。substitute -
q…マクロ記録。qaでレジスタaにマクロを記録する。記録開始した後またqを叩くと記録終了。 -
@…マクロ再生。@aでレジスタaのマクロを再生する。 ちなみにマクロの実体は文字列なので余裕でハックできる。 -
D…カーソル位置から行末まで削除。d$ -
C…行内でカーソル位置より後を編集する。d$i,Di -
Y…カーソル位置から行末までヤンク。y$。ただ昔古めのVimを触ったときにy$じゃなくてyy相当の動作をしてた気がする。 -
:r…ファイルの内容をカーソル位置に挿入する。:r !lsとかするとシェルでのlsの結果を挿入できる。 -
H/M/L…カーソルを画面の上、真ん中、下に移動する。 便利そうなのにH/Lをマッピングしている人がいるらしい…誰だろう…? 証拠 -
J…スペースありでjoinする。[a]\nbだったらa[ ]bになる。 -
gJ…スペースなしのjoin。[a]\nbはa[b]になる。 -
gf/gF…当該ファイルを開く。tes[t].txtで叩くとtest.txtが出てくる。gFは行指定までできる。tes[t].txt:10で叩く感じ。 -
gx…該当アプリを起動する。URLの上で叩くとそのページがブラウザで開いたりする。 -
cc/<</>>…オペレーター重ねの括りです。そのときいる行を範囲として操作する。ddとかyyと同じノリ。 -
mx…現在位置をxにマークする。多分レジスタとは別の名前空間っぽい。 -
\x/'x…マークしたxの位置にカーソル移動。`がちょうどその位置なのに対し'`は行頭。 このxとかのところは特殊なものもあるので後のセクションで書きます。
モーション
gj/gk…表示上の行で移動。折り返しがあるときにj/kよりも直感的だけどリズム悪い気がする。e/ge…end of word的な。w/bは知っていたがeは知らなかった。geは前の単語の最後。f…○○の文字まで移動する。例えばabcde[f]ghijklmnでflと叩くとabcdefghijk[l]mnになる。大文字は逆方向。t…fと似ていて、fがその文字まで移動するのに対してtはその文字の前まで移動する。 さっきの例で言うとlじゃなくてkの部分にカーソルが行く。;…f,t各モーションの繰り返し0…行頭。^は知っていた。^は行の最初の非空白文字、0は関係なく行の最初。Ctrl+f/Ctrl+b…1ページ移動。半ページ移動のCtrl+d/Ctrl+uは知っていた。(/)/{/}…段落移動。(/)は空行を段落として扱うっぽい。
オペレーター
dawのdの部分です。
</>…インデントを上げ下げする。=…インデントを整形する。gq/gw…テキストを整形する。80文字基準とかも適用できる。gqがカーソルを動かすのに対してgwは動かさないっぽいgu/gU/g~…大文字小文字を変える。guが小文字、gUが大文字、g~がトグル。
大体operatorはvisualでも使えます。
textobjects
dawのawの部分です。aはa word,iはin wordみたいな感じです。
awのうちwの部分を書きます。
(/)/[/]/{/}/</>…対応する括弧。a[だと括弧自体も含む、i[だと含まないみたいな挙動をする。b/B/t…bは()、Bは{}、tはHTMLタグです。HTMLタグと</>はまた違うので注意。"/'/```…対応する各クォート。
プラグインとかによる追加も結構あるっぽい。あとこっちもvisualで使える。
特殊レジスタ群
さっきのmarkのところで書いた特殊なものです。 この特殊なものはレジスタやmarkにあります。
今の私はレジスタの方が仕様頻度が高いのでレジスタから。
レジスタ
クリップボードだけ知ってました
0…最後にヤンクしたもの。1,2,…とどんどんスライドしていくシステム。多分無意識に使ってる。"…0よりももっと適用範囲が広い。というのはy以外にdやcでも反応する。%…現在のファイル名。コマンドモードで%で現在のファイルを対象にするのは直交性?/…最後に検索したもの。Normalで検索するときと同じなので直交性がここでも確保されていますね。:…最後に実行したコマンド。Normalでコマンドモードに入るときと同じ以下略。.…最後にInsertしたテキスト。skkeletonで入力したあとに見ると<C-H>の連発で見辛い。-…最後に一行未満で消去したもの。=…数式を入力してその結果を文字列として渡す。"=1+5<CR>pで現在位置に6がペーストされる。_…ブラックホールレジスタ。ここからペーストしても虚無しか出てこない。
マーク
0…Vimが以前終了したときの位置。ファイル名がついていないバッファだったら遡ってファイル名がついているバッファを開きにいく。"/.…当該ファイルを最後に編集したときの位置。"が対象の編集を始めた場所に対して、.は終わりです。\``…最後にジャンプしたとき、その元々の位置に移動する。ab[c]defgでabcd[e]fgになった後に``するとab[c]defg`に戻ってくる。
Insert
今度はInsertでのものを見ていきます。というかInsertにもマッピングあったんですね。
Ctrl+o…一度だけNormalモードのコマンドを実行する。 自分はカーソルを行頭に持っていくために使ったりしている。Ctrl+i/Ctrl+d/Ctrl+t…iは完全にTabの代わり。行頭の増減はd,tで。Ctrl+j/Ctrl+m…Enterの代わり。違いはマッピングしたとき。mだと通常Enterも巻き込まれる。 私はCapsLock+Oで既にkeydでマッピングしているので多分使わないと思います。 keydの記事はこちら(ダイマ)。Ctrl+h…BackSpaceの代わり。自分はCapsLock+bで既にkeydで以下略。Ctrl+r…レジスタ等の内容を挿入する。ここでさっきの0レジスタとかを覚えておくと(多分)若干楽になる。Ctrl+u…カーソル前のテキストを全削除する。
そういえばInsertから抜けるときについても書きましたね。 これです。
Visual
normalの方で書いたモーションも使えます。 参考の一つのスパルタンvimからするとあまりよくないようですが私はなんだかんだでないと生きていけません。
v/V/Ctrl+v…Visual系のモード切り替え。通常Visual、行Visual、ブロックVisual。 そのときのモードと切り替え先が同じだったらNormalになります。I/A…ブロックVisualのとき用。選択範囲の最初or最後に文字追加。 手動では最初の行にしか書いていないのにいきなり全部の行に追加されてビビります。:'<,'>w…選択範囲を指定ファイルに書き込み。 これに限らず:'<,'>は選択範囲を使ったコマンドによくついてます。o…選択範囲の反対側に移動。後ろに向かって進んでたけど前側に足りない区間があったら使いましょう。
先述の通りモーションやtextobjectsも使えます。
まとめ
元が狭すぎるとはいえVimの世界は広いですね…
