ホーム > タグ > lv3

lv3

Hack #124: Vimで非同期実行を行う

VimがEmacsと比較して一番劣っている機能として、コマンドの非同期実行があげられます。ここでは現状のコマンド実行の問題点とEmacsとの比較、その解決方法について議論を行います。

Vimのコマンド実行の欠点

Vimはsytem():readを用いて外部コマンドを実行し、その結果を得ることができます。これは非常に便利なのですが、Vimが起動した外部コマンドの終了を待ち合わせるため、Vimが停止してしまうという欠点があります。これは特にquickrunや:makeを実行しているときに問題となります。プログラムをバックグラウンドで実行すれば、終了を待ち合わせずにすみますが、それでは結果がとれません。さらにWindows上のGVimの場合、外部コマンドを実行するたびにDOS窓が開いて煩わしいです。 処理内容がシェルに依存するという欠点もあります。たとえば、Windowsでプログラムを起動するためには適切にエスケープしなければいけません。

Emacsとの比較

対するEmacsはどうでしょう。Emacsでは、start-process関数を用いてプロセスを生成することにより、コマンドを非同期的に実行できます。 comint-modeでもこれを用いてインタプリタを起動し、非同期で通信しています。 ただし、Emacsにはマルチスレッド関数がありません。全ての処理はシングルスレッドです。

外部インタフェースの欠点

RubyやPerl, Pythonといった外部インタフェースを用いるという解決策もあります。 しかし、外部インタフェースは通常のVimScriptとは文法が異なるため、連携が非常にややこしいです。時折フリーズしたり、エラーが起こったときにデバッグしづらいという欠点もあります。さらに、すべての環境で使えるわけでもありません。インストールしているRubyやPerl, Pythonのバージョンにも依存するなど、 非同期に通信するためだけに外部インタフェースを用いるのは大げさすぎます。 ただし外部インタフェース内ではマルチスレッドが使えるので、真の非同期通信をするためには、外部インタフェースを用いるほかありません。

vimprocについて

外部ライブラリであるvimprocを用いて外部コマンドと通信すれば、上記に挙げたほとんどの欠点が解消されます。 vimprocとはYukihiro Nakadairaさんが開発している、優れた非同期実行ライブラリです。私が改良したものをgithub上で開発しています。 http://github.com/Shougo/vimproc/tree/master ソースからコンパイルしてVimのautoloadディレクトリに、「proc.soまたはproc.dll」と「vimproc.vim」をコピーすれば準備完了です。

ここでは、vimprocで実装されているvimproc#system関数を紹介します。これは、標準のsystem関数を置き換えることができます。 ただしシェルを起動しないので、シェルの内部コマンドは動作しません。パイプやリダイレクトも動かないので注意してください。 パイプやリダイレクトについては、今後実装予定です。 let l:result = vimproc#system('ls') vimprocを駆使すれば非同期実行をエミュレーションできますが、スレッドの存在しないVimでは使い方がとてもややこしいので、ここでは説明を省略します。 興味がある場合にはvimprocのtestディレクトリにあるサンプルスクリプトを参照してください。 ネットワーク通信もできるので、Twit.vimみたいなプログラムも簡単に作成できます。 いずれはcomint-modeのように、インタプリタ実行機能を統合させたいと思っています。 ちなみにVimScriptでのシェル実装であるvimshellでも、vimprocを用いて非同期実行を行っています。

その他の非同期実行ライブラリ

その他のライブラリとして、vimprocやvimshellをもとにNico Raffatoさんが製作しているConqueというプラグインがあり、とても精力的に開発されています。Emacsのansi-term.elを目標にしているようで、動作が散漫なのが欠点ですが、多機能のようなので使用してみるといいかもしれません。

CursorHoldイベントの落とし穴

しかも、Vimには指定された時間が経過したら関数を呼び出すタイマー機能がありません。 CursorHoldICursorHoldイベントで代用するという手がありますが、これにはイベントごとに時間を設定できない、 ポップアップが表示されているときは呼ばれない、カーソルが動くまで呼ばれないといった欠点があります。 この欠点は本質的に回避不能です。Vim本体にタイマー実行機能が搭載されるのを待つしかありません。

clientserver機能を使う

Vimのclientserver機能を用いると、処理が完了した際に機能を呼び出すコールバック機能を実装することが可能です。 ただし、X環境が必要になります。Windows上でも使用できますが、あらかじめ別のVimを用意しておく必要があります。詳しくは:help clientserverを参照してください。

Shougo

Hack #118: ホームディレクトリをラクに入力する

問題

Vimのコマンドラインでホームディレクトリを入力する機会は比較的多いものの、~/という文字列を見ただけで小指に疲労が走ってくるのは、ほとんどのVimユーザに共通するのではないでしょうか。 もしも入力しやすいキー、例えばバックスラッシュなどで一発で~/が入力できれば、どんなに素晴らしいことでしょうか。

解決

以下のコードを~/.vimrcに記述することで、コマンドラインモードでバックスラッシュで~/が入力できる上、~/が来て欲しくなさそうなところではそのままバックスラッシュが入力されます。

function! HomedirOrBackslash()
  if getcmdtype() == ':' && (getcmdline() =~# '^e ' || getcmdline() =~? '^r\?!' || getcmdline() =~? '^cd ')
    return '~/'
  else
    return '\'
  endif
endfunction
cnoremap <expr> <Bslash> HomedirOrBackslash()

この設定を有効にしたVimで:e \と打鍵すると、ただちに:e ~/に展開されます。 また、:s/\と打鍵した場合は、:s/\とそのままになります。(:s/~/のように展開されません)

発展

本Hackはcho45さんの.zshrcへのハックへのアナロジーで考案されました。 残念ながら現在cho45さんの最新版の.zshrcにはそのコードは存在していないようですが、 少し古いところに残っています。 著者の手元の.zshrcから引用すると、以下のようなコードでした。

expand-to-home-or-insert () {
  if [ "$LBUFFER" = "" -o "$LBUFFER[-1]" = " " ]; then
    LBUFFER+="~/"
  else
    zle self-insert
  fi
}
zle -N expand-to-home-or-insert
bindkey "\\"  expand-to-home-or-insert
ujihisa

Hack#115: Vimのバージョンや拡張機能をチェックする

自分でプラグインを書く場合、プラグインが動作しているVimのバージョンやVimで有効になっている機能を確認したい場合があります。ここでは、そんなときに役立つ関数について解説します。

Vimのバージョンをチェックする方法

Vimのバージョンをチェックするには、v:version変数をチェックすればよいです。百の位がVimのメジャーバージョン、十の位と一の位がマイナーバージョンを表します。例えばVim 7.2で:echo v:versionすると、702が表示されます。720ではありません。Vimがバージョン7以上であることをチェックするには次のようにします。

if v:version < 700
    echoerr 'Does not work this version of Vim "' . v:version . '".'
    finish
endif

ちなみに、パッチレベルはhas('patch100')などでチェックします。詳しくは、:help has-patchを参照してください。

有効になっている拡張機能をチェックする方法

自分のVimがどのような拡張機能を持っているかは、:versionを実行するのが早いですが、 プラグインがチェックする場合には使えません。スクリプトでチェックするには、has()を用います。 たとえば、Windowsかどうかをチェックするには、

if has('win32') || has('win64')
    " Windowsの場合の処理
endif

です。GVimかどうかをチェックするには、has('gui_running')です。これはhas('gui')と間違えやすいので気をつけてください。has('gui')はGUI機能付きでコンパイルされているかどうかをチェックします。has('gui_running')でうまく条件を切り分ければ、.gvimrcを用いずにGVim用の設定を.vimrcだけで完結させることも可能です。 ただし、最初vimで起動して:guiでGUIになる場合は.vimrcのhas('gui_running')設定は読み込まれません。注意してください。(mattnさん情報)

使用上の注意

Vim6以下の場合はスクリプト機能が全然違うので、切り捨てても良いですが、Vim7以降の差異はそこまでありません。 本当にそのバージョンをチェックするべきなのかをよく考えましょう。 拡張機能も本当に必要なものだけを使うようにしましょう。

Shougo

Hack #110: Vimでプレゼンをする (Mac OS X編)

Vimというプレゼンツールソフトウェアは、ソフトウェア開発にも用いることができるということで知られています。 本HackではVimをMac OS Xでプレゼンツールとして便利に使うための手法を公開します。

iTerm + Vim

定番の組み合わせはiTermとターミナル上で動作する素のVimです。 特別なことがなければ、この組み合わせを選択するのがもっとも無難でしょう。

利点

  • 文字の大きさの変更が柔軟で容易 (単にCmd+Cmd-を連打するだけ)
  • screenを用いることにより、Vimからシェルへの移動をスムーズに行なうことができる
  • フルスクリーンなので無駄なスペースがない

欠点

  • 画像を表示することができない
  • 等幅フォント固定
  • 部分的にフォントサイズを変更することができない

(KeyNoteと組み合わせて使うこともできます)

MacVim

ターミナルではなく、単独のGUIアプリケーションであるMacVimを使う方法もあります。 フォントサイズの変更が柔軟でない一方、このパッチを適用することにより、プロポーショナルフォントを使うことができるという利点があります。

ただし、フルスクリーンにできない、文字のサイズ変更が容易でないなどデメリットが多過ぎますので、あまりお勧めしません。

シェルを使うときはvimshellを用いるとよいでしょう。

:TOHtml + Opera

もはやVimではないですが、見た目はVimですので、多くの観客を騙すことができます。 フルスクリーンにすることのできるブラウザならば何でも良いのですが、Operaが最も手っ取り早いでしょう。

:TOHtmlした結果のHTMLに対して画像のタグを貼付けることによって、Vimの素晴らしい見た目でかつ画像を表示でき、最高のプレゼン環境と言えるでしょう。 文字のサイズも柔軟に変更できます。

唯一の問題点は、Vim上で動作しているわけではないので、その場でquickrunやvimshellを動かすことができない点です。

ujihisa

Hack #109: 本当は怖いVim script – var{ia}ble編

問題

Hack #105: surroundをより便利に使う では、surroundの設定例として以下のものを取り上げました:

let g:surround_{char2nr('j')} = "「\r」"

Hack #105では本筋でないのため軽く流しましたが、 よくよく確認してみると変数名の記述が変態的なものになっています。 一体これはどういうことなのでしょうか。

解説

Vimでは変数名(および関数名)の中に任意の式を {expr}の形で埋め込むことができます。 変数名中に{expr}が含まれる場合、 実行時に{}中の式exprが評価され、 その結果で{expr}が置き換えられます。 最終的には{expr}が置き換えられた 変数名が参照されることになります。

例えばg:surround_{char2nr('j')}の場合、 式char2nr('j')を評価した結果(= 106)で {char2nr('j')}が置き換えられ、 最終的にg:surround_106が参照されることになります。 ですから、

let g:surround_{char2nr('j')} = "「\r」"

let g:surround_106 = "「\r」"

と等価です。 ただ{expr}による表記の方が意図するところが分かり易くなります。

現代的なVim scriptならば

let g:surround = {}
let g:surround['j'] = "「\r」"

のような形で記述するところですが、 surroundの場合は過去のバージョン(6.x)のVimでも動作するように記述されており、 またlistやdictionaryなどの現代的な要素はVim 7.xから追加されたものであるため、 このようになっています。

言い換えると、Vim scriptにはつい最近まで配列すら存在しなかったのです。 var{ia}ble表記が導入された理由の一つは、 値として数値と文字列しか存在しなかった時代に、 なんとかして配列を実現するための手段としてです。

参考資料

kana

Hack #106: 一つのウインドウに集中する

問題

通常、Vimでは縦横に画面を分割して複数のファイルを同時に閲覧しながら編集することになります。 常に一つのウインドウのみ表示して他のバッファに:bnなどで移動することもできますが、画面分割を行なうことで編集対象のウインドウ群を平面上の位置関係で認識することにより、人間にとって直感的な管理ができ、画面分割したままウインドウの移動で複数ファイルを同時に対処するという方法が好ましいシーンが多いです。

さて、ディスプレイのサイズやフォントサイズによっては、たとえばたった6分割するだけで各ウインドウがとても小さくなってしまいます。 とりわけプレゼンテーションを行なう際には、フォントサイズを通常よりもとても大きくするため、ウインドウサイズの制限がより厳しくなります。

1タブ1ファイルという1次元空間上にバッファ群を配置することで管理することもできますが、二次元空間上で行ないたい場合、どのようにすればいいのでしょうか。

解決

コマンドBigを定義します。以下の設定を~/.vimrcに記述します。

command! Big wincmd _ | wincmd |

以後、:Bigでそのウインドウサイズを可能な限り広げます。 逆に全てのウインドウサイズを同程度に戻したいときは、Vim標準機能である<C-w>=を使用します。

発展

著者は以下の関数とコマンドを定義し、<Space>aoで編集中バッファを別の単独のタブに切り出すようにしています。

" kana's useful tab function {{{
function! s:move_window_into_tab_page(target_tabpagenr)
  " Move the current window into a:target_tabpagenr.
  " If a:target_tabpagenr is 0, move into new tab page.
  if a:target_tabpagenr < 0  " ignore invalid number.
    return
  endif
  let original_tabnr = tabpagenr()
  let target_bufnr = bufnr('')
  let window_view = winsaveview()

  if a:target_tabpagenr == 0
    tabnew
    tabmove  " Move new tabpage at the last.
    execute target_bufnr 'buffer'
    let target_tabpagenr = tabpagenr()
  else
    execute a:target_tabpagenr 'tabnext'
    let target_tabpagenr = a:target_tabpagenr
    topleft new  " FIXME: be customizable?
    execute target_bufnr 'buffer'
  endif
  call winrestview(window_view)

  execute original_tabnr 'tabnext'
  if 1 < winnr('$')
    close
  else
    enew
  endif

  execute target_tabpagenr 'tabnext'
endfunction " }}}

" <space>ao move current buffer into a new tab.
nnoremap <silent> <Space>ao :<C-u>call <SID>move_window_into_tab_page(0)<Cr>
ujihisa

Hack #99: 起動に時間のかかるプラグインを探す

Vim には便利なプラグインがたくさんありますが、大量にインストールすると起動に時間がかかるようになってしまいます。そこで、Vim のプロファイリング機能を使って起動に時間のかかっているプラグインを探す方法を紹介します。

追記

Vim 7.2.269 から –startuptime と言う起動時のプロファイルを簡単に行うためのコマンドライン引数が追加されました。


vim --startuptime=result.txt

のようにすることで、Huge版でなくても手軽にプロファイルを行う事が出来ます。

本 Hack はこのパッチが公開される前に書かれたので少々複雑な手順を踏んでいますが、この方法で生成された result.txt には行単位でどれかけ時間がかかったのかも書かれているのでより詳しい調査ができる、という利点もあります。

準備

まず、+profile 機能の付いた Vim を用意する必要があります。これは Huge 版の Vim に付いている機能です。手元の Vim が Huge 版でない場合は、ソースから自分でコンパイルする必要があります。 コンパイル方法については本 Hack の範囲を超えるので省略します。

プロファイルを行う

以下のようにして vim を起動します。

vim --cmd "profile start result.txt" --cmd "profile file */plugin/*.vim" -c quit

このコマンドを実行すると、特にエラーが発生しない限り vim はすぐに終了します。そしてプロファイル結果が result.txt に出力されます。

また、ついでに自分の vimrc も確認したい、という場合は –cmd を増やせば大丈夫です。

vim --cmd "profile start result.txt" --cmd "profile file */plugin/*.vim" --cmd "profile file .vimrc" -c quit

ファイル名は適時変更してください。また、コマンドの実行タイミングにより $MYVIMRC は使えません。

結果を解析する

プロファイル結果の概要を知るために結果のファイルを加工してみます。 以下のような vim スクリプトを作成し、結果ファイルを開いてから作成したスクリプトを :source します。

let s:list = []
global/^SCRIPT/
\ call add(s:list, printf("%s\t%s",
\                         matchstr(getline(line('.')+2), '\d\+\.\d\+'),
\                         matchstr(getline('.'), 'SCRIPT\s*\zs.*$')))
new
put =reverse(sort(s:list))
1 delete _

これを実行すると新しいバッファが開かれて、そこに実行時間とスクリプトのファイル名が時間のかかった順に表示されます。 もっと細かい結果が知りたい場合はプロファイル結果を直接眺めたり別の方法で加工すると良いでしょう。 なお、今回の方法では 'runtimepath' の plugin ディレクトリ内にあるファイルのみを対象にし、各プラグインが外部の Vim スクリプトを実行している時間も含めた時間を出しました。

thinca

Hack #93: neocomplcacheを拡張する 前編

neocomplcacheはデフォルトのままでも使いやすいですが、自動補完になれてくると、自分でもneocomplcacheの機能を拡張させたいと思うでしょう。そんなときにはneocomplcacheのプラグインを作ると便利です。neocomplcacheに新たな命を吹き込みましょう。

プラグインの仕様

プラグインはautoload/neocomplcache/pluginにインストールしたものが自動的に読み込まれます。 プラグインには、絶対必要な関数がいくつかあります。ここではそれについて説明をしておきます。

neocomplcache#plugin#プラグイン名#initialize()

neocomplcacheが初期化するときに呼ばれます。ここで変数の初期化をしたり、初期設定を行います。

neocomplcache#plugin#プラグイン名#finalize()

neocomplcacheが無効化されるときに呼ばれます。ここで不要になったコマンドやautocmdを削除します。

neocomplcache#plugin#プラグイン名#get_keyword_list(cur_keyword_str)

a:cur_keyword_strにマッチするリストを返すために呼ばれます。get_keyword_list()が返す補完リストは、特定のキーを含むディクショナリのリストとなっています。詳しくは「補完リストの仕様」の項を参照してください。

補完リストの仕様

get_keyword_list()が返す補完リストは、特定のキーを含むディクショナリのリストとなっています。一部のキー以外はVim標準の補完で使用するものと同じです。

word, abbr, menu, info, icase, dup

Vim標準の補完で使用するものと同じです。word以外は省略することができます。詳しい解説は、[Hack #14: ]Insert mode補完 自作編を参照してください。 menuはどのプラグインの候補で補完しているかを[B]のような記号で表す習慣になっています。絞り込み時におかしくなるので、icaseは必ず1に設定してください。

プラグイン用ヘルパ関数

autoload/neocomplcache.vimには、プラグインから呼び出せるようにヘルパ関数が実装されています。ここでは、よく使われる関数について解説します。

neocomplcache#keyword_filter(list, cur_keyword_str)

get_keyword_list()で使用できる、単純なフィルターです。a:listの中から、a:cur_keyword_strにマッチするリストを返します。とは違って、listは変更されるとは限りません。

neocomplcache#unpack_dictionary(dict)

リストの辞書をリスト化して返します。

neocomplcache#unpack_dictionary_dictionary(dict)

辞書の辞書をリスト化して返します。

neocomplcache#keyword_escape(cur_keyword_str)

a:cur_keyword_strをマッチングに使えるようにエスケープします。

neocomplcache#get_cur_text()

現在のカーソル文字列を取得します。

neocomplcache#get_completion_length(plugin_name)

plugin_nameの自動補完する文字列長を返します。

neocomplcache#get_keyword_pattern_end(filetype)

文字列の最後にマッチするfiletypeのキーワードパターンを返します。filetypeは省略可能で、省略すると現在のバッファのfiletypeを参照します。

neocomplcache#get_keyword_pattern(filetype)

文字列にマッチするfiletypeのキーワードパターンを返します。filetypeは省略可能で、省略すると現在のバッファのfiletypeを参照します。

neocomplcache#check_skip_time()

補完開始時刻と現在の時刻を比べ、スキップするべき場合に1を返します。時間がかかりすぎる計算を中断する場合に使います。

neocomplcache#is_auto_complete()

自動補完の時に1を返します。

neocomplcache#print_caching(string)

キャッシュ時のメッセージを表示します。

neocomplcache#print_error(string)

エラーメッセージを表示します。

キャッシュ用ヘルパ関数

autoload/neocomplcache/cache.vimには、プラグインから呼び出せるキャッシュのヘルパ関数が含まれます。 量が多いので、ここでは詳しく説明することは避けますが、うまく利用すると簡単にキャッシュを使ったプラグインを記述できます。 ちなみに、neocomplcache Ver.4以降では、ほとんどのプラグインがキャッシュ用ヘルパ関数を使うように書き直されています。

プラグインのサンプル

neocomplcacheに標準添付のプラグインを参考にしても良いのですが、機能が複雑化しているため、プラグイン作りの勉強のために見るのは大変です。 thincaさんが作成したsnipMate_complte.vimはほどよい長さなので、勉強に最適でしょう。 ただし、これはneocomplcache Ver.4に対応しておらず、仕様が古いです。参考にする場合は注意しましょう。

プラグインと補完関数の違い

neocomplcache Ver.3.00より、補完関数が実装され、より自由度の高い補完が実装できるようになりました。 プラグインと補完関数の違いは、プラグインはカーソル前のキーワードから補完しますが、補完関数は独自に補完位置を決定できるというところです。 ただし、ワイルドカードに対応するためには独自に処理しなければいけないなど、ちょっと面倒な部分もあります。 補完関数の作り方についても、今後VimHacksで特集する予定です。

Shougo

Hack #89: 自動補完をさらに使いこなす

[Hack #49: ]自動補完を活用する 後編ではneocomplcacheの基本的な特徴について解説しました。ここではneocomplcacheの良くある質問について簡単に回答しようと思います。設定の参考になれば幸いです。

neocomplcacheで辞書補完をするには?

辞書ファイルへのパスは、変数g:NeoComplCache_DictionaryFileTypeListsに格納されています。 パスを設定すれば、ファイルを開いたときに自動的に読み込まれます。 例えば、私は次のように設定しています。defaultはファイルタイプに関係なく参照される辞書ファイルです。

let g:NeoComplCache_DictionaryFileTypeLists = {
            \ 'default' : '',
            \ 'vimshell' : $HOME.'/.vimshell_hist',
            \ 'scheme' : $HOME.'/.gosh_completions'
            \ }

自動補完が重い

g:NeoComplCache_KeywordCompletionStartLengthの値を増やすか、g:NeoComplCache_SkipCompletionTimeを増やす(例えば’0.3′)と少しイライラが解消されるでしょう。あまりやりすぎると、なかなか自動補完の候補が出なくなります。基本的には自動補完は重い処理なので、あまり性能の低いPCで有効にするものではありません。

Insertmodeでカーソル移動すると補完されて大変

この現象は、autocomplpop.vimでも起こります。neocomplcacheやautocomplpopは挿入モードでのカーソル位置移動をトリガーとして、補完候補をポップアップするようになっているからです。計算中にキー入力が続くと、neocomplcacheは補完をスキップしますが、挿入モードでカーソルキーを使うこと自体、Vimの使用方法として間違っています。

neocomplcacheでスニペット補完を使用するには?

まずはスニペットの展開にKey-mappingを割り当ててください。初期状態ではどのキーにも割り当てられていません。 スニペットのトリガーを補完するか直接入力してから、割り当てたスニペットの展開キーを押すことで展開されます。 展開キーを連打すると、プレースホルダの移動になります。

imap <silent>L     <Plug>(neocomplcache_snippets_expand)
smap <silent>L     <Plug>(neocomplcache_snippets_expand)

オムニ補完が重い

オムニ補完のためのキーワード設定は、変数g:NeoComplCache_OmniPatternsに格納されています。 ファイルタイプをキーとしているので、無効にしたいファイルタイプの正規表現を空にするとオムニ補完が呼ばれなくなります。 例えば、htmlのオムニ補完を無効にするためには、次のようにします。

let g:NeoComplCache_OmniPatterns['html'] = ''

他のプログラミング言語にも対応させたい

補完するためのキーワードの設定は、変数g:NeoComplCache_KeywordPatternsに格納されています。 ファイルタイプをキーとして、キーワードにマッチする正規表現を設定すれば、任意のプログラミング言語に対応します。

Vimのファイル名補完やオムニ補完の呼び出しをneocomplcache組み込みのものに置き換えたい

neocomplcacheに組み込まれているファイル名補完やオムニ補完は、クイックマッチや補完スキップに対応するなど、細かな部分で改良されています。 Vim標準の補完呼び出しを置き換えるためには、次のようにKey-mappingを定義します。

inoremap <expr><C-x><C-f>  neocomplcache#manual_filename_complete()
inoremap <expr> <C-j>  &filetype == 'vim' ? "\<C-x>\<C-v>\<C-p>" : neocomplcache#manual_omni_complete()

Vimで巨大なファイルを開くと、キャッシュ生成で待たされる

neocomplcacheはファイル読み込みを監視し、新たなファイルを開くと、自動的にキーワードをキャッシュするようになっています。 巨大なファイルの場合、このキャッシュを生成する動作が邪魔になることがあります。g:NeoComplCache_CachingLimitFileSizeの値を調節することで、巨大なファイルはキャッシュしないように設定することが可能です。初期値は1000000となっているので、約1メガバイト以上のファイルはキャッシュしません。手動でキャッシュさせるには、:NeoComplCacheCachingBufferコマンドを使用します。

補完がおかしい、クイックマッチが効かない

completeoptに問題があるのだと思います。補完動作がおかしくなるので、longestやmenuは指定しないでください。お勧めはmenuoneを指定することです。クイックマッチが正しく動作するようになります。previewを追加するかどうかはお好みで。

Shougo

Hack #82: コード片を貼付けしてインデントを正しくする

問題

Vimでコード片をヤンクして別の場所で貼付ける際に、インデントの深さが異なる場合があります。 インデントの再調整をどのようにして楽に行なうことができるでしょうか。

解決1 Vimに任せる

Vimには=で指定した範囲のインデントを整える機能が備わっています。これはファイルタイプに依存します。

例えばRubyで以下のようなコードを編集中に、

...

def fact(n)
if n == 0
0
else
n * fact(n - 1)
end
end

...

def fact(n)の行にカーソルがあり、そこから次の空行までをまとめてRubyとしての正しいインデントに整形するには=}とタイプします。 これは=} (次の空行までを示すmotion)まで適用するという意味です。

これを貼付け後に貼付けした範囲を指定して行なうことで本問題が解決します。まずPで貼付けを行ない、カーソル位置が貼付け位置の手前にある状態のまま移動せずに、=']を行い、貼付けしたコード片の末尾までを指定してインデントを整えさせます。

def fact(n)
  if n == 0
    0
  else
    n * fact(n - 1)
  end
end

必要ならば、P自体をP=']で置き換えることで、より簡単に行なうことができます。

nnoremap P P=']

解決2 手動で頑張る

解決1は=ではうまくいかないときに元のインデント情報が失われてしまい大変なことになってしまいます。このときは、><で手動でインデントの深さのみをまとめて変更させる手法をとるのが好ましいでしょう。

Pで貼付けした範囲を右にインデントするならばPのあとに>']を、左にインデントするならば<']を打鍵しましょう。続けてさらに深く/浅くするには、.を打鍵しましょう。

ujihisa

Home > Tags > lv3

Search
Feeds
Links
  • 公式
  • 勉強会
  • 情報
  • コミュニティ
  • プラグイン
  • vimrc
  • Meta
    Etc
    Creative Commons License
    This blog is licensed under a Creative Commons License.

    Return to page top