Track cursor offset before bias in Supermaven completion provider (#18858)

Track the cursor offset before biasing in the Supermaven completion
provider to better determine if the text should be suggested. The
underlying issue here is due to the way anchor biasing works, the
completion provider is not able to determine if a given suggestion's
cursor location no longer exists as it is always coalesced to a correct
location (specifically, the end of the line).

This change updates that logic so the offset is stored independently of
the buffer so it can be used to represent a location that may not exist
in the buffer anymore to represent locations that have been deleted.

The net effect is that suggestions can be backspaced much more cleanly
with Supermaven.


![image](https://github.com/user-attachments/assets/ff61aa09-54ea-4cad-b1ca-633a08bcdd96)


![image](https://github.com/user-attachments/assets/b49e2d6b-f1d3-41a1-9b75-c4bc3ac5f85b)

Release Notes:

- Improves https://github.com/zed-industries/zed/issues/17981 to prevent
suggesting completions based on out-of-date cursor locations.
This commit is contained in:
Kevin Wang 2024-10-10 07:39:20 -04:00 committed by GitHub
parent 4de05d18ed
commit 21c27cecba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -141,6 +141,7 @@ impl Supermaven {
SupermavenCompletionState {
buffer_id,
prefix_anchor: cursor_position,
prefix_offset: offset,
text: String::new(),
dedent: String::new(),
updates_tx,
@ -216,7 +217,7 @@ fn find_relevant_completion<'a>(
};
let current_cursor_offset = cursor_position.to_offset(buffer);
let original_cursor_offset = state.prefix_anchor.to_offset(buffer);
let original_cursor_offset = state.prefix_offset;
if current_cursor_offset < original_cursor_offset {
continue;
}
@ -419,6 +420,9 @@ pub struct SupermavenCompletionStateId(usize);
pub struct SupermavenCompletionState {
buffer_id: EntityId,
prefix_anchor: Anchor,
// prefix_offset is tracked independently because the anchor biases left which
// doesn't allow us to determine if the prior text has been deleted.
prefix_offset: usize,
text: String,
dedent: String,
updates_tx: watch::Sender<()>,