mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 19:02:07 +00:00
Trigger copilot only on insertion and deletion
Also, avoid showing the suggestion if a completion is in progress to avoid flickering.
This commit is contained in:
parent
971c88db80
commit
b58ac815a8
1 changed files with 68 additions and 56 deletions
|
@ -1459,7 +1459,7 @@ impl Editor {
|
||||||
self.refresh_code_actions(cx);
|
self.refresh_code_actions(cx);
|
||||||
self.refresh_document_highlights(cx);
|
self.refresh_document_highlights(cx);
|
||||||
refresh_matching_bracket_highlights(self, cx);
|
refresh_matching_bracket_highlights(self, cx);
|
||||||
self.refresh_copilot_suggestions(cx);
|
self.hide_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blink_manager.update(cx, BlinkManager::pause_blinking);
|
self.blink_manager.update(cx, BlinkManager::pause_blinking);
|
||||||
|
@ -1833,7 +1833,7 @@ impl Editor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.clear_copilot_suggestions(cx) {
|
if self.hide_copilot_suggestion(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2012,8 +2012,18 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(snapshot);
|
drop(snapshot);
|
||||||
|
let had_active_copilot_suggestion = this.has_active_copilot_suggestion(cx);
|
||||||
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
|
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
|
||||||
this.trigger_completion_on_input(&text, cx);
|
|
||||||
|
if had_active_copilot_suggestion {
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
|
if !this.has_active_copilot_suggestion(cx) {
|
||||||
|
this.trigger_completion_on_input(&text, cx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.trigger_completion_on_input(&text, cx);
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2094,6 +2104,7 @@ impl Editor {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
|
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(new_selections));
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2186,9 +2197,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext<Self>) {
|
fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext<Self>) {
|
||||||
if !cx.global::<Settings>().show_completions_on_input
|
if !cx.global::<Settings>().show_completions_on_input {
|
||||||
|| self.has_active_copilot_suggestion(cx)
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2375,8 +2384,8 @@ impl Editor {
|
||||||
this.completion_tasks.retain(|(id, _)| *id > menu.id);
|
this.completion_tasks.retain(|(id, _)| *id > menu.id);
|
||||||
if this.focused && !menu.matches.is_empty() {
|
if this.focused && !menu.matches.is_empty() {
|
||||||
this.show_context_menu(ContextMenu::Completions(menu), cx);
|
this.show_context_menu(ContextMenu::Completions(menu), cx);
|
||||||
} else {
|
} else if this.hide_context_menu(cx).is_none() {
|
||||||
this.hide_context_menu(cx);
|
this.update_visible_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2774,16 +2783,16 @@ impl Editor {
|
||||||
fn refresh_copilot_suggestions(&mut self, cx: &mut ViewContext<Self>) -> Option<()> {
|
fn refresh_copilot_suggestions(&mut self, cx: &mut ViewContext<Self>) -> Option<()> {
|
||||||
let copilot = Copilot::global(cx)?;
|
let copilot = Copilot::global(cx)?;
|
||||||
if self.mode != EditorMode::Full || !copilot.read(cx).status().is_authorized() {
|
if self.mode != EditorMode::Full || !copilot.read(cx).status().is_authorized() {
|
||||||
self.clear_copilot_suggestions(cx);
|
self.hide_copilot_suggestion(cx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.refresh_active_copilot_suggestion(cx);
|
self.update_visible_copilot_suggestion(cx);
|
||||||
|
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let cursor = self.selections.newest_anchor().head();
|
let cursor = self.selections.newest_anchor().head();
|
||||||
let language_name = snapshot.language_at(cursor).map(|language| language.name());
|
let language_name = snapshot.language_at(cursor).map(|language| language.name());
|
||||||
if !cx.global::<Settings>().copilot_on(language_name.as_deref()) {
|
if !cx.global::<Settings>().copilot_on(language_name.as_deref()) {
|
||||||
self.clear_copilot_suggestions(cx);
|
self.hide_copilot_suggestion(cx);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2810,7 +2819,7 @@ impl Editor {
|
||||||
for completion in completions {
|
for completion in completions {
|
||||||
this.copilot_state.push_completion(completion);
|
this.copilot_state.push_completion(completion);
|
||||||
}
|
}
|
||||||
this.refresh_active_copilot_suggestion(cx);
|
this.update_visible_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2829,7 +2838,7 @@ impl Editor {
|
||||||
self.copilot_state.active_completion_index =
|
self.copilot_state.active_completion_index =
|
||||||
(self.copilot_state.active_completion_index + 1) % self.copilot_state.completions.len();
|
(self.copilot_state.active_completion_index + 1) % self.copilot_state.completions.len();
|
||||||
|
|
||||||
self.refresh_active_copilot_suggestion(cx);
|
self.update_visible_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn previous_copilot_suggestion(
|
fn previous_copilot_suggestion(
|
||||||
|
@ -2849,18 +2858,51 @@ impl Editor {
|
||||||
self.copilot_state.active_completion_index - 1
|
self.copilot_state.active_completion_index - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
self.refresh_active_copilot_suggestion(cx);
|
self.update_visible_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh_active_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) {
|
fn accept_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
||||||
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
|
let cursor = self.selections.newest_anchor().head();
|
||||||
|
if let Some(text) = self
|
||||||
|
.copilot_state
|
||||||
|
.text_for_active_completion(cursor, &snapshot)
|
||||||
|
{
|
||||||
|
self.insert_with_autoindent_mode(&text.to_string(), None, cx);
|
||||||
|
self.hide_copilot_suggestion(cx);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_active_copilot_suggestion(&self, cx: &AppContext) -> bool {
|
||||||
|
self.display_map.read(cx).has_suggestion()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hide_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
||||||
|
let old_suggestion = self
|
||||||
|
.display_map
|
||||||
|
.update(cx, |map, cx| map.replace_suggestion::<usize>(None, cx));
|
||||||
|
|
||||||
|
if old_suggestion.is_some() {
|
||||||
|
cx.notify();
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_visible_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let selection = self.selections.newest_anchor();
|
let selection = self.selections.newest_anchor();
|
||||||
let cursor = selection.head();
|
let cursor = selection.head();
|
||||||
|
|
||||||
if self.context_menu.is_some() || selection.start != selection.end {
|
if self.context_menu.is_some()
|
||||||
self.display_map
|
|| !self.completion_tasks.is_empty()
|
||||||
.update(cx, |map, cx| map.replace_suggestion::<usize>(None, cx));
|
|| selection.start != selection.end
|
||||||
cx.notify();
|
{
|
||||||
|
self.hide_copilot_suggestion(cx);
|
||||||
} else if let Some(text) = self
|
} else if let Some(text) = self
|
||||||
.copilot_state
|
.copilot_state
|
||||||
.text_for_active_completion(cursor, &snapshot)
|
.text_for_active_completion(cursor, &snapshot)
|
||||||
|
@ -2875,44 +2917,11 @@ impl Editor {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
cx.notify();
|
cx.notify();
|
||||||
} else if self.has_active_copilot_suggestion(cx) {
|
|
||||||
self.display_map
|
|
||||||
.update(cx, |map, cx| map.replace_suggestion::<usize>(None, cx));
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn accept_copilot_suggestion(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
|
||||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
|
||||||
let cursor = self.selections.newest_anchor().head();
|
|
||||||
if let Some(text) = self
|
|
||||||
.copilot_state
|
|
||||||
.text_for_active_completion(cursor, &snapshot)
|
|
||||||
{
|
|
||||||
self.insert_with_autoindent_mode(&text.to_string(), None, cx);
|
|
||||||
self.clear_copilot_suggestions(cx);
|
|
||||||
true
|
|
||||||
} else {
|
} else {
|
||||||
false
|
self.hide_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_copilot_suggestions(&mut self, cx: &mut ViewContext<Self>) -> bool {
|
|
||||||
self.display_map
|
|
||||||
.update(cx, |map, cx| map.replace_suggestion::<usize>(None, cx));
|
|
||||||
let was_empty = self.copilot_state.completions.is_empty();
|
|
||||||
self.copilot_state.completions.clear();
|
|
||||||
self.copilot_state.active_completion_index = 0;
|
|
||||||
self.copilot_state.pending_refresh = Task::ready(None);
|
|
||||||
self.copilot_state.excerpt_id = None;
|
|
||||||
cx.notify();
|
|
||||||
!was_empty
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_active_copilot_suggestion(&self, cx: &AppContext) -> bool {
|
|
||||||
self.display_map.read(cx).has_suggestion()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_code_actions_indicator(
|
pub fn render_code_actions_indicator(
|
||||||
&self,
|
&self,
|
||||||
style: &EditorStyle,
|
style: &EditorStyle,
|
||||||
|
@ -3028,7 +3037,7 @@ impl Editor {
|
||||||
self.completion_tasks.clear();
|
self.completion_tasks.clear();
|
||||||
}
|
}
|
||||||
self.context_menu = Some(menu);
|
self.context_menu = Some(menu);
|
||||||
self.refresh_active_copilot_suggestion(cx);
|
self.hide_copilot_suggestion(cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3036,7 +3045,9 @@ impl Editor {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
self.completion_tasks.clear();
|
self.completion_tasks.clear();
|
||||||
let context_menu = self.context_menu.take();
|
let context_menu = self.context_menu.take();
|
||||||
self.refresh_active_copilot_suggestion(cx);
|
if context_menu.is_some() {
|
||||||
|
self.update_visible_copilot_suggestion(cx);
|
||||||
|
}
|
||||||
context_menu
|
context_menu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3196,6 +3207,7 @@ impl Editor {
|
||||||
|
|
||||||
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
|
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
|
||||||
this.insert("", cx);
|
this.insert("", cx);
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3211,6 +3223,7 @@ impl Editor {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
this.insert("", cx);
|
this.insert("", cx);
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6400,7 +6413,6 @@ impl Editor {
|
||||||
multi_buffer::Event::Edited => {
|
multi_buffer::Event::Edited => {
|
||||||
self.refresh_active_diagnostics(cx);
|
self.refresh_active_diagnostics(cx);
|
||||||
self.refresh_code_actions(cx);
|
self.refresh_code_actions(cx);
|
||||||
self.refresh_copilot_suggestions(cx);
|
|
||||||
cx.emit(Event::BufferEdited);
|
cx.emit(Event::BufferEdited);
|
||||||
}
|
}
|
||||||
multi_buffer::Event::ExcerptsAdded {
|
multi_buffer::Event::ExcerptsAdded {
|
||||||
|
|
Loading…
Reference in a new issue