# Installation & Editor Setup
## Installation
### Pre-built Binaries
Download the latest binary for your platform from [GitHub Releases](https://github.com/AJenbo/phpantom_lsp/releases/latest). Available for:
- `x86_64-unknown-linux-gnu`
- `aarch64-unknown-linux-gnu`
- `x86_64-apple-darwin`
- `aarch64-apple-darwin`
- `x86_64-pc-windows-msvc`
### Build from Source
See [BUILDING.md](BUILDING.md) for full instructions. Quick version:
```bash
cargo build --release
# Binary is at target/release/phpantom_lsp
```
## Editor Setup
PHPantom communicates over stdin/stdout using the standard [Language Server Protocol](https://microsoft.github.io/language-server-protocol/). Any editor with LSP support can use it. Point the client at the `phpantom_lsp` binary with `php` as the file type. No special initialization options are required.
<details>
<summary><b>Zed</b></summary>
A Zed extension is included in the `zed-extension/` directory:
1. Ensure you have `rustc` available in your `$PATH`. This is part of the Rust [toolchain](https://rust-lang.org/tools/install/)
2. Open Zed
3. Open the Extensions panel
4. Click **Install Dev Extension**
5. Select the `zed-extension/` directory
The extension automatically downloads the correct pre-built binary from GitHub releases for your platform. If you'd prefer to use a locally built binary, ensure `phpantom_lsp` is on your `PATH` and the extension will use it instead.
To make PHPantom the default PHP language server, add to your Zed `settings.json`:
```json
{
"languages": {
"PHP": {
"language_servers": ["phpantom_lsp", "!intelephense", "!phpactor", "!phptools", "..."]
}
}
}
```
</details>
<details>
<summary><b>Neovim</b></summary>
```lua
vim.lsp.config['phpantom'] = {
cmd = { '/path/to/phpantom_lsp' },
filetypes = { 'php' },
root_markers = { 'composer.json', '.git' },
}
vim.lsp.enable('phpantom')
```
</details>
<details>
<summary><b>VS Code</b></summary>
1. **Install a generic LSP client extension**
* Recommended: [Generic LSP Client (v2)](https://marketplace.visualstudio.com/items?itemName=zsol.vscode-glspc)
* Install via VS Code Marketplace:
```vscode-extensions
zsol.vscode-glspc
```
2. **Download PHPantom LSP binary**
* Get it from [GitHub Releases](https://github.com/AJenbo/phpantom_lsp/releases/latest)
* Extract the binary and place it in a preferred location
3. **Configure the extension**
* Open VS Code settings for Generic LSP Client (v2)
* Set the path to your PHPantom binary
* Add the Language ID: `php`
* Restart VS Code
</details>
<details>
<summary><b>PHPStorm</b></summary>
1. **Download PHPantom LSP binary**
* Get it from [GitHub Releases](https://github.com/AJenbo/phpantom_lsp/releases/latest)
* Extract the binary to a preferred location
2. **Install and configure LSP plugin**
* Go to **Editor → Plugins** and install [LSP4IJ](https://plugins.jetbrains.com/plugin/23257-lsp4ij)
* Restart PHPStorm
* Navigate to **Languages & Frameworks → Language Servers**
* Click **+** to add a new server
* Name: `PHPantom`
* Command: path to your PHPantom binary
* Mapping: set `PHP` on both the **Language** tab and the **File Type** tab (the dialogs are identical). Setting both ensures PHPStorm activates the server reliably.
<img width="779" height="645" alt="PHPStorm new language server dialog" src="https://github.com/user-attachments/assets/2da88e68-d012-476e-82e7-977dbfcd9653" />
<img width="779" height="645" alt="PHPStorm language server mapping dialog" src="https://github.com/user-attachments/assets/62358f9e-973c-487d-ac17-098d7dab007e" />
</details>
<details>
<summary><b>Sublime Text</b></summary>
> [!NOTE]
> This configuration is untested. If you get it working (or run into issues), please [open an issue](../../issues).
With [LSP for Sublime Text](https://github.com/sublimelsp/LSP):
```json
{
"clients": {
"phpantom": {
"enabled": true,
"command": ["/path/to/phpantom_lsp"],
"selector": "source.php"
}
}
}
```
</details>
<details>
<summary><b>Helix</b></summary>
Helix has built-in LSP support. Add PHPantom to your `languages.toml` (typically `~/.config/helix/languages.toml`):
```toml
[language-server.phpantom]
command = "phpantom_lsp"
[[language]]
name = "php"
language-servers = ["phpantom"]
```
</details>
<details>
<summary><b>Emacs (eglot)</b></summary>
> [!NOTE]
> This configuration is untested. If you get it working (or run into issues), please [open an issue](../../issues).
Eglot is built into Emacs 29+. Add to your `init.el`:
```elisp
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'(php-mode . ("phpantom_lsp"))))
```
Then open a PHP file and run `M-x eglot`.
</details>
<details>
<summary><b>Emacs (lsp-mode)</b></summary>
> [!NOTE]
> This configuration is untested. If you get it working (or run into issues), please [open an issue](../../issues).
Add to your `init.el`:
```elisp
(with-eval-after-load 'lsp-mode
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("phpantom_lsp"))
:activation-fn (lsp-activate-on "php")
:server-id 'phpantom)))
```
Then open a PHP file and run `M-x lsp`.
</details>
<details>
<summary><b>Kate</b></summary>
> [!NOTE]
> This configuration is untested. If you get it working (or run into issues), please [open an issue](../../issues).
Kate (KDE) has built-in LSP support. Open **Settings → Configure Kate → LSP Client → User Server Settings** and add:
```json
{
"servers": {
"php": {
"command": ["/path/to/phpantom_lsp"],
"url": "https://github.com/AJenbo/phpantom_lsp"
}
}
}
```
</details>
## Project Configuration
PHPantom works best with Composer projects. It reads `composer.json` to discover autoload directories and vendor packages, so completions and go-to-definition only surface classes that your autoloader can actually load. Projects without `composer.json` fall back to scanning every PHP file in the workspace.
### `.phpantom.toml`
PHPantom supports an optional per-project configuration file for settings like PHP version overrides and diagnostic toggles.
To generate a default config file with all options documented and commented out:
```bash
phpantom_lsp init
```
This creates a `.phpantom.toml` in the current directory. Currently supported settings:
```toml
[php]
# Override the detected PHP version (default: inferred from composer.json, or 8.5).
# version = "8.5"
[diagnostics]
# Report member access on subjects whose type could not be resolved.
# Useful for discovering gaps in type coverage. Off by default.
# unresolved-member-access = true
[indexing]
# How PHPantom discovers classes across the workspace.
# "composer" (default) - use Composer classmap, self-scan on fallback
# "self" - always self-scan, ignore Composer classmap
# "none" - no proactive scanning, Composer classmap only
# strategy = "composer"
```
The file is optional. When absent, all settings use their defaults. New settings will be added as features land. Unknown keys are silently ignored, so the file is forward-compatible.
### Indexing Strategy
By default, PHPantom trusts Composer's autoloader to determine which classes exist in your project. This is intentional: it means completions, diagnostics, and go-to-definition reflect what your code will actually see at runtime. Classes that aren't autoloadable don't appear, because using them would be an error.
The `strategy` setting controls this behaviour:
| `"composer"` (default) | Use Composer's classmap when available, self-scan to fill gaps. Results match what `composer dump-autoload` knows about. |
| `"self"` | Ignore Composer's classmap entirely and scan every PHP file in the workspace. Discovers all classes regardless of autoloading. |
| `"none"` | Use only Composer's classmap with no fallback scanning. The most conservative option. |
Most projects should leave this at the default. Change it to `"self"` if your project loads classes outside of Composer (custom autoloaders, `require_once`, legacy inclusion patterns). Be aware that `"self"` will also surface vendor-internal classes and potential duplicates that Composer's autoloader would never load.
### Classes from other files are not found
PHPantom resolves cross-file classes through Composer's autoloading rules (PSR-4 mappings and the generated classmap). If a class exists in your project but PHPantom reports it as unknown, the most common causes are:
1. **The class isn't Composer-autoloadable.** If your project loads classes via `require_once`, `include`, or a custom autoloader alongside Composer, those classes won't be discovered by default. Set `strategy = "self"` in `.phpantom.toml` to scan all files.
2. **Composer's classmap is stale.** Run `composer dump-autoload` to regenerate it. PHPantom reads the classmap at startup.
3. **The class is in a directory not covered by `autoload` or `autoload-dev`.** Check that your `composer.json` PSR-4 mappings cover the directory where the class lives.