plum

#treesitter#compiler#wasm

git clone https://git.pyrossh.dev/plum

A statically typed, imperative programming language inspired by rust, python


ab4f826Peter John 2026-07-21T10:53:09+05:30
fix editor
.recall/.capture.json CHANGED
@@ -1 +1 @@
1
- {"505dc4d5-42ca-45dc-8df3-1f5e1b1c5bc6": 1886367, "78fe4b8b-6ba2-4a17-b415-0bf00e4a0f4d": 4168472, "61ed18b5-cab0-453c-9a65-dcb8cfc58361": 5702751, "4126b3b8-6d8e-4ca3-8898-fa4ab65a979c": 2221039}
1
+ {"505dc4d5-42ca-45dc-8df3-1f5e1b1c5bc6": 1886367, "78fe4b8b-6ba2-4a17-b415-0bf00e4a0f4d": 4168472, "61ed18b5-cab0-453c-9a65-dcb8cfc58361": 5702751, "4126b3b8-6d8e-4ca3-8898-fa4ab65a979c": 2683872}
.recall/history.md CHANGED
@@ -7589,3 +7589,163 @@ Confirmed by checking `runtime/grammars/` directly (no `plum.so` there) and then
7589
7589
  **Fix**: [`plum editor helix`](plum-cli/src/editor.rs) now runs `hx --grammar build` automatically at the end of install, instead of just printing a hint to do it yourself. Verified by deleting `plum.so` and re-running the real install command — it rebuilt just the missing `plum` grammar and left the other 244 already-built ones alone.
7590
7590
 
7591
7591
  Your Plum syntax should now actually highlight — reopen the `.plum` file (or restart Helix). One remaining gap: `hx --health` still shows `Textobject queries: ✘` since there's no `textobjects.scm` in `tooling/tree-sitter-plum/queries/plum/` — that's a separate, non-blocking feature (things like "select inside function") rather than what was breaking highlighting. Let me know if you'd like that added too.
7592
+
7593
+ **You:** Yese queries, tags, highlights.scm add all of them as well
7594
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum for f in *.scm; do echo "=== $f ==="; cat "$f"; echo; done`
7595
+ - `Write: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/textobjects.scm`
7596
+
7597
+ **Claude:** Now let's fill in the gaps in `tags.scm` (missing `const` definitions).
7598
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/tags.scm`
7599
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/tags.scm`
7600
+
7601
+ **Claude:** Now let's round out `highlights.scm` with the missing operators (`..`, `->`, `=>`, `=`) and the `_` wildcard pattern.
7602
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7603
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7604
+
7605
+ **Claude:** Now let's wire `textobjects.scm` into the CLI installer.
7606
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7607
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7608
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7609
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7610
+
7611
+ **Claude:** Now let's validate all queries actually compile against the grammar, and rebuild.
7612
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli query queries/plum/textobjects.scm --test 2>&1 | head -30 echo "---validate via t`
7613
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli query queries/plum/textobjects.scm ../../examples/types.plum 2>&1 echo "---params`
7614
+
7615
+ **Claude:** All working as expected. Let's rebuild the `plum-cli` binary and re-install into the real Helix config to verify the full flow end-to-end.
7616
+ - `Bash: cd /Users/pyrossh/Code/plum && cargo build -p plum-cli 2>&1 | tail -20`
7617
+ - `Bash: /Users/pyrossh/Code/plum/target/debug/plum editor helix echo "---" ls /Users/pyrossh/Code/config/helix/runtime/queries/plum/ echo "---health---" hx --health plu`
7618
+
7619
+ **Claude:** All four checkmarks now — including `Textobject queries: ✓`. The `gotmpl` build failure is that unrelated pre-existing issue, not `plum` (which was already built and skipped). Let's run the full test suite to confirm nothing's broken.
7620
+ - `Bash: cargo test --workspace 2>&1 | tail -40`
7621
+
7622
+ **Claude:** Full suite green. Summary:
7623
+
7624
+ - **Added `tooling/tree-sitter-plum/queries/plum/textobjects.scm`** — `function.around/inside`, `class.around/inside` (covers `type`/`trait`/`enum`), `parameter.around/inside`, `comment.around/inside`. Verified each capture against real examples (`types.plum`, `functions.plum`, `methods.plum`).
7625
+ - **Filled gaps in `tags.scm`** — added `const` definitions and `fn_call` references (`reference.call`), which were both missing.
7626
+ - **Filled gaps in `highlights.scm`** — the bitwise operators `&`, `|`, `<<`, `>>` and the range operator `..` were never captured (only `...` was); added `->`/`=>` as `@punctuation.special`; added `_` (the wildcard pattern) as `@variable.builtin`.
7627
+ - **Wired `textobjects.scm` into the CLI installer** ([plum-cli/src/editor.rs](plum-cli/src/editor.rs)) alongside the other four query files.
7628
+
7629
+ Verified end-to-end against your real Helix config: `hx --health plum` now shows all four green checkmarks (Tree-sitter parser, Highlight queries, Textobject queries, Indent queries) — the last one was the `✘` from before.
7630
+
7631
+ **You:** The helix func receiver type needs to be highlighted as keyword color, right now its type color.
7632
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli parse ../../examples/methods.plum 2>&1 | head -20`
7633
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7634
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7635
+
7636
+ **Claude:** Let's verify the capture actually resolves to `@keyword` and not `@type` for the receiver position specifically.
7637
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight --html --config-path /dev/null ../../examples/methods.plum > /tmp/metho`
7638
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight --help 2>&1 | head -20`
7639
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight --html -p . --query-paths queries/plum ../../examples/methods.plum 2>/t`
7640
+ - `Bash: cd /Users/pyrossh/Code/plum && cargo build -p plum-cli 2>&1 | tail -10 /Users/pyrossh/Code/plum/target/debug/plum editor helix`
7641
+ - `Bash: grep -A3 "Receiver" /Users/pyrossh/Code/config/helix/runtime/queries/plum/highlights.scm`
7642
+
7643
+ **Claude:** Installed into your real Helix config and confirmed the updated query is live. Reopen a `.plum` file with methods (e.g. `examples/methods.plum`) and the `Cat` in `getAge<Cat>()`/`birthday<Cat>()` should now render in your theme's keyword color instead of the type color.
7644
+
7645
+ Summary of the change ([tooling/tree-sitter-plum/queries/plum/highlights.scm](tooling/tree-sitter-plum/queries/plum/highlights.scm)): the `<Receiver>` annotation is grammatically just a `type` field on `fn` (identical shape to an ordinary field/param type — `type: (type (type_identifier))`), so it was being swept up by the generic `(type_identifier) @type` rule. Added a more specific `(fn type: (type (type_identifier) @keyword))` pattern anchored to `fn` specifically, placed *after* the generic rule — tree-sitter highlighting gives priority to whichever matching pattern appears last in the query file, so this one wins only for the receiver position.
7646
+
7647
+ Verified precisely with `tree-sitter query` against `examples/methods.plum`: the `Cat` in `getAge<Cat>()`/`birthday<Cat>()` now matches both the generic `@type` pattern and the new `@keyword` pattern, while every other `Cat` occurrence (the `type Cat` declaration name, the `inner: Cat` field type, the `-> Cat` return type) matches only `@type` as before — so the change is scoped correctly and doesn't bleed into unrelated type references.
7648
+
7649
+ **You:** Failure 243/246: caddyfile Failed to read directory "/Users/pyrossh/Code/plum/runtime/grammars/sources/caddyfile". Did you use 'hx --grammar fetch'?
7650
+ Failure 244/246: clarity Failed to read directory "/Users/pyrossh/Code/plum/runtime/grammars/sources/clarity". Did you use 'hx --grammar fetch'?
7651
+ Failure 245/246: rust-format-args Failed to read directory "/Users/pyrossh/Code/plum/runtime/grammars/sources/rust-format-args". Did you use 'hx --grammar fetch'?
7652
+ Failure 246/246: plum Parser compilation failed.
7653
+ Stdout:
7654
+ Stderr: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/src/scanner.c:62:20: warning: unused function 'set_raw' [-Wunused-function]
7655
+ 62 | static inline void set_raw(Delimiter *delimiter) { delimiter->flags |= Raw; }
7656
+ | ^~~~~~~
7657
+ /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/src/scanner.c:66:20: warning: unused function 'set_bytes' [-Wunused-function]
7658
+ 66 | static inline void set_bytes(Delimiter *delimiter) { delimiter->flags |= Bytes; }
7659
+ | ^~~~~~~~~
7660
+ 2 warnings generated.
7661
+ ld: open() failed, errno=2 (No such file or directory) for '/Users/pyrossh/Code/plum/runtime/grammars/plum.so'
7662
+ clang++: error: linker command failed with exit code 1 (use -v to see invocation)
7663
+
7664
+ Error: 246 grammars failed to build
7665
+ `hx --grammar build` exited with exit status: 1; run it manually to compile the Plum grammar
7666
+ @pyrossh ➜ plum git(master) $> cargo run --bin plum editor helix
7667
+ - `Bash: cd /tmp && env -i HOME=/Users/pyrossh PATH=/opt/homebrew/bin:/usr/bin:/bin hx --health plum 2>&1 | head -5 echo "---" env -i HOME=/Users/pyrossh PATH=/opt/homeb`
7668
+ - `Bash: echo "$XDG_CONFIG_HOME" ls -la ~/.config/helix 2>&1 echo "---" env -i HOME=/Users/pyrossh PATH=/opt/homebrew/bin:/usr/bin:/bin hx --health hare 2>&1 | head -3`
7669
+ - `Bash: cd /Users/pyrossh/Code/plum env -i HOME=/Users/pyrossh PATH=/opt/homebrew/bin:/usr/bin:/bin hx --grammar build 2>&1 | tail -15`
7670
+ - `Bash: echo "HELIX_RUNTIME=$HELIX_RUNTIME" echo "HELIX_CONFIG_HOME=$HELIX_CONFIG_HOME" env | grep -i helix cat ~/.config/nushell/env.nu 2>/dev/null | grep -i helix cat`
7671
+
7672
+ **Claude:** Let me reproduce this precisely — running `hx --grammar build` from the plum repo root, matching exactly what the user did.
7673
+ - `Bash: cd /Users/pyrossh/Code/plum pwd hx --grammar build 2>&1 | tail -15`
7674
+ - `Bash: which -a hx cargo run --bin plum -- editor helix 2>&1 | tail -20`
7675
+ - `Bash: cd /Users/pyrossh/Code/plum cat > /tmp/print_env.sh << 'EOF' #!/bin/bash echo "CARGO_MANIFEST_DIR=$CARGO_MANIFEST_DIR" echo "CARGO=$CARGO" env | grep -i cargo E`
7676
+
7677
+ **Claude:** Found it — smoking gun confirmed. `cargo run --bin plum` injects `CARGO_MANIFEST_DIR=/Users/pyrossh/Code/plum/plum-cli` into the process environment (not just as a compile-time `env!()` constant), and our `hx` subprocess inherits it. Helix's own runtime-directory resolution apparently treats a present `CARGO_MANIFEST_DIR` as "I'm being run via `cargo run` inside my own dev checkout" and derives `<parent-of-that>/runtime` — which, since it's *our* workspace's manifest dir, resolves to `/Users/pyrossh/Code/plum/runtime` instead of your real Helix config. That's purely an artifact of us spawning `hx` from inside a `cargo run`-invoked process — nothing to do with your shell or config at all.
7678
+ - `Bash: rm -rf /tmp/fakebin /tmp/print_env.sh`
7679
+
7680
+ **Claude:** Let's fix `build_grammar()` to strip Cargo's environment before spawning `hx`.
7681
+ - `Bash: grep -n "fn build_grammar" -A 15 /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7682
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7683
+
7684
+ **Claude:** Now let's rebuild and verify this actually fixes it via `cargo run`.
7685
+ - `Bash: cd /Users/pyrossh/Code/plum cargo build -p plum-cli 2>&1 | tail -10 echo "=== now via cargo run (matching user's exact invocation) ===" cargo run --bin plum --`
7686
+
7687
+ **Claude:** Fixed — it now correctly resolves to `~/Code/config/helix` (245 already built, only the pre-existing unrelated `gotmpl` failure remains, `plum` built successfully). Let's confirm `plum.so` is intact and run the full test suite.
7688
+ - `Bash: ls -la /Users/pyrossh/Code/config/helix/runtime/grammars/plum.so hx --health plum 2>&1 cargo test -p plum-cli 2>&1 | tail -15`
7689
+
7690
+ **Claude:** **Root cause**: nothing to do with your environment or the grammar itself. When you ran `cargo run --bin plum -- editor helix`, Cargo injected `CARGO_MANIFEST_DIR=/Users/pyrossh/Code/plum/plum-cli` into the process — and our `hx --grammar build` subprocess call inherited it. Helix treats a present `CARGO_MANIFEST_DIR` as a signal that it's Helix's own dev build running under `cargo run`, and resolves its runtime/grammar-output directory relative to that path instead of your actual `~/Code/config/helix` config — hence it tried (and failed) to write `plum.so` into `/Users/pyrossh/Code/plum/runtime/grammars/`, a directory that never existed.
7691
+
7692
+ I confirmed this precisely: captured the real subprocess environment (`CARGO_MANIFEST_DIR` was indeed set), reproduced your exact failure via `cargo run --bin plum -- editor helix`, and confirmed a plain `hx --grammar build` run directly from a shell (no `cargo run` wrapper) never hit this.
7693
+
7694
+ **Fix** ([plum-cli/src/editor.rs](plum-cli/src/editor.rs)): `build_grammar()` now strips every `CARGO*` environment variable before spawning `hx`, so it can't mistake our workspace for its own.
7695
+
7696
+ Verified: rebuilt, reran `cargo run --bin plum -- editor helix` — it now correctly targets `~/Code/config/helix`, builds only the missing `plum` grammar (245 already-built ones untouched), and `hx --health plum` shows all four green checkmarks again. `cargo test -p plum-cli` still passes.
7697
+
7698
+ **You:** This is not fixed?
7699
+ The helix func receiver type needs to be highlighted as keyword color, right now its type color.
7700
+ Also else if is not colored.
7701
+ - `Bash: grep -n "else" /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/grammar.js echo "---" cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitte`
7702
+ - `Bash: grep -n "Receiver\|type_identifier) @keyword" /Users/pyrossh/Code/config/helix/runtime/queries/plum/highlights.scm echo "---diff vs repo source---" diff /Users/`
7703
+ - `Bash: mkdir -p ~/.config/tree-sitter cat ~/.config/tree-sitter/config.json 2>/dev/null || echo "NO CONFIG YET"`
7704
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight --help 2>&1`
7705
+ - `Bash: cat /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/tree-sitter.json 2>/dev/null`
7706
+
7707
+ **You:** [Request interrupted by user]
7708
+
7709
+ **You:** make build under tree-sitter folder is not working?
7710
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum ls -la Makefile makefile 2>&1 find . -iname "makefile" -maxdepth 2 2>&1`
7711
+ - `Bash: cat /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/Makefile echo "---running make build---" cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum make build 2`
7712
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum ls node_modules/.bin/ 2>&1 | grep -i tree cat package.json 2>/dev/null | head -30 which tree-sitter 2>&1 np`
7713
+
7714
+ **Claude:** The `Makefile` calls the bare `tree-sitter` binary, but it's not installed globally on this machine — we've only ever been invoking it via `npx --yes tree-sitter-cli`. Let's fix the `Makefile` to be self-sufficient.
7715
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/Makefile`
7716
+ - `Write: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/Makefile`
7717
+
7718
+ **Claude:** Let's verify it actually works now.
7719
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum make build 2>&1 | tail -30 echo "---" ls -la grammars/plum.so 2>&1`
7720
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum make corpus_test 2>&1 | tail -15 echo "---gitignore check---" git check-ignore -v grammars/plum.so 2>&1 ||`
7721
+
7722
+ **Claude:** Both `make build` and `make corpus_test` now work, and `grammars/plum.so` is already properly gitignored. This also conveniently gives us a real compiled `.so` to test the highlighting question with — let's continue that investigation now.
7723
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight -p . --html ../../examples/methods.plum > /tmp/methods_hl.html 2>/tmp/h`
7724
+
7725
+ **Claude:** Good news on the receiver-type question — I rendered the file through the actual tree-sitter-highlight engine (same conflict-resolution logic Helix embeds) and it's working correctly:
7726
+ - `Bash: grep -A2 "^47:" /tmp/methods_hl.html 2>/dev/null sed -n '47p;55p' /tmp/methods_hl.html`
7727
+
7728
+ **Claude:** That confirms the query logic is correct: the `Cat` in `type Cat =` renders as `#005f5f` (the `@type` color), while the `Cat` in `getAge<Cat>()` renders as `#5f00d7` — the exact same purple as the `type` keyword itself. So the receiver-highlighting fix does work at the query-engine level.
7729
+
7730
+ Now let's fix `else if`, which is a real bug — confirmed it's a single combined token in the grammar, not separate `else`/`if` tokens.
7731
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7732
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7733
+
7734
+ **Claude:** Let's verify against the real highlight engine before reinstalling.
7735
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum npx --yes tree-sitter-cli highlight -p . --html ../../examples/control_flow.plum > /tmp/cf_hl.html 2>/tmp/h`
7736
+
7737
+ **Claude:** `else if` now colors correctly (`#5f00d7`, same as `else`/`if`). Let's rebuild the tree-sitter query tests, reinstall into your real Helix config, and run the full workspace suite.
7738
+ - `Bash: cd /Users/pyrossh/Code/plum/tooling/tree-sitter-plum make corpus_test 2>&1 | tail -10 cd /Users/pyrossh/Code/plum cargo build -p plum-cli 2>&1 | tail -5 cargo r`
7739
+
7740
+ **Claude:** Reinstalled — `plum` grammar rebuilt (only one that needed it, unrelated `gotmpl` still pre-existing/unaffected). Let's run the full workspace test suite too.
7741
+ - `Bash: cargo test --workspace 2>&1 | tail -15 hx --health plum 2>&1`
7742
+
7743
+ **Claude:** Both fixed and reinstalled into your real config. Two separate things happened here:
7744
+
7745
+ 1. **`else if` — real bug, now fixed.** In the grammar, `"else if"` is literally a single combined token (not `else` followed by `if`), so it never matched the `["if" "else"] @keyword.control.conditional` list. Added `"else if"` to that list, verified against the real tree-sitter-highlight engine (`examples/control_flow.plum` — both now render in the same conditional-keyword color).
7746
+
7747
+ 2. **Receiver-type highlighting — the query is actually correct, not broken.** I rendered `examples/methods.plum` through the real tree-sitter-highlight engine (the same core library Helix embeds) and confirmed: the `Cat` in `type Cat =` gets `#005f5f` (the `@type` color), while the `Cat` in `getAge<Cat>()` gets `#5f00d7` — the *exact same purple* as the `type` keyword itself. So the override is winning correctly at the query-resolution level.
7748
+
7749
+ If it's still showing as type-color in your actual running Helix session, that's very likely a **stale cache** — Helix compiles and caches the query set once per running instance, and picks up `highlights.scm` changes only on a full restart, not just closing/reopening the buffer or `:reload`. Fully quit Helix and reopen it (not just the file) and it should show correctly now — let me know if it still doesn't after that, since I'd want to dig further rather than assume.
7750
+
7751
+ Also fixed along the way: `tooling/tree-sitter-plum/Makefile`'s `make build`/`make corpus_test` called a bare `tree-sitter` binary that isn't installed globally on this machine — updated it to use `npx --yes tree-sitter-cli`, verified both targets now work and produce `grammars/plum.so`.
plum-cli/src/editor.rs CHANGED
@@ -41,6 +41,8 @@ const HELIX_INJECTIONS: &str =
41
41
  include_str!("../../tooling/tree-sitter-plum/queries/plum/injections.scm");
42
42
  const HELIX_TAGS: &str =
43
43
  include_str!("../../tooling/tree-sitter-plum/queries/plum/tags.scm");
44
+ const HELIX_TEXTOBJECTS: &str =
45
+ include_str!("../../tooling/tree-sitter-plum/queries/plum/textobjects.scm");
44
46
 
45
47
  /// The absolute path to the `tree-sitter-plum` grammar crate on the machine that
46
48
  /// *built* this `plum` binary. Baked in at compile time so a contributor running
@@ -98,6 +100,7 @@ fn install_helix() -> Result<()> {
98
100
  fs::write(queries_dir.join("indents.scm"), HELIX_INDENTS)?;
99
101
  fs::write(queries_dir.join("injections.scm"), HELIX_INJECTIONS)?;
100
102
  fs::write(queries_dir.join("tags.scm"), HELIX_TAGS)?;
103
+ fs::write(queries_dir.join("textobjects.scm"), HELIX_TEXTOBJECTS)?;
101
104
 
102
105
  println!("installed Plum support for Helix in {}", config_dir.display());
103
106
 
@@ -112,7 +115,25 @@ fn install_helix() -> Result<()> {
112
115
  }
113
116
 
114
117
  fn build_grammar() {
118
+ let mut cmd = std::process::Command::new("hx");
115
- match std::process::Command::new("hx").arg("--grammar").arg("build").status() {
119
+ cmd.arg("--grammar").arg("build");
120
+
121
+ // When `plum` itself is run via `cargo run`/`cargo test`, Cargo sets
122
+ // CARGO_MANIFEST_DIR (and friends) in *this* process's environment, and a
123
+ // plain `Command` inherits it into the `hx` child. Helix's own runtime-dir
124
+ // resolution treats a present CARGO_MANIFEST_DIR as "I'm Helix's own dev
125
+ // build running under cargo", and resolves grammar output relative to
126
+ // *our* workspace root instead of the user's real Helix config — so `hx`
127
+ // silently tries to write the compiled grammar to `<plum repo>/runtime/`
128
+ // rather than `~/.config/helix/runtime/`. Strip every CARGO_* var so `hx`
129
+ // falls back to its normal (non-dev) config/runtime-dir resolution.
130
+ for (key, _) in env::vars() {
131
+ if key.starts_with("CARGO") {
132
+ cmd.env_remove(key);
133
+ }
134
+ }
135
+
136
+ match cmd.status() {
116
137
  Ok(status) if status.success() => {
117
138
  println!("compiled the Plum tree-sitter grammar (hx --grammar build)");
118
139
  }
tooling/tree-sitter-plum/Makefile CHANGED
@@ -1,7 +1,9 @@
1
+ TREE_SITTER := npx --yes tree-sitter-cli
2
+
1
3
  build:
2
- tree-sitter generate
4
+ $(TREE_SITTER) generate
3
- tree-sitter build -o grammars/plum.so
5
+ $(TREE_SITTER) build -o grammars/plum.so
4
6
 
5
7
  corpus_test:
6
- tree-sitter generate
8
+ $(TREE_SITTER) generate
7
- tree-sitter test
9
+ $(TREE_SITTER) test
tooling/tree-sitter-plum/queries/plum/highlights.scm CHANGED
@@ -44,6 +44,10 @@
44
44
  "/"
45
45
  "%"
46
46
  "^"
47
+ "&"
48
+ "|"
49
+ "<<"
50
+ ">>"
47
51
  "-"
48
52
  "+"
49
53
  ">"
@@ -53,9 +57,17 @@
53
57
  "<>"
54
58
  "||"
55
59
  "&&"
60
+ ".."
56
61
  "..."
57
62
  ] @operator
58
63
 
64
+ [
65
+ "->"
66
+ "=>"
67
+ ] @punctuation.special
68
+
69
+ "_" @variable.builtin
70
+
59
71
  [
60
72
  "import"
61
73
  "module"
@@ -73,6 +85,7 @@
73
85
  [
74
86
  "if"
75
87
  "else"
88
+ "else if"
76
89
  ] @keyword.control.conditional
77
90
 
78
91
  [
@@ -84,4 +97,15 @@
84
97
 
85
98
  (todo) @keyword.control.exception
86
99
 
87
- "match" @keyword
100
+ "match" @keyword
101
+
102
+ ; `name<Receiver>(...)` — the `<Receiver>` method annotation is grammatically a
103
+ ; `type` field on `fn` (same shape as an ordinary field/param type), but
104
+ ; semantically it's the method's receiver, not a type reference — highlight it
105
+ ; like the `self` it implicitly binds rather than like `@type`. This pattern is
106
+ ; listed after the generic `(type_identifier) @type` above so it wins: when a
107
+ ; node matches more than one pattern, tree-sitter highlighting gives priority
108
+ ; to whichever pattern appears last in the query file.
109
+ (fn
110
+ type: (type
111
+ (type_identifier) @keyword))
tooling/tree-sitter-plum/queries/plum/tags.scm CHANGED
@@ -9,3 +9,12 @@
9
9
 
10
10
  (fn
11
11
  name: (fn_identifier) @name) @definition.function
12
+
13
+ (const
14
+ (const_identifier) @name) @definition.constant
15
+
16
+ (fn_call
17
+ function: (var_identifier) @name) @reference.call
18
+
19
+ (fn_call
20
+ function: (type_identifier) @name) @reference.call
tooling/tree-sitter-plum/queries/plum/textobjects.scm ADDED
@@ -0,0 +1,17 @@
1
+ (fn
2
+ body: (_) @function.inside) @function.around
3
+
4
+ (class
5
+ fields: (field) @class.inside) @class.around
6
+
7
+ (trait
8
+ fields: (field) @class.inside) @class.around
9
+
10
+ (enum
11
+ (field) @class.inside) @class.around
12
+
13
+ (param) @parameter.inside
14
+ (param) @parameter.around
15
+
16
+ (comment) @comment.inside
17
+ (comment) @comment.around