Skip to content

Commit

Permalink
duplicate-token zip logic
Browse files Browse the repository at this point in the history
  • Loading branch information
dm0n3y committed Jul 10, 2024
1 parent 3367c9d commit 7e5d24c
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 176 deletions.
18 changes: 12 additions & 6 deletions src/core/editor/Ctx.re
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ let rec pull = (~from as d: Dir.t, ctx: t): option((Token.t, t)) => {
};
};
};
let try_pull = (~from, ctx) =>
switch (pull(~from, ctx)) {
| None => (None, ctx)
| Some((tok, ctx)) => (Some(tok), ctx)
};

module Tl = {
include Chain.Affix;
Expand Down Expand Up @@ -145,24 +150,25 @@ let push_zigg = (~onto as d: Dir.t, zigg: Zigg.t, ~fill=Cell.empty, ctx: t) => {
map_hd(Frame.Open.cat(rest), ctx);
};

let zip_toks = (~caret=?, ctx: t): option((Meld.t, t)) => {
let zip_toks = (~save_cursor=false, ctx: t): option((Meld.t, t)) => {
let (hd, tl) = uncons(ctx);
Frame.Open.zip_toks(~caret?, hd)
Frame.Open.zip_toks(~save_cursor, hd)
|> Option.map(Tuples.map_snd(hd => cons(hd, tl)));
};

let zip = (~zipped: Cell.t) =>
fold(Frame.Open.zip(~zipped), (zipped, closed, open_) =>
let zip = (~save_cursor, ~zipped: Cell.t) =>
fold(Frame.Open.zip(~zipped, ~save_cursor), (zipped, closed, open_) =>
Frame.Open.zip(open_, ~zipped=Frame.Closed.zip(closed, ~zipped))
);
let zip_step =
(~zipped: Cell.t, ctx: t): option((Rel.t(unit, Dir.t), Cell.t, t)) =>
switch (unlink(ctx)) {
| Error(open_) =>
Frame.Open.zip_step(~zipped, open_)
// todo: review these save_cursor flags
Frame.Open.zip_step(~save_cursor=true, ~zipped, open_)
|> Option.map(((rel, zipped, open_)) => (rel, zipped, unit(open_)))
| Ok((open_, (l, r), ctx)) =>
switch (Frame.Open.zip_step(~zipped, open_)) {
switch (Frame.Open.zip_step(~save_cursor=true, ~zipped, open_)) {
| None => Some((Eq(), Frame.zip_eq(l, zipped, r), ctx))
| Some((rel, zipped, open_)) =>
Some((rel, zipped, link(~open_, (l, r), ctx)))
Expand Down
14 changes: 7 additions & 7 deletions src/core/editor/Frame.re
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ module Open = {
when Option.is_some(Token.zip(Wald.hd(hd_l), Wald.hd(hd_r))) =>
true
| _ => false;
let zip_toks = (~caret=?) =>
let zip_toks = (~save_cursor=false) =>
fun
| (([hd_l, ...tl_l], [hd_r, ...tl_r]): t) =>
Wald.zip_hds(~from=L, hd_l.wald, ~caret?, hd_r.wald)
Wald.zip_hds(~save_cursor, ~from=L, hd_l.wald, hd_r.wald)
|> Option.map(w => (Meld.M(hd_l.cell, w, hd_r.cell), (tl_l, tl_r)))
| _ => None;

let zip_step = (~zipped: Cell.t, (dn, up): t) =>
let zip_step = (~save_cursor, ~zipped: Cell.t, (dn, up): t) =>
switch (dn, up) {
| ([], []) => None
| ([], [hd, ...tl]) =>
Some((Rel.Neq(Dir.L), zip_lt(zipped, hd), (dn, tl)))
| ([hd, ...tl], []) => Some((Neq(R), zip_gt(hd, zipped), (tl, up)))
| ([l, ...dn], [r, ...up])
when Option.is_some(Token.zip(Terr.hd(l), Terr.hd(r))) =>
let caret = Cell.is_caret(zipped);
let w = Option.get(Wald.zip_hds(~from=L, l.wald, ~caret?, r.wald));
let w =
Option.get(Wald.zip_hds(~save_cursor, ~from=L, l.wald, r.wald));
Some((Eq(), Cell.put(M(l.cell, w, r.cell)), (dn, up)));
| ([l, ..._], [r, ...up]) when Melder.lt(l.wald, r.wald) =>
Some((Neq(L), zip_lt(zipped, r), (dn, up)))
Expand All @@ -57,8 +57,8 @@ module Open = {
Some((Eq(), zip_eq(l, zipped, r), (dn, up)));
};

let rec zip = (~zipped: Cell.t, (dn, up): t) =>
switch (zip_step(~zipped, (dn, up))) {
let rec zip = (~save_cursor=false, ~zipped: Cell.t, (dn, up): t) =>
switch (zip_step(~save_cursor, ~zipped, (dn, up))) {
| None => zipped
| Some((_, zipped, rest)) => zip(~zipped, rest)
};
Expand Down
25 changes: 11 additions & 14 deletions src/core/editor/Insert.re
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,24 @@ let rec remold = (~fill=Cell.empty, ctx: Ctx.t): (Cell.t, Ctx.t) => {
};
};

let pull_neighbors = ctx => {
let pull = (from: Dir.t, ctx) =>
switch (Ctx.pull(~from, ctx)) {
| Some((tok, ctx)) when tok.text != "" =>
Effects.remove(tok);
(tok.text, ctx);
| _ => ("", ctx)
};
let (l, ctx) = pull(L, ctx);
let (r, ctx) = pull(R, ctx);
((l, r), ctx);
let relabel = (s: string, ctx: Ctx.t): (list(Token.Unmolded.t), int, Ctx.t) => {
let (l, ctx) = Ctx.try_pull(~from=L, ctx);
let (r, ctx) = Ctx.try_pull(~from=R, ctx);
let l =
l |> Option.map(Token.affix(~side=L)) |> Option.value(~default="");
let r =
r |> Option.map(Token.affix(~side=R)) |> Option.value(~default="");
(Labeler.label(l ++ s ++ r), Stds.Utf8.length(r), ctx);
};

let perform = (s: string, z: Zipper.t) => {
List.iter(Effects.remove, Zipper.Cursor.flatten(z.cur));
let ((l, r), ctx) = pull_neighbors(z.ctx);
let (toks, r, ctx) = relabel(s, z.ctx);
let (cell, ctx) =
Labeler.label(l ++ s ++ r)
toks
|> List.fold_left((ctx, tok) => mold(ctx, tok), ctx)
|> remold(~fill=Cell.point(Focus));
Zipper.unzip(cell, ~ctx)
|> Option.map(Move.hstep_n(- Stds.Utf8.length(r)))
|> Option.map(Move.hstep_n(- r))
|> Option.value(~default=Zipper.mk_unroll(R, cell, ~ctx));
};
31 changes: 1 addition & 30 deletions src/core/editor/Move.re
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,12 @@ let hstep = (d: Dir.t, z: Zipper.t): option(Zipper.t) => {
let+ (tok, ctx) = Ctx.pull(~from=d, z.ctx);
switch (hstep_tok(d, tok)) {
| None => ctx |> Ctx.push(~onto=b, Token.clear_marks(tok))
| Some(tok) =>
// more efficient to push onto z.ctx instead of ctx
z.ctx |> Ctx.push(~onto=d, tok) |> Ctx.push(~onto=b, tok)
| Some(tok) => ctx |> Ctx.push(~onto=d, tok) |> Ctx.push(~onto=b, tok)
};
};
Zipper.(button(mk(ctx)));
};

// let hstep = (d: Dir.t, z: Zipper.t): option(Zipper.t) => {
// open Options.Syntax;
// let b = Dir.toggle(d);
// // print_endline("--- Move.hstep ---");
// // print_endline("z = " ++ Zipper.show(z));
// let+ ctx =
// switch (z.cur) {
// // move to d end of selection
// | Select({range: zigg, _}) =>
// return(Ctx.push_zigg(~onto=b, zigg, z.ctx))
// | Point(_) =>
// let+ (tok, ctx) = Ctx.pull(~from=d, z.ctx);
// // todo: add movement granularity
// switch (Token.pull(~from=b, tok)) {
// | None => Ctx.push(~onto=b, tok, ctx)
// | Some((l, r)) =>
// // print_endline("l = " ++ Token.show(l));
// // print_endline("r = " ++ Token.show(r));
// let (c, tok) = Dir.order(b, (l, r));
// ctx |> Ctx.push(~onto=d, tok) |> Ctx.push(~onto=b, c);
// };
// };
// // print_endline("ctx = " ++ Ctx.show(ctx));
// // print_endline("buttoned = " ++ Zipper.(show(button(mk(ctx)))));
// Zipper.(button(mk(ctx)));
// };

let rec hstep_n = (n: int, z: Zipper.t): Zipper.t => {
let move = (d, z) =>
hstep(d, z) |> Options.get_exn(Invalid_argument("Move.move_n"));
Expand Down
51 changes: 0 additions & 51 deletions src/core/editor/Select.re
Original file line number Diff line number Diff line change
Expand Up @@ -98,57 +98,6 @@ let hstep = (d: Dir.t, z: Zipper.t): option(Zipper.t) => {
};
};

// let hstep = (d: Dir.t, z: Zipper.t): option(Zipper.t) => {
// open Options.Syntax;
// let b = Dir.toggle(d);
// switch (z.cur) {
// | Point(_) =>
// let+ (tok, ctx) = Ctx.pull(~from=d, z.ctx);
// let (tok, ctx) =
// switch (Token.pull(~from=b, tok)) {
// | None => (tok, ctx)
// | Some((l, r)) =>
// let (c, tok) = Dir.order(b, (l, r));
// (c, Ctx.push(~onto=d, tok, ctx));
// };
// Zipper.mk(~cur=Select({focus: d, range: Zigg.of_tok(tok)}), ctx);
// | Select({focus: side, range: zigg}) =>
// if (side == d) {
// let+ (tok, ctx) = Ctx.pull(~from=d, z.ctx);
// let (tok, ctx) =
// switch (Token.pull(~from=b, tok)) {
// | None => (tok, ctx)
// | Some((l, r)) =>
// let (c, tok) = Dir.order(b, (l, r));
// (c, Ctx.push(~onto=d, tok, ctx));
// };
// let zigg = Zigg.grow(~side, tok, zigg);
// Zipper.mk(~cur=Select({focus: d, range: zigg}), ctx);
// } else {
// let (tok, rest) = Zigg.pull(~side=d, zigg);
// let (tok, cur) =
// switch (Token.pull(~from=b, tok), rest) {
// | (None, None) => (tok, Cursor.Point(Caret.focus()))
// | (None, Some(zigg)) => (
// tok,
// Select(Selection.{focus: side, range: zigg}),
// )
// | (Some((l, r)), None) =>
// let (c, tok) = Dir.order(b, (l, r));
// (c, Select({focus: side, range: Zigg.of_tok(tok)}));
// | (Some((l, r)), Some(zigg)) =>
// let (c, tok) = Dir.order(b, (l, r));
// let zigg = Zigg.push_fail(~side, tok, zigg);
// (c, Select({focus: side, range: zigg}));
// };
// Ctx.push(~onto=b, tok, z.ctx)
// |> Zipper.mk(~cur)
// |> Zipper.button
// |> Option.some;
// }
// };
// };

let perform = (a: Action.t, z: Zipper.t): option(Zipper.t) =>
switch (a) {
| Un(d) => Some(unselect(~toward=d, z))
Expand Down
29 changes: 15 additions & 14 deletions src/core/editor/Zipper.re
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Caret = {
[@deriving (show({with_path: false}), sexp, yojson)]
type t = Caret.t(unit);
let mk = hand => mk(hand, ());
let focus = focus();
// let focus = focus();
};
module Selection = {
include Selection;
Expand All @@ -34,7 +34,7 @@ type t = {
ctx: Ctx.t,
};

let mk = (~cur=Cursor.point(Caret.focus), ctx) => {cur, ctx};
let mk = (~cur=Cursor.point(Caret.focus()), ctx) => {cur, ctx};

let unroll = (~ctx=Ctx.empty, side: Dir.t, cell: Cell.t) => {
let f_open =
Expand All @@ -61,24 +61,24 @@ let rec unzip = (~ctx=Ctx.empty, cell: Cell.t) => {
switch (Meld.unzip(step, m)) {
| Loop((pre, cell, suf)) => unzip(~ctx=Ctx.add((pre, suf), ctx), cell)
| Link((pre, tok, suf)) =>
let (l, cur, r) = Options.get_exn(Marks.Invalid, Token.unzip(tok));
let mk = mk(~cur=Cursor.map(Fun.id, Selection.map(Zigg.of_tok), cur));
switch (l, r) {
| (None, None) => failwith("todo")
| (None, Some(r)) =>
let map = Cursor.map(Fun.id, Selection.map(Zigg.of_tok));
switch (Token.unzip(tok)) {
// | (_, None, _) => go_l(Point(Caret.focus), tok)
| (None, _, None) => failwith("todo")
| (None, cur, Some(r)) =>
let (cell, pre) = Chain.uncons(pre);
let suf = Chain.Affix.cons(r, suf);
let ctx = Ctx.add((pre, suf), ctx);
Some(mk(unroll(R, cell, ~ctx)));
| (Some(l), None) =>
Some(mk(~cur=map(cur), unroll(R, cell, ~ctx)));
| (Some(l), cur, None) =>
let pre = Chain.Affix.cons(l, pre);
let (cell, suf) = Chain.uncons(suf);
let ctx = Ctx.add((pre, suf), ctx);
Some(mk(unroll(L, cell, ~ctx)));
| (Some(l), Some(r)) =>
Some(mk(~cur=map(cur), unroll(L, cell, ~ctx)));
| (Some(l), cur, Some(r)) =>
let pre = Chain.Affix.cons(l, pre);
let suf = Chain.Affix.cons(r, suf);
Some(mk(Ctx.add((pre, suf), ctx)));
Some(mk(~cur=map(cur), Ctx.add((pre, suf), ctx)));
};
};
};
Expand Down Expand Up @@ -138,7 +138,7 @@ let rec zip_neighbor = (~side: Dir.t, ~zipped: Cell.t, ctx: Ctx.t) => {
let zip_init = (~save_cursor=false, z: t): (Cell.t, Ctx.t) =>
switch (z.cur) {
| Point(car) =>
switch (Ctx.zip_toks(~caret=?save_cursor ? Some(car.hand) : None, z.ctx)) {
switch (Ctx.zip_toks(~save_cursor, z.ctx)) {
// within token
| Some((m, ctx)) => (Cell.put(m), ctx)
| None =>
Expand Down Expand Up @@ -181,7 +181,8 @@ let zip = (~save_cursor=false, z: t) => {
let fill = save_cursor ? Cell.point(Anchor) : Cell.empty;
Ctx.push_zigg(~onto=Dir.toggle(focus), zigg, ~fill, z.ctx);
};
Ctx.zip(ctx, ~zipped=save_cursor ? Cell.point(Focus) : Cell.empty);
let zipped = save_cursor ? Cell.point(Focus) : Cell.empty;
Ctx.zip(ctx, ~zipped, ~save_cursor);
};

let path_of_ctx = (ctx: Ctx.t) => {
Expand Down
3 changes: 1 addition & 2 deletions src/core/structure/Terr.re
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ let unlink = (terr: t) =>
let zip_hd = (~onto: Dir.t, t: Token.t, terr: t) => {
open Options.Syntax;
let (l, r) = Dir.order(onto, (hd(terr), t));
let+ zipped = Token.zip(l, r);
let+ zipped = Token.zip(~save_cursor=Dir.toggle(onto), l, r);
put_hd(zipped, terr);
};

// module Tl = {
// // a terrace minus its hd token
// type t = Chain.t(Cell.t, Token.t);
Expand Down
Loading

0 comments on commit 7e5d24c

Please sign in to comment.