Skip to content

Commit

Permalink
basic selectability for leaf projectors
Browse files Browse the repository at this point in the history
  • Loading branch information
disconcision committed Apr 30, 2024
1 parent ee16647 commit f4d10f1
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 54 deletions.
6 changes: 2 additions & 4 deletions src/haz3lcore/zipper/action/Move.re
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,9 @@ module Make = (M: Editor.Meta.S) => {
(select an open parens to left of a multichar token and press left) */
| _ when z.selection.content != [] => pop_move(d, z)
| (Left, Outer, (SkipTo(pid), _)) =>
// print_endline("Left Projected");
ProjectorAction.Move.over(Left, pid, z)
ProjectorAction.skip_to(Left, pid, z)
| (Right, Outer, (_, SkipTo(pid))) =>
// print_endline("Right Projected");
ProjectorAction.Move.over(Right, pid, z)
ProjectorAction.skip_to(Right, pid, z)
| (Left, Outer, (CanEnter(dlm, c_max), _)) =>
inner_end(d, dlm, c_max, z)
| (Left, Outer, _) => Zipper.move(d, z)
Expand Down
86 changes: 56 additions & 30 deletions src/haz3lcore/zipper/action/ProjectorAction.re
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,64 @@ let neighbor_is =
(l, r);
};

module Move = {
/* Do move_action until the indicated piece is such that piece_p is true.
If no such piece is found, don't move. */
let rec do_until_sib =
(move: t => option(t), z_pred: Zipper.t => bool, z: t): option(t) =>
z_pred(z)
? Some(z)
: {
let* z = move(z);
do_until_sib(move, z_pred, z);
};

let is_right_of = (pid: Id.t, z) =>
switch (z.relatives.siblings, z.relatives.ancestors) {
| ((_, [r, ..._]), _) => Piece.id(r) == pid
| ((_, []), []) => true // end of program
| ((_, []), _) => false
/* Do move_action until the indicated piece is such that piece_p is true.
If no such piece is found, don't move. */
let rec do_until_sib =
(move: t => option(t), z_pred: Zipper.t => bool, z: t): option(t) =>
z_pred(z)
? Some(z)
: {
let* z = move(z);
do_until_sib(move, z_pred, z);
};

let is_left_of = (pid: Id.t, z) =>
switch (z.relatives.siblings, z.relatives.ancestors) {
| (([_, ..._] as ls, _), _) => Piece.id(ListUtil.last(ls)) == pid
| (([], _), []) => true // beginning of program
| (([], _), _) => false
};
let is_right_of = (pid: Id.t, z) =>
switch (z.relatives.siblings, z.relatives.ancestors) {
| ((_, [r, ..._]), _) => Piece.id(r) == pid
| ((_, []), []) => true // end of program
| ((_, []), _) => false
};

let is_on = (d: Direction.t, pid: Id.t) =>
switch (d) {
| Left => is_left_of(pid)
| Right => is_right_of(pid)
};
let is_left_of = (pid: Id.t, z) =>
switch (z.relatives.siblings, z.relatives.ancestors) {
| (([_, ..._] as ls, _), _) => Piece.id(ListUtil.last(ls)) == pid
| (([], _), []) => true // beginning of program
| (([], _), _) => false
};

let is_on = (d: Direction.t, pid: Id.t) =>
switch (d) {
| Left => is_left_of(pid)
| Right => is_right_of(pid)
};

let skip_to = (d: Direction.t, proj_id, z) => {
// print_endline("ProjectorAction.skip_to");
do_until_sib(
Zipper.move(d),
is_on(d, proj_id),
z,
);
};

//TODO(andrew): relocalize
let primary' = (d: Direction.t, z: Zipper.t): option(Zipper.t) =>
if (z.caret == Outer) {
Zipper.select(d, z);
} else if (d == Left) {
z
|> Zipper.set_caret(Outer)
|> Zipper.move(Right)
|> OptUtil.and_then(Zipper.select(d));
} else {
z |> Zipper.set_caret(Outer) |> Zipper.select(d);
};

let over = (d: Direction.t, proj_id, z) =>
do_until_sib(Zipper.move(d), is_on(d, proj_id), z);
let skip_select_to = (d: Direction.t, proj_id, z) => {
// print_endline("ProjectorAction.skip_to");
do_until_sib(
z => z |> primary'(d),
is_on(d, proj_id),
z,
);
};
14 changes: 13 additions & 1 deletion src/haz3lcore/zipper/action/Select.re
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open OptUtil.Syntax;
module Make = (M: Editor.Meta.S) => {
module Move = Move.Make(M);

let primary = (d: Direction.t, z: Zipper.t): option(Zipper.t) =>
let primary' = (d: Direction.t, z: Zipper.t): option(Zipper.t) =>
if (z.caret == Outer) {
Zipper.select(d, z);
} else if (d == Left) {
Expand All @@ -16,6 +16,18 @@ module Make = (M: Editor.Meta.S) => {
z |> Zipper.set_caret(Outer) |> Zipper.select(d);
};

let primary = (d: Direction.t, z: Zipper.t): option(Zipper.t) => {
let (l_proj, r_proj) =
ProjectorAction.neighbor_is(M.start_map, M.last_map, z);
switch (d, z.caret, (l_proj, r_proj)) {
| (Left, Outer, (Some(id), _)) =>
ProjectorAction.skip_select_to(Left, id, z)
| (Right, Outer, (_, Some(id))) =>
ProjectorAction.skip_select_to(Right, id, z)
| _ => primary'(d, z)
};
};

let vertical = (d: Direction.t, ed: Zipper.t): option(Zipper.t) =>
Move.do_vertical(primary, d, ed);

Expand Down
45 changes: 26 additions & 19 deletions src/haz3lweb/view/Deco.re
Original file line number Diff line number Diff line change
Expand Up @@ -43,27 +43,34 @@ module Deco =
(start_shape: Nib.Shape.t, p: Piece.t)
: (Nib.Shape.t, list(option(shard_data))) => {
let shard_data =
switch (p) {
| Tile(t) => sel_of_tile(~start_shape, t)
| Grout(g) => [
Some(
sel_shard_svg(
~start_shape,
Measured.find_g(~msg="Deco.sel_of_piece", g, M.map),
p,
try(
switch (p) {
| Tile(t) => sel_of_tile(~start_shape, t)
| Grout(g) => [
Some(
sel_shard_svg(
~start_shape,
Measured.find_g(~msg="Deco.sel_of_piece", g, M.map),
p,
),
),
),
]
| Secondary(w) when Secondary.is_linebreak(w) => [None]
| Secondary(w) => [
Some(
sel_shard_svg(
~start_shape,
Measured.find_w(~msg="Deco.sel_of_piece", w, M.map),
p,
]
| Secondary(w) when Secondary.is_linebreak(w) => [None]
| Secondary(w) => [
Some(
sel_shard_svg(
~start_shape,
Measured.find_w(~msg="Deco.sel_of_piece", w, M.map),
p,
),
),
),
]
]
}
) {
| _ =>
//TODO(andrew): relax. this is the case when tiles are missing
//measured info due to being hidden by a projector
[]
};
let start_shape =
switch (Piece.nibs(p)) {
Expand Down

0 comments on commit f4d10f1

Please sign in to comment.