Skip to content

About

[READ-ONLY] A Language Server for the regex patterns of PHP files: diagnostics, hovers and code actions in any LSP editor. Split of php-regex/php-regex.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

PHPRegex Language Server

Documentation Badge Author Badge GitHub Release Badge License Badge Packagist Downloads Badge GitHub Stars Badge Supported PHP Version Badge

PHPRegex Language Server

A language server for the regex patterns of PHP files: diagnostics, hovers, completions and code actions in any LSP editor.

The server reads PHP source over stdio, finds the regex literals in it — the patterns of preg_* calls, of library calls such as Preg::match() or $this->assertMatchesRegularExpression(), and of the calls to functions whose parameter is marked #[RegexPattern] — and answers in JSON-RPC, so every LSP editor can check patterns while you type.

Documentation: php-regex.com — the LSP guide gets diagnostics into your editor.

Features

  • Diagnostics on open and on change: every pattern of the file is parsed, validated and linted, and the findings are published to the editor; a pattern PCRE refuses gets that error alone.
  • Hovers in plain English: hold the pointer on a pattern to read what it matches, token by token.
  • Completions inside patterns: shorthands after a backslash, Unicode properties after \p{, POSIX classes after [:, groups after (?, flags after the closing delimiter.
  • Code actions: one action adds the u flag a Unicode pattern lacks, one applies the optimizer's rewrite — /[0-9]{1,}/ becomes /\d+/ — and two lay a long pattern out over lines under x or compact it back to one line.
  • The calls regex lint reads: the native ones (preg_*, RegexIterator, filter_var()), the presets extraction.interop in regex.json names (every one by default; an unknown name is an error, shown, and the server reads as without regex.json), the helpers extraction.functions names, and a pattern held in a constant, a variable or a property of the same file, diagnosed at its literal; @regex-ignore works as in the lint. A pattern assembled from several pieces at the call, or written as a heredoc, is reported by regex lint but gets no diagnostic in the editor.
  • Functions marked #[RegexPattern] (or PhpStorm's #[Language('RegExp')]): their calls are checked at that argument, the declarations read at start-up from the workspace's PHP files (under paths, out of exclude in regex.json) and from vendor/ whatever exclude says (read again when the editor reports vendor/composer/installed.json changed), and from the open documents as you type. A document in vendor/ gets no diagnostics.
  • One target per workspace: patterns are judged for one PHP and PCRE2 pair, resolved from the editor settings, regex.json, composer.json or the running PHP.

Installation

composer require --dev php-regex/regex-language-server

Requires PHP 8.1+ with the tokenizer extension. The binary is installed as vendor/bin/regex-lsp; --help prints its options, --version the release it was built from.

Configuration

Every pattern of the workspace is judged for one target, a PHP and PCRE2 pair, resolved once at initialize and logged where the editor shows the server output (Target: PHP 8.4.26, PCRE2 10.49 (running PHP)).

Option Accepts When absent
initializationOptions.phpVersion "8.2", "8.2.4" or 80200 phpVersion in regex.json, then composer.json, then the running PHP
initializationOptions.pcreVersion a PCRE2 release, "10.42" for instance pcreVersion in regex.json, then the release the target PHP bundles

regex.json (and regex.dist.json) sits at the root of the first workspace folder. A value the server cannot read is logged as a warning and the next source is used. Changing the target takes a server restart.

Usage

A file opens, and a broken pattern is reported where it sits. This notification was captured from a live session:

{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///demo/Mailer.php","diagnostics":[
  {"range":{"start":{"line":2,"character":13},"end":{"line":2,"character":16}},"severity":1,"code":"regex.delimiter.unclosed",
   "source":"php-regex","message":"No closing delimiter \"/\" found. You opened with \"/\"; expected closing \"/\". Tip: escape \"/\" inside the pattern (\\/) or use a different delimiter, e.g. #[a-#."}]}}

Hovering the pattern /^\w+@\w+\.\w+$/ returns this markdown (abridged):

**Regex Pattern**

```
/^\w+@\w+\.\w+$/
```

**Explanation**

Regex matches
  Anchor: the beginning of a line
    Character Type: A word character: [a-zA-Z_0-9] (one or more times)
  …
  Anchor: the end of a line

Code actions are offered on the pattern they fix:

  • /\p{L}+/ without the u flag gets "Add /u flag for Unicode support", rewriting the literal to '/\p{L}+/u'.
  • /[0-9]{1,}/ gets "Apply regex optimization", rewriting the literal to '/\d+/'; a rewrite is offered only once the automata prove it, as regex lint checks its suggestions.
  • A pattern too long for its line gets "Format pattern over lines", which lays it out under x, its continuation lines indented four spaces past the literal's line; a laid-out pattern gets "Compact pattern to one line". Each is offered only when it changes the literal.

Integration

VS Code

VS Code has no setting that points at an arbitrary language server: a small extension built on vscode-languageclient starts vendor/bin/regex-lsp for PHP files. The editor guide shows the whole client.

PhpStorm

Install LSP4IJ from the JetBrains Marketplace, then Settings → Languages & Frameworks → Language Servers: a server definition named PHPRegex, command vendor/bin/regex-lsp, file mappings *.php.

Neovim

init.lua with nvim-lspconfig:

local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')
if not configs.php_regex then
  configs.php_regex = {
    default_config = {
      cmd = { 'vendor/bin/regex-lsp' },
      filetypes = { 'php' },
      root_dir = lspconfig.util.root_pattern('composer.json', '.git'),
    },
  }
end
lspconfig.php_regex.setup({})

Vim, Emacs, Sublime Text, Helix and Zed are wired the same way; the LSP guide holds each snippet.

Documentation

Resources

Sponsors

Sponsor

If PHPRegex saves you time, consider sponsoring its maintenance.

License

MIT. See LICENSE.

About

[READ-ONLY] A Language Server for the regex patterns of PHP files: diagnostics, hovers and code actions in any LSP editor. Split of php-regex/php-regex.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages