Skip to content

Commit 04781fe

Browse files
committed
[ty] Fix range calculation in variable binding completions
Previously the cursor position was calculated using the length of the typed token even if the cursor position was in the middle of the token (f<CURSOR>oo). I haven't managed to construct a test based on autocomplete suggestions that would fail because of this but if you test the `is_in_variable_binding` function directly it becomes clear that the previous calculation was not entirely correct.
1 parent 09d457a commit 04781fe

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

crates/ty_ide/src/completion.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,18 @@ fn is_in_definition_place(
13411341
/// E.g. naming a parameter, type parameter, or `for` <name>).
13421342
fn is_in_variable_binding(parsed: &ParsedModuleRef, offset: TextSize, typed: Option<&str>) -> bool {
13431343
let range = if let Some(typed) = typed {
1344-
let start = offset.saturating_sub(typed.text_len());
1344+
let tokens = tokens_start_before(parsed.tokens(), offset);
1345+
// `typed` contains the entire token even if the cursor sits in the
1346+
// middle of it (pa<CURSOR>ram). To correctly suggest completions
1347+
// based on the cursor's current position, we must only consider
1348+
// the characters in the token that are left of the cursor.
1349+
// E.g. we should only count "pa" if the state is "pa<CUSROR>ram".
1350+
let typed_len = typed
1351+
.text_len()
1352+
.min(tokens.last().map_or(typed.text_len(), |token| {
1353+
offset.saturating_sub(token.start())
1354+
}));
1355+
let start = offset.saturating_sub(typed_len);
13451356
TextRange::new(start, offset)
13461357
} else {
13471358
TextRange::empty(offset)

0 commit comments

Comments
 (0)