Skip to content

Commit

Permalink
auto newlines for case and let
Browse files Browse the repository at this point in the history
  • Loading branch information
dm0n3y committed Sep 9, 2024
1 parent 0bfd6e6 commit 0a78a78
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 51 deletions.
28 changes: 14 additions & 14 deletions src/core/grammar/Padding.re
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@ open Ppx_yojson_conv_lib.Yojson_conv.Primitives;
// specifies preferred whitespace padding around a token
[@deriving (show({with_path: false}), sexp, yojson, ord)]
type t = {
// whether to pad token with spaces in horizontal layout
h: (bool, bool),
// whether to pad token with newlines in vertical layout
// whether to pad token with space in horizontal layout
// (generally (true, true) but eg (false, true) for commas)
v: (bool, bool),
// whether to indent contents of the following cell
space: (bool, bool),
// whether vertical layout should be preferred on either side
break: (bool, bool),
// whether to indent contents of the following cell in vertical layout
indent: bool,
};

let none = {h: (false, false), v: (false, false), indent: false};
let none = {space: (false, false), break: (false, false), indent: false};

let kw = (~l=true, ~r=true, ~indent=true, ()) => {
h: (l, r),
v: (l, r),
let kw = (~space=(true, true), ~break=(false, false), ~indent=true, ()) => {
space,
break,
indent,
};
let op = (~l=true, ~r=true, ~indent=true, ()) => {
h: (l, r),
v: (l, r),
let op = (~space=(true, true), ~break=(false, false), ~indent=true, ()) => {
space,
break,
indent,
};
let brc = (side: Dir.t) => {
h: (false, false),
v: Dir.pick(side, ((false, true), (true, false))),
space: (false, false),
break: (false, false),
indent: Dir.pick(side, (true, false)),
};
2 changes: 1 addition & 1 deletion src/core/material/Grout.re
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module T = {
let in_ = s => (s, Tip.(Conc, Conc));
let padding = ((_, (l, r)): t) => {
let (l, r) = Tip.(is_conc(l), is_conc(r));
Padding.op(~l, ~r, ~indent=r, ());
Padding.op(~space=(l, r), ~indent=r, ());
};
let all = s => [op(s), pre(s), pos(s), in_(s)];
};
Expand Down
25 changes: 15 additions & 10 deletions src/core/parser/Linter.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
let pad_wrap = (c: Cell.t) => {
let w = Wald.of_tok(Token.mk(~text=" ", Mtrl.Space(White(Sys))));
let pad_wrap = (~break=false, c: Cell.t) => {
let text = break ? "\n" : " ";
let w = Wald.of_tok(Token.mk(~text, Mtrl.Space(White(Sys))));
let m = {
// this choice only matters when c has caret
let (l, r) = Meld.(mk(~l=c, w), mk(w, ~r=c));
Expand All @@ -11,7 +12,7 @@ let pad_wrap = (c: Cell.t) => {
| Navigating => l
};
};
// let m = pad_r ? Meld.mk(~l=c, w) : Meld.mk(w, ~r=c);
// let m = spc_r ? Meld.mk(~l=c, w) : Meld.mk(w, ~r=c);
// let m = Meld.mk(~l=c, w);
Cell.put(m);
};
Expand All @@ -33,19 +34,23 @@ let rec repad = (~l=Delim.root, ~r=Delim.root, c: Cell.t) => {
|> Cell.put;
| Some(_) when Cell.has_clean_cursor(c) => Cell.mark_clean(c)
| Some(_) =>
let (_, pad_l) = Delim.padding(l).h;
let (pad_r, _) = Delim.padding(r).h;
let (_, spc_l) = Delim.padding(l).space;
let (_, brk_l) = Delim.padding(l).break;
let (spc_r, _) = Delim.padding(r).space;
let (brk_r, _) = Delim.padding(r).break;
let no_pad = !(spc_l || spc_r || brk_l || brk_r);
let break = brk_l || brk_r;
switch (Cell.get(c)) {
| None when !pad_l && !pad_r => c
| None => pad_wrap(c)
| None when no_pad => c
| None => pad_wrap(~break, c)
| Some(m) =>
let pruned =
Meld.to_chain(m)
|> Chain.fold_right(
(c, tok: Token.t, acc) => {
let found_space = Result.is_ok(Chain.unlink(acc));
switch (tok.mtrl) {
| Space(White(Sys)) when found_space || !pad_l && !pad_r =>
| Space(White(Sys)) when found_space || no_pad =>
Chain.map_hd(Cell.Space.merge(c, ~fill=Cell.empty), acc)
| _ => Chain.link(c, tok, acc)
};
Expand All @@ -54,8 +59,8 @@ let rec repad = (~l=Delim.root, ~r=Delim.root, c: Cell.t) => {
);
switch (Chain.unlink(pruned)) {
| Ok(_) => Cell.put(Meld.of_chain(pruned))
| Error(c) when !pad_l && !pad_r => c
| Error(c) => pad_wrap(c)
| Error(c) when no_pad => c
| Error(c) => pad_wrap(~break, c)
};
};
};
Expand Down
63 changes: 37 additions & 26 deletions src/hazel/Grammar.re
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ let t = (lbl: Label.t) => Regex.atom(Sym.t(lbl));
let nt = (srt: Sort.t) => Regex.atom(Sym.nt(srt));

let c = (~p=Padding.none, s) => t(Label.const(~padding=p, s));
let kw = (~l=true, ~r=true, ~indent=true) =>
c(~p=Padding.kw(~l, ~r, ~indent, ()));
let op = (~l=true, ~r=true, ~indent=true) =>
c(~p=Padding.op(~l, ~r, ~indent, ()));
let kw = (~space=(true, true), ~break=(false, false), ~indent=true) =>
c(~p=Padding.kw(~space, ~break, ~indent, ()));
let op = (~space=(true, true), ~break=(false, false), ~indent=true) =>
c(~p=Padding.op(~space, ~break, ~indent, ()));
let brc = (side: Dir.t) => c(~p=Padding.brc(side));

let comma = op(~space=(false, true), ",");
let comma_sep = atom => seq([atom, Star(seq([comma, atom]))]);

module Typ = {
let sort = Sort.of_str("Typ");
let typ = nt(sort);

let comma_sep = seq([typ, Star(seq([op(~l=false, ","), typ]))]);

let operand =
alt([
c("Int"),
Expand All @@ -36,7 +37,7 @@ module Typ = {
//List type
seq([c("list"), brc(L, "("), typ, brc(R, ")")]),
//Tuple type
seq([brc(L, "("), comma_sep, brc(R, ")")]),
seq([brc(L, "("), comma_sep(typ), brc(R, ")")]),
]);

let tbl = [
Expand All @@ -53,8 +54,6 @@ module Pat = {
let sort = Sort.of_str("Pat");
let pat = nt(sort);

let comma_sep = seq([pat, Star(seq([op(~l=false, ","), pat]))]);

let bool_lit = alt([c("true"), c("false")]);
let operand =
alt([
Expand All @@ -64,8 +63,8 @@ module Pat = {
bool_lit,
//Constructor
t(Id_upper),
seq([brc(L, "("), comma_sep, brc(R, ")")]),
seq([brc(L, "["), comma_sep, brc(R, "]")]),
seq([brc(L, "("), comma_sep(pat), brc(R, ")")]),
seq([brc(L, "["), comma_sep(pat), brc(R, "]")]),
//Wild
c("_"),
]);
Expand All @@ -85,20 +84,30 @@ module Exp = {
let sort = Sort.of_str("Exp");
let exp = nt(sort);

[@warning "-32"]
let comma_sep = seq([exp, Star(seq([op(~l=false, ","), exp]))]);

let rul = seq([op("|"), nt(Pat.sort), op("=>"), exp]);
let bool_lit = alt([c("true"), c("false")]);

let rul =
seq([op(~break=(true, false), "|"), nt(Pat.sort), op("=>"), exp]);
let case = seq([kw(~space=(false, true), "case"), exp, rul, star(rul)]);

let let_ =
seq([
kw("let", ~space=(false, true)),
nt(Pat.sort),
op("="),
exp,
kw("in", ~break=(false, true), ~indent=false),
exp,
]);

let operand =
alt([
t(Int_lit),
t(Float_lit),
t(Id_lower),
bool_lit,
seq([brc(L, "("), comma_sep, brc(R, ")")]),
seq([brc(L, "["), comma_sep, brc(R, "]")]),
seq([brc(L, "("), comma_sep(exp), brc(R, ")")]),
seq([brc(L, "["), comma_sep(exp), brc(R, "]")]),
]);

let op_alt = ss => alt(List.map(op, ss));
Expand All @@ -108,22 +117,24 @@ module Exp = {

let tbl = [
//case
p(seq([kw(~l=false, "case"), exp, rul, star(rul)])),
p(case),
//let
p(let_),
//fun
p(
seq([kw(~space=(false, true), "fun"), nt(Pat.sort), op("->"), exp]),
),
//if
p(
seq([
kw(~l=false, "let"),
nt(Pat.sort),
op("="),
kw(~space=(false, true), "if"),
exp,
kw("in", ~indent=false),
kw("then"),
exp,
kw("else"),
exp,
]),
),
//fun
p(seq([kw(~l=false, "fun"), nt(Pat.sort), op("->"), exp])),
//if
p(seq([kw(~l=false, "if"), exp, kw("then"), exp, kw("else"), exp])),
//Math operations
p(~a=L, seq([exp, add_op, exp])),
p(~a=L, seq([exp, mult_op, exp])),
Expand Down

0 comments on commit 0a78a78

Please sign in to comment.