Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

VimでPHPを書くならPhpactorを使うと便利そう(入力補完・ジャンプ・リファクタリング)

$
0
0

1. はじめに

私は職場でVimを使ってPHP(Laravel)を書いています。今回、VimをPHP開発環境として整備したいと思いこちらの記事を読んでいましたら、Phpactorというプラグインが割りと推しで紹介されていました。

Phpactorは入力補完やリファクタリング、定義ジャンプなどが可能なとても高機能そうなプラグインなんですが、日本語の記事が非常に少なかったので簡単にご紹介します。

2. Phpactorとは

百聞は一見にしかずといいますので、Phpactorを軽く動かしてみたところを撮影したGIFを貼ります。Phpactorの機能を利用している箇所は、右上に青字でその機能名を記載しています。

Phpactor Introduction

↑のGIFでおこなっているのは、

  1. 新しいクラスApp\Models\ItemExampleを作成するため、ファイルapp/Models/ItemExample.phpを開く
  2. Phpactorで空のクラス定義を生成(ClassNew)。この際、なぜかファイル名がItem.phpに変わっています(^^;
  3. Kernelインタフェースを実装するimplementsを追記(Completion (Class Name))。Phpactorの入力補完を使うことで、useによる名前空間のインポートも自動でやってくれます。
  4. Kernelインタフェースで定義されているメソッドを、作業中のファイルに取込む(Import Contract)。{@inheritDoc}つきでインポートしてくれます。
  5. コンストラクタを入力。引数のタイプヒントでPhpactorの入力補完を使い、ここでもPhpactorがuseを追加してくれています。
  6. コンストラクタの引数を同名のプロパティに代入する記述と、プロパティの定義(宣言?)の補完(Complete Constructor)。
  7. Kernelインタフェースのソースコードに画面を割ってジャンプ。ジャンプもできますよ、という実演のためなのですぐ閉じています。
  8. プロパティへのアクセサ(ゲッタ)を同名のメソッドとして作成(Generate Accessor)。
  9. コンストラクタに処理を記述する際にPhpactorの入力補完を利用(Completion)。
  10. 追記した処理をビジュアルモードで選択し、$is_jsonという名前の変数に代入(Extract Expression)。

という操作です。

多機能さをご理解いただけるかなと思います。スマートな入力補完やリファクタリング、コード一部の生成代行など、IDEを知らない私にとっては驚愕でした。

公式ドキュメントによると、Phpactorは高機能な入力補完とリファクタリングツールであり、次のような特長を備えています。

  • 発音は「Phpactor」で「ふぁくたー」
  • 文脈を考慮したスマートな入力補完
  • Composerに最適化されており、リアルタイムで高速に動作する
  • クラスやメソッド定義元へのジャンプ機能
  • クラスの移動、コンストラクタ補完、メソッド生成などのリファクタリング機能
  • 公式でVimをサポート(Emacsサポートは目下製作中)
  • コマンドライン上で実行するツールとしても使用可能
  • 自身と似たプロジェクトとして、PHP Language Serverを挙げている

GitHubを見ると、現在は開発段階で最新リリースは0.9.0(2018-09-13)です。

3. Phpactorの導入

動作には

  • PHP7.0以上
  • Composer
  • Vim8 / Neovim

が必要になります。参考までに、私の環境は

  • Ubuntu 18.04 / CentOS7
  • Vim 8.1
  • PHP 7.2
  • Composer 1.6.3
  • Python3.6 / Python3.4

です。

3.1. インストール

私はプラグイン管理にdein.vimを利用しています。tomlにこんな具合に書いて保存してVimを再起動し、:call dein#install()でインストールできました。

[[plugins]]repo='phpactor/phpactor'on_ft=['php']build='composerinstall'

:call phpactor#Status()で、きちんとPhpactorが導入できたか確認できます。パフォーマンスの関係で、Phpactorは既定の動きではXDebugを無効にします。

Info
----
Version: a516257 (7 days ago) Change-visiblity-617
Work dir: /home/cyrt/wk/repo/laravel5-5-example

Diagnostics
-----------
[✔] 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
------------
[✘] /etc/xdg/phpactor/phpactor.yml
[✘] /home/cyrt/.config/phpactor/phpactor.yml
[✘] /home/cyrt/wk/repo/laravel5-5-example/.phpactor.yml

3.2. キーマップ

Phpactorは導入時に独自のキーマップを定義しませんので、自分で設定してやる必要があります。
公式には、設定例として<Leader>をプリフィクスにしたキーバインド例がのっています。以下はそれを少しだけ書きかえたものです。<Leader>oで定義元へのジャンプができますが、私は窓を分割してジャンプすることが多いため、<Leader>o<C-w><Leader>oの2種類のジャンプを用意しています。

function! DefinitionJumpWithPhpactor()
    split
    call phpactor#GotoDefinition()endfunction

aug enablePhpactorKeyBindings
    au!" useの補完
    nmap <Leader>u:<C-u>call phpactor#UseAdd()<CR>" コンテキストメニューの起動(カーソル下のクラスやメンバに対して実行可能な選択肢を表示してくれます)
    nmap <Leader>mm :<C-u>call phpactor#ContextMenu()<CR>" ナビゲーションメニューの起動(クラスの参照元を列挙したり、他ファイルへのジャンプなど)
    nmap <Leader>nn :<C-u>call phpactor#Navigate()<CR>" カーソル下のクラスやメンバの定義元にジャンプ
    nmap <Leader>o:<C-u>call phpactor#GotoDefinition()<CR>" split → jump
    nmap <C-w><Leader>o:<C-u>call DefinitionJumpWithPhpactor()<CR>" 編集中のクラスに対し各種の変更を加える(コンストラクタ補完、インタフェース実装など)
    nmap <Leader>tt :<C-u>call phpactor#Transform()<CR>" 新しいクラスを生成する(編集中のファイルに)
    nmap <Leader>cc:<C-u>call phpactor#ClassNew()<CR>" 選択した範囲を変数に抽出する
    nmap <silent><Leader>ee :<C-u>call phpactor#ExtractExpression(v:false)<CR>" 選択した範囲を変数に抽出する
    vmap <silent><Leader>ee :<C-u>call phpactor#ExtractExpression(v:true)<CR>" 選択した範囲を新たなメソッドとして抽出する
    vmap <silent><Leader>em:<C-u>call phpactor#ExtractMethod()<CR>
aug END

3.3. 設定ファイル

設定ファイルを記述することで細かい挙動の制御ができますが、リファレンスを見た限りでは特に設定を書く必要はなさそうだったので、なにも設定は記述しませんでした。以下をコンフィグファイルとして認識するようです。

  • /etc/xdg/phpactor/phpactor.yml
  • ~/.config/phpactor/phpactor.yml
  • プロジェクトのルートディレクトリ/.phpactor.yml

4. ざっくり機能紹介

基本的には入力補完、ジャンプ、リファクタ機能に大別できます。
このうち、ジャンプとリファクタ機能は↓でご紹介のコンテキストメニューから選択肢を辿って実行することができます。そのため、慣れないうちは「コンテキストメニューを各所で立上げて、おこないたい処理を選んで実行」という使い方をおすすめします。

他にもNavigation機能(うえのキーマップでは<Leader>nn)があるんですが、使いどころを間違えているのかどこで立上げても「選択肢はありません」と表示されてしまうため、ただいま調査中です。

4.1. 入力補完

入力補完については、.vimrcに次のように記述することで、Vimの組込みオムニ補完でPhpactorを利用できます。

.vimrc
" <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に移行することができました。lua(neocomplete.vim)のためにVimを自前ビルドする生活とはこれでお別れしました。

deoplete.nvimでphpactorの補完を利用する場合は、deoplete-phpactorをあわせてインストールします。 正しくインストールできていれば、次のようにグレートな補完ライフを享受することができるようになります。

補完の様子

ちゃんとDocコメントを見て補完してくれています。

とはいえ、deoplete.nvimで常時自動の補完候補表示を有効にしておくとカクつきは否めないかな~というところですね。また、タイプヒントに対する補完を呼ぶ際は手動でオムニ補完を呼ぶ必要があります。
個人的にはオムニ補完の設定だけやっておいて、あとは補完がほしいときだけ呼ぶ、というかたちで十分かなという気がします。

4.2. ジャンプ

冒頭のGIFでちょこっと定義元ジャンプを使ってソースコードの移動をおこなっています。この他にも、編集中のクラスに対応する単体テストへのジャンプ(要設定)や親クラスへのジャンプなどができます。

4.3. リファクタリング

4.3.1. コンテキストメニュー

操作をおこないたいクラスやメンバにカーソルを置いた状態で<Leader>mmを入力するとコンテキストメニューが立上がり、状況に応じて実行可能な操作の一覧を表示してくれます。立上げたメニューのキャンセルは<C-c><C-[>の2回打ちでできるようです。

あまり詳しく調べていませんが、上でキーマップがあてられている他の機能もだいたい呼出せるみたいなので、とりあえず迷ったら<Leader>mmしておけばいいように思います。

変数にカーソルを置いた状態でメニューを立上げると、次のようなメニューが表示されます。ここではメソッドローカル変数reqnew_reqへのリネームをしています。

context_menu_for_variable

変数にカーソルを置いた状態でメニューを立上げると、次のようになりました。find referenceを実行しCategoryクラスを参照している箇所をソースコードから検索してQuickFixにして表示してくれます。
gtagsにも同様の機能があるので比較がてら直後に実行していますが、候補の表示量にだいぶ差がありますね…。

context_menu_finding_reference

4.3.2. クラス整形

メニューが開き、編集中のファイルに対する各種の整形がおこなえます(Transformを「整形」としました)。

コンテキストメニューからも辿れますが、キーマップ<Leader>ttで直接整形に関するメニューを開くことができます。

class_transform

ここでは、

  • Composerのautoload設定やファイル名に基づいて名前空間・クラス名を修正
  • コンストラクタの補完
  • 宣言なしに使われているプロパティ宣言の生成
  • インタフェースで宣言されているメソッドを編集中のクラスへ取込み

が候補として表示されています。うしろ3つの処理については冒頭のGIFのなかで実行しているので、そちらを参考にしてください。

名前空間の修正について、次のGIFではapp/Models/NewItem.phpの誤った名前空間App\Models\IncorrectNamespaceを、ファイルパスを見てApp\Modelsに修正しています。

fix_namespace.gif

ファイルの移動やクラス名・名前空間の変更などをおこなった際に役立つかもしれません。

4.4. 他の機能

useの追加はタイプヒントの入力補完の際にもやってくれますが、useの追加だけでひとつの操作としておこなうことができます。うえのキーマップでは<Leader>uにあてられています。下のGIFではRequestをインポートする様子です。複数候補がある場合は選択するよう促されます。

useの補完の様子

5. おわりに

うえで紹介したほかにも、紹介しきれない各種のIDE的機能が備わっています。開発段階であるとはいえ様々な機能が用意されていますので、興味のある方はさわってみてはいかがでしょうか?

6. 参考

公式です。

GitHubのリポジトリです。

この記事でPhpactorを知りました。Phpactorを"phpactor is simply a must have."と紹介していたり、他の箇所では「怪物」と評しているので、気になってPhpactorを使うきっかけになりました。
vim-bbyeなど、他にも日本では知名度が低いが便利そうなプラグインが紹介されています。

Phpactorの紹介スライド。

日本語記事そのいち。

日本語記事そのに。Phpactor以外にも、PHP開発で役立つツールを紹介されています。


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>