Indent instead of accepting suggestion if cursor is in leading whitespace
This commit is contained in:
parent
908a7cf47e
commit
f920e02d96
2 changed files with 51 additions and 10 deletions
|
@ -3230,10 +3230,6 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
|
pub fn tab(&mut self, _: &Tab, cx: &mut ViewContext<Self>) {
|
||||||
if self.accept_copilot_suggestion(cx) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.move_to_next_snippet_tabstop(cx) {
|
if self.move_to_next_snippet_tabstop(cx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3263,8 +3259,8 @@ impl Editor {
|
||||||
// If the selection is empty and the cursor is in the leading whitespace before the
|
// If the selection is empty and the cursor is in the leading whitespace before the
|
||||||
// suggested indentation, then auto-indent the line.
|
// suggested indentation, then auto-indent the line.
|
||||||
let cursor = selection.head();
|
let cursor = selection.head();
|
||||||
if let Some(suggested_indent) = suggested_indents.get(&cursor.row).copied() {
|
|
||||||
let current_indent = snapshot.indent_size_for_line(cursor.row);
|
let current_indent = snapshot.indent_size_for_line(cursor.row);
|
||||||
|
if let Some(suggested_indent) = suggested_indents.get(&cursor.row).copied() {
|
||||||
if cursor.column < suggested_indent.len
|
if cursor.column < suggested_indent.len
|
||||||
&& cursor.column <= current_indent.len
|
&& cursor.column <= current_indent.len
|
||||||
&& current_indent.len <= suggested_indent.len
|
&& current_indent.len <= suggested_indent.len
|
||||||
|
@ -3283,6 +3279,16 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accept copilot suggestion if there is only one selection and the cursor is
|
||||||
|
// in the leading whitespace.
|
||||||
|
if self.selections.count() == 1
|
||||||
|
&& selection.start.column >= current_indent.len
|
||||||
|
&& self.has_active_copilot_suggestion(cx)
|
||||||
|
{
|
||||||
|
self.accept_copilot_suggestion(cx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, insert a hard or soft tab.
|
// Otherwise, insert a hard or soft tab.
|
||||||
let settings = cx.global::<Settings>();
|
let settings = cx.global::<Settings>();
|
||||||
let language_name = buffer.language_at(cursor, cx).map(|l| l.name());
|
let language_name = buffer.language_at(cursor, cx).map(|l| l.name());
|
||||||
|
@ -3306,7 +3312,8 @@ impl Editor {
|
||||||
|
|
||||||
self.transact(cx, |this, cx| {
|
self.transact(cx, |this, cx| {
|
||||||
this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
|
this.buffer.update(cx, |b, cx| b.edit(edits, None, cx));
|
||||||
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections))
|
this.change_selections(Some(Autoscroll::fit()), cx, |s| s.select(selections));
|
||||||
|
this.refresh_copilot_suggestions(cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5881,7 +5881,7 @@ async fn test_move_to_enclosing_bracket(cx: &mut gpui::TestAppContext) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test(iterations = 10)]
|
||||||
async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
|
async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
|
||||||
let (copilot, copilot_lsp) = Copilot::fake(cx);
|
let (copilot, copilot_lsp) = Copilot::fake(cx);
|
||||||
cx.update(|cx| cx.set_global(copilot));
|
cx.update(|cx| cx.set_global(copilot));
|
||||||
|
@ -5918,7 +5918,6 @@ async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppC
|
||||||
&copilot_lsp,
|
&copilot_lsp,
|
||||||
vec![copilot::request::Completion {
|
vec![copilot::request::Completion {
|
||||||
text: "copilot1".into(),
|
text: "copilot1".into(),
|
||||||
position: lsp::Position::new(0, 5),
|
|
||||||
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 5)),
|
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 5)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
|
@ -5962,7 +5961,6 @@ async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppC
|
||||||
&copilot_lsp,
|
&copilot_lsp,
|
||||||
vec![copilot::request::Completion {
|
vec![copilot::request::Completion {
|
||||||
text: "one.copilot1".into(),
|
text: "one.copilot1".into(),
|
||||||
position: lsp::Position::new(0, 4),
|
|
||||||
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 4)),
|
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 4)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
|
@ -5996,7 +5994,6 @@ async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppC
|
||||||
&copilot_lsp,
|
&copilot_lsp,
|
||||||
vec![copilot::request::Completion {
|
vec![copilot::request::Completion {
|
||||||
text: "one.copilot2".into(),
|
text: "one.copilot2".into(),
|
||||||
position: lsp::Position::new(0, 5),
|
|
||||||
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 5)),
|
range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 5)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
|
@ -6062,6 +6059,43 @@ async fn test_copilot(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppC
|
||||||
assert_eq!(editor.display_text(cx), "one.cop\ntwo\nthree\n");
|
assert_eq!(editor.display_text(cx), "one.cop\ntwo\nthree\n");
|
||||||
assert_eq!(editor.text(cx), "one.cop\ntwo\nthree\n");
|
assert_eq!(editor.text(cx), "one.cop\ntwo\nthree\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Reset the editor to verify how suggestions behave when tabbing on leading indentation.
|
||||||
|
cx.update_editor(|editor, cx| {
|
||||||
|
editor.set_text("fn foo() {\n \n}", cx);
|
||||||
|
editor.change_selections(None, cx, |s| {
|
||||||
|
s.select_ranges([Point::new(1, 2)..Point::new(1, 2)])
|
||||||
|
});
|
||||||
|
});
|
||||||
|
handle_copilot_completion_request(
|
||||||
|
&copilot_lsp,
|
||||||
|
vec![copilot::request::Completion {
|
||||||
|
text: " let x = 4;".into(),
|
||||||
|
range: lsp::Range::new(lsp::Position::new(1, 0), lsp::Position::new(1, 2)),
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
vec![],
|
||||||
|
);
|
||||||
|
|
||||||
|
cx.update_editor(|editor, cx| editor.next_copilot_suggestion(&Default::default(), cx));
|
||||||
|
deterministic.advance_clock(COPILOT_DEBOUNCE_TIMEOUT);
|
||||||
|
cx.update_editor(|editor, cx| {
|
||||||
|
assert!(editor.has_active_copilot_suggestion(cx));
|
||||||
|
assert_eq!(editor.display_text(cx), "fn foo() {\n let x = 4;\n}");
|
||||||
|
assert_eq!(editor.text(cx), "fn foo() {\n \n}");
|
||||||
|
|
||||||
|
// Tabbing inside of leading whitespace inserts indentation without accepting the suggestion.
|
||||||
|
editor.tab(&Default::default(), cx);
|
||||||
|
assert!(editor.has_active_copilot_suggestion(cx));
|
||||||
|
assert_eq!(editor.text(cx), "fn foo() {\n \n}");
|
||||||
|
assert_eq!(editor.display_text(cx), "fn foo() {\n let x = 4;\n}");
|
||||||
|
|
||||||
|
// Tabbing again accepts the suggestion.
|
||||||
|
editor.tab(&Default::default(), cx);
|
||||||
|
assert!(!editor.has_active_copilot_suggestion(cx));
|
||||||
|
assert_eq!(editor.text(cx), "fn foo() {\n let x = 4;\n}");
|
||||||
|
assert_eq!(editor.display_text(cx), "fn foo() {\n let x = 4;\n}");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
fn empty_range(row: usize, column: usize) -> Range<DisplayPoint> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue