vim-users.jp

Hack #156: PHPで配列リテラルを楽に入力する

Posted at 2010/06/21
このエントリーをはてなブックマークに追加

問題

プログラミング言語Ruby, JavaScript, Vim scriptにおける配列は角括弧のみで構成された配列リテラルを用いて[1, 2, 3]のように表現することができます。一方、PHPというプログラミング言語ではarray(1, 2, 3)のように、arrayという予約語を用いて表現する必要があり、このことがRuby, JavaScript, Vim scriptプログラマを当惑させてきたという伝統があります。

<?php [1, 2, 3] ?>
#=> Parse error: syntax error, unexpected '[' in a.php on line 1

<?php array(1, 2, 3) ?>
#=> (nothing)

解決法

[array(と入力するようにします。ただしこのままだと[自体を入力したいときに困りますので、文脈に応じて挙動を変化させます。

PHPのFiletype Pluginファイルに以下のコードを追加します。

function! s:last_char()
  return matchstr(getline('.'), '.', col('.')-2)
endfunction
inoremap <buffer><expr> [ a:last_char =~ '\w\\|]' ? '[' : 'array(')

Filetyle Pluginは~/.vim/ftplugin/{filetype}.vimあるいは~/.vim/ftplugin/{filetype}/*.vimです。とりあえずすぐに上記機能を導入したいのであれば、

~/.vim/ftplugin/php/ujihisa.vim

に上記4行のみを記述すればよいでしょう。

上記設定を導入すると、英数文字あるいは]の直後に[を打鍵すると[がそのまま入力され、そうでない文字の直後ならばarray(に展開されます。

もう少し詳しく説明しましょう。そもそもPHPで[という記号を入力する必要があるのは、配列の要素を参照するときでしょう。配列の要素を参照するのは、カーソル位置を_で示すとして

print($aaa_

のように変数名の直後か、

print($aaa['bbb']_

このように配列の要素の参照の直後です。なお、fff()['aaa']といった書き方は言語仕様上Syntax Errorとなるので)の直後に[がくることはないと仮定できます。

それ以外の場合は[が必要ないので、全てarray(に展開します。

補足1

PHPのarray()はてっきり関数だと思っていたのですが、公式ドキュメントによるとリテラルとのことです。

Note: array() is a language construct used to represent literal arrays, and not a regular function.

http://www.php.net/manual/en/function.array.php

補足2

s:last_char()という関数で定義した、カーソルの直前位置の文字を取得する機能に関連して、カーソル位置の文字を取得する機能の実装が以下のページで議論されています。Vim scriptを書く人は参考にしてみてはいかがでしょうか。

http://gist.github.com/444017

補足3

はじめは[1, 2, 3]といった記法でも配列となるようにPHPのパーサの方をいじろうと思ったのですが、PHPをビルドするためにはかなり古いバージョンのautoconfが必要で、それをインストールするのが大変面倒そうであったため、挫折しました。

補足4

冒頭のサンプルコード

<?php array(1, 2, 3) ?>

はセミコロンがないことからエラーになりそうで、実はエラーになりません。

補足5

いろいろあって、いま著者の~/.vim/ftplugin/php.vimの該当部分以下のようになっています。

function! s:last_char()
  return matchstr(getline('.'), '.', col('.')-2)
endfunction

function! s:php_smart_bracket(last_char)
  if a:last_char == '['
    return "\<BS>("
  elseif a:last_char =~ '\w\|]'
    return '['
  else
    return 'array('
  endif
endfunction

inoremap <buffer><expr> [ <SID>php_smart_bracket(<SID>last_char())
inoremap <buffer><expr> ] smartchr#one_of(']', ')')

smartchrプラグインと組み合わせ、[を二回打鍵すると(になるようにしています。そもそもPHPでは[[は必ず出現しないため、わざわざ(を打鍵するよりもより容易な[[を用いるのが合理的と判断したためです。

ujihisa

もどる
blog comments powered by Disqus