Home

Vim-users.jp

Hack #164: JavaScript開発環境 その2 CoffeeScriptを使う

問題

JavScriptはその動的性と柔軟な構文により、ブラウザ上で動作するアプリケーションに限らず多くの場で活躍する便利なプログラミング言語です。しかしそれでもいくつか問題が残されています。

  1. セミコロン

    多くのVimユーザはコロンとセミコロンの配置を入れ替え、コロンの入力を容易にするよう調整しているといわれています。しかしながらJavaScriptでは文末にセミコロンの入力を必要とします。

    var a = 1;
    

    上記のような簡素な例だと単純にFPの消費量のみの問題なのですが、しかし以下のようにセミコロンが必要な場合と必要でない場合がすぐに判別しないときもあり、このとき若干の面倒さが残ります。

    function f1() {
      return 1;
    }
    
    var f2 = function() {
      return 1;
    };
    
  2. 括弧

    JavaScriptは関数と変数の名前空間が一致しているためか、関数適用の括弧を省略できない言語仕様となっています。

    f();
    
    f(x);
    

    引数がない場合は()の有無により関数自体か関数実行結果の値かを区別できるというので納得できるのですが、しかし引数がある場合には納得できません。

    f x;
    

    もしこのように書けば、これはf(x)以外に考えられないはずです。それなのに毎回f(x);と記述しなければならないのは冗長で、開発効率の大幅な低下を招きます。

解決法

~/.vim/ftplugin/javascript.vimなどで努力することで、容易に間違いなくセミコロンを入力するためのサポートを行なう、あるいは括弧を自動的に入力するなどやりかたはありますが、いずれもまじめに対処するとなかなか難しい問題です。

もっとも容易な解決策は、例えばJavaScriptを避けることです。

CoffeeScriptでプログラムを書き、JavaScriptにコンパイルする手法を紹介します。CoffeeScriptでは前述の2つの問題を解決し、ほかにもHack #160: JavaScript開発環境で挙げた長い予約語functionをいかにして入力するかという問題も解決します。

例を挙げます。0から2までの数字を出力するコードをCoffeeScriptで記述してみましょう。

f: ->
  memo: 0
  ->
    memo++

Number.prototype.times: (f) ->
  f i for i in [1..this]

g: f()

3.times (i) ->
  p g()

coffee -cpコマンドで、上記コードが以下のようなJavaScriptにコンパイルされます。

(function(){
  var f, g;
  f = function() {
    var memo;
    memo = 0;
    return function() {
      return memo++;
    };
  };
  Number.prototype.times = function(f) {
    var _a, _b, i;
    _a = []; (_b = (1));

    for (i = _b; i <= this; i += 1) {
      _a.push(f(i));
    }
    return _a;
  };
  g = f();
  (3).times(function(i) {
    return p(g());
  });
})();

前述の問題が全て解決したことが分かります。

CoffeeScriptを使うためにはNodeJsCoffeeScript処理系の二つが必要です。2010年7月現在、MacPortsでインストールできるNodeJsはバージョン0.1.92ですが、0.1.98以降で導入されたreadlineや、一部の正規表現エンジンの動作の違いから、0.1.92ではCoffeeScriptの一部の機能しか利用できません。折角ですのでNodeJsは最新版を導入しましょう。

また、CoffeeScriptをVimから快適に使うためのツールがいくつか存在します。以下で紹介する全てを導入することを強くお勧めします。

  1. vim-coffee-script

    http://github.com/kchmck/vim-coffee-script

    ftdetect, ftplugin, indent, syntax全てがそろっています。

    a

  2. quickrun

    http://github.com/thinca/vim-quickrun

    <Space>rなどで編集中ファイルを実行します。CoffeeScriptに対応しています。

    b

    また、明示的に:QuickRun 'coffee -cp'などとすることで、QuickRun出力バッファに, CoffeeScriptからコンパイルした結果のJavaScriptを表示し続けることができ、大変便利です。

新たな問題

JavaScriptでは変数名や関数名をcamelCaseでつけます。つまり、this_is_a_penよりもthisIsAPenが好まれます。JavaScriptを書き慣れている人ならば何の問題もなくcamelCaseで命名していくでしょうが、しかしCoffeeScriptはむしろPythonやRubyのように見えるため、混乱してアンダースコアで小文字の単語を繋げてしまう傾向にあります。

すぐに思い付く解決方法はCoffeeScriptのコンパイラ部分を書き換えて識別子名を自動で置換することでしょうが、しかしこの方法ですともとのCoffeeScriptのコードはcamelCaseでないままです。

解決法

挿入モードの_をシフトキーとして扱うようにし、this_is_a_penと打鍵するだけでthisIsAPenと打鍵したことになるようVim側の挙動を変更します。そのためにstickykey.vimを用います。

  1. http://www.vim.org/scripts/script.php?script_id=2990 からstickykeyをインストールする
  2. ~/.vim/ftplugin/coffee.vimに以下を記述する

    function! JavaScriptUnderScoreBecomesCamelCase()
      if matchstr(getline('.'), '.', col('.')-2) =~ '\w'
        return "\<Plug>(stickykey-shift)"
      else
        return '_'
      endif
    endfunction!
    
    imap <buffer><expr> _ JavaScriptUnderScoreBecomesCamelCase()
    

カーソル位置が[a-zA-Z0-9_]のときのみ_がシフトキーとして動作します。空白文字の上で_を打鍵したときなどは_のままになりますので、例えば_ではじまる関数名の関数を定義するときなどに気兼ねなく_を打鍵できます。

補足

本HackでCoffeeScriptを用いた効率的なJavaScriptの開発方法を紹介しましたが、しかしながら、CoffeeScriptも万能ではありません。無引数関数の値を取り出すための(), 関数リテラルの仮引数指定の(x), 条件演算子a ? b : cの違いなど。これらの問題を解決するためのパッチが勇士によって開発中とのことです。

また、coffee -iで起動するインタラクティブなcoffeeインタプリタをvimshellを用いたVim内で操作できるはずなのですが、現時点ではなぜかうまく動作しないという問題があります。

ujihisa

Hack #163: VimをVimスクリプトインタプリタとして使う

viの前身であるedは、シェルスクリプトなどで文字列置き換えのために使うことができます。 (fileというファイルの中身を全行逆転させる例です)

ed - file <<EOS
g/^/m0
write
qall!
EOS

g/^/m0^にマッチする行に対して:m0という操作を適用するコマンドです。 :m0は分かりやすく書くと:move 0で、引数の行の下に現在の行を持っていくという動作をします。 ^はどの行にもマッチするので、:m0で全部の行に対して上からマッチした順に1行目に持っていきます。 操作が終わると全行が逆になっているというわけです。

また:write:qall!は全行逆になったバッファをfileに書き込むために必要です。

VimについてくるexというコマンドはedのVim版とも言えるものですのでもちろん上のようなことができます。 しかしデフォルトでは.vimrcやプラグインなども読み込んでしまうため、 「素のex」として使いたい場合は「-u NORC –noplugin」を指定する必要があります。 さらにVimmerとしてはVimの機能が使えず戸惑わないように「-N」も指定する必要があります。 よってexをVimスクリプトインタプリタとして使うには以下のように起動すればできそうです。

ex -N -u NORC --noplugin

冒頭の例のex版はこのようになります。

ex -N -u NORC --noplugin file <<EOS
g/^/m0
write
qall!
EOS

デフォルトでもこのようにVimスクリプトインタプリタのように使えなくはないのですが、以下のような難点があります。

  1. ファイルに対して実行するには末尾に必ず:write:qall!をつけなければならず面倒
  2. ファイルに対して実行する際に元のデータを壊してしまう
  3. いくつかの定型的なオプションを付けるのが面倒
  4. 標準入力からスクリプトを読み込むのでファイルを標準入力から読み込めない

解決

iexを使います。 これはVimスクリプトをPerl、Ruby、Pythonなどの多くのLLのインタプリタと同じ感覚でVimスクリプトを実行させることができる優れ物です。

$ echo 'g/^/m0' >reverse.vim
$ cat ~/.vimrc | iex reverse.vim -

# -eオプションで指定することも可能
$ cat ~/.vimrc | iex -e 'g/^/m0' -

$ iex    # /bin/exが開く

詳しくはiex -hを見てください。

いくつかのVimスクリプト

おまけとしていくつかのUNIXコマンドをVimスクリプトで実装します。

tac

$ cat tac.vim
g/^/m0
$ iex tac.vim file

sort

$ cat sort.vim
sort
$ iex sort.vim file

sort -u (sort | uniq)

$ cat uniq.vim
sort u
$ iex uniq.vim file

grep

$ cat grep.vim
edit `=ARGS[1]`
execute 'v/' . ARGS[2] . '/d'
$ iex -s grep.vim ~/.vimrc vim

("vim"のみを含んだ行が表示される)

また-eオプションを使ったやり方を示すと

$ iex -s -e 'edit `=ARGS[1]' -e 'execute "v/" . ARGS[2] . "/d"' ~/.vimrc vim

のようになります。
これは一般のLLインタプリタと同じようにワンライナーのようなものを書くのに適しています。

また-sを与えることで引数の扱いを変えています。
-sを与えると中身を読み込まずにg:ARGSというListに代入するだけにします。
その他細かい違いなどはiex -hを見てください。

tyru

Vim 7.3の新機能まとめ

とりあえず自分も今調べている最中なので:help version7.3をそのまま紹介する形にします。
他にもこれは紹介するべきというものや間違い等があったらどんどん追加/修正お願いします。 >Vim Hacksのメンバー

Persistent undo

Hack #162: Vimを終了しても undo 履歴を復元するですでに紹介されていますが、Vimを終了してもundo履歴が復元できる機能です。

ファイル暗号化方式の追加

ファイルを暗号化して保存する際、従来はPkZip方式での暗号化が行われていましたが、
新たにBlowfish方式での暗号化も選べるようになりました(:help ‘cryptmethod’)。

conceal

シンタックスハイライトで特定のハイライトグループを見た目「消す」ことができます。
すでに最新版のVimをインストールすると、syntax/help.vimがこの機能を使っていて単語を囲んでいる*|などの文字が消えています。

シンタックスハイライトで文字を隠すことができるようになったわけで、いろいろと応用できそうです。
プラグイン開発者にとって見逃せない新機能となっています。

例としてすでにsyntax/markdown.vimでこの機能を使い

[リンク](URL)

というmarkdownの記法を

リンク

に見た目を変えてしまうパッチがメーリングリストに投げられました

またオプションとしてconceallevelが加えられています。

Luaインターフェース

LuaでVimプラグインが書けるようになりました。
詳しくは:help luaを。

Python3インターフェース

Pythonインターフェースに加えPython3インターフェースが加えられたようです。
両者はコマンドが分かれていて、それぞれ:python, :python3となっています。

‘encoding’をmodelineで変更することの禁止

modelineでencodingを変更することができなくなりました。

‘relativenumber’オプション

これはオンにしてみれば分かりやすいと思いますが、相対的な行番号を表示します。
つまり現在行の横に「0」と表示されて、一行上と一行下は「1」、二行上と二行下は「2」と表示されるようになります。
このオプションがセットされたとき’number’の値はリセットされます。
この機能は、jkに数値を付けて移動する場合(13jなど)のために追加されました。

詳しくは:help 'relativenumber'を。

いくつかの関数追加

More floating point functions: |acos()|, |asin()|, |atan2()|, |cosh()|,
|exp()|, |fmod()|, |log()|, |sinh()|, |tan()|, |tanh()|.  (Bill McCarthy)

Added the |gettabvar()| and |settabvar()| functions. (Yegappan Lakshmanan)

Added the |strchars()|, |strwidth()| and |strdisplaywidth()| functions.

詳しくは:help added-7.3を。

新機能の解説

また以下のサイトで

  1. ‘cursorbind’
  2. conceal
  3. :ownsyntax

の3つの新機能の解説があります。 英語ですがスクリーンショットなどもありなかなか分かりやすいです。

http://sites.google.com/site/vincenegri/concealownsyntaxforvim

Hack #162: Vimを終了しても undo 履歴を復元する

Hack #8: 作業の履歴を辿るでも紹介したように Vim には編集履歴を辿る機能が充実していますが、Vim を終了したりファイルを開きなおしたりするとこの undo 履歴は消えてしまいます。

undo-persistence

現在開発中の Vim 7.3 から、新しく undo-persistence (:help undo-persistence) と言う機能が追加されました。これを使うと undo の情報をファイルに保存し、Vim を終了しても次に起動したときに undo の履歴を復元してくれるようになります。

設定

'undodir'

まず、undo 履歴を保存するファイルが作成されるディレクトリを 'undodir' オプションに設定します。これにはディレクトリをカンマ区切りのリストで指定します。 ディレクトリの指定に "." を使うと、対象ファイルのあるディレクトリを指します。デフォルトはこれです。

指定したディレクトリの中で、最初に存在したディレクトリに undo 履歴のファイルが保存されます。また、復元する際は最初に見付かったファイルから履歴を復元します。

例えば、ファイルと同じディレクトリに .vimundo と言うディレクトリがあったらそのディレクトリへ、なければ ~/.vimundo へ保存するには、以下のように設定します。

set undodir=./.vimundo,~/.vimundo

'undofile'

これはバッファローカルなオプションで、これが on のバッファはバッファの保存時に undo 履歴をファイルに保存します。また、読み込み時に undo 履歴を復元します。

全てのファイルで有効にしたい場合は単に :set undofile とすれば良いでしょう。特定のファイル、例えばホームディレクトリ以下のファイルのみで設定したい場合は以下のようにします。

augroup vimrc-undofile
  autocmd!
  autocmd BufReadPre ~/* setlocal undofile
augroup END

+persistent_undo

これらの機能は +persistent_undo がないと利用できないので、if で囲っておくと良いでしょう。

if has('persistent_undo')
  set undodir=./.vimundo,~/.vimundo
  augroup vimrc-undofile
    autocmd!
    autocmd BufReadPre ~/* setlocal undofile
  augroup END
endif

注意点

undo 履歴ファイルは 'undodir' で指定したディレクトリが "." 以外だった場合は対象のディレクトリに、フルパスのパスの区切りを "%" で置き換えたファイル名で保存されます。つまり、ファイルを移動すると履歴ファイルの名前を手動で変更しない限り undo 履歴は失われます。

また、この機能は現在開発中の Vim に含まれているものです。利用する場合は自己責任で利用してください。

thinca

Hack #161: Command-line windowを使いこなす

普段我々が何げなく使っているCommand-line modeですが、使いこなすうちに様々な欠点が目につきます。このHackでは、Command-line modeを捨て去ってしまうことを提唱します。

Command-line modeの欠点

なぜCommand-line modeが使えないかというと、次のような欠点があるからです。

編集能力が貧弱

Command-line modeは基本的にラインエディタなので、シェル並の編集しかできません。テキストオブジェクトといった便利な機能も使えないのです。

自動補完ができない

もはや筆者は自動補完のある環境が普通になってしまい、neocomplcacheがないと仕事になりませんが、残念ながらCommand-line modeでは使えません。さらに、Command-line modeは補完も貧弱なので、困ったものです。

設定が分散する

Insert modeとCommand-line modeは独立しているので、キーマップ等は別々に定義しなければなりません。これは不便です。

履歴検索が面倒

Command-line modeでは、履歴検索が簡単にはできません。

cnoremap <C-n>          <Down>
cnoremap <C-p>          <Up>

とキーマップを定義する手はあります。これなら現在入力されているものにマッチする候補を検索することができます。しかしvimshellのように一覧から履歴を検索する方法はなく、そもそも設定が面倒です。検索にはfuzzyfinderkuを使うという手もありますが、この程度のことで外部プラグインに依存するというのもどうでしょうか。

Command-line window

そこで、本HackではCommand-line modeの代わりに、Command-line windowという機能を使うことを提案します。 Command-line windowとは何かというと、Vimに組み込まれている、Ex commandを実行できるバッファのことです。 Command-line windowは'filetype'がvimであるため、Vimのvim filetype pluginがすべて使えます。 特にneocomplcacheはVimのオムニ補完を搭載し、ユーザー定義のコマンドも解析できるため、併用するとneocomplcacheのパワーを存分に発揮することができます。 neocomplcacheは補完だけでなく、コマンドの引数情報をエコー領域に表示することもできます。 neocomplcacheに実装されている、Vimのオムニ補完は仕組みが複雑なので、今後のVim Hacksで詳しく解説する予定です。 Command-line windowについて詳しい情報は、:help cmdwinを参照してください。

Command-line windowを設定する

Command-line windowはウインドウに入ったときにInsert modeにならなかったり、neocomplcacheと相性が悪かったりして使いづらいので、カスタマイズする必要があります。筆者は.vimrc中で、次のように設定しています。この設定では:を入力したときにCommand-line windowに遷移するようにしています。CmdwinEnterにautocmdを設定すれば簡単にカスタマイズできるので、皆さんも最適な設定を探してみてください。

nnoremap <sid>(command-line-enter) q:
xnoremap <sid>(command-line-enter) q:
nnoremap <sid>(command-line-norange) q:<C-u>

nmap :  <sid>(command-line-enter)
xmap :  <sid>(command-line-enter)

autocmd MyAutoCmd CmdwinEnter * call s:init_cmdwin()
function! s:init_cmdwin()
  nnoremap <buffer> q :<C-u>quit<CR>
  nnoremap <buffer> <TAB> :<C-u>quit<CR>
  inoremap <buffer><expr><CR> pumvisible() ? "\<C-y>\<CR>" : "\<CR>"
  inoremap <buffer><expr><C-h> pumvisible() ? "\<C-y>\<C-h>" : "\<C-h>"
  inoremap <buffer><expr><BS> pumvisible() ? "\<C-y>\<C-h>" : "\<C-h>"

  " Completion.
  inoremap <buffer><expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"

  startinsert!
endfunction

追記: Command-line windowでは、altercmdが使用できません。これでは不便なので、tyruさんがCommand-line windowでも使えるように改造したものを公開しているので、こちらを使ってください。 私は次のように設定しています。

function! s:init_cmdwin()
        call altercmd#define('b', 'gr[ep]', 'Grep', 'i')
        " AlterCommand <buffer><mode:i> gr[ep] Grepでも可
endfunction
Shougo

Hack #160: JavaScript開発環境

問題

Vimのデフォルトの状態でJavaScriptのコードを書くと、以下のような問題が発生します。

  1. インデントがおかしい

    var a = {
      a_
    

    この状態で:を打鍵しますと、

    var a = {
    a:_
    

    のようにインデントが一つもどってしまいます。

  2. キーワードがおかしい

    jQuery時代、$ではじまる変数名を使う機会が増えています。

    var $a = 1;
    

    このaの位置から*を打鍵しますと、$aではなくaという単語だけを検索対象にしてしまいます。

  3. 予約語functionが長い

    JavaScriptでは関数定義時だけでなく無名関数を用いるときにもfunctionという長い予約語を打鍵する必要があります。

解決法

いつくかのプラグインを導入します。

  1. JavaScript syntax プラグインの導入

    http://www.vim.org/scripts/script.php?script_id=1491

  2. Javascript Indentation プラグインの導入

    http://www.vim.org/scripts/script.php?script_id=1840

    var a = {
      a_
    

    この状態で:を打鍵しますと、

    var a = {
      a:
    

    のようになります。

    このプラグインはIndentAnythingというライブラリを使用しているため、こちらのライブラリも導入する必要があります。

    http://www.vim.org/scripts/script.php?script_id=1839

  3. smartchr.vimプラグインの導入

    たとえばプログラミング言語Haskellでは、無名関数を作成するにあたってバックスラッシュを使用します。

    map (\x -> f (x * 2)) [1, 2, 3]
    

    これはJavaScriptでは, jQueryを用いると

    $.map([1, 2, 3], function(x) { return f(x * 2); });
    

    となります。このことから類推すると、\と打鍵することでfunction(と入力されることが望ましいことが分かるのですが、 文字列リテラル内で\を入力するときにfunction(と展開されてしまうと開発に大きな支障をきたしてしまいます。

    文脈に応じて\キーの意味を動的に変更させるという解決方法もありますが、もっと単純にsmartchr.vimを用いて、\一回打鍵するとfunction(に展開し、その状態でもう一度\を打鍵すると\になるという挙動をとるようにすれば、シンプルにして必要十分な解決策となりうるのでないかと筆者は思っています。

    smartchr.vimについて詳しくはHack #131: Rubyで#{をラクに入力するをご覧ください。

    smartchr.vim導入後、以下の設定を~/.vimrcに記述しましょう。

    augroup Ujihisa " {{{
      autocmd!
      autocmd FileType javascript inoremap <buffer> <expr> \  smartchr#one_of('function(', '\')
    augroup END
    

    あるいは、以下の設定を~/.vim/ftplugin/javascript/ujihisa.vimに記述しましょう。

    inoremap <buffer> <expr> \  smartchr#one_of('function(', '\')
    

補足

そもそもJavaScriptを直接記述するのを避け、CoffeeScriptで代用するという手もあります。

ujihisa

Hack #159: オプションの値を気にせずsplit, vsplitする

Vimの標準のコマンドである:split:vsplit、 またはそのマッピング版である<C-w>s<C-w>vは それぞれ&splitbelow&splitrightに依存しており、 自分の思った通りの方向にウインドウを開いてくれない場合があります。

そこで、このようなマッピングを定義します。

nmap spj <SID>(split-to-j)
nmap spk <SID>(split-to-k)
nmap sph <SID>(split-to-h)
nmap spl <SID>(split-to-l)

nnoremap <SID>(split-to-j) :<C-u>execute 'belowright' (v:count == 0 ? '' : v:count) 'split'<CR>
nnoremap <SID>(split-to-k) :<C-u>execute 'aboveleft'  (v:count == 0 ? '' : v:count) 'split'<CR>
nnoremap <SID>(split-to-h) :<C-u>execute 'topleft'    (v:count == 0 ? '' : v:count) 'vsplit'<CR>
nnoremap <SID>(split-to-l) :<C-u>execute 'botright'   (v:count == 0 ? '' : v:count) 'vsplit'<CR>

こうすることでいつでも自分の思った通りの方向にウインドウを開くことができます。

また

nmap spj <SID>(split-to-j)
nmap spk <SID>(split-to-k)
nmap sph <SID>(split-to-h)
nmap spl <SID>(split-to-l)

の部分は自分の好きなように変えてください。 筆者は上のようにそれぞれspj, spk, sph, splに割り当てています。

追記: kana氏の指摘によりコードを大幅修正しました。

追記2: [count]を取れるようにしました。30sphなどとすると30の幅を持つウインドウが左に開きます。 ちなみに現在筆者はマッピングを<Space>sj, <Space>sk, <Space>sh, <Space>slに変更しました。 押しやすいマッピングはVimmerの数だけあるので、各人押しやすいマッピングを常に追求しましょう。 ちょっとでも押しにくいと感じたら積極的に他のマッピングを検討すべきです。

tyru

Hack #158: ユーザコマンドを定義する

: でコマンドラインモードに入ると使えるコマンドは、ユーザが自由に定義することができます。

定義方法

:command コマンドを使用します。書式は以下のようになります。

:command[!] [{属性}...] {コマンド名} {実行するコマンド}

これを見てわかるように、コマンドを定義すると言うことは誤解を恐れずに言うと別のコマンドに対するショートカットを定義しているに過ぎません。 複雑なことをしたい場合、ここは大抵関数の呼び出しになります。 :command 自体に ! を付けた場合、同名のコマンドが定義済みだった場合に上書きします。通常はエラーになります。

コマンド名

コマンド名は、組み込みコマンドと区別が付くように大文字で始めなくてはいけません。また、コマンド名には英数字のみ使用できます。

属性

属性は、-{属性名} もしくは -{属性名}={引数} の形式で指定します。詳細な説明は :help に譲るとして、ここでは概要を紹介します。

-nargs
コマンドの引数の数を指定します。
-nargs=00 個
-nargs=11 個
-nargs=*0 個以上
-nargs=?0 個もしくは 1 個
-nargs=+1 個以上
記号は正規表現と同じと考えれば覚えやすいでしょう。この属性を指定しなかった場合、0 (引数なし) を指定したことになります。
-complete
コマンドの補完方法を指定します。
-complete=augroupオートコマンドのグループ
-complete=bufferバッファ
-complete=commandEx コマンド(と、引数)
-complete=dirディレクトリ
-complete=environment環境変数
-complete=eventオートコマンドのイベント
-complete=expressionVimの式
-complete=fileファイルとディレクトリ
-complete=shellcmdシェルコマンド
-complete=function関数
-complete=helpヘルプの主題
-complete=highlight強調グループ
-complete=mappingマップ
-complete=menuメニュー
-complete=optionオプション
-complete=tagタグ
-complete=tag_listfilesCTRL-D を押した時にタグ、ファイル名を表示
-complete=varユーザ変数
-complete=custom,{func}{func}によるユーザ定義の補完
-complete=customlist,{func}{func}によるユーザ定義の補完
custom や customlist では関数を指定できますが、ここでは割愛します。
-range
コマンドに範囲(:[range]Command)を指定できるようにします。この属性がない場合、範囲の指定はできません。属性の引数で無指定時の初期値を指定します。
-range範囲指定。無指定時は現在行
-range=%範囲指定。無指定時はファイル全体(1,$)
-range=N範囲指定。無指定時は任意の数字 N
-count
コマンドにカウント(:[N]Command [N]) を指定できるようにします。この属性がない場合、カウントの指定はできません。属性の引数で無指定時の初期値を指定します。
-countカウント指定。無指定時は 0
-count=Nカウント指定。無指定時は任意の数字 N
コマンドにカウントを両方(コマンドの前と後)に指定した場合、後に指定したものが有効になります。
-bang
コマンドに ! を付けられるようになります。
-bar
コマンドの後ろに | を付けることで別のコマンドを実行することができます。また、" はコメントの開始になります。 コマンドの引数に | や " を含めたい場合は、| や " とします。 別の言い方をすると、普通に定義したコマンドの引数は :map 系のコマンドのように扱われますが、-bar を付けることでその他のコマンドのような扱いになります。
-register
:delete:yank のように、1つ目の引数にレジスタ名を指定できます。
-buffer
バッファローカルなコマンドになります。

{実行するコマンド}で使える書式

実行するコマンドを指定する箇所では、以下の <…> の形式の特別な文字列を使用できます。

<line1>
指定された範囲の最初の行
<line2>
指定された範囲の最後の行
<count>
与えられたカウント
<bang>
-bang がある場合で、コマンドが ! 付きで実行された場合は ‘!’ と言う 1 文字に、それ以外は空文字列になります。
<reg> <register>
レジスタ名に置換されます。指定なしの場合は空文字列になります。
<args>
与えられた通りのコマンド引数。カウントやレジスタは含まれません。
<lt>
‘<’文字。特別な文字列をそのままの意味で使用したい場合に使います。

特別な文字列の最初に q- を加えると、式の文字列として扱えるようにクォートされます。 例えば、<args> の代わりに <q-args> を指定すると abc は "abc" に、a"bc は "a\"bc" に置き換えられます。引数がない場合は空文字列になります。

<f-args> を使うと、引数を空白で区切ったものを関数の引数として渡せるようにそれぞれをクォートしてカンマで区切ったものに展開します。 実際のルールはもう少し複雑です。詳細は :help <f-args> を参照してください。

thinca

Vim Quiz 1

以下のようにウインドウが分割されています。

1

これを以下のように配置しなおすにはどうすればよいでしょうか。

2

文責: ujihisa

Hack #157: neocomplcache Hacks(5) タグ補完 ディクショナリ補完

今回はタグ補完とディクショナリ補完です。タグ補完は微妙ですが、ディクショナリ補完は便利に使えるでしょう。

タグ補完とは

タグ補完とは、’tags’から補完候補を取ってくることで補完することです。 Vim標準では<C-x><C-v>を用います。 neocomplcacheではtags_completeというプラグインによって実装されています。 .->といったg:neocomplcache_member_prefix_patterns[&filetype]にマッチする入力のあるときに補完を行うと、 クラスのメンバのみが補完候補となる機能を持っています。 要望があったので実装しましたが、私は個人的にタグ補完が好きではありません。なぜなら、タグ補完は候補が多くなりすぎるからです。 候補が多いとneocomplcacheのキャッシュや補完動作が明らかに遅くなります。 そこでtags_complete.vimでは、g:neocomplcache_caching_limit_file_sizeよりも大きいタグファイルは自動的にキャッシュしません。 どうしても使いたいならば、:NeoComplCacheCachingTagsコマンドを実行してください。 ctagsではタグを生成できない言語も多いので、現在ではより高機能なインクルード補完を用いるべきでしょう。インクルード補完については、今後のVim Hacksで解説予定です。

ディクショナリ補完とは

ディクショナリ補完とは、登録された辞書ファイルから補完候補を取ってくることで補完することです。 前回解説したシンタックス補完も一種のディクショナリ補完と言えます。 Vim標準では<C-x><C-k>を用います。 neocomplcacheではdictionary_completeというプラグインによって実装されています。 g:neocomplcache_dictionary_filetype_lists[&filetype]に辞書ファイルを登録しておけば、自動的にキャッシュされます。 例えば、vimshellでは履歴ファイルを辞書ファイルとして登録しておけば便利です。 g:neocomplcache_dictionary_filetype_lists[&filetype]が存在していない場合、自動的に’dictionary’の値が使われます。

Shougo

Home

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

    Return to page top