plum

#treesitter#compiler#wasm

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

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


0c55384 — Peter John 2026-11-01T17:35:19+05:30
T2: tooling queries
plum-core/tests/formatter_test.rs CHANGED
@@ -265,3 +265,28 @@ fn formatsZigStyleErrors() {
265
265
  assert!(h.contains("-> (ParseError || error{C, D})!Int ="), "{h}");
266
266
  assert_eq!(formatSource(&h).expect("second"), h, "idempotent");
267
267
  }
268
+
269
+ fn assertFormatStable(input: &str) {
270
+ let once = formatSource(input).expect("first pass");
271
+ assert_eq!(once, input);
272
+ let twice = formatSource(&once).expect("second pass");
273
+ assert_eq!(twice, once);
274
+ }
275
+
276
+ #[test]
277
+ fn formatStructWithBody() {
278
+ assertFormatStable(
279
+ "struct Vec2(x: Float, y: Float) =\n ZERO = Vec2(x: 0.0, y: 0.0)\n\n fun len(self) -> Float =\n self.x\n",
280
+ );
281
+ }
282
+
283
+ #[test]
284
+ fn formatStructNoBody() {
285
+ assertFormatStable("struct Vec2(x: Float, y: Float)\n\nfun f() -> Int =\n 1\n");
286
+ }
287
+
288
+ #[test]
289
+ fn formatRecordGeneric() {
290
+ assertFormatStable("record Pair[K, V](key: K, val: V)\n");
291
+ assertFormatStable("record Pair[K, V](key: K, val: V) =\n fun first(self) -> K =\n self.key\n");
292
+ }
plum-lsp/src/completion.rs CHANGED
@@ -25,7 +25,7 @@ use plum_core::ast;
25
25
  use tower_lsp::lsp_types::*;
26
26
 
27
27
  const KEYWORDS: &[&str] = &[
28
- "fun", "fun*", "fn", "yield", "crash", "error", "catch", "value", "enum", "primitive", "import", "module", "extern", "if", "then", "else", "while", "for", "range", "match",
28
+ "fun", "fun*", "fn", "yield", "crash", "error", "catch", "struct", "record", "enum", "primitive", "import", "module", "extern", "if", "then", "else", "while", "for", "range", "match",
29
29
  "when", "break", "continue", "return", "todo", "assert", "test", "self", "true",
30
30
  "false", "null", "try",
31
31
  ];
plum-tooling/tree-sitter-plum/queries/plum/format.scm CHANGED
@@ -12,6 +12,12 @@
12
12
  (source
13
13
  (enum) @allow_blank_line_before)
14
14
 
15
+ (source
16
+ (struct) @allow_blank_line_before)
17
+
18
+ (source
19
+ (record) @allow_blank_line_before)
20
+
15
21
  (source
16
22
  (primitive) @allow_blank_line_before)
17
23
 
@@ -91,10 +97,12 @@
91
97
 
92
98
  (import "import" @append_space)
93
99
 
94
- (enum "value" @append_space)
95
-
96
100
  (enum "enum" @append_space)
97
101
 
102
+ (struct "struct" @append_space)
103
+
104
+ (record "record" @append_space)
105
+
98
106
  (primitive "primitive" @append_space)
99
107
 
100
108
  (primitive
@@ -244,6 +252,50 @@
244
252
  (_) @append_indent_end
245
253
  .)
246
254
 
255
+ ; `struct` bodies mirror `enum`: methods/consts indent under the `=`; the body is
256
+ ; optional, so the indent only closes when an `=` exists.
257
+ (struct
258
+ (fn) @prepend_hardline)
259
+
260
+ (struct
261
+ (const) @prepend_hardline)
262
+
263
+ (struct
264
+ (const) @allow_blank_line_before)
265
+
266
+ (struct
267
+ (fn) @allow_blank_line_before)
268
+
269
+ (struct
270
+ "=" @append_indent_start)
271
+
272
+ (struct
273
+ "="
274
+ (_) @append_indent_end
275
+ .)
276
+
277
+ ; `record` bodies mirror `enum`: methods/consts indent under the `=`; the body is
278
+ ; optional, so the indent only closes when an `=` exists.
279
+ (record
280
+ (fn) @prepend_hardline)
281
+
282
+ (record
283
+ (const) @prepend_hardline)
284
+
285
+ (record
286
+ (const) @allow_blank_line_before)
287
+
288
+ (record
289
+ (fn) @allow_blank_line_before)
290
+
291
+ (record
292
+ "=" @append_indent_start)
293
+
294
+ (record
295
+ "="
296
+ (_) @append_indent_end
297
+ .)
298
+
247
299
  ; `enum_field` (a variant like `| Circle(r: Float)`) is ALIASED to the visible
248
300
  ; node kind "field"; only it has a literal "|" — safe to target unscoped by
249
301
  ; parent.
plum-tooling/tree-sitter-plum/queries/plum/highlights.scm CHANGED
@@ -112,7 +112,8 @@
112
112
  "module"
113
113
  "enum"
114
114
  "primitive"
115
- "value"
115
+ "struct"
116
+ "record"
116
117
  "fun"
117
118
  "fun*"
118
119
  "extern"
plum-tooling/vscode-plum/syntaxes/plum.tmLanguage.json CHANGED
@@ -67,7 +67,7 @@
67
67
  }
68
68
  },
69
69
  {
70
- "match": "\\b(module|value|enum|error|primitive|fun\\*?|fn|extern|self|test)(?![A-Za-z0-9_])",
70
+ "match": "\\b(module|struct|record|enum|error|primitive|fun\\*?|fn|extern|self|test)(?![A-Za-z0-9_])",
71
71
  "name": "keyword.const.plum"
72
72
  },
73
73
  {