Skip to content

Commit

Permalink
refactor Location
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpombrio committed Mar 20, 2024
1 parent 8db6ea6 commit 8b26474
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 35 deletions.
53 changes: 45 additions & 8 deletions src/language/location.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,58 @@
use super::node::Node;
use super::storage::Storage;

// TODO: rejigger the Location type, and maybe move it
/// A location between nodes, or within text, where a cursor could go.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Location {
InText(Node, usize),
After(Node),
BeforeFirstChild(Node),
InText {
node: Node,
/// Between characters, so it can be equal to the len
char_pos: usize,
},
InTree {
parent: Option<Node>,
left: Option<Node>,
right: Option<Node>,
},
}

impl Location {
pub fn cursor_halves(self, s: &Storage) -> (Option<Node>, Option<Node>) {
pub fn left(self) -> Option<Node> {
match self {
Location::InText(..) => (None, None),
Location::After(left_sibling) => (Some(left_sibling), left_sibling.next_sibling(s)),
Location::BeforeFirstChild(parent) => (None, parent.first_child(s)),
Location::InText { .. } => None,
Location::InTree { left, .. } => left,
}
}

pub fn right(self) -> Option<Node> {
match self {
Location::InText { .. } => None,
Location::InTree { left, .. } => left,
}
}

pub fn parent(self) -> Option<Node> {
match self {
Location::InText { .. } => None,
Location::InTree { parent, .. } => parent,
}
}
}

impl Node {
pub fn loc_before(self, s: &Storage) -> Location {
Location::InTree {
parent: self.parent(s),
left: self.prev_sibling(s),
right: Some(self),
}
}

pub fn loc_after(self, s: &Storage) -> Location {
Location::InTree {
parent: self.parent(s),
left: Some(self),
right: self.next_sibling(s),
}
}
}
35 changes: 11 additions & 24 deletions src/pretty_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,16 @@ fn get_text_notation() -> &'static ValidNotation {
#[derive(Clone, Copy)]
pub struct DocRef<'d> {
storage: &'d Storage,
cursor_pos: Location,
left_cursor: Option<Node>,
right_cursor: Option<Node>,
cursor_loc: Location,
node: Node,
text_pos: Option<CursorHalf>,
}

impl<'d> DocRef<'d> {
pub fn new(storage: &'d Storage, cursor_pos: Location, node: Node) -> DocRef<'d> {
let (left_cursor, right_cursor) = cursor_pos.cursor_halves(storage);
pub fn new(storage: &'d Storage, cursor_loc: Location, node: Node) -> DocRef<'d> {
DocRef {
storage,
cursor_pos,
left_cursor,
right_cursor,
cursor_loc,
node,
text_pos: None,
}
Expand All @@ -45,9 +40,9 @@ impl<'d> DocRef<'d> {

/// Char index to split this node's text at
fn text_index(&self) -> usize {
if let Location::InText(node, i) = self.cursor_pos {
if let Location::InText { node, char_pos } = self.cursor_loc {
if node == self.node {
i
char_pos
} else {
0
}
Expand Down Expand Up @@ -107,23 +102,15 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> {
match style_label {
StyleLabel::Hole => HOLE_STYLE,
StyleLabel::Open => {
if self.cursor_pos == Location::BeforeFirstChild(self.node) {
if self.cursor_loc.parent() == Some(self.node) && self.cursor_loc.left().is_none() {
LEFT_CURSOR_STYLE
} else {
Style::default()
}
}
StyleLabel::Close => {
let at_end = match self.cursor_pos {
Location::InText(..) => todo!(),
Location::BeforeFirstChild(parent) => {
parent == self.node && self.node.first_child(self.storage).is_none()
}
Location::After(sibling) => self.node.last_child(self.storage) == Some(sibling),
};
// TODO: perhaps rewrite as:
// if self.node.gap_after_children(self.storage) == self.cursor_pos
if at_end {
if self.cursor_loc.parent() == Some(self.node) && self.cursor_loc.right().is_none()
{
RIGHT_CURSOR_STYLE
} else {
Style::default()
Expand Down Expand Up @@ -151,9 +138,9 @@ impl<'d> ppp::PrettyDoc<'d> for DocRef<'d> {
fn node_style(self) -> Style {
if self.text_pos.is_some() {
Style::default()
} else if self.left_cursor == Some(self.node) {
} else if self.cursor_loc.left() == Some(self.node) {
LEFT_CURSOR_STYLE
} else if self.right_cursor == Some(self.node) {
} else if self.cursor_loc.right() == Some(self.node) {
RIGHT_CURSOR_STYLE
} else {
Style::default()
Expand Down Expand Up @@ -235,7 +222,7 @@ impl<'d> fmt::Debug for DocRef<'d> {
write!(
f,
"DocRef({:?}, {:?}, {:?})",
self.node, self.cursor_pos, self.text_pos
self.node, self.cursor_loc, self.text_pos
)
}
}
6 changes: 3 additions & 3 deletions tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use partial_pretty_printer as ppp;
use synless::{
AritySpec, ConstructSpec, DocRef, GrammarSpec, LanguageSpec, Location, Node, NotationSetSpec,
SortSpec, Storage,
AritySpec, ConstructSpec, DocRef, GrammarSpec, LanguageSpec, Node, NotationSetSpec, SortSpec,
Storage,
};

// e.g. example.com?p1=v1,p2=v2,p3,p4=v4
Expand Down Expand Up @@ -117,7 +117,7 @@ fn test_doc_ref() {
let params = node_with_children(&mut s, "urllang", "Params", [eq_1, eq_2, done]);
let url = node_with_children(&mut s, "urllang", "Url", [domain, params]);

let doc_ref = DocRef::new(&s, Location::After(url), url);
let doc_ref = DocRef::new(&s, url.loc_after(&s), url);

let actual = match ppp::pretty_print_to_string(doc_ref, 80) {
Ok(actual) => actual,
Expand Down

0 comments on commit 8b26474

Please sign in to comment.