※これはPHPのリファクタリングツールPhpactorの紹介記事ですが、試せていない機能が多く現時点では入力補完についてしか書いていません。随時加筆いたします。
※記事中あやまり等ありましたら、ご指摘いただけますと幸いです。
1. はじめに
私は職場でVimを使ってPHP(Laravel)を書いています。
入力補完や定義ジャンプにはphpcd.vimとctags
、gtags
によるジャンプを併用しています。トレイトやインタフェースへのジャンプがうまくいかなかったり、補完に失敗することもあるので「もう少し安定してジャンプや補完ができればいいなあ」と思い、こちらの記事を読んでいましたら、Phpactorというプラグインが紹介されていました。
phpactor is simply a must have. It can help you for a lot of things (see the Refactoring / code styling plugins section).
The autocompletion it provides is very good and pretty stable.It allows you as well to import automatically class namespaces or even to jump to classes or methods definition without ctags.
「単純に必携」「超goodかつ安定」(意訳)と銘打たれていたので、気になって日本語の記事を探しましたが、こちらの記事をはじめとする数件(いずれも同じ方が書いていました)が見つかったのみでした。
「日本では知名度も低くて流行ってないのかな?」と思いつつも、とても高性能かつ多機能なツールだと感じたので、私自身もさわりはじめたばかりですが、簡単ながらご紹介します。
2. Phactorとは
2.1. 概要
公式ドキュメントによると、Phpactorは高機能な入力補完とリファクタリングツールであり、次のような特長を備えています。
- 発音は「Phpactor」で「ふぁくたー」
- 文脈を考慮したスマートな入力補完
- Composerに最適化されており、リアルタイムで高速に動作する
- クラスやメソッド定義元へのジャンプ機能
- クラスの移動、コンストラクタ補完、メソッド生成などのリファクタリング機能
- 公式でVimをサポート(Emacsサポートは目下製作中)
- コマンドライン上で実行するツールとしても使用可能
- 自身と似たプロジェクトとして、PHP Language Serverを挙げている
GitHubを見ると、現在は開発段階で最新リリースは0.9.0
(2018-09-13)です。
2.2. Phpactorの導入
動作には
- PHP7.0以上
- Composer
- Vim8/Neovim(Vimで利用する場合)
が必要になります。
プラグイン管理にdein.vimを利用しています。tomlにこんな具合に書いて保存してVimを再起動し、:call dein#install()
でインストールできます。
[[plugins]]repo='phactor/phactor'on_ft=['php']build='composerinstall'
手動で導入する場合は、git clone
でお好みのディレクトリにPhactorをダウンロードして、そのディレクトリでcomposer install
をすればOKなんでしょうかね?必要がなかったので未調査です。
:call phpactor#Status()
で、きちんとPhactorが導入できたか確認できます(以下の表示例は公式からのコピペです)。見たところ、パフォーマンスの関係で既定の動きではXDebugを無効にするようです。
Support
-------
[✔] Composer detected - faster class location and more features!
[✔] Git detected - enables faster refactorings in your repository scope!
[✔] XDebug is disabled. XDebug has a negative effect on performance.
Config files
------------
[✔] /home/daniel/www/phpactor/phpactor/.phpactor.yml
[✔] /home/daniel/.config/phpactor/phpactor.yml
[✘] /etc/xdg/phpactor/phpactor.yml
以下は、コマンドラインから実行可能なコマンドの一覧を表示したところです。
Phpactor dev-develop@a5162573d8766d00d54601190e06a7240d77eacc
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-d, --working-dir=WORKING-DIR Working directory
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
complete Suggest completions DEPRECATED! Use RPC instead
help Displays help for a command
list Lists commands
rpc Execute one or many actions from stdin and receive an imperative response
status
cache
cache:clear Clear the cache
class
class:copy Copy class (path or FQN)
class:inflect Inflect new class from existing class (path or FQN)
class:move Move class (path or FQN) and update all references to it
class:new Create new class (path or FQN)
class:reflect Reflect a given class (path or FQN)
class:search Search for class by (short) name and return informations on candidates
class:transform Apply a transformation to an existing class (path or FQN)
config
config:dump Show loaded config files and dump current configuration.
file
file:info Return information about given file
offset
offset:info Return information about given file at the given offset
references
references:class Find and/or replace references for a given path or FQN
references:member Find reference to a member
server
server:start EXPERIMENTAL start a Phpactor language server
いろいろなことができそうですね。
また、Phactorは導入しても既存のキーマップを変更しないようです。なので、自分で設定してやる必要があります。
公式には、設定例として<Leader>
をプリフィクスにしたキーバインド例がのっています。<C-U>
があったりなかったり…記法が微妙に統一されていない…。
" Include use statement
nmap <Leader>u:call phpactor#UseAdd()<CR>" Invoke the context menu
nmap <Leader>mm :call phpactor#ContextMenu()<CR>" Invoke the navigation menu
nmap <Leader>nn :call phpactor#Navigate()<CR>" Goto definition of class or class member under the cursor
nmap <Leader>o:call phpactor#GotoDefinition()<CR>" Transform the classes in the current file
nmap <Leader>tt :call phpactor#Transform()<CR>" Generate a new class (replacing the current file)
nmap <Leader>cc:call phpactor#ClassNew()<CR>" Extract expression (normal mode)
nmap <silent><Leader>ee :call phpactor#ExtractExpression(v:false)<CR>" Extract expression from selection
vmap <silent><Leader>ee :<C-U>call phpactor#ExtractExpression(v:true)<CR>" Extract method from selection
vmap <silent><Leader>em:<C-U>call phpactor#ExtractMethod()<CR>
2.3. 入力補完
入力補完については、.vimrc
に次のように記述することで、Vimの組込みオムニ補完でPhpactorを利用できます。
" <C-x><C-o>で補完候補を表示できます。
autocmd FileType php setlocal omnifunc=phpactor#Complete
導入さえしてしまえれば、Composerプロジェクトでなくても入力補完機能の大部分は使えるようです(未検証)。ただ、動作が多少遅くなるかもしれないそうです。
自動補完を有効にするため、入力補完プラグインを使うことができます。公式に対応している入力補完プラグインとして、
が記載されています。
ncm2ではVim8への対応はおまけのようだったので("Note that vim8 support is simply a bonus."とある)、deoplete.nvimを使ってみることにしました。私はこれまでneocomplete.vimを使い続けてきたので、これを機にようやくdeoplete.nvimに移行することができました。
deoplete.nvimでphpactorの補完を利用する場合は、deoplete-phpactorをあわせてインストールします。 正しくインストールできていれば、次のようにグレートな補完ライフを享受することができるようになります(例はLaravelです)。
おめでとうございます。ちゃんとDocコメントを見て補完してくれています。動作の軽快さ・重さについては、これから常用してみて確かめていこうと思っています。
3. おわりに
一部しかご紹介できていないので、便利そうな機能をもっと探していければ、と思います。
ちなみに冒頭の記事はググっていたらたまたま見つけたものですが、ほかにもおもしろそうなプラグインが紹介されています(vim-bbyeとか)ので、興味のある方はご一読ください。