plum
git clone https://git.pyrossh.dev/plum
A statically typed, imperative programming language inspired by rust, python
2ba2a03
— Peter John
2026-11-04T15:36:02+05:30
format: blank line after the module line
- plum-core/src/formatter.rs +18 -1
- plum-core/tests/formatter_test.rs +10 -0
- plum-game/tests/fixtures/assets_fixture.plum +1 -0
- plum-game/tests/fixtures/host_fixture.plum +1 -0
- plum-game/tests/fixtures/target_fixture.plum +1 -0
- plum-std/Array.plum +1 -0
- plum-std/Base64.plum +1 -0
- plum-std/Bool.plum +1 -0
- plum-std/Buffer.plum +1 -0
- plum-std/Byte.plum +1 -0
- plum-std/Deque.plum +1 -0
- plum-std/Float.plum +1 -0
- plum-std/Grid.plum +1 -0
- plum-std/Heap.plum +1 -0
- plum-std/Int.plum +1 -0
- plum-std/Io.plum +1 -0
- plum-std/Map.plum +1 -0
- plum-std/Math.plum +1 -0
- plum-std/Mem.plum +1 -0
- plum-std/Os.plum +1 -0
- plum-std/Random.plum +1 -0
- plum-std/Set.plum +1 -0
- plum-std/Time.plum +1 -0
- plum-std/Uuid.plum +1 -0
- plum-std/game/Affine.plum +1 -0
- plum-std/game/Color.plum +1 -0
- plum-std/game/Game.plum +1 -0
- plum-std/game/Input.plum +1 -0
- plum-std/game/Vec2.plum +1 -0
- plum-std/game/functional/Anim.plum +1 -0
- plum-std/game/functional/FunctionalScene.plum +1 -0
- plum-std/game/functional/Ui.plum +1 -0
- plum-std/game/imperative/Scene.plum +1 -0
- plum-std/game/pure/Actions.plum +1 -0
- plum-std/game/pure/PureScene.plum +1 -0
- plum-std/game/pure/SceneInput.plum +1 -0
plum-core/src/formatter.rs
CHANGED
|
@@ -74,7 +74,24 @@ pub fn formatSourceWithOpts(
|
|
|
74
74
|
tolerate_parsing_errors: false,
|
|
75
75
|
},
|
|
76
76
|
)?;
|
|
77
|
-
|
|
77
|
+
let formatted = String::from_utf8(output).expect("Topiary output is valid UTF-8");
|
|
78
|
+
Ok(blankLineAfterModule(&formatted))
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Ensures exactly one blank line after the leading `module` line (when anything
|
|
82
|
+
/// follows it). Topiary has no capture that inserts a blank line, so this is a text
|
|
83
|
+
/// pass on its output; Topiary keeps at most one blank line between top-level items,
|
|
84
|
+
/// so the result formats to itself.
|
|
85
|
+
pub fn blankLineAfterModule(source: &str) -> String {
|
|
86
|
+
let Some(end) = source.find('\n') else { return source.to_string() };
|
|
87
|
+
if !source.starts_with("module ") {
|
|
88
|
+
return source.to_string();
|
|
89
|
+
}
|
|
90
|
+
let rest = &source[end + 1..];
|
|
91
|
+
if rest.is_empty() || rest.starts_with('\n') {
|
|
92
|
+
return source.to_string();
|
|
93
|
+
}
|
|
94
|
+
format!("{}\n{}", &source[..=end], rest)
|
|
78
95
|
}
|
|
79
96
|
|
|
80
97
|
/// Collapses a `match` case (or `guard_case`) whose body is an indented block
|
plum-core/tests/formatter_test.rs
CHANGED
|
@@ -494,3 +494,13 @@ fn format_multiline_record_fields_one_per_line() {
|
|
|
494
494
|
fn format_mut_and_export_keywords() {
|
|
495
495
|
assertFormatsUnchanged("record World(mut s: Int, t: Int)\n\nexport fun f() -> Int =\n 1\n");
|
|
496
496
|
}
|
|
497
|
+
|
|
498
|
+
/// A blank line always follows the `module` line, and formatting again keeps it.
|
|
499
|
+
#[test]
|
|
500
|
+
fn format_blank_line_after_module() {
|
|
501
|
+
let input = "module app\nimport std/Int\n\nfun f() -> Int =\n 1\n";
|
|
502
|
+
let expected = "module app\n\nimport std/Int\n\nfun f() -> Int =\n 1\n";
|
|
503
|
+
assert_eq!(formatSource(input).unwrap(), expected);
|
|
504
|
+
assertFormatsUnchanged(expected);
|
|
505
|
+
assertFormatsUnchanged("module app\n");
|
|
506
|
+
}
|
plum-game/tests/fixtures/assets_fixture.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module assets_fixture
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-game/tests/fixtures/host_fixture.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module host_fixture
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-game/tests/fixtures/target_fixture.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module target_fixture
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/Array.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/Base64.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Str
|
|
3
4
|
import std/Buffer
|
|
4
5
|
import std/Int
|
plum-std/Bool.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Str
|
|
3
4
|
|
|
4
5
|
# The API of the built-in `Bool` type: `Bool.parse` and `toStr` (also used by
|
plum-std/Buffer.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Array
|
|
3
4
|
import std/Str
|
|
4
5
|
import std/Int
|
plum-std/Byte.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/Deque.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Array
|
|
3
4
|
import std/Slice
|
|
4
5
|
import std/Int
|
plum-std/Float.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Str
|
|
3
4
|
import std/Int
|
|
4
5
|
import std/Math
|
plum-std/Grid.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Array
|
|
3
4
|
import std/Int
|
|
4
5
|
import std/Float
|
plum-std/Heap.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Array
|
|
3
4
|
import std/Slice
|
|
4
5
|
import std/Int
|
plum-std/Int.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Str
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Math
|
plum-std/Io.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/Map.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Slice
|
|
3
4
|
import std/Array
|
|
4
5
|
import std/Int
|
plum-std/Math.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
|
plum-std/Mem.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
|
plum-std/Os.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Slice
|
|
3
4
|
import std/Str
|
|
4
5
|
import std/Uuid
|
plum-std/Random.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
|
plum-std/Set.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Map
|
|
3
4
|
import std/Slice
|
|
4
5
|
import std/Int
|
plum-std/Time.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/Uuid.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/Affine.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Float
|
|
3
4
|
import std/Math
|
|
4
5
|
import std/game/Vec2
|
plum-std/game/Color.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Float
|
|
3
4
|
|
|
4
5
|
# An RGBA colour with each channel in 0..1.
|
plum-std/game/Game.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/Input.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Slice
|
plum-std/game/Vec2.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Float
|
|
3
4
|
import std/Math
|
|
4
5
|
|
plum-std/game/functional/Anim.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/List
|
plum-std/game/functional/FunctionalScene.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/functional/Ui.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/imperative/Scene.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/pure/Actions.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Slice
|
|
3
4
|
import std/Int
|
|
4
5
|
import std/Float
|
plum-std/game/pure/PureScene.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|
plum-std/game/pure/SceneInput.plum
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
module std
|
|
2
|
+
|
|
2
3
|
import std/Int
|
|
3
4
|
import std/Float
|
|
4
5
|
import std/Str
|