Skip to content

Commit bc477fa

Browse files
refactor: remove custom NodeUnderCursor
1 parent 6e72b72 commit bc477fa

File tree

2 files changed

+79
-174
lines changed

2 files changed

+79
-174
lines changed

crates/pgt_completions/src/relevance/filtering.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use pgt_schema_cache::ProcKind;
2-
use pgt_treesitter::context::{NodeUnderCursor, TreesitterContext, WrappingClause, WrappingNode};
2+
use pgt_treesitter::context::{TreesitterContext, WrappingClause, WrappingNode};
33

44
use super::CompletionRelevanceData;
55

@@ -67,23 +67,20 @@ impl CompletionFilter<'_> {
6767
}
6868

6969
// No autocompletions if there are two identifiers without a separator.
70-
if ctx.node_under_cursor.as_ref().is_some_and(|n| match n {
71-
NodeUnderCursor::TsNode(node) => node.prev_sibling().is_some_and(|p| {
70+
if ctx.node_under_cursor.as_ref().is_some_and(|node| {
71+
node.prev_sibling().is_some_and(|p| {
7272
(p.kind() == "identifier" || p.kind() == "object_reference")
73-
&& n.kind() == "identifier"
74-
}),
75-
NodeUnderCursor::CustomNode { .. } => false,
73+
&& node.kind() == "identifier"
74+
})
7675
}) {
7776
return None;
7877
}
7978

8079
// no completions if we're right after an asterisk:
8180
// `select * {}`
82-
if ctx.node_under_cursor.as_ref().is_some_and(|n| match n {
83-
NodeUnderCursor::TsNode(node) => node
84-
.prev_sibling()
85-
.is_some_and(|p| (p.kind() == "all_fields") && n.kind() == "identifier"),
86-
NodeUnderCursor::CustomNode { .. } => false,
81+
if ctx.node_under_cursor.as_ref().is_some_and(|node| {
82+
node.prev_sibling()
83+
.is_some_and(|p| (p.kind() == "all_fields") && node.kind() == "identifier")
8784
}) {
8885
return None;
8986
}

crates/pgt_treesitter/src/context/mod.rs

Lines changed: 71 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
};
55

66
use crate::queries::{self, QueryResult, TreeSitterQueriesExecutor};
7-
use pgt_text_size::{TextRange, TextSize};
7+
use pgt_text_size::TextSize;
88

99
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1010
pub enum WrappingClause<'a> {
@@ -57,45 +57,6 @@ pub enum WrappingNode {
5757
List,
5858
}
5959

60-
#[derive(Debug)]
61-
pub enum NodeUnderCursor<'a> {
62-
TsNode(tree_sitter::Node<'a>),
63-
CustomNode {
64-
text: String,
65-
range: TextRange,
66-
kind: String,
67-
previous_node_kind: Option<String>,
68-
},
69-
}
70-
71-
impl NodeUnderCursor<'_> {
72-
pub fn start_byte(&self) -> usize {
73-
match self {
74-
NodeUnderCursor::TsNode(node) => node.start_byte(),
75-
NodeUnderCursor::CustomNode { range, .. } => range.start().into(),
76-
}
77-
}
78-
79-
pub fn end_byte(&self) -> usize {
80-
match self {
81-
NodeUnderCursor::TsNode(node) => node.end_byte(),
82-
NodeUnderCursor::CustomNode { range, .. } => range.end().into(),
83-
}
84-
}
85-
86-
pub fn kind(&self) -> &str {
87-
match self {
88-
NodeUnderCursor::TsNode(node) => node.kind(),
89-
NodeUnderCursor::CustomNode { kind, .. } => kind.as_str(),
90-
}
91-
}
92-
}
93-
94-
impl<'a> From<tree_sitter::Node<'a>> for NodeUnderCursor<'a> {
95-
fn from(node: tree_sitter::Node<'a>) -> Self {
96-
NodeUnderCursor::TsNode(node)
97-
}
98-
}
9960

10061
impl TryFrom<&str> for WrappingNode {
10162
type Error = String;
@@ -135,7 +96,7 @@ pub struct TreeSitterContextParams<'a> {
13596

13697
#[derive(Debug)]
13798
pub struct TreesitterContext<'a> {
138-
pub node_under_cursor: Option<NodeUnderCursor<'a>>,
99+
pub node_under_cursor: Option<tree_sitter::Node<'a>>,
139100

140101
pub tree: &'a tree_sitter::Tree,
141102
pub text: &'a str,
@@ -284,10 +245,9 @@ impl<'a> TreesitterContext<'a> {
284245
}
285246

286247
pub fn get_node_under_cursor_content(&self) -> Option<String> {
287-
match self.node_under_cursor.as_ref()? {
288-
NodeUnderCursor::TsNode(node) => self.get_ts_node_content(node),
289-
NodeUnderCursor::CustomNode { text, .. } => Some(text.clone()),
290-
}
248+
self.node_under_cursor
249+
.as_ref()
250+
.and_then(|node| self.get_ts_node_content(node))
291251
}
292252

293253
fn gather_tree_context(&mut self) {
@@ -339,7 +299,7 @@ impl<'a> TreesitterContext<'a> {
339299
// prevent infinite recursion – this can happen with ERROR nodes
340300
if current_node_kind == parent_node_kind && ["ERROR", "program"].contains(&parent_node_kind)
341301
{
342-
self.node_under_cursor = Some(NodeUnderCursor::from(current_node));
302+
self.node_under_cursor = Some(current_node);
343303
return;
344304
}
345305

@@ -408,7 +368,7 @@ impl<'a> TreesitterContext<'a> {
408368
if current_node.child_count() == 0
409369
|| current_node.first_child_for_byte(self.position).is_none()
410370
{
411-
self.node_under_cursor = Some(NodeUnderCursor::from(current_node));
371+
self.node_under_cursor = Some(current_node);
412372
return;
413373
}
414374

@@ -644,27 +604,17 @@ impl<'a> TreesitterContext<'a> {
644604
}
645605

646606
pub fn before_cursor_matches_kind(&self, kinds: &[&'static str]) -> bool {
647-
self.node_under_cursor.as_ref().is_some_and(|under_cursor| {
648-
match under_cursor {
649-
NodeUnderCursor::TsNode(node) => {
650-
let mut current = *node;
651-
652-
// move up to the parent until we're at top OR we have a prev sibling
653-
while current.prev_sibling().is_none() && current.parent().is_some() {
654-
current = current.parent().unwrap();
655-
}
656-
657-
current
658-
.prev_sibling()
659-
.is_some_and(|sib| kinds.contains(&sib.kind()))
660-
}
607+
self.node_under_cursor.as_ref().is_some_and(|node| {
608+
let mut current = *node;
661609

662-
NodeUnderCursor::CustomNode {
663-
previous_node_kind, ..
664-
} => previous_node_kind
665-
.as_ref()
666-
.is_some_and(|k| kinds.contains(&k.as_str())),
610+
// move up to the parent until we're at top OR we have a prev sibling
611+
while current.prev_sibling().is_none() && current.parent().is_some() {
612+
current = current.parent().unwrap();
667613
}
614+
615+
current
616+
.prev_sibling()
617+
.is_some_and(|sib| kinds.contains(&sib.kind()))
668618
})
669619
}
670620

@@ -674,25 +624,20 @@ impl<'a> TreesitterContext<'a> {
674624
/// If the tree shows `relation > object_reference > identifier` and the "identifier" is a leaf node,
675625
/// you need to pass `&["relation", "object_reference"]`.
676626
pub fn matches_ancestor_history(&self, expected_ancestors: &[&'static str]) -> bool {
677-
self.node_under_cursor
678-
.as_ref()
679-
.is_some_and(|under_cursor| match under_cursor {
680-
NodeUnderCursor::TsNode(node) => {
681-
let mut current = Some(*node);
627+
self.node_under_cursor.as_ref().is_some_and(|node| {
628+
let mut current = Some(*node);
682629

683-
for &expected_kind in expected_ancestors.iter().rev() {
684-
current = current.and_then(|n| n.parent());
685-
686-
match current {
687-
Some(ancestor) if ancestor.kind() == expected_kind => continue,
688-
_ => return false,
689-
}
690-
}
630+
for &expected_kind in expected_ancestors.iter().rev() {
631+
current = current.and_then(|n| n.parent());
691632

692-
true
633+
match current {
634+
Some(ancestor) if ancestor.kind() == expected_kind => continue,
635+
_ => return false,
693636
}
694-
NodeUnderCursor::CustomNode { .. } => false,
695-
})
637+
}
638+
639+
true
640+
})
696641
}
697642

698643
/// Verifies whether the node_under_cursor has the passed in ancestors in the right order.
@@ -703,12 +648,7 @@ impl<'a> TreesitterContext<'a> {
703648
pub fn matches_one_of_ancestors(&self, expected_ancestors: &[&'static str]) -> bool {
704649
self.node_under_cursor
705650
.as_ref()
706-
.is_some_and(|under_cursor| match under_cursor {
707-
NodeUnderCursor::TsNode(node) => node
708-
.parent()
709-
.is_some_and(|p| expected_ancestors.contains(&p.kind())),
710-
NodeUnderCursor::CustomNode { .. } => false,
711-
})
651+
.is_some_and(|node| node.parent().is_some_and(|p| expected_ancestors.contains(&p.kind())))
712652
}
713653

714654
/// Checks whether the Node under the cursor is the nth child of the parent.
@@ -735,32 +675,24 @@ impl<'a> TreesitterContext<'a> {
735675
/// }
736676
/// ```
737677
pub fn node_under_cursor_is_nth_child(&self, nth: usize) -> bool {
738-
self.node_under_cursor
739-
.as_ref()
740-
.is_some_and(|under_cursor| match under_cursor {
741-
NodeUnderCursor::TsNode(node) => {
742-
let mut cursor = node.walk();
743-
node.parent().is_some_and(|p| {
744-
p.children(&mut cursor)
745-
.nth(nth - 1)
746-
.is_some_and(|n| n.id() == node.id())
747-
})
748-
}
749-
NodeUnderCursor::CustomNode { .. } => false,
678+
self.node_under_cursor.as_ref().is_some_and(|node| {
679+
let mut cursor = node.walk();
680+
node.parent().is_some_and(|p| {
681+
p.children(&mut cursor)
682+
.nth(nth - 1)
683+
.is_some_and(|n| n.id() == node.id())
750684
})
685+
})
751686
}
752687

753688
/// Returns the number of siblings of the node under the cursor.
754689
pub fn num_siblings(&self) -> usize {
755690
self.node_under_cursor
756691
.as_ref()
757-
.map(|n| match n {
758-
NodeUnderCursor::TsNode(node) => {
759-
// if there's no parent, we're on the top of the tree,
760-
// where we have 0 siblings.
761-
node.parent().map(|p| p.child_count() - 1).unwrap_or(0)
762-
}
763-
NodeUnderCursor::CustomNode { .. } => 0,
692+
.map(|node| {
693+
// if there's no parent, we're on the top of the tree,
694+
// where we have 0 siblings.
695+
node.parent().map(|p| p.child_count() - 1).unwrap_or(0)
764696
})
765697
.unwrap_or(0)
766698
}
@@ -769,34 +701,31 @@ impl<'a> TreesitterContext<'a> {
769701
pub fn node_under_cursor_is_within_field_name(&self, name: &str) -> bool {
770702
self.node_under_cursor
771703
.as_ref()
772-
.map(|n| match n {
773-
NodeUnderCursor::TsNode(node) => {
774-
// It might seem weird that we have to check for the field_name from the parent,
775-
// but TreeSitter wants it this way, since nodes often can only be named in
776-
// the context of their parents.
777-
let root_node = self.tree.root_node();
778-
let mut cursor = node.walk();
779-
let mut parent = node.parent();
780-
781-
while let Some(p) = parent {
782-
if p == root_node {
783-
break;
784-
}
785-
786-
if p.children_by_field_name(name, &mut cursor).any(|c| {
787-
let r = c.range();
788-
// if the parent range contains the node range, the node is of the field_name.
789-
r.start_byte <= node.start_byte() && r.end_byte >= node.end_byte()
790-
}) {
791-
return true;
792-
} else {
793-
parent = p.parent();
794-
}
704+
.map(|node| {
705+
// It might seem weird that we have to check for the field_name from the parent,
706+
// but TreeSitter wants it this way, since nodes often can only be named in
707+
// the context of their parents.
708+
let root_node = self.tree.root_node();
709+
let mut cursor = node.walk();
710+
let mut parent = node.parent();
711+
712+
while let Some(p) = parent {
713+
if p == root_node {
714+
break;
795715
}
796716

797-
false
717+
if p.children_by_field_name(name, &mut cursor).any(|c| {
718+
let r = c.range();
719+
// if the parent range contains the node range, the node is of the field_name.
720+
r.start_byte <= node.start_byte() && r.end_byte >= node.end_byte()
721+
}) {
722+
return true;
723+
} else {
724+
parent = p.parent();
725+
}
798726
}
799-
NodeUnderCursor::CustomNode { .. } => false,
727+
728+
false
800729
})
801730
.unwrap_or(false)
802731
}
@@ -858,7 +787,6 @@ mod tests {
858787

859788
use pgt_test_utils::QueryWithCursorPosition;
860789

861-
use super::NodeUnderCursor;
862790

863791
fn get_tree(input: &str) -> tree_sitter::Tree {
864792
let mut parser = tree_sitter::Parser::new();
@@ -1091,17 +1019,12 @@ mod tests {
10911019

10921020
let node = ctx.node_under_cursor.as_ref().unwrap();
10931021

1094-
match node {
1095-
NodeUnderCursor::TsNode(node) => {
1096-
assert_eq!(ctx.get_ts_node_content(node), Some("select".into()));
1022+
assert_eq!(ctx.get_ts_node_content(node), Some("select".into()));
10971023

1098-
assert_eq!(
1099-
ctx.wrapping_clause_type,
1100-
Some(crate::context::WrappingClause::Select)
1101-
);
1102-
}
1103-
_ => unreachable!(),
1104-
}
1024+
assert_eq!(
1025+
ctx.wrapping_clause_type,
1026+
Some(crate::context::WrappingClause::Select)
1027+
);
11051028
}
11061029
}
11071030

@@ -1126,12 +1049,7 @@ mod tests {
11261049

11271050
let node = ctx.node_under_cursor.as_ref().unwrap();
11281051

1129-
match node {
1130-
NodeUnderCursor::TsNode(node) => {
1131-
assert_eq!(ctx.get_ts_node_content(node), Some("from".into()));
1132-
}
1133-
_ => unreachable!(),
1134-
}
1052+
assert_eq!(ctx.get_ts_node_content(node), Some("from".into()));
11351053
}
11361054

11371055
#[test]
@@ -1152,13 +1070,8 @@ mod tests {
11521070

11531071
let node = ctx.node_under_cursor.as_ref().unwrap();
11541072

1155-
match node {
1156-
NodeUnderCursor::TsNode(node) => {
1157-
assert_eq!(ctx.get_ts_node_content(node), Some("".into()));
1158-
assert_eq!(ctx.wrapping_clause_type, None);
1159-
}
1160-
_ => unreachable!(),
1161-
}
1073+
assert_eq!(ctx.get_ts_node_content(node), Some("".into()));
1074+
assert_eq!(ctx.wrapping_clause_type, None);
11621075
}
11631076

11641077
#[test]
@@ -1181,13 +1094,8 @@ mod tests {
11811094

11821095
let node = ctx.node_under_cursor.as_ref().unwrap();
11831096

1184-
match node {
1185-
NodeUnderCursor::TsNode(node) => {
1186-
assert_eq!(ctx.get_ts_node_content(node), Some("fro".into()));
1187-
assert_eq!(ctx.wrapping_clause_type, Some(WrappingClause::Select));
1188-
}
1189-
_ => unreachable!(),
1190-
}
1097+
assert_eq!(ctx.get_ts_node_content(node), Some("fro".into()));
1098+
assert_eq!(ctx.wrapping_clause_type, Some(WrappingClause::Select));
11911099
}
11921100

11931101
#[test]

0 commit comments

Comments
 (0)