pike-language-server 0.8.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/bin/pike-language-server +83 -0
- package/docs/helix-installation.md +275 -0
- package/docs/other-editors.md +242 -0
- package/package.json +37 -0
- package/standalone/predef-autodoc.json +2601 -0
- package/standalone/predef-builtin-index.json +1 -0
- package/standalone/server.js +60663 -0
- package/standalone/stdlib-autodoc.json +22194 -0
- package/standalone/tree-sitter-pike.wasm +0 -0
- package/standalone/web-tree-sitter.wasm +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TheSmuks
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Pike Language Server
|
|
2
|
+
|
|
3
|
+
Tier-3 LSP implementation for [Pike](https://pike.lysator.liu.se/), for any
|
|
4
|
+
LSP-capable editor. Runs on Node 18+ or Bun — nothing to build.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
npm install -g pike-language-server
|
|
9
|
+
|
|
10
|
+
## Use
|
|
11
|
+
|
|
12
|
+
pike-language-server --stdio
|
|
13
|
+
|
|
14
|
+
### Helix — `~/.config/helix/languages.toml`
|
|
15
|
+
|
|
16
|
+
[language-server.pike-lsp]
|
|
17
|
+
command = "pike-language-server"
|
|
18
|
+
args = ["--stdio"]
|
|
19
|
+
|
|
20
|
+
[[language]]
|
|
21
|
+
name = "pike"
|
|
22
|
+
scope = "source.pike"
|
|
23
|
+
file-types = ["pike", "pmod", "mmod"]
|
|
24
|
+
comment-token = "//"
|
|
25
|
+
indent = { tab-width = 2, unit = " " }
|
|
26
|
+
roots = ["pike.json", ".git"]
|
|
27
|
+
language-servers = ["pike-lsp"]
|
|
28
|
+
|
|
29
|
+
Full guide, including syntax highlighting:
|
|
30
|
+
[docs/helix-installation.md](docs/helix-installation.md)
|
|
31
|
+
|
|
32
|
+
### Neovim and other clients
|
|
33
|
+
|
|
34
|
+
[docs/other-editors.md](docs/other-editors.md)
|
|
35
|
+
|
|
36
|
+
## Diagnostics
|
|
37
|
+
|
|
38
|
+
Install [Pike](https://pike.lysator.liu.se/) 8.0+ and keep `pike` on PATH.
|
|
39
|
+
Every other feature works without it.
|
|
40
|
+
|
|
41
|
+
## VS Code
|
|
42
|
+
|
|
43
|
+
Use the
|
|
44
|
+
[marketplace extension](https://marketplace.visualstudio.com/items?itemName=thesmuks.pike-language-server)
|
|
45
|
+
instead — this package is for other editors.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Pike Language Server — executable entry point.
|
|
4
|
+
*
|
|
5
|
+
* Speaks LSP over stdio. Point your editor at this file:
|
|
6
|
+
* pike-language-server --stdio
|
|
7
|
+
*
|
|
8
|
+
* Runs the server in-process on whichever runtime launched it (Node or Bun) —
|
|
9
|
+
* the standalone bundle is built with a createRequire banner so it works on
|
|
10
|
+
* both. It used to spawn a `bun` child process, which made Bun a hard
|
|
11
|
+
* requirement and broke `npx pike-language-server` for Node-only users.
|
|
12
|
+
*
|
|
13
|
+
* Resolves the bundle from either layout:
|
|
14
|
+
* - npm package: <pkg>/standalone/server.js
|
|
15
|
+
* - repo clone: <repo>/standalone/server.js (after build:standalone)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { resolve, dirname } from "node:path";
|
|
19
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
20
|
+
import { existsSync } from "node:fs";
|
|
21
|
+
|
|
22
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const serverPath = resolve(here, "..", "standalone", "server.js");
|
|
24
|
+
|
|
25
|
+
if (!existsSync(serverPath)) {
|
|
26
|
+
process.stderr.write(
|
|
27
|
+
`pike-language-server: server bundle not found at ${serverPath}\n` +
|
|
28
|
+
`If you are running from a clone, build it first:\n` +
|
|
29
|
+
` bun install && bun run build:standalone\n`,
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// main.ts starts listening only when PIKE_LSP_STDIO=1 or --stdio is present.
|
|
35
|
+
// Default to stdio so a bare `pike-language-server` still serves, and keep the
|
|
36
|
+
// env var so an explicit --socket=/--node-ipc transport also starts listening.
|
|
37
|
+
const args = process.argv.slice(2);
|
|
38
|
+
if (!args.some(a => a === "--stdio" || a === "--node-ipc" || a.startsWith("--socket="))) {
|
|
39
|
+
process.argv.push("--stdio");
|
|
40
|
+
}
|
|
41
|
+
process.env.PIKE_LSP_STDIO = "1";
|
|
42
|
+
|
|
43
|
+
// ─── V8 memory flags (Node only) ────────────────────────────────────────────
|
|
44
|
+
//
|
|
45
|
+
// The VSCode client launches the server with --max-old-space-size and
|
|
46
|
+
// --expose-gc: the cap bounds V8's allocation high-water during indexing
|
|
47
|
+
// bursts (measured on Pike's own stdlib: ~620MB uncapped vs ~335MB capped,
|
|
48
|
+
// with no latency cost), and --expose-gc lets the memory governor force a
|
|
49
|
+
// collection under budget pressure. Editors that launch this script directly
|
|
50
|
+
// (Neovim, Helix) would get neither, so re-exec Node once with the same flags.
|
|
51
|
+
//
|
|
52
|
+
// Skipped when: already re-execed; running under Bun (no V8 flags); or the
|
|
53
|
+
// user supplied their own Node flags (an explicit execArgv wins).
|
|
54
|
+
// PIKE_LSP_MEMORY_BUDGET_MB overrides the 512MB default budget; the cap
|
|
55
|
+
// formula mirrors computeHeapCapMb in the VSCode client.
|
|
56
|
+
const isNode = !process.versions.bun;
|
|
57
|
+
if (isNode && !process.env.PIKE_LSP_NO_REEXEC && process.execArgv.length === 0) {
|
|
58
|
+
const rawBudget = Number.parseInt(process.env.PIKE_LSP_MEMORY_BUDGET_MB ?? "512", 10);
|
|
59
|
+
const budget = Number.isFinite(rawBudget) ? Math.min(8192, Math.max(64, rawBudget)) : 512;
|
|
60
|
+
const capMb = Math.max(budget + 256, Math.round(budget * 1.5));
|
|
61
|
+
|
|
62
|
+
const { spawn } = await import("node:child_process");
|
|
63
|
+
const child = spawn(
|
|
64
|
+
process.execPath,
|
|
65
|
+
[`--max-old-space-size=${capMb}`, "--expose-gc", fileURLToPath(import.meta.url), ...process.argv.slice(2)],
|
|
66
|
+
{
|
|
67
|
+
stdio: "inherit",
|
|
68
|
+
env: { ...process.env, PIKE_LSP_NO_REEXEC: "1" },
|
|
69
|
+
},
|
|
70
|
+
);
|
|
71
|
+
// Mirror the child's lifecycle: the editor manages THIS process, so its
|
|
72
|
+
// signals must reach the server and the server's exit code must come back.
|
|
73
|
+
for (const signal of ["SIGTERM", "SIGINT", "SIGHUP"]) {
|
|
74
|
+
process.on(signal, () => child.kill(signal));
|
|
75
|
+
}
|
|
76
|
+
child.on("exit", (code, signal) => {
|
|
77
|
+
if (signal) process.kill(process.pid, signal);
|
|
78
|
+
process.exit(code ?? 0);
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
// pathToFileURL: a bare Windows path (C:\...) is not a valid import specifier.
|
|
82
|
+
await import(pathToFileURL(serverPath).href);
|
|
83
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Installing the Pike Language Server for Helix
|
|
2
|
+
|
|
3
|
+
A complete, step-by-step setup for Helix — from nothing to a working Pike LSP
|
|
4
|
+
with syntax highlighting.
|
|
5
|
+
|
|
6
|
+
Verified against **Helix 25.01.1** on Linux. Every command and config block
|
|
7
|
+
below was run end-to-end against a real Helix install.
|
|
8
|
+
|
|
9
|
+
Helix needs two independent things, and they are configured separately:
|
|
10
|
+
|
|
11
|
+
| What | Gives you | Needs |
|
|
12
|
+
|------|-----------|-------|
|
|
13
|
+
| **Language server** | hover, completion, goto, references, rename, diagnostics | `[language-server.pike-lsp]` + `[[language]]` |
|
|
14
|
+
| **Tree-sitter grammar** | syntax highlighting | `[[grammar]]` + `hx --grammar build` + highlight queries |
|
|
15
|
+
|
|
16
|
+
Setting up only the first leaves you with a working LSP and **no highlighting**.
|
|
17
|
+
Steps 1–5 cover the LSP; step 6 covers highlighting.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Install Helix
|
|
22
|
+
|
|
23
|
+
Follow the official instructions: <https://docs.helix-editor.com/install.html>
|
|
24
|
+
|
|
25
|
+
Verify:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
hx --version
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 2. Install the server
|
|
32
|
+
|
|
33
|
+
Pick **one**. Nothing here requires cloning or building.
|
|
34
|
+
|
|
35
|
+
[Pike](https://pike.lysator.liu.se/) 8.0+ on `PATH` is optional: it powers
|
|
36
|
+
diagnostics only. Hover, completion, goto, references, and rename all work
|
|
37
|
+
without it.
|
|
38
|
+
|
|
39
|
+
### a. Native binary — no runtime at all (simplest)
|
|
40
|
+
|
|
41
|
+
One self-contained executable. No Node, no Bun.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# pick your platform: linux-x64, linux-arm64, darwin-x64, darwin-arm64, windows-x64.exe
|
|
45
|
+
curl -L -o pike-language-server \
|
|
46
|
+
https://github.com/TheSmuks/pike-language-server/releases/latest/download/pike-language-server-linux-x64
|
|
47
|
+
chmod +x pike-language-server
|
|
48
|
+
sudo mv pike-language-server /usr/local/bin/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The binary embeds its own tree-sitter grammar and stdlib index, so it works from
|
|
52
|
+
anywhere. It is ~90MB — that is a whole JavaScript runtime inside.
|
|
53
|
+
|
|
54
|
+
### b. npm — needs Node 18+ (easiest to update)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm install -g pike-language-server
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### c. Tarball — needs Node 18+ or Bun
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -L https://github.com/TheSmuks/pike-language-server/releases/latest/download/pike-language-server-standalone.tar.gz \
|
|
64
|
+
| tar xz -C ~/.local/share
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Extracts to `~/.local/share/pike-language-server/`. Keep the `.wasm` and `.json`
|
|
68
|
+
files next to `server.js` — they are resolved relative to it.
|
|
69
|
+
|
|
70
|
+
### Verify
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pike-language-server --stdio # binary or npm
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
It waits silently for LSP traffic on stdin; `Ctrl-D` exits. (It will also exit
|
|
77
|
+
immediately on end-of-input, which is normal — a client keeps the stream open.)
|
|
78
|
+
|
|
79
|
+
### d. From source
|
|
80
|
+
|
|
81
|
+
Only if you want to modify the server:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/TheSmuks/pike-language-server.git
|
|
85
|
+
cd pike-language-server
|
|
86
|
+
bun install
|
|
87
|
+
bun run build:standalone
|
|
88
|
+
bun run check:standalone # asserts it really answers LSP
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 4. Configure Helix
|
|
92
|
+
|
|
93
|
+
Add to `~/.config/helix/languages.toml` (create the file if it does not exist).
|
|
94
|
+
|
|
95
|
+
If you installed the **binary** or the **npm package**, `command` is just the
|
|
96
|
+
executable name:
|
|
97
|
+
|
|
98
|
+
```toml
|
|
99
|
+
[language-server.pike-lsp]
|
|
100
|
+
command = "pike-language-server"
|
|
101
|
+
args = ["--stdio"]
|
|
102
|
+
# Optional — see "Helix configuration" below:
|
|
103
|
+
# config = { diagnosticMode = "realtime" }
|
|
104
|
+
|
|
105
|
+
[[language]]
|
|
106
|
+
name = "pike"
|
|
107
|
+
scope = "source.pike"
|
|
108
|
+
file-types = ["pike", "pmod", "mmod"]
|
|
109
|
+
comment-token = "//"
|
|
110
|
+
indent = { tab-width = 2, unit = " " }
|
|
111
|
+
roots = ["pike.json", ".git"]
|
|
112
|
+
language-servers = ["pike-lsp"]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
If you installed the **tarball** (or built from source), replace the first two
|
|
116
|
+
lines with the interpreter plus the path to `server.js` — everything else is
|
|
117
|
+
identical:
|
|
118
|
+
|
|
119
|
+
```toml
|
|
120
|
+
command = "node" # or "bun"
|
|
121
|
+
args = ["/home/you/.local/share/pike-language-server/server.js", "--stdio"]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Helix ships no built-in Pike language, so you define it yourself. Two fields are
|
|
125
|
+
easy to omit and both are fatal:
|
|
126
|
+
|
|
127
|
+
- **`scope` is mandatory.** Without it Helix rejects the *entire* user language
|
|
128
|
+
config — every language, not just Pike — and falls back to defaults.
|
|
129
|
+
- **`file-types` is what attaches Pike to your files.** Without it, Helix never
|
|
130
|
+
recognises a `.pike` file and the server never starts.
|
|
131
|
+
|
|
132
|
+
## 5. Verify the language server
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
hx --health pike
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
You want a green check next to `bun`:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
Configured language servers:
|
|
142
|
+
✓ bun: /home/you/.bun/bin/bun
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then open a Pike file and confirm the server actually attached:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
hx -v some-file.pike
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`-v` logs LSP traffic to `~/.cache/helix/helix.log`. In another shell:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
grep -c "pike-lsp" ~/.cache/helix/helix.log
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
A non-zero count means Helix and the server are talking. Inside the editor,
|
|
158
|
+
`gd` (goto definition), `K` (hover), and `<space>r` (rename) should now work.
|
|
159
|
+
|
|
160
|
+
At this point the LSP is fully working, but the file is **not highlighted**.
|
|
161
|
+
|
|
162
|
+
## 6. Syntax highlighting
|
|
163
|
+
|
|
164
|
+
Highlighting is tree-sitter, entirely separate from the LSP. It needs a
|
|
165
|
+
compiled grammar **and** highlight queries — one without the other gives you
|
|
166
|
+
nothing.
|
|
167
|
+
|
|
168
|
+
Add the grammar to the same `~/.config/helix/languages.toml`:
|
|
169
|
+
|
|
170
|
+
```toml
|
|
171
|
+
[[grammar]]
|
|
172
|
+
name = "pike"
|
|
173
|
+
source = { git = "https://github.com/TheSmuks/tree-sitter-pike", rev = "main" }
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Fetch and compile it, then install the queries from this repository:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
hx --grammar fetch
|
|
180
|
+
hx --grammar build
|
|
181
|
+
mkdir -p ~/.config/helix/runtime/queries/pike/
|
|
182
|
+
cp queries/highlights.scm ~/.config/helix/runtime/queries/pike/highlights.scm
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
`hx --grammar fetch` and `build` operate on *every* grammar Helix knows about,
|
|
186
|
+
so they take a while and may report unrelated grammars failing — that is
|
|
187
|
+
expected and harmless. Only the Pike result matters:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
hx --health pike
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Tree-sitter parser: ✓
|
|
195
|
+
Highlight queries: ✓
|
|
196
|
+
Textobject queries: ✘
|
|
197
|
+
Indent queries: ✘
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`Textobject` and `Indent` stay `✘` — this repository ships no such queries.
|
|
201
|
+
|
|
202
|
+
## 7. Optional configuration
|
|
203
|
+
|
|
204
|
+
Server settings go in a `config` key on the language-server block you already
|
|
205
|
+
created. Helix delivers it as `initializationOptions`, which is the only place
|
|
206
|
+
this server reads settings from:
|
|
207
|
+
|
|
208
|
+
```toml
|
|
209
|
+
config = { diagnosticMode = "realtime" } # "realtime" | "saveOnly" | "off"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Do **not** repeat the `[language-server.pike-lsp]` header a second time in the
|
|
213
|
+
file — duplicate TOML tables make Helix reject the whole config.
|
|
214
|
+
|
|
215
|
+
| Option | Values | Default |
|
|
216
|
+
|--------|--------|---------|
|
|
217
|
+
| `diagnosticMode` | `"realtime"`, `"saveOnly"`, `"off"` | `"realtime"` |
|
|
218
|
+
| `diagnosticDebounceMs` | positive integer | `500` |
|
|
219
|
+
| `maxNumberOfProblems` | positive integer | `100` |
|
|
220
|
+
|
|
221
|
+
## Troubleshooting
|
|
222
|
+
|
|
223
|
+
**`Language 'pike' not found`** — `file-types` is missing, or the config failed
|
|
224
|
+
to parse and Helix silently fell back to defaults. Run `hx --health pike` and
|
|
225
|
+
read the first line of output.
|
|
226
|
+
|
|
227
|
+
**`Error parsing user language config: missing field 'scope'`** — add
|
|
228
|
+
`scope = "source.pike"`. Until you do, *no* language config of yours loads.
|
|
229
|
+
|
|
230
|
+
**`Error parsing user language config: TOML parse error`** — you almost
|
|
231
|
+
certainly declared `[language-server.pike-lsp]` twice. Merge the blocks.
|
|
232
|
+
|
|
233
|
+
**`hx --health pike` shows `✘ bun`** — Bun is not on the `PATH` Helix sees. Use
|
|
234
|
+
an absolute path in `command`, e.g. `command = "/home/you/.bun/bin/bun"`.
|
|
235
|
+
|
|
236
|
+
**Server never attaches** — check the path in `args` resolves, then re-test the
|
|
237
|
+
build from the repository clone:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
bun run check:standalone
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
This spawns the server exactly as Helix does and asserts it answers an LSP
|
|
244
|
+
`initialize`. If it fails, re-run `bun run build:standalone`. (Running
|
|
245
|
+
`bun standalone/server.js --stdio` by hand proves little: with no LSP client on
|
|
246
|
+
the other end it reads end-of-input and exits 0 straight away.)
|
|
247
|
+
|
|
248
|
+
**No highlighting, LSP works** — `hx --health pike` reports
|
|
249
|
+
`Tree-sitter parser: None`. Finish step 6; queries alone are not enough.
|
|
250
|
+
|
|
251
|
+
**No diagnostics, everything else works** — Pike is not on `PATH`. Check
|
|
252
|
+
`pike --version`. Diagnostics are the only feature that needs the Pike binary.
|
|
253
|
+
|
|
254
|
+
**Nothing works after an upgrade** — Helix config errors are printed at startup
|
|
255
|
+
and scroll past instantly. `hx --health pike` reprints them.
|
|
256
|
+
|
|
257
|
+
## What works
|
|
258
|
+
|
|
259
|
+
Every feature below was exercised against Helix 25.01.1's own client
|
|
260
|
+
capabilities and confirmed to return real results (`bun run check:helix`
|
|
261
|
+
re-runs this):
|
|
262
|
+
|
|
263
|
+
- Document symbols, hover, goto-definition, find references
|
|
264
|
+
- Completion (trigger characters `.`, `>`, `:`, `!`) and signature help
|
|
265
|
+
- Rename and prepareRename
|
|
266
|
+
- Document highlight, selection range, workspace symbols
|
|
267
|
+
- Formatting, inlay hints, code actions
|
|
268
|
+
- Diagnostics (pushed by the server; requires Pike on `PATH`)
|
|
269
|
+
|
|
270
|
+
Helix 25.01 has no semantic-token support, so the server's semantic tokens are
|
|
271
|
+
unused there — highlighting comes from the tree-sitter grammar instead.
|
|
272
|
+
|
|
273
|
+
**One known limitation:** a *file-scope* declaration whose name collides with a
|
|
274
|
+
Pike stdlib or predef name (`write`, `count`, `size`, …) cannot be renamed, in
|
|
275
|
+
any editor. Locals, parameters, and class members are always renameable.
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Using Pike LSP with Other Editors
|
|
2
|
+
|
|
3
|
+
The Pike Language Server communicates over stdio using the standard LSP protocol. It works with any LSP-capable editor.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
1. [Bun](https://bun.sh/) runtime installed and on PATH
|
|
8
|
+
2. [Pike](https://pike.lysator.liu.se/) 8.0+ installed and on PATH
|
|
9
|
+
3. Clone and build the server:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/TheSmuks/pike-language-server.git
|
|
13
|
+
cd pike-language-server
|
|
14
|
+
bun install
|
|
15
|
+
bun run build:standalone
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The server binary is at `standalone/server.js`. Run it with:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun /path/to/pike-language-server/standalone/server.js --stdio
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Neovim (verified)
|
|
25
|
+
|
|
26
|
+
Tested with Neovim 0.10.4 and [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig).
|
|
27
|
+
|
|
28
|
+
### Setup with nvim-lspconfig
|
|
29
|
+
|
|
30
|
+
Install nvim-lspconfig, then add to your `init.lua`:
|
|
31
|
+
|
|
32
|
+
```lua
|
|
33
|
+
local configs = require("lspconfig.configs")
|
|
34
|
+
local lspconfig = require("lspconfig")
|
|
35
|
+
|
|
36
|
+
-- Register the pike-lsp config (if not already registered)
|
|
37
|
+
if not configs.pike_lsp then
|
|
38
|
+
configs.pike_lsp = {
|
|
39
|
+
default_config = {
|
|
40
|
+
cmd = { "bun", "/path/to/pike-language-server/standalone/server.js", "--stdio" },
|
|
41
|
+
filetypes = { "pike", "pmod" },
|
|
42
|
+
root_dir = function(fname)
|
|
43
|
+
return vim.fs.dirname(vim.fs.find(".git", { path = fname, upward = true })[1])
|
|
44
|
+
or vim.fn.getcwd()
|
|
45
|
+
end,
|
|
46
|
+
single_file_support = true,
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
lspconfig.pike_lsp.setup({})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Replace `/path/to/pike-language-server` with the actual clone path.
|
|
55
|
+
|
|
56
|
+
### Features verified on Neovim
|
|
57
|
+
|
|
58
|
+
- LSP client attaches on `.pike` and `.pmod` files
|
|
59
|
+
- Document symbols (classes, functions, variables, enums)
|
|
60
|
+
- Hover (type info, AutoDoc documentation)
|
|
61
|
+
- Completion with trigger characters `.`, `>`, `:`
|
|
62
|
+
- Go-to-definition (same-file and cross-file)
|
|
63
|
+
- Find references (workspace-wide)
|
|
64
|
+
- Rename (with prepareRename support)
|
|
65
|
+
|
|
66
|
+
### Configuration
|
|
67
|
+
|
|
68
|
+
The server reads its configuration from `initializationOptions` only — it never
|
|
69
|
+
issues a `workspace/configuration` request. Use `init_options`; a `settings`
|
|
70
|
+
block is silently ignored.
|
|
71
|
+
|
|
72
|
+
```lua
|
|
73
|
+
lspconfig.pike_lsp.setup({
|
|
74
|
+
init_options = {
|
|
75
|
+
diagnosticMode = "realtime", -- "realtime" | "saveOnly" | "off"
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Helix (verified)
|
|
81
|
+
|
|
82
|
+
> **Setting up Helix from scratch?** Follow the step-by-step
|
|
83
|
+
> [Helix installation guide](helix-installation.md) instead — it covers
|
|
84
|
+
> installing Helix, syntax highlighting, and troubleshooting. The summary below
|
|
85
|
+
> assumes you already know your way around `languages.toml`.
|
|
86
|
+
|
|
87
|
+
Tested with Helix 25.01.1. Helix has no built-in Pike language, so you must
|
|
88
|
+
define it yourself — `scope` and `file-types` are both required, and Helix
|
|
89
|
+
rejects the *entire* user language config if `scope` is missing.
|
|
90
|
+
|
|
91
|
+
Add to `~/.config/helix/languages.toml`:
|
|
92
|
+
|
|
93
|
+
```toml
|
|
94
|
+
[language-server.pike-lsp]
|
|
95
|
+
command = "bun"
|
|
96
|
+
args = ["/path/to/pike-language-server/standalone/server.js", "--stdio"]
|
|
97
|
+
# Optional — see "Helix configuration" below:
|
|
98
|
+
# config = { diagnosticMode = "realtime" }
|
|
99
|
+
|
|
100
|
+
[[language]]
|
|
101
|
+
name = "pike"
|
|
102
|
+
scope = "source.pike"
|
|
103
|
+
file-types = ["pike", "pmod", "mmod"]
|
|
104
|
+
comment-token = "//"
|
|
105
|
+
indent = { tab-width = 2, unit = " " }
|
|
106
|
+
roots = ["pike.json", ".git"]
|
|
107
|
+
language-servers = ["pike-lsp"]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Verify the language server is wired up:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
hx --health pike
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Helix configuration
|
|
117
|
+
|
|
118
|
+
Helix passes a `config` block to the server as `initializationOptions`, which is
|
|
119
|
+
exactly where this server reads its settings from. Add the `config` key to the
|
|
120
|
+
`[language-server.pike-lsp]` block you already defined above — do not repeat the
|
|
121
|
+
block, or Helix will reject the file as a duplicate TOML table:
|
|
122
|
+
|
|
123
|
+
```toml
|
|
124
|
+
config = { diagnosticMode = "realtime" } # "realtime" | "saveOnly" | "off"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Features verified on Helix
|
|
128
|
+
|
|
129
|
+
Exercised against the standalone bundle using Helix 25.01.1's own client
|
|
130
|
+
capabilities, and confirmed to return real results:
|
|
131
|
+
|
|
132
|
+
- Document symbols, hover, goto-definition, find references
|
|
133
|
+
- Completion (trigger characters `.`, `>`, `:`, `!`) and signature help
|
|
134
|
+
- Rename and prepareRename — see the limitation below
|
|
135
|
+
- Document highlight, selection range, workspace symbols
|
|
136
|
+
- Formatting, inlay hints, code actions
|
|
137
|
+
- Diagnostics (pushed by the server)
|
|
138
|
+
|
|
139
|
+
Helix 25.01 has no semantic-token support, so the server's semantic tokens go
|
|
140
|
+
unused there; highlighting comes from the tree-sitter grammar instead.
|
|
141
|
+
|
|
142
|
+
**Rename limitation:** a *file-scope* declaration whose name collides with a
|
|
143
|
+
Pike stdlib or predef name (`write`, `count`, `size`, …) cannot be renamed — it
|
|
144
|
+
shadows the predef and propagates to dependent files by name, which the rename
|
|
145
|
+
engine cannot disambiguate. Locals, parameters, and class members are always
|
|
146
|
+
renameable, whatever they are called. This is not Helix-specific; it applies to
|
|
147
|
+
every client, VSCode included.
|
|
148
|
+
|
|
149
|
+
### Helix syntax highlighting with tree-sitter
|
|
150
|
+
|
|
151
|
+
Highlight queries alone are **not** enough — Helix also needs a compiled Pike
|
|
152
|
+
grammar, or it loads no parser and nothing is highlighted. You need both.
|
|
153
|
+
|
|
154
|
+
Add the grammar to the same `languages.toml`:
|
|
155
|
+
|
|
156
|
+
```toml
|
|
157
|
+
[[grammar]]
|
|
158
|
+
name = "pike"
|
|
159
|
+
source = { git = "https://github.com/TheSmuks/tree-sitter-pike", rev = "main" }
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Then fetch and build it, and install the highlight queries:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
hx --grammar fetch
|
|
166
|
+
hx --grammar build
|
|
167
|
+
mkdir -p ~/.config/helix/runtime/queries/pike/
|
|
168
|
+
cp queries/highlights.scm ~/.config/helix/runtime/queries/pike/highlights.scm
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Confirm both parts are present — `hx --health pike` should report
|
|
172
|
+
`Tree-sitter parser: ✓` and `Highlight queries: ✓`. This repository ships no
|
|
173
|
+
textobject or indent queries, so those stay `✘`.
|
|
174
|
+
|
|
175
|
+
### Neovim with nvim-treesitter
|
|
176
|
+
|
|
177
|
+
nvim-treesitter uses tree-sitter queries for syntax highlighting. Copy
|
|
178
|
+
`queries/highlights.scm` from this repository to your nvim-treesitter queries
|
|
179
|
+
directory:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
mkdir -p ~/.local/share/nvim/site/queries/pike/
|
|
183
|
+
cp queries/highlights.scm ~/.local/share/nvim/site/queries/pike/
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```lua
|
|
187
|
+
-- In your init.lua or treesitter config:
|
|
188
|
+
require('nvim-treesitter.configs').setup {
|
|
189
|
+
ensure_installed = { 'pike' }, -- requires tree-sitter-pike parser
|
|
190
|
+
highlight = {
|
|
191
|
+
enable = true,
|
|
192
|
+
custom_captures = {
|
|
193
|
+
-- Map @keyword.import to @include for consistent styling
|
|
194
|
+
['keyword.import'] = 'include',
|
|
195
|
+
['function.method'] = 'function',
|
|
196
|
+
['variable.parameter'] = 'variable',
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The `custom_captures` map the audit-required captures to standard nvim-treesitter
|
|
203
|
+
highlight groups. The tree-sitter-pike parser must be installed separately
|
|
204
|
+
(via `:TSInstall pike` or your plugin manager).
|
|
205
|
+
|
|
206
|
+
## Generic LSP client configuration
|
|
207
|
+
|
|
208
|
+
The server requires:
|
|
209
|
+
- **Transport:** stdio
|
|
210
|
+
- **Command:** `bun /path/to/pike-language-server/standalone/server.js --stdio`
|
|
211
|
+
- **File types:** `.pike`, `.pmod`, `.mmod`
|
|
212
|
+
- **Trigger characters:** `.`, `>`, `:`
|
|
213
|
+
|
|
214
|
+
### Server capabilities
|
|
215
|
+
|
|
216
|
+
| Capability | Supported |
|
|
217
|
+
|------------|-----------|
|
|
218
|
+
| documentSymbol | Yes |
|
|
219
|
+
| definition | Yes |
|
|
220
|
+
| references | Yes |
|
|
221
|
+
| hover | Yes |
|
|
222
|
+
| completion | Yes |
|
|
223
|
+
| rename | Yes (with prepareRename) |
|
|
224
|
+
| diagnostics | Yes (pushed by server) |
|
|
225
|
+
|
|
226
|
+
## Troubleshooting
|
|
227
|
+
|
|
228
|
+
### "Parser not initialized" errors
|
|
229
|
+
|
|
230
|
+
The server initializes the tree-sitter parser on the `initialized` notification. If your client doesn't send this notification, parsing won't work. This is a bug in the client, not the server.
|
|
231
|
+
|
|
232
|
+
### No diagnostics
|
|
233
|
+
|
|
234
|
+
Diagnostics require Pike 8.0+ on PATH. Verify with:
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pike --version
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### No completion for stdlib symbols
|
|
241
|
+
|
|
242
|
+
The server includes a pre-built stdlib index (5,505 symbols). This should work without any configuration. If completions are missing, check that `stdlib-autodoc.json` exists in the same directory as `server.js`.
|