Fix anchor biases for completion replacement ranges (esp slash commands) (#32262)
Closes #32205 The issue was that in some places the end of the replacement range used anchors with `Bias::Left` instead of `Bias::Right`. Before #31872 completions were recomputed on every change and so the anchor bias didn't matter. After that change, the end anchor didn't move as the user's typing. Changing it to `Bias::Right` to "stick" to the character to the right of the cursor fixes this. Release Notes: - Fixes incorrect auto-completion of `/files` in text threads (Preview Only)
This commit is contained in:
parent
51585e770d
commit
e0057ccd0f
4 changed files with 20 additions and 12 deletions
|
@ -765,7 +765,7 @@ impl CompletionProvider for ContextPickerCompletionProvider {
|
||||||
|
|
||||||
let snapshot = buffer.read(cx).snapshot();
|
let snapshot = buffer.read(cx).snapshot();
|
||||||
let source_range = snapshot.anchor_before(state.source_range.start)
|
let source_range = snapshot.anchor_before(state.source_range.start)
|
||||||
..snapshot.anchor_before(state.source_range.end);
|
..snapshot.anchor_after(state.source_range.end);
|
||||||
|
|
||||||
let thread_store = self.thread_store.clone();
|
let thread_store = self.thread_store.clone();
|
||||||
let text_thread_store = self.text_thread_store.clone();
|
let text_thread_store = self.text_thread_store.clone();
|
||||||
|
|
|
@ -238,13 +238,14 @@ impl SlashCommandCompletionProvider {
|
||||||
|
|
||||||
Ok(vec![project::CompletionResponse {
|
Ok(vec![project::CompletionResponse {
|
||||||
completions,
|
completions,
|
||||||
is_incomplete: false,
|
// TODO: Could have slash commands indicate whether their completions are incomplete.
|
||||||
|
is_incomplete: true,
|
||||||
}])
|
}])
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Task::ready(Ok(vec![project::CompletionResponse {
|
Task::ready(Ok(vec![project::CompletionResponse {
|
||||||
completions: Vec::new(),
|
completions: Vec::new(),
|
||||||
is_incomplete: false,
|
is_incomplete: true,
|
||||||
}]))
|
}]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,17 +274,17 @@ impl CompletionProvider for SlashCommandCompletionProvider {
|
||||||
position.row,
|
position.row,
|
||||||
call.arguments.last().map_or(call.name.end, |arg| arg.end) as u32,
|
call.arguments.last().map_or(call.name.end, |arg| arg.end) as u32,
|
||||||
);
|
);
|
||||||
let command_range = buffer.anchor_after(command_range_start)
|
let command_range = buffer.anchor_before(command_range_start)
|
||||||
..buffer.anchor_after(command_range_end);
|
..buffer.anchor_after(command_range_end);
|
||||||
|
|
||||||
let name = line[call.name.clone()].to_string();
|
let name = line[call.name.clone()].to_string();
|
||||||
let (arguments, last_argument_range) = if let Some(argument) = call.arguments.last()
|
let (arguments, last_argument_range) = if let Some(argument) = call.arguments.last()
|
||||||
{
|
{
|
||||||
let last_arg_start =
|
let last_arg_start =
|
||||||
buffer.anchor_after(Point::new(position.row, argument.start as u32));
|
buffer.anchor_before(Point::new(position.row, argument.start as u32));
|
||||||
let first_arg_start = call.arguments.first().expect("we have the last element");
|
let first_arg_start = call.arguments.first().expect("we have the last element");
|
||||||
let first_arg_start =
|
let first_arg_start = buffer
|
||||||
buffer.anchor_after(Point::new(position.row, first_arg_start.start as u32));
|
.anchor_before(Point::new(position.row, first_arg_start.start as u32));
|
||||||
let arguments = call
|
let arguments = call
|
||||||
.arguments
|
.arguments
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -296,7 +297,7 @@ impl CompletionProvider for SlashCommandCompletionProvider {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let start =
|
let start =
|
||||||
buffer.anchor_after(Point::new(position.row, call.name.start as u32));
|
buffer.anchor_before(Point::new(position.row, call.name.start as u32));
|
||||||
(None, start..buffer_position)
|
(None, start..buffer_position)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5067,10 +5067,16 @@ impl Editor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let multibuffer_snapshot = self.buffer.read(cx).read(cx);
|
||||||
|
|
||||||
// Typically `start` == `end`, but with snippet tabstop choices the default choice is
|
// Typically `start` == `end`, but with snippet tabstop choices the default choice is
|
||||||
// inserted and selected. To handle that case, the start of the selection is used so that
|
// inserted and selected. To handle that case, the start of the selection is used so that
|
||||||
// the menu starts with all choices.
|
// the menu starts with all choices.
|
||||||
let position = self.selections.newest_anchor().start;
|
let position = self
|
||||||
|
.selections
|
||||||
|
.newest_anchor()
|
||||||
|
.start
|
||||||
|
.bias_right(&multibuffer_snapshot);
|
||||||
if position.diff_base_anchor.is_some() {
|
if position.diff_base_anchor.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5083,8 +5089,9 @@ impl Editor {
|
||||||
let buffer_snapshot = buffer.read(cx).snapshot();
|
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||||
|
|
||||||
let query: Option<Arc<String>> =
|
let query: Option<Arc<String>> =
|
||||||
Self::completion_query(&self.buffer.read(cx).read(cx), position)
|
Self::completion_query(&multibuffer_snapshot, position).map(|query| query.into());
|
||||||
.map(|query| query.into());
|
|
||||||
|
drop(multibuffer_snapshot);
|
||||||
|
|
||||||
let provider = match requested_source {
|
let provider = match requested_source {
|
||||||
Some(CompletionsMenuSource::Normal) | None => self.completion_provider.clone(),
|
Some(CompletionsMenuSource::Normal) | None => self.completion_provider.clone(),
|
||||||
|
|
|
@ -715,7 +715,7 @@ fn completion_replace_range(snapshot: &BufferSnapshot, anchor: &Anchor) -> Optio
|
||||||
|
|
||||||
if end_in_line > start_in_line {
|
if end_in_line > start_in_line {
|
||||||
let replace_start = snapshot.anchor_before(line_start + start_in_line);
|
let replace_start = snapshot.anchor_before(line_start + start_in_line);
|
||||||
let replace_end = snapshot.anchor_before(line_start + end_in_line);
|
let replace_end = snapshot.anchor_after(line_start + end_in_line);
|
||||||
Some(replace_start..replace_end)
|
Some(replace_start..replace_end)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue