Editor Integration (LSP)¶
GMX includes a built-in Language Server Protocol (LSP) server that provides real-time editor support for .gmx files.
Features¶
| Feature | Description |
|---|---|
| Diagnostics | Parse errors displayed in real-time as you type |
| Semantic Highlighting | Syntax-aware coloring for keywords, types, variables, strings, numbers, operators, and annotations |
| Hover Information | Documentation on hover for models (fields), functions (signature), services, annotations, keywords, and types |
| Autocompletion | Context-aware suggestions: annotations after @, types after :, section tags after <, ORM methods after ., keywords and model names elsewhere |
Starting the Server¶
The LSP server communicates over stdio (stdin/stdout), which is the standard transport for most editors.
Editor Setup¶
VS Code¶
Create or edit .vscode/settings.json in your workspace:
If you use a generic LSP client extension (e.g. vscode-lsp-client), configure it to run gmx lsp for files matching *.gmx.
Neovim (nvim-lspconfig)¶
Add to your Neovim configuration:
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*.gmx",
callback = function()
vim.bo.filetype = "gmx"
end,
})
vim.lsp.config('gmx', {
cmd = { 'gmx', 'lsp' },
filetypes = { 'gmx' },
root_markers = { 'go.mod', '.git' },
})
vim.lsp.enable('gmx')
Helix¶
Add to ~/.config/helix/languages.toml:
[[language]]
name = "gmx"
scope = "source.gmx"
file-types = ["gmx"]
roots = ["go.mod"]
language-servers = ["gmx-lsp"]
[language-server.gmx-lsp]
command = "gmx"
args = ["lsp"]
Zed¶
Add to your Zed settings (settings.json):
{
"lsp": {
"gmx": {
"binary": {
"path": "gmx",
"arguments": ["lsp"]
}
}
},
"languages": {
"GMX": {
"language_servers": ["gmx"]
}
},
"file_types": {
"GMX": ["gmx"]
}
}
Sublime Text (LSP package)¶
Install the LSP package, then add to LSP settings:
Emacs (lsp-mode)¶
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-language-id-configuration '(gmx-mode . "gmx"))
(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection '("gmx" "lsp"))
:activation-fn (lsp-activate-on "gmx")
:server-id 'gmx-lsp)))
Capabilities¶
Diagnostics¶
The LSP re-parses your .gmx file on every change and reports parse errors as diagnostics. Errors appear inline in your editor with line and column information.
Semantic Tokens¶
The server provides full semantic token highlighting with these token types:
| Token Type | Examples |
|---|---|
keyword |
model, func, let, const, if, else, return, try, render, import |
type |
Task, User (capitalized identifiers) |
function |
(reserved for future use) |
variable |
title, done, count (lowercase identifiers) |
string |
"hello", `template` |
number |
42, 3.14 |
operator |
=, +, -, ==, !=, &&, || |
decorator |
@ (annotation marker) |
Hover¶
Hovering over an identifier shows contextual documentation:
- Model names — list of fields with types and annotations
- Function names — full signature with parameters and return type
- Service names — provider and available methods
- Annotations (
pk,unique,default, etc.) — description and syntax - Keywords (
try,render,ctx, etc.) — usage description - Types (
string,int,uuid, etc.) — type description
Completion¶
Autocompletion triggers depend on context:
| Trigger | Context | Suggestions |
|---|---|---|
@ |
After @ in a field |
Annotations: pk, unique, default(...), min(...), max(...), email, relation(...) |
: |
After field name colon | Types: string, int, float, bool, uuid, datetime |
< |
Start of a section tag | Tags: script, template, style, style scoped |
. |
After an identifier | ORM methods: findMany, findUnique, create, update, delete, count |
| (default) | Anywhere else | Keywords + declared model names |
Architecture¶
The LSP server reuses the existing GMX compiler pipeline:
Editor ──stdio──▶ gmx lsp
│
▼
DocumentStore (thread-safe)
│
┌───────┼───────┐
▼ ▼ ▼
Lexer Parser AST
│ │ │
▼ ▼ ▼
Semantic Errors Hover &
Tokens → Diags Completion
Each open document is stored with its latest content, AST, and parse errors. On every change, the document is re-parsed using the same lexer.New() → parser.New().ParseGMXFile() pipeline as the compiler.