doomemacs/modules/lang/php
Henrik Lissner 5718e4e96e
bump: :lang
Andersbakken/rtags@05117a9a29 -> Andersbakken/rtags@bd1c818a99
FStarLang/fstar-mode.el@7d353de892 -> FStarLang/fstar-mode.el@6e5d3ea858
JuliaEditorSupport/julia-emacs@2dfc869ff6 -> JuliaEditorSupport/julia-emacs@d360ad5285
ProofGeneral/PG@a38857a6a0 -> ProofGeneral/PG@99f91e873e
Raku/raku-mode@977b14a7c1 -> Raku/raku-mode@14f9b9bba0
Wilfred/pip-requirements.el@216cd1690f -> Wilfred/pip-requirements.el@31e0dc62ab
Wilfred/pyimport@c006a5fd0e -> Wilfred/pyimport@4398ce8dd6
ananthakumaran/exunit.el@e008c89e01 -> ananthakumaran/exunit.el@ee06b14b61
beancount/beancount-mode@546163fd2c -> beancount/beancount-mode@71c1622246
cybniv/poetry.el@ca2cffb0b1 -> cybniv/poetry.el@1dff0d4a51
davazp/graphql-mode@49a391b529 -> davazp/graphql-mode@ef4aecaead
dgutov/robe@4ecd868da9 -> dgutov/robe@6bc8a07fc4
diml/utop@8cc5632825 -> diml/utop@384b3098c8
dominikh/go-mode.el@6f4ff9ef87 -> dominikh/go-mode.el@636d36e37a
emacs-lsp/emacs-ccls@9b4a47e041 -> emacs-lsp/emacs-ccls@8648238a92
emacs-lsp/lsp-dart@f51c80f545 -> emacs-lsp/lsp-dart@1f52e81c93
emacs-lsp/lsp-haskell@89d1637043 -> emacs-lsp/lsp-haskell@18a7c7881f
emacs-lsp/lsp-java@c962a3b3ac -> emacs-lsp/lsp-java@4909c14b90
emacs-lsp/lsp-metals@e55d544996 -> emacs-lsp/lsp-metals@fa4072cbe7
emacs-lsp/lsp-pyright@2f2631ae24 -> emacs-lsp/lsp-pyright@cc6df06aea
emacs-lsp/lsp-sourcekit@1cd5e7d269 -> emacs-lsp/lsp-sourcekit@bb2b7e0278
emacs-lsp/lsp-treemacs@e54e74deb8 -> emacs-lsp/lsp-treemacs@1d43e9e030
emacs-php/composer.el@91945f1bdb -> emacs-php/composer.el@42cf9848d4
emacs-php/php-mode@a0bcafbe30 -> emacs-php/php-mode@4792988a12
emacs-php/phpactor.el@8733fef84b -> emacs-php/phpactor.el@6b5269ff82
emacs-php/psysh.el@c7dde979d9 -> emacs-php/psysh.el@ae15a36301
emacs-straight/adaptive-wrap@70005d2012 -> emacs-straight/adaptive-wrap@a3b179ea21
emacs-straight/auctex@86b2397abd -> emacs-straight/auctex@280cd4a0ca
emacs-straight/csv-mode@81c1a9febd -> emacs-straight/csv-mode@cdb73a771b
emacs-straight/sml-mode@e5354371f3 -> emacs-straight/sml-mode@d114e5a27f
emacsorphanage/dart-mode@dffc0209a1 -> emacsorphanage/dart-mode@44beb628e5
erlang/otp@0ca7e064f5 -> erlang/otp@2a64588d4a
factor/factor@12fc9d5071 -> factor/factor@d143007778
fosskers/sly-overlay@916b50297a -> fosskers/sly-overlay@4c6135c260
fsharp/emacs-fsharp-mode@b4d31c3da0 -> fsharp/emacs-fsharp-mode@677d78c4d6
gcv/julia-snail@a25ce84748 -> gcv/julia-snail@f7784c5007
godotengine/emacs-gdscript-mode@8a28276daa -> godotengine/emacs-gdscript-mode@32086df833
greghendershott/racket-mode@d3ab936af1 -> greghendershott/racket-mode@40ecb87f40
haskell/haskell-mode@43b4036bf0 -> haskell/haskell-mode@727f72a2a4
hhvm/hack-mode@278e4cc403 -> hhvm/hack-mode@ccf20511f0
idris-hackers/idris-mode@37c6b81990 -> idris-hackers/idris-mode@38dd2380dc
joaotavora/sly@ed17d2c2bd -> joaotavora/sly@ba40c8f054
jrblevin/markdown-mode@e096bb97a9 -> jrblevin/markdown-mode@8aab017f47
json-emacs/json-mode@bfd1557aaa -> json-emacs/json-mode@77125b01c0
jwiegley/emacs-async@d040f72cb0 -> jwiegley/emacs-async@cff2bd0be3
ledger/ledger-mode@11e748d483 -> ledger/ledger-mode@b0e65f74a5
ljos/jq-mode@37028e1200 -> ljos/jq-mode@a0f79eba78
nonsequitur/inf-ruby@dac615c7fd -> nonsequitur/inf-ruby@0cfe8b2fb1
ocaml-ppx/ocamlformat@b8b0956690 -> ocaml-ppx/ocamlformat@c43f89bc0e
ocaml/dune@64d19876ad -> ocaml/dune@aac3d84f1d
ocaml/merlin@8404f96693 -> ocaml/merlin@b6ff2d4d56
pythonic-emacs/anaconda-mode@efd42aa873 -> pythonic-emacs/anaconda-mode@79fa9b4d2b
pythonic-emacs/company-anaconda@dabc0adc9a -> pythonic-emacs/company-anaconda@1fe526163c
pythonic-emacs/pyenv-mode@c93dc07e85 -> pythonic-emacs/pyenv-mode@de0d750b9c
rust-lang/rust-mode@d8a09f218e -> rust-lang/rust-mode@d00d83d3a2
salmanebah/opencl-mode@15091eff92 -> salmanebah/opencl-mode@10ae7742d5
seagle0128/grip-mode@e145adb225 -> seagle0128/grip-mode@7c42b8f61d
smihica/emmet-mode@63b6932603 -> smihica/emmet-mode@322d3bb112
swift-emacs/swift-mode@84059659de -> swift-emacs/swift-mode@b06c97b909
technomancy/fennel-mode@5965c8fc69 -> technomancy/fennel-mode@a4ddd1750f
tpapp/julia-repl@4947319bc9 -> tpapp/julia-repl@801d0fc3d8
wbolster/emacs-python-pytest@bdfb3e81ee -> wbolster/emacs-python-pytest@9f850e22df
yoshiki/yaml-mode@5b58248ab2 -> yoshiki/yaml-mode@7b5ce294fb
2024-06-26 22:58:01 -04:00
..
autoload.el feat(php): replace php-boris with psysh (#5967) 2022-01-10 02:24:21 +01:00
config.el refactor(format): replace with apheleia 2023-09-13 20:19:59 +01:00
doctor.el feat(php): doctor: rudimentary php & composer checks 2023-09-12 21:30:52 +02:00
packages.el bump: :lang 2024-06-26 22:58:01 -04:00
README.org docs(*): replace all-the-icons with nerd-icons 2023-09-16 20:19:11 +02:00

:lang php

Description   unfold

This module adds support for PHP 5.3+ (including PHP8) to Doom Emacs.

  • ctags-based code completion (company-php and phpctags)
  • eldoc support (ac-php and php-extras)
  • REPL (psysh)
  • Code refactoring commands (php-refactor-mode)
  • Unit-test commands (phpunit)
  • Support for laravel and composer projects (with project-specific snippets)
  • File templates
  • Snippets

󰟶 PHP was the first programming language I got paid to code in, back in the Cretaceous period (2003). My sincerest apologies go out to all the programmers who inherited my earliest PHP work. I know you're out there, writhing in your straitjackets.

Module flags

+hack
Add support for the Hack dialect of PHP by Facebook.
+lsp
Enable LSP support for php-mode. Requires doom-module::tools lsp and a langserver (supports phpactor and intelephense).
+tree-sitter
Leverages tree-sitter for better syntax highlighting and structural text editing. Requires doom-module::tools tree-sitter.

Hacks

No hacks documented for this module.

TODO Changelog

This module does not have a changelog yet.

Installation

Enable this module in your doom! block.

This module requires php (5.3+) and composer.

If doom-module:+lsp is enabled, you'll also need one of these LSP servers:

  • Phpactor requires php 7.3+.
  • Intelephense requires node and npm.

PHP

MacOS

PHP 5.5 comes prepackaged with newer versions of MacOS. These instructions are provided for reference:

brew tap homebrew/homebrew-php
brew install php@8.0  # or php53, php54, php55
brew install composer

# If you use intelephense:
brew install node
brew install npm

Arch Linux

sudo pacman --needed --noconfirm -S php composer  # or php53, php54, php55

# If you use intelephense:
sudo pacman -S nodejs npm

openSUSE

sudo zypper install php-composer

# If you use intelephense:
sudo zypper install nodejs npm

Debian

sudo apt-get install php php-common

# If you use intelephense:
sudo apt-get install nodejs npm

LSP Support

There are a number of currently supported LSP servers:

Intelephense is currently the only server that supports automatic installation, which will trigger either when you open a PHP project or manually invoke lsp-install-server through M-x.

The others have to be installed manually and added to your $PATH.

Dependencies

  • pysh (REPL)
  • phpctags (better code completion)
  • phpunit (unit test commands)
  • php-cs-fixer and @prettier/plugin-php (for code formatting)
  • phpactor (for LSP if intelephense isn't desired)
composer global require \
    psy/psysh \
    phpunit/phpunit \
    techlivezheng/phpctags \
    friendsofphp/php-cs-fixer \
    phpactor/phpactor

# Needed by php-cs-fixer, otherwise you'll get "Couldn't resolve parser
# 'php'" errors
npm install -g @prettier/plugin-php

You must ensure that $HOME/.composer/vendor/bin is in $PATH, so these executables are visible to Emacs:

# place this in your profile file, like ~/.bash_profile or ~/.zshenv
export PATH="~/.composer/vendor/bin:$PATH"

You may also need to regenerate your envvar file by running $ doom env on the command line.

NOTE phpactor doesn't have to be installed via composer, just has to exist in your $PATH.

NOTE Phpactor cannot be installed, globally at least, with PHP ^8.

TODO Usage

󱌣 This module's usage documentation is incomplete. Complete it?

PHPUnit

This module provides an interface to PHPUnit through a number of commands as detailed below. By default, it loads configuration from the root phpunit.xml.

  • phpunit-current-project Launch all tests for the project
  • phpunit-current-class Launch all tests for the current class/fixture
  • phpunit-current-test Launch the current test at point

If for some reason, the default phpunit.xml is in a different location (or you use the phpunit.xml.dist convention) , the path can be changed via phpunit-configuration-file

(setq phpunit-configuration-file "phpunit.xml")

Composer

This module provides several convenience methods for triggering composer commands:

Binding Function
<localleader> m c c composer
<localleader> m c i composer-install
<localleader> m c r composer-require
<localleader> m c u composer-update
<localleader> m c d composer-dump-autoload
<localleader> m c s composer-run-scripts
<localleader> m c v composer-run-vendor-bin-command
<localleader> m c o composer-find-json-file
<localleader> m c l composer-view-lock-file

These are all run via M-x too.

TODO Configuration

󱌣 This module's configuration documentation is incomplete. Complete it?

Docker Compose

A lot of projects rely on running inside docker compose (ie Laravel), and as such a minor mode has been configured to attempt to run tests inside the php-fpm (by default) container.

This mode is disabled by default, to opt-in set +php-run-tests-in-docker to t in your config. If this is done during Emacs running, you will also have to reload php-mode (i.e. through M-x php-mode)

If you wish to specify a different container, modify the +php-default-docker-container variable (ideally inside a .dir-locals.el file)

((php-mode . ((+php-default-docker-container . "php-octane"))))

Troubleshooting

Report an issue?

"I'm missing functionality on lsp-mode"

Unfortunately, intelephense currently operates under a "freemium" model, and as such requires a license for extended features. Once purchased, this can be (insecurely) added directly to your config:

(setq lsp-intelephense-licence-key "<key>")

A more recommended approach would be to utilise Emacs' own auth-sources for storing authentication info, which can also be encrypted.

Create a file in your home directory (which can optionally be encrypted, verify your auth-sources has the correct values) called ~/.authinfo:

machine * login intelephense password <key>

And add the following to your config:

(defun my-fetch-password (&rest params)
  (require 'auth-source)
  (let ((match (car (apply #'auth-source-search params))))
    (if match
        (let ((secret (plist-get match :secret)))
          (if (functionp secret)
              (funcall secret)
            secret))
      (error "Password not found for %S" params))))

(setq lsp-intelephense-licence-key (my-fetch-password :user intelephense))

Frequently asked questions

This module has no FAQs yet. Ask one?

TODO Appendix

󱌣 This module has no appendix yet. Write one?