265 lines
12 KiB
Org Mode
265 lines
12 KiB
Org Mode
#+TITLE: PHP layer
|
|
|
|
#+TAGS: general|layer|multi-paradigm|programming
|
|
|
|
[[file:img/php.png]]
|
|
|
|
* Table of Contents :TOC_5_gh:noexport:
|
|
- [[#description][Description]]
|
|
- [[#features][Features:]]
|
|
- [[#install][Install]]
|
|
- [[#layer][Layer]]
|
|
- [[#backends][Backends]]
|
|
- [[#lsp][LSP]]
|
|
- [[#intelephense][intelephense]]
|
|
- [[#php-language-server][php-language-server]]
|
|
- [[#debugging][Debugging]]
|
|
- [[#ac-php-core][ac-php-core]]
|
|
- [[#setup][Setup]]
|
|
- [[#refactoring][Refactoring]]
|
|
- [[#debugging-1][Debugging]]
|
|
- [[#key-bindings][Key bindings]]
|
|
- [[#general][General]]
|
|
- [[#refactoring-for-non-lsp-backends][Refactoring for non LSP backends]]
|
|
- [[#debugging-for-non-lsp-backends][Debugging for non LSP backends]]
|
|
- [[#lsp-key-bindings][LSP key bindings]]
|
|
- [[#debugging-for-lsp-backends][Debugging for LSP backends]]
|
|
|
|
* Description
|
|
This layer adds PHP language support to Spacemacs.
|
|
|
|
** Features:
|
|
- Edit PHP files using [[https://github.com/ejmr/php-mode][php-mode]]
|
|
- Edit Drupal files
|
|
- Complete and jump to define with [[https://github.com/xcwen/ac-php][company-php]]
|
|
- Run tests with PHPUnit
|
|
- Reformat code with PHP CBF
|
|
- Debug your programs with XDebug (via [[https://github.com/ahungry/geben][geben]] or [[https://github.com/emacs-lsp/dap-mode][dap-mode]])
|
|
- Refactor source files with help of [[https://github.com/emacs-php/phpactor.el][phpactor.el]]
|
|
- Support for the [[https://langserver.org/][Language Server Protocol]] (experimental)
|
|
|
|
The =gtags= layer is recommended to benefit from better =eldoc= and
|
|
=helm-gtags=.
|
|
|
|
* Install
|
|
** Layer
|
|
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
|
|
add =php= to the existing =dotspacemacs-configuration-layers= list in this
|
|
file.
|
|
|
|
** Backends
|
|
For php you have the choice between a set of possible backends with
|
|
different setup instructions and different capabilities.
|
|
|
|
*** LSP
|
|
Note that you'll need to use the =lsp= layer to enable these backends.
|
|
|
|
**** intelephense
|
|
This is the recommended LSP server solution. To activate it set the
|
|
layer variable =php-backend=:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(php :variables php-backend 'lsp)
|
|
#+END_SRC
|
|
|
|
and install the npm server with:
|
|
|
|
#+BEGIN_SRC sh
|
|
npm install -g intelephense
|
|
#+END_SRC
|
|
|
|
You can find further information on the project's [[http://intelephense.net/][website]] and [[https://github.com/bmewburn/vscode-intelephense][GitHub page]].
|
|
|
|
**** php-language-server
|
|
This is an alternative LSP server implementation working on PHP basis rather
|
|
than nodejs. To activate it set the layer variable =php-backend= like for the
|
|
intelephense backend and install the server via [[https://getcomposer.org/][composer]]:
|
|
|
|
#+BEGIN_SRC sh
|
|
composer require felixfbecker/language-server
|
|
composer run-script --working-dir=vendor/felixfbecker/language-server parse-stubs
|
|
#+END_SRC
|
|
|
|
You can find further information on the project's [[https://github.com/felixfbecker/php-language-server][GitHub page]].
|
|
|
|
**** Debugging
|
|
In case of using any of LSP backends You can debug using [[https://microsoft.github.io/debug-adapter-protocol][dap]].
|
|
|
|
First of all You have to add =dap= to layer list of Your =dotspacemacs/layers=
|
|
function of a =.spacemacs= config file.
|
|
|
|
As mentioned in [[https://github.com/emacs-lsp/dap-mode#php][dap-mode doc for php]], dap-mode uses a [[https://marketplace.visualstudio.com/items?itemName=webfreak.debug][VSCode extension]] as a
|
|
debugging backend and includes a convenient =dap-php-setup= command to install
|
|
it into Your emacs. To embrace it open any PHP file in any PHP project just
|
|
after restarting emacs with =dap= layer enabled. Now You can call the extension
|
|
installation command: =<M-x> dap-php-setup=.
|
|
|
|
After that You can try to debug something. For example add a breakpoint to any
|
|
of Your phpunit tests with =SPC m d b a=. And start debugging with =SPC m d d d=
|
|
and selecting a debug template. Now run the test to ensure everything is
|
|
working. You may refer to one of the following examples to run Your tests.
|
|
|
|
For xdebug v2:
|
|
|
|
#+BEGIN_SRC sh
|
|
php -d xdebug.idekey=PHPSTORM -d xdebug.remote_autostart=1 -d xdebug.remote_enable=1 -d xdebug.remote_host=127.0.0.1 -d xdebug.remote_port=9000 bin/phpunit ./path/to/Test.php
|
|
#+END_SRC
|
|
|
|
For xdebug v3:
|
|
|
|
#+BEGIN_SRC sh
|
|
php -d xdebug.idekey=PHPSTORM -d xdebug.start_with_request=yes -d xdebug.mode=debug -d xdebug.client_host=127.0.0.1 -d xdebug.client_port=9000 bin/phpunit ./path/to/Test.php
|
|
#+END_SRC
|
|
|
|
Make sure You use the proper host. For example both =localhost= and =127.0.0.1=
|
|
most likely will not work while debugging inside of docker. You have to use either
|
|
=host.docker.internal= or Your machine's external IP if it doesn't work.
|
|
See [[https://github.com/docker/for-linux/issues/264][this docker issue]] for reasons of troubles with =host.docker.internal=.
|
|
|
|
The test is now expected to be paused by emacs/dap when it catches code at the
|
|
breakpoint.
|
|
|
|
You may wish to propagate some config options for the VSCode extension which is
|
|
used as a debug server. For example if You are running Your code in a docker
|
|
container the project source path may differ between the container (and Xdebug
|
|
PHP extension consequently) and Emacs. The VSCode extension provides a config
|
|
option to map the path. In VSCode it is done by adding an appropriate json
|
|
config. For spacemacs it could be done for example by adding a next call to
|
|
=dotspacemacs/user-config= function of Your =.spacemacs= config:
|
|
|
|
#+BEGIN_SRC emacs-lisp
|
|
(with-eval-after-load 'dap-php
|
|
(dap-register-debug-template "PHP debug with custom path"
|
|
(list :type "php"
|
|
:cwd nil
|
|
:request "launch"
|
|
:name "Php Debug with path"
|
|
:args '("--server=4711")
|
|
:pathMappings (ht ("/docker/src/path" "/emacs/src/path"))
|
|
:sourceMaps t)))
|
|
#+END_SRC
|
|
|
|
*** ac-php-core
|
|
This is a non server solution working entirely from an elisp package.
|
|
This requires no installation of external services but also delivers
|
|
the least amount of IDE like integrations with spacemacs.
|
|
|
|
To activate it just don't set the variable =php-backend= in your dotfile.
|
|
Remember that additional setup instructions are necessary on a per project basis
|
|
which you can find below.
|
|
|
|
**** Setup
|
|
Because of the way that the ac-php-core package works, there are a couple of
|
|
simple initialization tasks which must occur to get the completion working as it
|
|
should. On any new project make sure to perform the following initialization
|
|
tasks:
|
|
1. Run the following
|
|
|
|
#+BEGIN_SRC shell
|
|
cd /root/of/project
|
|
touch .ac-php-conf.json
|
|
#+END_SRC
|
|
|
|
2. Inside of spacemacs run:
|
|
= ac-php-remake-tags =
|
|
|
|
The =.ac-php-conf.json= file is required to enable auto-completion. When you run
|
|
=ac-php-remake-tags= and your =.ac-php-conf.json= file is empty the default
|
|
configuration will be used and inserted in the file.
|
|
|
|
If your project contains the following files at the root folder:
|
|
1. =.projectile=
|
|
2. =vendor/autoload.php=
|
|
|
|
the necessary configuration file (=.ac-php-conf.json=) will be created
|
|
automatically if it does not exist.
|
|
|
|
**** Refactoring
|
|
This backend provides refactoring and class auto-completion capabilities via
|
|
[[https://github.com/emacs-php/phpactor.el][phpactor.el]]. To ensure that the phpactor package is intact, just run
|
|
=M-x phpactor-install-or-update= and the package itself will make sure that
|
|
you're good to go.
|
|
|
|
**** Debugging
|
|
While using ac-php-core debug capabilities are provided via the [[https://github.com/ahungry/geben][geben package]].
|
|
Please refer for details to the project page.
|
|
|
|
* Key bindings
|
|
** General
|
|
|
|
| Key binding | Description |
|
|
|-------------+-------------------------|
|
|
| ~SPC m g g~ | jump to define at point |
|
|
| ~C-t~ | jump back |
|
|
|
|
** Refactoring for non LSP backends
|
|
For more precise insights on the meaning of the key bindings please refer to
|
|
[[https://phpactor.github.io/phpactor/refactorings.html][phpactor API reference.]]
|
|
|
|
| Key binding | Description |
|
|
|---------------+---------------------------------------------------------|
|
|
| ~SPC m r i~ | import class under cursor |
|
|
| ~SPC m r r~ | rename local variable |
|
|
| ~SPC m r R~ | rename variable in a whole file |
|
|
| ~SPC m r n~ | synchronize namespace with file location |
|
|
| ~SPC m r v~ | toggle method visibility (public->protected->private) |
|
|
| ~SPC m r g a~ | generate unknown property accessors |
|
|
| ~SPC m r g m~ | generate a method signature by a call example |
|
|
| ~SPC m r c n~ | create a new class at a given path |
|
|
| ~SPC m r c c~ | copy current class elsewhere |
|
|
| ~SPC m r c m~ | move (rename) current class |
|
|
| ~SPC m r c i~ | generate an interface from class' public methods |
|
|
| ~SPC m r p c~ | declare class properties by constructor signature |
|
|
| ~SPC m r p p~ | add missing class properties |
|
|
| ~SPC m r e c~ | extract constant under cursor from a class |
|
|
| ~SPC m r e e~ | extract expression to a variable |
|
|
| ~SPC m r e m~ | extract a code hunk to a method |
|
|
| ~SPC m r m c~ | add non-implemented stubs from parent classes/contracts |
|
|
| ~SPC m P s~ | ask phpactor about it's status |
|
|
| ~SPC m P u~ | install/update phpactor package |
|
|
|
|
** Debugging for non LSP backends
|
|
XDebug client management:
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------------------|
|
|
| ~SPC m d x~ | start XDebug client |
|
|
| ~SPC m d X~ | stop XDebug client |
|
|
| ~SPC m d b~ | set a predefined breakpoint on current line |
|
|
| ~SPC m d C~ | clear predefined breakpoints |
|
|
|
|
Debugger interaction:
|
|
|
|
| Key binding | Description |
|
|
|-------------+------------------------------------------------------------------|
|
|
| ~o~ or ~n~ | step over statement |
|
|
| ~s~ or ~i~ | step into current call |
|
|
| ~r~ | step out of function |
|
|
| ~c~ | resume execution until cursor position or next breakpoint |
|
|
| ~e~ | evaluate expression in local context |
|
|
| ~L~ | focus line the execution stopped on |
|
|
| ~v~ | display context (local/global variables, user-defined constants) |
|
|
| ~b b~ | set breakpoint here |
|
|
| ~b c~ | set conditional breakpoint here |
|
|
| ~b e~ | set breakpoint on exception here |
|
|
| ~u~ | unset breakpoint here |
|
|
| ~U~ | clear all breakpoints (in all files!) |
|
|
| ~w~ | show current stack trace |
|
|
| ~g f~ | find debugged file in a worktree |
|
|
| ~q~ | quit debugging |
|
|
|
|
Variable listing:
|
|
|
|
| Key binding | Description |
|
|
|-------------+---------------------------------|
|
|
| ~j~ | next variable or section |
|
|
| ~k~ | previous variable or section |
|
|
| ~TAB~ | fold/unfold variable or section |
|
|
| ~q~ | close variable listing |
|
|
|
|
** LSP key bindings
|
|
For a detailed list of key bindings in =lsp-mode= please checkout the README.org
|
|
file of the =lsp layer=.
|
|
|
|
** Debugging for LSP backends
|
|
See README.org file of the =dap-layer= for key bindings available in =dap-mode=
|