Hatena::ブログ(Diary)

pekeblog! このページをアンテナに追加 RSSフィード

2013-01-14

Vim を高速にしたたったひとつの作業

| 01:06 |  Vim を高速にしたたったひとつの作業を含むブックマーク  Vim を高速にしたたったひとつの作業のブックマークコメント

# こんなことがおこってしまいました

見に覚えがないのですが、ある日突然 vim が激重になってしまいました。

vim が重い…

それは vimmer にとっては耐え難いもの…

単純に重いといっても色々あると思います。

重い症状といえば、大体は以下の2つに分類されるかと思います。

  • 起動が遅い
  • ある特定の処理が遅い

- FileType の処理とか、あと、特定の重めなプラギンの処理とか

ところか、Vim の操作の一つ一つが遅いという現象が発生してしまいました。

具体的に言うと、起動はもちろん、バッファの移動、タブの作成、ファイルの保存ですら重い。

ついでにいうと、gui だけでなく、cui も激重です。

というわけで、僕は結構前から vimrc の高速化を図りつつ、乗り換えるエディタを探していました。

候補にあがったのは以下のエディタです

# Emacs を使う

昔、結構長いことつかっていたのですが、設定ファイルのメンテがカオスなのと、

プラグインの管理とキーバインドの管理で挫折。

evil のおかげで割りと快適だったりしたんですけど…最近の elisp 事情を漁るのも結構大変で…むー

# Vico を使う

vi clone な Macエディタ

Nvu (だっけか?)を使うことで、結構カスタマイズができそうなことと、

そこそこ軽快に動作するため、一時期ハマる。

が、しかし、plugin ぽいものが TextMate 互換だったり、

ドキュメントというものはあるものの、ほぼ、ソースを読め的な感じだったので、

結局使用をやめた。

Obj-Cレベルでいじれるので、カスタマイズによっては化けるエディタだと思うのだけれど、

Lisp を使うのであれば Emacs 使うわと思って、挫折

# CotEditor を使う

今でも使ってます。

とりあえず、全体的にバランスがよいのでとても使いやすい。

というか、今でも使っているので…

エディタとしての機能はほぼ網羅していると思うし、プラグインがとても作りやすいので

未だに重宝しています。

が、がっつり使うエディタとしては物足りなかった。

あと、大容量なファイルを開くのがとても苦手なエディタというのもマイナス要因。

# Sublime Edit 2 を使う

これも今でも使っています。

標準でもそこそこ使える上、プラグインも豊富。

で、もごもごしているうちに、Web 上でも注目され、解説 Blog が一気に増えたことでもお馴染みのエディタ

とても高機能で、文句もないのですが、どうしても CUIGUI が混在してしまうため、

Vim代替ではないなと感じました。

ちなみに、Vim ユーザーの方は Vintage を使っているのでしょうが、僕は Vintage なしで使っています。

Vintage なしで使っているのは、やはり CUIGUI の違和感…というところでしょうか。。。なんか、使っていて Vim じゃないと思うといちいち気にかかってしまうのです…orz

ともあれ、簡単な拡張も書きやすいし、すでにたくさんのプラギンがあるため、今でも使っていますし、使うことで勉強にもなっていたりします。

# Vimにもどる。そして改善をはかる

結局 Vim に戻って来ました。

とりあえず、遅い原因は vimrc だろうと思い、vimrc を最適化することにしました。

まず最初にやることと言えば… プラグインの整理…

とりあえず、特定の filetype でしか使わないようなものは、遅延ロードするように修正しました。

その時のコードがこれ

```vim

let s:lazyutil = {

\ '_' : {},

\ }

function! s:lazyutil.add(on, mode, source)

let k = a:on."_".a:mode

if !self.has(k)

let self[k] = []

endif

call add(self[k], a:source)

endfunction

function! s:lazyutil.has(key)

return exists('s:lazyutil["' . a:key . '"]')

endfunction

function! s:lazyutil.get(on, mode)

let k = a:on."_".a:mode

if !self.has(k)

return []

endif

return self[k]

endfunction

function! s:lazyutil.clear(on, mode)

let k = a:on."_".a:mode

if !self.has(k)

return []

endif

let sources = self[k]

unlet self[k]

return sources

endfunction

function! s:lazyutil.load(on, mode)

let sources = self.clear(a:on, a:mode)

if empty(sources)

return

endif

let F = function('neobundle#config#source')

" call call(F, sources)

call call(F, [sources])

" syntax enable

endfunction

function! s:lazyutil.register(on, modes, source)

silent execute 'NeoBundleLazy' a:source

let modes = type(a:modes) == type([]) ? a:modes : split(a:modes, ",")

let name = fnamemodify(a:source, ':te')

let name = substitute(name, '^[''"]*\|\.git[''"]*$\|[''"]*$', '', 'g')

for mode in modes

call self.add(a:on, mode, name)

let k = a:on . "_" . mode

if !self.has("_".k)

let self._[k] = 1

let cmd = printf('autocmd vimrc-neobundle-lazy %s %s NeoBundleLazyOnSource %s %s', a:on, mode, a:on, mode)

silent execute cmd

endif

endfor

endfunction

function! s:neobundle_lazy_source(on, mode)

call s:lazyutil.load(a:on, a:mode)

endfunction

command! -nargs=+ NeoBundleLazyOnSource call <SID>neobundle_lazy_source(<f-args>)

function! s:neobundle_lazy_on(on, modes, source)

call s:lazyutil.register(a:on, a:modes, a:source)

endfunction

command! -nargs=+ NeoBundleLazyOn call <SID>neobundle_lazy_on(<f-args>)

```

なお、今では `NeoBundle 'fuga/piyo' {'autoload': {'filetypes':'ruby'}}` みたいな感じで、遅延ロードできるようになっているようです。

# 結果。。。

あまり変わりませんでした。

多少は早くなったものの、やっぱり操作の一つ一つが遅いのです。

# 悶々とする・・・

ただただ悶々としていたある日のこと…

「むきーーーーー!!!」

と、思いながら、おもむろに ps aux | bash を連打したときのこと。。。

```shell

user 18365 0.0 0.0 2423336 188 s001 RN 12:54PM 0:00.00 bash /Users/user/.rbenv/bin/rbenv init -

user 19381 0.0 0.0 2423336 188 s001 RN 12:54PM 0:00.00 bash /Users/user/.rbenv/bin/rbenv rehash ...

user 20322 0.0 0.0 2423336 188 s001 RN 12:54PM 0:00.00 bash /Users/user/.rbenv/bin/rbenv rehash ...

```


異様に rbenv 関連のスクリプトが多いことに気づいたのでした。

なんじゃこれ・・・?とおもいつつも、デバッグコードをいれたところ、zshenv が異様に遅いことが判明。

遅いのは rbenv 関連というのは明らかだったので、とりあえずそこら辺をコメント化。

で、 vim を起動すると…


なんじゃこりゃぁぁぁーーー


立ち上りチョッパヤ、バッファ移動チョッパヤ、プラギン起動チョッパヤ…


これは…と思い、zshenv の処理をごにょごにょして最適化した結果、キビキビとした vim を取り戻すことができました。

と、いうお話。

これの問題に関しては、さんざんぐぐったのだけれど、

bashrc/zshenv のせいで遅いという話はあまり見受けられなかった。

というわけで、遅くなったのは僕のめちゃくちゃな環境のせいなのかもしれないのだけれど、 Vimmer で、かつ Vim が遅いと思っている方には, シェル初期化ファイル

(.bashrc/.zshenv)の見直しをお勧めします。


※ちなみに rbenv が遅かったわけですが、これは色々と plugin を導入していたためで、一般的に rbenv が遅いということではありません。あしからず。

markdown でかけると思ってたら、、、hatenablog only だったのか…死

tyrutyru 2013/01/14 15:27 .zshenvは非対話環境でも読み込まれる(Vimでcall system('hoge')とか:!hogeとかした時にも実行される)ので、環境変数の設定以外の凝った事は.zprofileに書きます。

pekepekesamuraipekepekesamurai 2013/01/28 01:22 > tyru さん
> .zshenvは非対話環境でも読み込まれる(Vimでcall system('hoge')とか:!hogeとかした時にも実行される)ので、環境変数の設定以外の凝った事は.zprofileに書きます。

.zshenv の件は承知の上だった(xxbrew/xxenv/xxvm の vm 使いたい…)ので、逆に不思議だったのです。なんやらの設定は .zshrc とかに書いていたので。
なんというか、自分の予想以上に .zshenv が呼び出しされているのでビックリしたのです。。。 executable('hoge') とかでも読み込まれているんですかねぇ…?謎

トラックバック - http://d.hatena.ne.jp/pekepekesamurai/20130114/1358093193