2016年2月26日
Vim-Galore : Vimについて知っておくべき全てのこと (5/5)
本記事は、原著者の許諾のもとに翻訳・掲載しております。
特定のトピックについての記述をご希望ですか? Issue を立てるか、 Twitter で私までお知らせください!ありがとう!
はじめに
基礎
- バッファ/ウインドウ/タブ
- アクティブ/読み込み済み/一覧表示/名前付きバッファ
- 引数リスト
- マッピング
- マップリーダー
- レジスタ
- 範囲
- マーク機能
- 補完
- モーション/オペレータ/テキストオブジェクト
- autocmd
- 変更履歴リスト/ジャンプリスト
- アンドゥツリー
- クイックフィックスと位置リスト
- マクロ
- カラースキーム
- 折り畳み機能
- セッション
- ローカリティ
使用方法
- オフラインでのヘルプ
- オフラインでのヘルプ(代替案)
- オンラインでのヘルプ
- クリップボード
- ファイルを開いたときのカーソルの位置を元に戻す
- バックアップ/スワップ/アンドゥ/viminfoファイル
- リモートファイルの編集
- プラグインの管理
- ブロックの挿入
- 外部プログラムの実行とフィルタの使用
- matchit
ヒント
- 適切なnとNの振る舞い
- 適切なコマンドライン履歴
- 適切なCTRL-L
- ビープ音とビジュアルベルを無効にする
- 現在の行を動かす
- 空行を追加する
- マクロを編集する
- ヘッダやソースファイルにジャンプする
- GUIのフォントサイズを変更する
- モードに応じてカーソルスタイルを変更する
- セレクションを横に移動させた時に見失わない
- 保存時にファイルをリロードする
- スマートなカーソルライン
- より速いキーワード補完
コマンド
デバッグ
その他
Quirks
カラースキームのリスト
プラグインのリスト
Neovim
その他
その他の資料
リソース | 説明 |
---|---|
効果的なテキスト編集のための7つの習慣 | Vimの作成者Bram Moolenaar著。 |
効果的なテキスト編集のための7つの習慣 2.0 (PDF) | 同上。 |
IBM DeveloperWorks: Vimエディタのスクリプト作成 | Vimスクリプト作成に関する5部作。 |
コツコツ学ぶVimスクリプト | ゼロから始めるVimプラグインの開発。 |
実習Vim (第2版) | 間違いなくVimの良書。 |
Vimcasts.org | Vimのスクリーンキャスト集。 |
なぜ頭のおかしい人はviを使うのか | 一般的な勘違いに対する説明。 |
あなたのVimの問題点はViの理解不足だ | 簡潔で、有益、的確。とっておきの一冊。 |
Vimのディストリビューション
Vimのディストリビューションはある作成者の目線によるVim+カスタムセッティング+カスタムプラグインです。そのため、非常に独りよがりなものです。
このディストリビューションの問題は、初心者によって使われる傾向があることです。(より上級のユーザは、結局、自分自身のプラグインとセッティングの選び方を心得ています)。問題が表面化するまでは全て順調です。さて、問題はどこで起こったのでしょう? 初心者はどうしていいかわからず、インターネットでアドバイスを得ようとします。長い堂々巡りのあと、ディストリビューションにより提供された妙なマッピングが問題だと見当が付きます。でも初心者は、Vimのマッピングはデフォルトのままなのにと思います。時間の無駄でした。うんざりです。
ディストリビューションそれ自体に問題があるわけではありません。お願いです、何をしているのかを正確に理解できないなら、緊急時に誰かに助けてもらおうとしないでください。
エディタのカスタマイズに何時間もかけたくはないと考える人が多いことは分かっています(実際、いよいよ夢中になって、vimrcのカスタマイズをやめられません)。しかし長期的には、最初の段階でマニュアル作業の方法を学ぶのは素晴らしいことで、時間効率も良くなります。
私に続いて繰り返してください。「プログラマーはツールを理解すべし」
とにかく、何をしているのかが分かっていれば、ディストリビューションを見て、そこから何らかのインスピレーションが得られるかもしれません。
標準プラグイン
多くの人が驚くでしょうが、Vimはデフォルトでは、自動的にロードされるようなプラグインをほんのわずかしか搭載していません。すべてのソースファイルを確認するために、Vimを起動した後、 :scriptnames
をチェックしてください。
ほとんどが使われていないので、適当に判断し無効にしてください。ソースとして表示はされますが、実際には最初の行だけを読み込んで、Vimはプラグインから抜けていきます。それ以上のコード(マッピング、コマンド、ロジック)は処理されません。
プラグイン | 無効化するには | ヘルプ |
---|---|---|
2html | let g:loaded_2html_plugin = 1 |
:h 2html |
getscript | let g:loaded_getscriptPlugin = 1 |
:h pi_getscript |
gzip | let g:loaded_gzip = 1 |
:h pi_gzip |
logipat | let g:loaded_logipat = 1 |
:h pi_logipat |
matchparen | let g:loaded_matchparen = 1 |
:h pi_paren |
netrw | let g:loaded_netrwPlugin = 1 |
:h pi_netrw |
rrhelper | let g:loaded_rrhelper = 1 |
:e $VIMRUNTIME/plugin/rrhelper.vim |
spellfile | let g:loaded_spellfile_plugin = 1 |
:h spellfile.vim |
tar | let g:loaded_tarPlugin = 1 |
:h pi_tar |
vimball | let g:loaded_vimballPlugin = 1 |
:h pi_vimball |
zip | let g:loaded_zipPlugin = 1 |
:h pi_zip |
CapsLockをCtrlにマップする
CapsLockはキーボードで一番役に立たないキーのうちの1つですが、 ホームポジション と同じ行にあるため、Controlよりも押しやすいのです。大量にプログラミングを行うような場合、CapsLockにControlをマッピングすることは、 RSI を防いだり、少なくとも軽減させたりするのに有効な手段となります。
留意点: そのキー配置に慣れてしまうと、それ以外ではもう生きていけないかもしれません。
OSXの場合 :
System Preferences -> Keyboard -> Keyboard Tab -> Modifier Keys
“CapsLock” を “Control” に変更します。
Linuxの場合 :
Xのキーを変更するには、以下を ~/.xmodmap
に追加します。
remove Lock = Caps_Lock
keysym Caps_Lock = Control_L
add Control = Control_L
ソースを追加した後、 $ xmodmap ~/.xmodmap
を実行して有効にします。
他にも xcape を使うことがあります。
Windowsの場合
superuser.comの「Windows 8.1でCaps LockをCtrlに変換する方法」 を確認してください。
イースターエッグ
コマンド | メッセージ |
---|---|
:Ni! |
Do you demand a shrubbery?(低木が欲しい? 訳注:『モンティ・パイソン・アンド・ホーリー・グレイル』に登場する「ニ!」と言う騎士が「低木」の贈り物をもらうとおとなしくなることから) |
:h 'sm' |
NOTE: Use of the short form is rated PG.(注:短縮形はPG指定) |
:h 42 |
What is the meaning of life, the universe and everything? Douglas Adams, the only person who knew what this question really was about is now dead, unfortunately. So now you might wonder what the meaning of death is…(人生とは、宇宙とは、万物とは? この質問に唯一答えられるDouglas Adamsは残念ながらもうこの世の人ではない。あなたは今、死の意味について思い悩んでいるのでは?) |
:h UserGettingBored |
When the user presses the same key 42 times. Just kidding! :-)(ユーザが同一キーを42回押した時。冗談です) |
:h bar |
Ceci n’est pas une pipe.(これはパイプではありません) |
:h holy-grail |
You found it, Arthur!(アーサー王よ、聖杯を見つけましたね) |
:h map-modes |
:nunmap can also be used outside of a monastery.(:nunmapは修道院の外でも使えます) |
:help! |
E478: Don’t panic!(E478:慌てないで)不具合ですか? helpバッファ(buftype=help)では:h help.txtと同様に機能します。 |
:smile |
ご自分で試してみてください。7.4.1005.から追加されました。 |
なぜナビゲーションはhjklなのか?
Bill Joy がVimの前進である vi を作った時、カーソルキーのない ADM3A 上で開発しました。皆さんお分かりですよね? 代わりにhjklを使ったのです。
実際のキーボードレイアウトを見るには クリック して下さい。
Unixシステムでホームディレクトリを表すのに ~
を使うのも同様の理由です。
Quirks
小さいファイルの編集が遅い
パフォーマンスに大きな影響を与える要素は2つあります。
- 複雑な 正規表現 。特にRubyの構文ファイルは、過去に遅延をもたらしたようです。( 構文ファイルのデバッグ )も参照してください)。
- 画面の再描画 。機能によっては強制的に全ての行が再描画されてしまいます。
考えられる要因 | 理由 | 解決法 |
---|---|---|
:set cursorline |
全行が再描画される。 | :set nocursorline |
:set cursorcolumn |
全行が再描画される。 | :set nocursorcolumn |
:set relativenumber |
全行が再描画される。 | :set norelativenumber |
:set foldmethod=syntax |
構文ファイル自体が遅延を引き起こしている場合、これによって更に悪化する。 | :set foldmethod=manual , :set foldmethod=marker or FastFold |
:set synmaxcol=3000 |
内部表現のせいでVimは行が長くなると問題を起こしやすい。3000文字までハイライトする。 | :set synmaxcol=200 |
matchparen.vim | デフォルトで起動される。対応する括弧を見つけるまで正規表現を使う。 | プラグイン :h matchparen を無効にする |
注:本当にパフォーマンスの問題がある時だけ対策をすれば大丈夫です。大抵の場合、上記の対応で事足りるはずです。
大きいファイルの編集が遅い
大きいファイルの最大の問題点は、Vimがファイル全体を一度に読み込んでしまうという点です。なぜそんなことが行われるのかというと、その理由は内部でバッファを表わす方法に関係しています( Discussion on vim_dev@ )。
読み取りだけを行いたい場合、 tail hugefile | vim -
は優れた回避策です。
差し当たり、構文や設定、プラグインなどがなくても大丈夫なら、下のコードを使ってください。
$ vim -u NONE -N
これでナビゲーションが格段に速くなります。なぜなら構文をハイライトする負荷の高い正規表現が使われなくなるからです。また、書き込みに時間がかかりすぎないように以下のコードを使って、Vimがswapファイルやviminfoファイルを使わないようにするといいでしょう。
$ vim -n -u NONE -i NONE –N
簡単に言えば、とても大きなファイルを書く場合はVimを避けたほうが賢明です。
NULに使われる改行
ファイル内のNUL文字( \0
)は、メモリ内に改行文字( \n
)としてメモリ内に保存され、バッファ内で ^@
と表示されます。
さらに詳しい情報は man 7 ascii
や :h NL-used-for-Nul
を確認してください。
括弧付きペースト(なぜいつも”paste”を設定しなくてはならないのか)
括弧付きペーストモードを使うと、ターミナルエミュレータがタイプされたテキストとペーストされたテキストを区別できるようになります。
Vimにコードをペーストしようとして、全てがめちゃくちゃになってしまった経験はありませんか。
これは、 cmd+v
や shift-insert
、 middle-click
などのショートカット機能を使ってペーストした場合にのみ起こります。原因はテキストの塊がターミナルエミュレータに一瞬で書き込まれてしまうことにあります。Vimはテキストがペーストされているだけだということが分からず、ものすごい速さでタイピングされていると思ってしまうのです。そのため、ラインにインデントを付けようとしますが失敗してしまいます。
もちろん、 "+p
などのVimレジスタを使えばVimはペースとされていると分かるので、全く問題ありません。
この問題を回避するために、 set paste
を使うと、そのままペーストできます。 :h 'paste'
や :h 'pastetoggle'
を試してみてください。
毎回、 paste
に切り替えるのが面倒であれば、皆さんの代わりに切り替えてくれる、 bracketed-paste という便利なプラグインがあります。
更に興味がありましたら、このプラグインの作者が書いた記事を こちら からご覧ください。
Neovim: ターミナルエミュレータにサポートされている場合、Neovimはこれら全てをよりシームレスにし、括弧付きペーストモードが自動で設定されるようにします。
ターミナルでEscキーを使った時の遅延
コマンドラインに慣れている方の場合、xtermやgnome-terminanal、iTerm2などのいわゆる ターミナルエミュレータ を使うことがあると思います(本来の ターミナル とは別の物です)。
ターミナルエミュレータの祖先と同様に、これらはカーソルの移動や文字色を変更するなどの操作をコントロールするために、 エスケープシーケンス (または 制御シーケンス )を使います。これらは、エスケープ文字で始まる単純なASCII文字コードの文字列で(画面では、 ^[
といった キャレット文字 で表示されます)、このような文字列が現れると、ターミナルエミュレータは、 terminfo データベースから付随して生じる動作を探し出します。
問題を明確にするために、まずマッピングのタイムアウトについて説明しましょう。これは、マッピング間で曖昧な表現が出てきた場合に常に起こります。
:nnoremap ,a :echo 'foo'<cr>
:nnoremap ,ab :echo 'bar'<cr>
どちらのマッピングも期待通りの反応を示しますが、 ,a
と入力すると、1秒の遅延があります。これは、ユーザが次に b
と入力するかどうかをVimが判断しているためです。
エスケープシーケンスでも同様の問題が起きます。
- 標準モードに戻る、もしくはアクションを終了するために、
<esc>
が多く使用される。 - エスケープシーケンスを使ってカーソルキーをエンコードする。
- Vimでは、
Alt
( メタキー とも呼ばれる)を使えば、高位ビットに設定された適切な8ビットにエンコードして送信される。しかし多くのターミナルエミュレータは、これをサポートしていない(もしくはデフォルトでは有効になっていない)ので、代わりにエスケープシーケンスで送信する。
実際に試してみてください。 vim -u NONE –N
、 i<c-v><left>
と入力すると、エスケープ文字を意味する ^[
で始まるシーケンスが挿入されるのが分かると思います。
ひと言でいうと、Vimは、 <esc>
文字と適切なエスケープシーケンスが入力された場合の違いを認識するのが困難なのです。
Vimでは、デフォルトで :set timeout timeoutlen=1000
を使用するので、曖昧なマッピングかつキーコードが入力された場合、1秒の遅延が起こります。1秒という時間は、マッピングする上では良識的な値ではありますが、キーコードのタイムアウトを任意で設定することができます。これがこの問題に対する、最も一般的な回避策でしょう。
set timeout " for mappings
set timeoutlen=1000 " default value
set ttimeout " for key codes
set ttimeoutlen=10 " unnoticeable small value
:h ttimeout
の下に小さな表がありますが、これはこれらのオプション間の関係性を示しています。
Vimとターミナルエミュレータ間でtmuxを使用するのであれば、これを ~/.tmux.conf
に入れてください。
set -sg escape-time 0
カラースキームのリスト
以下は、一般的に使用されているカラースキームのリストです。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa