Skip to content

Commit 0701724

Browse files
fix(completions): cursor on dot, other issues
1 parent a5ba9cb commit 0701724

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

crates/pgt_completions/src/sanitization.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::borrow::Cow;
1+
use std::{borrow::Cow, cmp::max};
22

33
use pgt_text_size::TextSize;
44

@@ -24,6 +24,7 @@ where
2424
if cursor_inbetween_nodes(params.tree, params.position)
2525
|| cursor_prepared_to_write_token_after_last_node(params.tree, params.position)
2626
|| cursor_before_semicolon(params.tree, params.position)
27+
|| cursor_on_a_dot(&params.text, params.position)
2728
{
2829
SanitizedCompletionParams::with_adjusted_sql(params)
2930
} else {
@@ -44,12 +45,13 @@ where
4445

4546
let mut sql_iter = params.text.chars();
4647

47-
for idx in 0..cursor_pos + 1 {
48+
let max = max(cursor_pos + 1, params.text.len());
49+
50+
for idx in 0..max {
4851
match sql_iter.next() {
4952
Some(c) => {
5053
if idx == cursor_pos {
5154
sql.push_str(SANITIZED_TOKEN);
52-
sql.push(' ');
5355
}
5456
sql.push(c);
5557
}
@@ -149,6 +151,11 @@ fn cursor_prepared_to_write_token_after_last_node(
149151
cursor_pos == tree.root_node().end_byte() + 1
150152
}
151153

154+
fn cursor_on_a_dot(sql: &str, position: TextSize) -> bool {
155+
let position: usize = position.into();
156+
sql.chars().nth(position - 1).is_some_and(|c| c == '.')
157+
}
158+
152159
fn cursor_before_semicolon(tree: &tree_sitter::Tree, position: TextSize) -> bool {
153160
let mut cursor = tree.walk();
154161
let mut leaf_node = tree.root_node();
@@ -198,7 +205,7 @@ mod tests {
198205
use pgt_text_size::TextSize;
199206

200207
use crate::sanitization::{
201-
cursor_before_semicolon, cursor_inbetween_nodes,
208+
cursor_before_semicolon, cursor_inbetween_nodes, cursor_on_a_dot,
202209
cursor_prepared_to_write_token_after_last_node,
203210
};
204211

@@ -212,7 +219,7 @@ mod tests {
212219
.set_language(tree_sitter_sql::language())
213220
.expect("Error loading sql language");
214221

215-
let mut tree = parser.parse(input, None).unwrap();
222+
let mut tree = parser.parse(input.to_string(), None).unwrap();
216223

217224
// select | from users; <-- just right, one space after select token, one space before from
218225
assert!(cursor_inbetween_nodes(&mut tree, TextSize::new(7)));
@@ -236,7 +243,7 @@ mod tests {
236243
.set_language(tree_sitter_sql::language())
237244
.expect("Error loading sql language");
238245

239-
let mut tree = parser.parse(input, None).unwrap();
246+
let mut tree = parser.parse(input.to_string(), None).unwrap();
240247

241248
// select * from| <-- still on previous token
242249
assert!(!cursor_prepared_to_write_token_after_last_node(
@@ -263,6 +270,20 @@ mod tests {
263270
));
264271
}
265272

273+
#[test]
274+
fn on_a_dot() {
275+
let input = "select * from private.";
276+
277+
// select * from private.| <-- on a dot
278+
assert!(cursor_on_a_dot(&input, TextSize::new(22)));
279+
280+
// select * from private|. <-- before the dot
281+
assert!(!cursor_on_a_dot(&input, TextSize::new(21)));
282+
283+
// select * from private. | <-- too far off the dot
284+
assert!(!cursor_on_a_dot(&input, TextSize::new(23)));
285+
}
286+
266287
#[test]
267288
fn test_cursor_before_semicolon() {
268289
// Idx "13" is the exlusive end of `select * from` (first space after from)
@@ -274,7 +295,7 @@ mod tests {
274295
.set_language(tree_sitter_sql::language())
275296
.expect("Error loading sql language");
276297

277-
let mut tree = parser.parse(input, None).unwrap();
298+
let mut tree = parser.parse(input.to_string(), None).unwrap();
278299

279300
// select * from ;| <-- it's after the statement
280301
assert!(!cursor_before_semicolon(&mut tree, TextSize::new(19)));

0 commit comments

Comments
 (0)