plum

#treesitter#compiler#wasm

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

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


8eeb785Peter John 2026-07-21T10:20:44+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": 5702668, "4126b3b8-6d8e-4ca3-8898-fa4ab65a979c": 1652714}
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}
.recall/history.md CHANGED
@@ -7444,3 +7444,148 @@ Ex: remove<List>(self, v: a) =
7444
7444
  **Standard library**: mechanically added `self` as the first parameter to every method with a `<Receiver>` annotation across all 15 `libs/std` files (`list.plum`, `map.plum`, `str.plum`, `bool.plum`, `int.plum`, `float.plum`, `json.plum`, `result.plum`), re-verified all of them still parse and type-check, and confirmed the full workspace test suite (`cargo test --workspace`) is still green.
7445
7445
 
7446
7446
  The old implicit form (no `self` in the param list) still works too — this is purely additive.
7447
+
7448
+ **You:** Can you update the tooling editors syntax vscode and helix and also create a cli command to install these plugins/sytaxes to their respective editor configuration. See hica for example.
7449
+ - `Agent: Survey editor tooling setup for plum and hica`
7450
+ - `Bash: cd /Users/pyrossh/Code/plum echo "=== vscode-plum tree ==="; find tooling/vscode-plum -type f | grep -v node_modules echo "=== package.json ==="; cat tooling/vs`
7451
+ - `Read: /Users/pyrossh/Code/plum/tooling/vscode-plum/syntaxes/plum.tmLanguage.json`
7452
+ - `Bash: cd /Users/pyrossh/Code/plum cat plum-cli/Cargo.toml echo ---MAIN--- cat plum-cli/src/main.rs echo ---QUERIES--- ls tooling/tree-sitter-plum/queries/plum/ echo -`
7453
+ - `Bash: cd /Users/pyrossh/Code/plum cat tooling/tree-sitter-plum/queries/plum/highlights.scm`
7454
+ - `Edit: /Users/pyrossh/Code/plum/tooling/vscode-plum/syntaxes/plum.tmLanguage.json`
7455
+ - `Edit: /Users/pyrossh/Code/plum/tooling/vscode-plum/syntaxes/plum.tmLanguage.json`
7456
+
7457
+ **Claude:** Now the `language-configuration.json` — backtick is a string delimiter, not a block-comment marker.
7458
+ - `Read: /Users/pyrossh/Code/plum/tooling/vscode-plum/language-configuration.json`
7459
+ - `Write: /Users/pyrossh/Code/plum/tooling/vscode-plum/language-configuration.json`
7460
+
7461
+ **Claude:** Now let's polish the `package.json` (add `publisher`/`displayName`/repository, matching hica's convention).
7462
+ - `Write: /Users/pyrossh/Code/plum/tooling/vscode-plum/package.json`
7463
+ - `Read: /Users/pyrossh/Code/plum/tooling/vscode-plum/package.json`
7464
+ - `Write: /Users/pyrossh/Code/plum/tooling/vscode-plum/package.json`
7465
+ - `Bash: cd /Users/pyrossh/Code/plum python3 -c "import json; json.load(open('tooling/vscode-plum/syntaxes/plum.tmLanguage.json')); print('tmLanguage OK')" python3 -c "i`
7466
+
7467
+ **Claude:** Now let's add `todo` to the Helix highlights query (currently missing).
7468
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/queries/plum/highlights.scm`
7469
+
7470
+ **Claude:** Fix the stale absolute path in the local Helix dev config.
7471
+ - `Read: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/.helix/languages.toml`
7472
+ - `Edit: /Users/pyrossh/Code/plum/tooling/tree-sitter-plum/.helix/languages.toml`
7473
+
7474
+ **Claude:** Now let's implement the CLI subcommand. First, add the `toml_edit` dependency for structural merging.
7475
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/Cargo.toml`
7476
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/Cargo.toml`
7477
+ - `Write: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7478
+
7479
+ **Claude:** Let me clean up that sloppy test I left in.
7480
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7481
+
7482
+ **Claude:** Now let's wire this into `main.rs`.
7483
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/main.rs`
7484
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/main.rs`
7485
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/main.rs`
7486
+
7487
+ **Claude:** Now let's build to make sure everything compiles.
7488
+ - `Bash: cargo build -p plum-cli 2>&1 | tail -80`
7489
+
7490
+ **Claude:** Compiles cleanly. Let's fix that unused import warning.
7491
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7492
+
7493
+ **Claude:** Now let's run the unit tests and actually exercise both install paths end-to-end in a sandboxed HOME.
7494
+ - `Bash: cargo test -p plum-cli 2>&1 | tail -30`
7495
+
7496
+ **Claude:** Now let's do a real end-to-end run with a sandboxed fake `$HOME`, for both editors.
7497
+ - `Bash: rm -rf /tmp/fake_home && mkdir -p /tmp/fake_home cd /Users/pyrossh/Code/plum HOME=/tmp/fake_home cargo run -p plum-cli -- editor helix 2>&1 | tail -20 echo "---`
7498
+ - `Bash: cd /Users/pyrossh/Code/plum BIN=$(cargo build -p plum-cli --message-format=json 2>/dev/null | python3 -c " import json,sys for line in sys.stdin: d=json.loads(l`
7499
+ - `Bash: echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME" ls -la /Users/pyrossh/Code/config/helix 2>&1 cd /Users/pyrossh/Code/config 2>/dev/null && git status 2>&1 | head -20`
7500
+
7501
+ **Claude:** I accidentally installed into your real Helix config (`/Users/pyrossh/Code/config`, since `$XDG_CONFIG_HOME` is set) while testing — let me revert that immediately.
7502
+ - `Bash: cd /Users/pyrossh/Code/config git diff helix/languages.toml echo "---untracked runtime---" find helix/runtime -type f`
7503
+
7504
+ **Claude:** Good, easy to revert cleanly since it's git-tracked.
7505
+ - `Bash: cd /Users/pyrossh/Code/config git restore helix/languages.toml rm -rf helix/runtime/queries/plum rmdir helix/runtime/queries helix/runtime 2>/dev/null git statu`
7506
+ - `Bash: rm -rf /tmp/fake_home find /Users/pyrossh -maxdepth 4 -iname "plum-lang.plum*" 2>/dev/null`
7507
+
7508
+ **Claude:** Let me re-test properly with a fully isolated environment (no inherited `XDG_CONFIG_HOME`).
7509
+ - `Bash: rm -rf /tmp/fake_home && mkdir -p /tmp/fake_home BIN=/Users/pyrossh/Code/plum/target/debug/plum env -i HOME=/tmp/fake_home "$BIN" editor helix echo "--- vscode`
7510
+
7511
+ **Claude:** Both installers work correctly and idempotently in isolation. Let's check the generated `languages.toml` content and clean up.
7512
+ - `Bash: cat /tmp/fake_home/.config/helix/languages.toml rm -rf /tmp/fake_home`
7513
+
7514
+ **Claude:** Let me clean up that path (it works, but resolving the `..` makes it tidier).
7515
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7516
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7517
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7518
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7519
+ - `Bash: cargo build -p plum-cli 2>&1 | tail -30 && cargo test -p plum-cli 2>&1 | tail -20`
7520
+
7521
+ **Claude:** Let's re-verify end-to-end with the sandboxed environment once more, and run the full workspace suite.
7522
+ - `Bash: rm -rf /tmp/fake_home && mkdir -p /tmp/fake_home BIN=/Users/pyrossh/Code/plum/target/debug/plum env -i HOME=/tmp/fake_home "$BIN" editor helix cat /tmp/fake_hom`
7523
+
7524
+ **Claude:** Clean path, and the full workspace suite is green. Let's view the final diff summary.
7525
+ - `Bash: git status --short`
7526
+
7527
+ **Claude:** Done. Summary:
7528
+
7529
+ **VSCode extension** ([tooling/vscode-plum/](tooling/vscode-plum/)):
7530
+ - Fixed a bug where the raw-string grammar include was missing its `#` prefix (`"include": "raw_quoted_string"` → `"#raw_quoted_string"`), meaning backtick-quoted strings were never actually highlighted.
7531
+ - Rewrote the keyword list to match the real grammar (dropped `extern`/`include`/`try`/`as`/`is`/`panic`, which were never real Plum tokens — `is` in particular was literally the wrong trait-syntax we fixed earlier in this project; added `fn` and `todo`).
7532
+ - Fixed `language-configuration.json`: it declared backtick pairs as a *block comment*, but backtick is Plum's string-quote character, not a comment marker — removed that and registered backtick as a proper auto-closing/surrounding string-quote pair instead.
7533
+ - Filled in `publisher`/`displayName` so the extension has a real identity for install targeting.
7534
+
7535
+ **Helix** ([tooling/tree-sitter-plum/queries/plum/highlights.scm](tooling/tree-sitter-plum/queries/plum/highlights.scm)): added the missing `todo` keyword highlight; fixed a stale hardcoded absolute path in the local dev `.helix/languages.toml`.
7536
+
7537
+ **`plum editor` CLI subcommand** ([plum-cli/src/editor.rs](plum-cli/src/editor.rs)): `plum editor helix` and `plum editor vscode [--insiders]`, modeled on hica's but with two deliberate improvements over that reference:
7538
+ 1. **Everything is `include_str!`-embedded at compile time** rather than read via relative paths from CWD, so it works regardless of where you run it from (hica's version only works from its own repo root).
7539
+ 2. **`languages.toml` is structurally merged via `toml_edit`**, not string-appended — idempotent re-runs, and it won't corrupt existing formatting/entries the way hica's substring-check-then-append does.
7540
+
7541
+ The Helix grammar path is baked in via `CARGO_MANIFEST_DIR` at build time (correct for the machine that built the binary, unlike hica's hand-copied stale path) and then canonicalized at install time for a clean `languages.toml`.
7542
+
7543
+ One thing worth flagging: **while testing, `editor helix` briefly wrote into your real `~/.config` (a git-tracked dotfiles repo) because `$XDG_CONFIG_HOME` was set in my shell** — I caught it immediately, ran `git restore` on `helix/languages.toml`, and deleted the `helix/runtime/queries/plum/` directory it had created. `git status` there is clean now (verified). All actual testing after that used an isolated `env -i HOME=/tmp/fake_home`.
7544
+
7545
+ Verified end-to-end in that sandbox: both installers run, both are idempotent (`helix` twice is a no-op with a clear message; `vscode` fully replaces the extension dir), and `cargo test --workspace` is green.
7546
+
7547
+ **You:** Why is the helix editor not loading the syntax?
7548
+ - `Bash: echo "XDG_CONFIG_HOME=$XDG_CONFIG_HOME" cat /Users/pyrossh/Code/config/helix/languages.toml 2>/dev/null echo "---grammars dir---" find /Users/pyrossh/Code/confi`
7549
+ - `Bash: hx --health plum 2>&1`
7550
+ - `Bash: find /Users/pyrossh/Code/config/helix -iname "*plum*" 2>&1 echo "---" find / -iname "plum.so" 2>/dev/null find / -path "*helix*grammars*plum*" 2>/dev/null`
7551
+
7552
+ **You:** [Request interrupted by user for tool use]
7553
+
7554
+ **You:** It shows the language option but even after setting the language as plum the syntax is not highlighted.
7555
+
7556
+ **Claude:** I won't run a full filesystem scan — let me check the specific Helix runtime grammar directory directly instead.
7557
+ - `Bash: ls -la /Users/pyrossh/Code/config/helix/runtime/ 2>&1 echo "---grammars subdir if any---" ls -la /Users/pyrossh/Code/config/helix/runtime/grammars/ 2>&1 echo "-`
7558
+ - `Bash: hx --grammar fetch 2>&1 | grep -i plum echo "---build---" hx --grammar build 2>&1 | grep -i plum echo "---after build, grammars dir---" ls -la /Users/pyrossh/Co`
7559
+
7560
+ **Claude:** Found it — the compiled grammar shared library (`plum.so`) never existed until just now. Let's confirm.
7561
+ - `Bash: hx --health plum 2>&1`
7562
+
7563
+ **Claude:** **Root cause found**: registering the language in `languages.toml` and dropping the query files into `runtime/queries/plum/` is not enough — Helix needs the tree-sitter grammar actually **compiled into a shared library** (`runtime/grammars/plum.so`) before it can parse anything for highlighting. That file didn't exist. `hx --health plum` showing `Tree-sitter parser: ✓` is misleading — it only checks that the *config* is valid (a `[[grammar]]` entry with a resolvable source), not that the `.so` was ever built.
7564
+
7565
+ I just ran `hx --grammar build`, and it compiled successfully — `runtime/grammars/plum.so` now exists (150KB, alongside all the built-in languages' `.so` files). Open (or re-open) a `.plum` file now and highlighting should work.
7566
+
7567
+ Two things worth fixing on my end so this doesn't bite anyone else who runs `plum editor helix`:
7568
+ - `TodoWrite: [{"content":"Make `plum editor helix` run/prompt for `hx --grammar build` automatically instead of just printing a hint","status":"pending"},{"content":"Add tex`
7569
+
7570
+ **Claude:** Let me fix the CLI so it actually runs the build step automatically instead of just printing a hint that's easy to miss.
7571
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7572
+ - `Read: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7573
+ - `Edit: /Users/pyrossh/Code/plum/plum-cli/src/editor.rs`
7574
+ - `Bash: hx --grammar --help 2>&1`
7575
+ - `Bash: cargo build -p plum-cli 2>&1 | tail -20`
7576
+
7577
+ **Claude:** Let's verify it now auto-builds correctly, by temporarily removing the `.so` and re-running the real install command.
7578
+ - `Bash: rm -f /Users/pyrossh/Code/config/helix/runtime/grammars/plum.so /Users/pyrossh/Code/plum/target/debug/plum editor helix echo "---check---" ls -la /Users/pyrossh`
7579
+
7580
+ **Claude:** Works correctly — `plum` was the only grammar rebuilt, and it succeeded (the one failure, `gotmpl`, is an unrelated pre-existing grammar on this machine, not something we touched). Let's run the test suite and confirm everything's still clean.
7581
+ - `Bash: cargo test -p plum-cli 2>&1 | tail -20`
7582
+
7583
+ **Claude:** Fixed. Summary:
7584
+
7585
+ **Root cause**: registering the language in `languages.toml` and copying the query files was never enough — Helix needs the tree-sitter grammar compiled into a shared library at `runtime/grammars/plum.so`, and that build step never happened. `hx --health plum` misleadingly shows `Tree-sitter parser: ✓` just because the config is valid, not because the `.so` exists — easy to miss.
7586
+
7587
+ Confirmed by checking `runtime/grammars/` directly (no `plum.so` there) and then running `hx --grammar build` myself, which compiled it successfully.
7588
+
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
+
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.
libs/std/int.plum CHANGED
@@ -4,6 +4,8 @@ MIN_VALUE = -0x8000_0000_0000_0000 # Lowest value of Int
4
4
  MAX_VALUE = 0x7FFF_FFFF_FFFF_FFFF # Highest value of Int
5
5
  LARGE = 1 << 28 # 2**28
6
6
 
7
+ type Int
8
+
7
9
  # returns a random Int
8
10
  random() -> Float =
9
11
  todo
plum-cli/src/editor.rs CHANGED
@@ -50,6 +50,15 @@ const HELIX_TAGS: &str =
50
50
  const TREE_SITTER_PLUM_DIR: &str =
51
51
  concat!(env!("CARGO_MANIFEST_DIR"), "/../tooling/tree-sitter-plum");
52
52
 
53
+ /// [`TREE_SITTER_PLUM_DIR`] with the `..` component resolved away, for a tidier
54
+ /// `languages.toml`. Falls back to the raw (still-correct, just uglier) path if
55
+ /// the directory has moved since this binary was built.
56
+ fn tree_sitter_plum_dir() -> String {
57
+ fs::canonicalize(TREE_SITTER_PLUM_DIR)
58
+ .map(|p| p.display().to_string())
59
+ .unwrap_or_else(|_| TREE_SITTER_PLUM_DIR.to_string())
60
+ }
61
+
53
62
  pub fn install(editor: EditorType, insiders: bool) -> Result<()> {
54
63
  match editor {
55
64
  EditorType::Helix => install_helix(),
@@ -91,10 +100,33 @@ fn install_helix() -> Result<()> {
91
100
  fs::write(queries_dir.join("tags.scm"), HELIX_TAGS)?;
92
101
 
93
102
  println!("installed Plum support for Helix in {}", config_dir.display());
103
+
104
+ // Registering the language and dropping in query files isn't enough on its
105
+ // own — Helix only highlights a file once the grammar has been compiled
106
+ // into a shared library under runtime/grammars/. `hx --health <lang>`
107
+ // reports the tree-sitter parser as present just because the config is
108
+ // valid, even when that .so has never been built, which makes a missing
94
- println!("run `hx --grammar build` to compile the Plum tree-sitter grammar");
109
+ // build step easy to miss. Build it now instead of just telling the user to.
110
+ build_grammar();
95
111
  Ok(())
96
112
  }
97
113
 
114
+ fn build_grammar() {
115
+ match std::process::Command::new("hx").arg("--grammar").arg("build").status() {
116
+ Ok(status) if status.success() => {
117
+ println!("compiled the Plum tree-sitter grammar (hx --grammar build)");
118
+ }
119
+ Ok(status) => {
120
+ println!(
121
+ "`hx --grammar build` exited with {status}; run it manually to compile the Plum grammar"
122
+ );
123
+ }
124
+ Err(_) => {
125
+ println!("could not find `hx` on PATH; run `hx --grammar build` manually to compile the Plum grammar");
126
+ }
127
+ }
128
+ }
129
+
98
130
  /// Structurally merges (rather than blindly appends, unlike a plain text-append)
99
131
  /// a `[[language]]` + `[[grammar]]` entry for `plum` into the user's
100
132
  /// `languages.toml`, using `toml_edit` so existing formatting/comments survive
@@ -142,7 +174,7 @@ fn merge_languages_toml(path: &Path) -> Result<()> {
142
174
  let mut grammar = toml_edit::Table::new();
143
175
  grammar["name"] = toml_edit::value("plum");
144
176
  let mut source = toml_edit::InlineTable::new();
145
- source.insert("path", TREE_SITTER_PLUM_DIR.into());
177
+ source.insert("path", tree_sitter_plum_dir().into());
146
178
  grammar["source"] = toml_edit::Item::Value(toml_edit::Value::InlineTable(source));
147
179
 
148
180
  doc.entry("grammar")