Emacs-Kotlin-Mode-Maintainers/kotlin-mode@876cc27dc1 -> Emacs-Kotlin-Mode-Maintainers/kotlin-mode@3e0c34087b FStarLang/fstar-mode.el@3afbf04e4e -> FStarLang/fstar-mode.el@c95c2a61a6 Fanael/edit-indirect@7fffd87ac3 -> Fanael/edit-indirect@e3d86416bc Fuco1/sphinx-mode@b5ac514e21 -> Fuco1/sphinx-mode@9d4075c106 Groovy-Emacs-Modes/groovy-emacs-modes@84f89b68ec -> Groovy-Emacs-Modes/groovy-emacs-modes@bf732d367b NixOS/nix-mode@8e20de5ba7 -> NixOS/nix-mode@20ee8d8890 OCamlPro/ocp-indent@9e26c0a269 -> OCamlPro/ocp-indent@7c4d434132 ProofGeneral/PG@df19c7ba0e -> ProofGeneral/PG@e1e29acb04 Raku/raku-mode@eaac071f17 -> Raku/raku-mode@977b14a7c1 Sarcasm/irony-mode@5063d6b16d -> Sarcasm/irony-mode@870d1576fb agda/agda@2816605bfd -> agda/agda@2816605bfd amake/flutter.el@81c524a43c -> amake/flutter.el@08138f8c95 ananthakumaran/exunit.el@5bb115f327 -> ananthakumaran/exunit.el@0715c2dc2d ananthakumaran/tide@28137ed904 -> ananthakumaran/tide@b93e555858 asok/projectile-rails@30828afbfa -> asok/projectile-rails@772f4766b5 asok/rake@9c204334b0 -> asok/rake@452ea0caca brotzeit/rustic@f4b5c288af -> brotzeit/rustic@6eec971387 cdominik/cdlatex@f215b70c5c -> cdominik/cdlatex@8e963c6853 clojure-emacs/cider@36277802a4 -> clojure-emacs/cider@86dd3fee9d codesuki/add-node-modules-path@7d9be65b3b -> codesuki/add-node-modules-path@63f047fd84 crystal-lang-tools/emacs-crystal-mode@15998140b0 -> crystal-lang-tools/emacs-crystal-mode@96a8058205 cython/cython@5b325c9860 -> cython/cython@fdea2d6bed diml/utop@c87b8b2817 -> diml/utop@5d72a0ab34 dominikh/go-mode.el@32cbd78c0a -> dominikh/go-mode.el@3273fcece5 elixir-editors/emacs-elixir@6bbc1e5ac4 -> elixir-editors/emacs-elixir@e0d0466d83 emacs-csharp/csharp-mode@9917e1b97d -> emacs-csharp/csharp-mode@856ecbc0a7 emacs-ess/ESS@a7ce81bb76 -> emacs-ess/ESS@39eba28300 emacs-geiser/geiser@c1cc4da1ed -> emacs-geiser/geiser@9507e81a07 emacs-geiser/guile@cfd9116dcb -> emacs-geiser/guile@c641fcc50b emacs-lsp/lsp-dart@813d3c92db -> emacs-lsp/lsp-dart@fda433671f emacs-lsp/lsp-haskell@4e62cf897d -> emacs-lsp/lsp-haskell@7cf64944ab emacs-lsp/lsp-java@ce03cb6574 -> emacs-lsp/lsp-java@0968038b9a emacs-lsp/lsp-metals@695291761b -> emacs-lsp/lsp-metals@b7f77de694 emacs-lsp/lsp-pyright@d428dbcf18 -> emacs-lsp/lsp-pyright@3598bc7c47 emacs-php/php-mode@535aec8173 -> emacs-php/php-mode@5f26bec865 emacs-php/phpactor.el@272217fbb6 -> emacs-php/phpactor.el@34195f1533 emacs-straight/auctex@3b0a080ae5 -> emacs-straight/auctex@830e40a063 emacs-straight/csv-mode@8da54e8b4e -> emacs-straight/csv-mode@43f6106f0d emacs-typescript/typescript.el@e824162051 -> emacs-typescript/typescript.el@88f317f0b6 erlang/otp@c1ab4b5424 -> erlang/otp@9ba9f6e60d ethereum/emacs-solidity@6f7bd1641e -> ethereum/emacs-solidity@20fb77e089 factor/factor@7b451bb813 -> factor/factor@1aeafdb87b fsharp/emacs-fsharp-mode@c90d762c06 -> fsharp/emacs-fsharp-mode@b3aa4c53fc fxbois/web-mode@61f057a6ba -> fxbois/web-mode@efa853e5cf godotengine/emacs-gdscript-mode@b7bfa6a3b2 -> godotengine/emacs-gdscript-mode@4badcf6a0c greghendershott/racket-mode@a879a8d67b -> greghendershott/racket-mode@af9b760e7b hakimel/reveal.js@918ee5610a -> hakimel/reveal.js@e281b3234e haskell/haskell-mode@8402caa341 -> haskell/haskell-mode@cb573c8db5 hhvm/hack-mode@4c1c2b0939 -> hhvm/hack-mode@a522f61c08 technomancy/fennel-mode@47152970a9 -> https://git.sr.ht/~technomancy/fennel-mode@50ef3c6246f3 hvesalai/emacs-sbt-mode@e29464a82b -> hvesalai/emacs-sbt-mode@9fe1e8807c hylang/hy-mode@5253533ddb -> hylang/hy-mode@df814865a1 idris-hackers/idris-mode@3cc9361b4c -> idris-hackers/idris-mode@65d6db1b75 iyefrat/evil-tex@aa0ddf8e76 -> iyefrat/evil-tex@0fa85c3fc8 jcollard/elm-mode@f2e2d0053f -> jcollard/elm-mode@d4e434fa18 joaotavora/sly@2e00c3bd4b -> joaotavora/sly@4513c382f0 jorgenschaefer/emacs-buttercup@1de6be465c -> jorgenschaefer/emacs-buttercup@f5cbf97e10 joshwnj/json-mode@0e819e519a -> joshwnj/json-mode@eedb456003 jrblevin/markdown-mode@541bd7b48a -> jrblevin/markdown-mode@521658eb32 jschaf/powershell.el@d1b3f95669 -> jschaf/powershell.el@ce1f0ae0b2 jwiegley/emacs-async@5d365ffc6a -> jwiegley/emacs-async@c78bab7506 leanprover/lean-mode@bf32bb9793 -> leanprover/lean-mode@c1c68cc946 ledger/ledger-mode@19b84dc766 -> ledger/ledger-mode@b55384d9cd necaris/conda.el@7a34e06931 -> necaris/conda.el@9c28d7a853 nonsequitur/inf-ruby@03dd9c9d4e -> nonsequitur/inf-ruby@dbf4386bac ocaml-ppx/ocamlformat@22a3707da3 -> ocaml-ppx/ocamlformat@9324ea439a ocaml/dune@4d0a47edd5 -> ocaml/dune@4bc7629a5e ocaml/merlin@e4791e2298 -> ocaml/merlin@5d59c70659 ocaml/tuareg@00faf47a7c -> ocaml/tuareg@04f5ab6be9 osv/company-web@f0cc9187c9 -> osv/company-web@863fb84b81 pashky/restclient.el@176d9cb655 -> pashky/restclient.el@9e2cfa8652 pezra/rspec-mode@92ef785010 -> pezra/rspec-mode@4215ff1f2d polymode/polymode@54888d6c15 -> polymode/polymode@2094c92403 seagle0128/grip-mode@9220a560b4 -> seagle0128/grip-mode@6b427143a8 sebasmonia/sharper@08277b6c30 -> sebasmonia/sharper@96edd4a1db stan-dev/stan-mode@9bb858b9f1 -> stan-dev/stan-mode@150bbbe5fd swift-emacs/swift-mode@800efe2910 -> swift-emacs/swift-mode@0d1ef0ef18 tpapp/julia-repl@e90b1ed2cc -> tpapp/julia-repl@6c1d63511f wbolster/emacs-python-pytest@b603c5c7f2 -> wbolster/emacs-python-pytest@ea53891a21 yoshiki/yaml-mode@63b637f846 -> yoshiki/yaml-mode@535273d5a1 ziglang/zig-mode@aba01b6199 -> ziglang/zig-mode@aa20d630b8 - Refactors the :lang rust module to reflect changes upstream, in rustic (thanks to #6154). Close: #6154 Fix: #6070
lang/php
Description
This module adds support for PHP 5.3+ (including PHP7).
- ctags-based code completion (
company-php
andphpctags
) - eldoc support (
ac-php
andphp-extras
) - REPL (
php-boris
) - Code refactoring commands (
php-refactor-mode
) - Unit-test commands (
phpunit
) - Support for
laravel
andcomposer
projects (with project-specific snippets) - Shortcuts for composer commands
- 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.
Save a programmer today. Stop a friend from choosing PHP as their first language.
Maintainers
This module has no dedicated maintainers.
Module Flags
+hack
Add support for the Hack dialect of PHP by Facebook.+lsp
Enable LSP support through phpactor or intelephense. Requires the:tools lsp
module and the phpactor server to be installed on your system.
Plugins
- async
- php-boris
- php-extras
- php-mode
- php-refactor-mode
- phpunit
- composer.el
-
+hack
-
+lsp
-
:editor format
Prerequisites
PHP
To get started with PHP, you'll need php
(5.3+) and composer
.
Note for +lsp
:
- In order to make full use of phpactor server,
php
(7.3+) is recommended. - If you use intelephense,
node
andnpm
are needed.
MacOS
PHP 5.5 comes prepackaged with newer versions of MacOS. These instructions are provided for reference:
brew tap homebrew/homebrew-php
brew install php71 # 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
Dependencies
This module has no required dependencies, but it has a couple optional ones.
boris
(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 \
d11wtq/boris \
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 ~/.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
.
Features
LSP Support
There are a number of currently supported LSP servers:
- Intelephense (Recommended)
- phpactor
- Serenata
- felixbecker (Considered unsupported)
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
.
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 projectphpunit-current-class
Launch all tests for the current class/fixturephpunit-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 invokable via M-x
too.
Configuration
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
"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-license-key (my-fetch-password :user intelephense))