A struct or union fits on one line, struct Pt(x: i32, y: i32), and flan convert writes that form when it fits.
This commit is contained in:
parent
de0c8791f3
commit
905a4c53be
@ -1153,6 +1153,11 @@ Before it at the same level, else out to the line that owns this block."
|
||||
((member w '("defer" "quote" "else")) alone)
|
||||
((member w '("fn" "fn-"))
|
||||
(not (re-search-forward "[ \t]=[ \t]" end t)))
|
||||
;; `struct Pt(x: i32)' has its fields on the line.
|
||||
((member w '("struct" "union"))
|
||||
(not (save-excursion
|
||||
(goto-char w-end)
|
||||
(looking-at "[ \t]+[^][ \t\n(){},;\":]+("))))
|
||||
((member w '("if" "elif")) (not (flan-fln--then start)))
|
||||
(t t)))))
|
||||
;; `let r = match n', `x = if c', `fn f(x) = match x', a lambda
|
||||
@ -1606,7 +1611,8 @@ lambda or a `Fn(...)' type, and not after a match arm's."
|
||||
flan--definers))
|
||||
(1 font-lock-keyword-face) (2 font-lock-function-name-face))
|
||||
;; A condition's parent, `struct DiskFull :parent IoError'.
|
||||
(,(concat "^struct[ \t]+[^][ \t\n(){},;\":]+[ \t]+:parent[ \t]+" flan-fln--name-re)
|
||||
(,(concat "^struct[ \t]+[^][ \t\n(){},;\":]+\\(?:([^)\n]*)\\)?[ \t]+:parent[ \t]+"
|
||||
flan-fln--name-re)
|
||||
1 font-lock-type-face)
|
||||
(,(concat "^\\(?:def\\|once\\|const\\)[ \t]+" flan-fln--name-re)
|
||||
1 font-lock-variable-name-face)
|
||||
|
||||
@ -90,6 +90,10 @@ struct Oops :parent Error
|
||||
|
||||
type Count = i64
|
||||
|
||||
struct Pair(a: i64, b: i64)
|
||||
|
||||
fn pair-sum(p: Pair) -> i64 = p.a + p.b
|
||||
|
||||
fn counted(n: Count) -> Count = n + 1
|
||||
|
||||
fn oops-code() -> i64
|
||||
@ -240,6 +244,8 @@ comment():
|
||||
("fn dir" "(dir :north)" "7")
|
||||
("struct Oops" "(oops-code)" "7")
|
||||
("type Count" "(counted 1)" "2")
|
||||
("struct Pair" "(pair-sum (Pair {.a 1 .b 2}))" "3")
|
||||
("fn pair-sum" "(pair-sum (Pair {.a 1 .b 2}))" "3")
|
||||
("fn counted" "(counted 1)" "2")
|
||||
("fn oops-code" "(oops-code)" "7")
|
||||
("macro dbl-of" "(use-mac 5)" "10")
|
||||
|
||||
@ -903,6 +903,23 @@ defconst(k, 3)
|
||||
(test-flan-fln--tabs "macro repeat(i, n, & body)\n|" 1) 2)
|
||||
(test-flan-fln--is "and a struct with a parent"
|
||||
(test-flan-fln--tabs "struct DiskFull :parent IoError\n|" 1) 2)
|
||||
(test-flan-fln--is "but not a struct on one line"
|
||||
(test-flan-fln--tabs "struct Pt(x: i32, y: i32)\n|" 1) 0)
|
||||
(test-flan-fln--is "nor one with a parent"
|
||||
(test-flan-fln--tabs "struct D(free: i64) :parent IoError\n|" 1) 0)
|
||||
(test-flan-fln--in "struct D(free: i64) :parent IoError\n\nunion U(a: i32)\n"
|
||||
(font-lock-ensure)
|
||||
(let ((face (lambda (needle)
|
||||
(save-excursion (goto-char (point-min)) (search-forward needle)
|
||||
(get-text-property (match-beginning 0) 'face)))))
|
||||
(test-flan-fln--is "a one-line struct's name is a type" (funcall face "D(") 'font-lock-type-face)
|
||||
(test-flan-fln--is "its field's type too" (funcall face "i64") 'font-lock-type-face)
|
||||
(test-flan-fln--is "and its parent" (funcall face "IoError") 'font-lock-type-face)
|
||||
(test-flan-fln--is "a one-line union's name" (funcall face "U(") 'font-lock-type-face))
|
||||
(goto-char (point-min))
|
||||
(test-flan-fln--is "a one-line struct is a top-level form of one line"
|
||||
(test-flan-fln--thing 'flan-fln-toplevel)
|
||||
"struct D(free: i64) :parent IoError"))
|
||||
(test-flan-fln--is "a one-line fn whose value is a match opens it"
|
||||
(test-flan-fln--tabs "fn f(x) = match x\n|" 1) 2)
|
||||
(test-flan-fln--is "no deeper after a one-line else"
|
||||
|
||||
@ -1060,7 +1060,19 @@ and sugar n (f : Form.t) : string list option =
|
||||
| [ _; pf; { v = Form.Vec fs; _ } ] -> (" :parent " ^ ty pf, fs)
|
||||
| _ -> assert false
|
||||
in
|
||||
(* One line when it fits, [struct Pt(x: i32, y: i32)], and a line per
|
||||
field otherwise. *)
|
||||
let one =
|
||||
match fs, params_text fs with
|
||||
| _ :: _, Some pt ->
|
||||
let line =
|
||||
i ^ (if d = "defstruct" then "struct " else "union ") ^ name ^ "(" ^ pt ^ ")" ^ parent
|
||||
in
|
||||
if String.length line <= width && not (!inside f) then Some [ line ] else None
|
||||
| _ -> None
|
||||
in
|
||||
(match pairs fs with
|
||||
| _ when one <> None -> one
|
||||
| Some prs when List.for_all (fun ((f : Form.t), _) ->
|
||||
match f.v with Form.Sym x -> def_name x | _ -> false) prs ->
|
||||
Some
|
||||
|
||||
@ -1531,6 +1531,13 @@ and header (s : st) w : Form.t =
|
||||
named head items
|
||||
| "struct" | "union" ->
|
||||
let name = name_tok p ~what:"the type's name" in
|
||||
(* [struct Pt(x: i32, y: i32)]: the fields on the header's line, as a
|
||||
data case writes them, with no block under it. *)
|
||||
let inline =
|
||||
match (peek p).tok with
|
||||
| LP when not (peek p).sp -> let lp = advance p in Some (params p lp)
|
||||
| _ -> None
|
||||
in
|
||||
(* [struct DiskFull :parent IoError]: a condition's parent, before the
|
||||
fields as in the paren form. *)
|
||||
let parent =
|
||||
@ -1541,9 +1548,17 @@ and header (s : st) w : Form.t =
|
||||
Some (Form.make (Form.Kw "parent") kt.loc, pt)
|
||||
| _ -> None
|
||||
in
|
||||
expect_eol_block p
|
||||
~after:(match parent with Some (_, pt) -> text_of pt | None -> w ^ " " ^ text_of name);
|
||||
let after =
|
||||
match parent, inline with
|
||||
| Some (_, pt), _ -> text_of pt
|
||||
| None, Some _ -> ")"
|
||||
| None, None -> w ^ " " ^ text_of name
|
||||
in
|
||||
let fields =
|
||||
match inline with
|
||||
| Some fs -> expect_eol p ~after; fs
|
||||
| None ->
|
||||
expect_eol_block p ~after;
|
||||
lines s (fun () ->
|
||||
let f = name_tok p ~what:"a field's name" in
|
||||
let tf =
|
||||
|
||||
@ -290,7 +290,10 @@ Each item: the proposal, then the reason in one line.
|
||||
syntaxes (section 3, item 8). A condition names its parent after the name,
|
||||
`struct DiskFull :parent IoError` with its field lines, reading
|
||||
`(defstruct DiskFull :parent IoError [free i64])`; with no field lines it
|
||||
reads `(defstruct IoError :parent Error)`. **Built.**
|
||||
reads `(defstruct IoError :parent Error)`. A struct or union fits on one
|
||||
line with its fields in parentheses, `struct Pt(x: i32, y: i32)` or
|
||||
`struct DiskFull(free: i64) :parent IoError`; `flan convert` writes that
|
||||
when it fits the line and no comment sits among the fields. **Built.**
|
||||
- `type Row = Vec(i32)` reads `(defalias Row (Vec i32))`. **Built.**
|
||||
- `macro repeat(i, n, & body)` plus a block reads
|
||||
`(defmacro repeat [i n & body] …)`. A parameter is a bare name, a
|
||||
|
||||
@ -6,9 +6,7 @@ struct Overdraft :parent Error
|
||||
account: i32
|
||||
short: i64
|
||||
|
||||
struct Audit
|
||||
account: i32
|
||||
amount: i64
|
||||
struct Audit(account: i32, amount: i64)
|
||||
|
||||
once balances: [4 i64]
|
||||
once audits: i32
|
||||
|
||||
@ -563,6 +563,12 @@ let () =
|
||||
"handler-case\n g()\non E(c)\n h(c)\non = 2"
|
||||
"(handler-case (g) [(E [c] (h c))])\n(set on 2)";
|
||||
reads "an else assigned after an if" "if a\n b\nelse = 2" "(when a b)\n(set else 2)";
|
||||
reads "a one-line struct" "struct Pt(x: i32, y)" "(defstruct Pt [x i32 y dyn])";
|
||||
reads "a one-line union" "union U(a: i32)" "(defunion U [a i32])";
|
||||
reads "a one-line struct with a parent" "struct D(free: i64) :parent Io"
|
||||
"(defstruct D :parent Io [free i64])";
|
||||
refuses "a one-line struct takes no block" "struct Pt(x: i32)\n y: i32" "indent/stray-indent"
|
||||
"takes no block";
|
||||
reads "a parent and no fields" "struct Io :parent Error" "(defstruct Io :parent Error)";
|
||||
reads "macro" "macro repeat(i, n, & body)\n quote\n f(~i)\n ~@body"
|
||||
"(defmacro repeat [i n & body] (quasiquote (do (f (unquote i)) (unquote-splicing body))))";
|
||||
@ -836,7 +842,14 @@ let () =
|
||||
"(defn f [] () (set data 3) (set loop 4) (set on 5))" " data = 3\n loop = 4\n on = 5";
|
||||
prints "a type alias" "(defalias Row (Vec i32))" "type Row = Vec(i32)";
|
||||
prints "a struct with a parent" "(defstruct D :parent Io [free i64])"
|
||||
"struct D :parent Io\n free: i64";
|
||||
"struct D(free: i64) :parent Io";
|
||||
prints "a struct on one line" "(defstruct Pt [x i32 y dyn])" "struct Pt(x: i32, y)\n";
|
||||
prints "a union too" "(defunion U [a i32 b f32])" "union U(a: i32, b: f32)";
|
||||
prints "a struct too long for a line takes a line per field"
|
||||
("(defstruct W [" ^ String.concat " " (List.init 8 (Printf.sprintf "field-number-%d i32")) ^ "])")
|
||||
"struct W\n field-number-0: i32\n";
|
||||
prints "and so does one with a comment among its fields"
|
||||
"(defstruct C [a i32 ; first\n b i32])" "struct C\n a: i32 ; first\n b: i32";
|
||||
prints "a parent with no fields" "(defstruct D :parent Io)" "struct D :parent Io";
|
||||
prints "an empty field vector under a parent keeps the fallback"
|
||||
"(defstruct D :parent Io [])" "defstruct(D, :parent, Io, [])";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user