Vim-Galore : Vimについて知っておくべき全てのこと (5/5)

vim-galore


特定のトピックについての記述をご希望ですか? Issueを立てるか、Twitterで私までお知らせください!ありがとう!


はじめに

基礎

使用方法

ヒント

コマンド

デバッグ

その他

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のカスタマイズをやめられません)。しかし長期的には、最初の段階でマニュアル作業の方法を学ぶのは素晴らしいことで、時間効率も良くなります。

私に続いて繰り返してください。「プログラマーはツールを理解すべし」

とにかく、何をしているのかが分かっていれば、ディストリビューションを見て、そこから何らかのインスピレーションが得られるかもしれません。

* cream
* janus
* spf13

標準プラグイン

多くの人が驚くでしょうが、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つあります。

  1. 複雑な正規表現。特にRubyの構文ファイルは、過去に遅延をもたらしたようです。(構文ファイルのデバッグ)も参照してください)。
  2. 画面の再描画。機能によっては強制的に全ての行が再描画されてしまいます。

考えられる要因 理由 解決法
: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+vshift-insertmiddle-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 –Ni<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

カラースキームのリスト

以下は、一般的に使用されているカラースキームのリストです。