plum
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", "
|
|
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
|
-
"
|
|
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|
|
|
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
|
{
|