mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-24 02:46:43 +00:00
Improve handling tab when inline completion is visible (#22892)
This changes the behaviour of `<tab>` when inline completion is visible. When the cursor is before the suggested indentation level, accepting a completion should just indent. cc @nathansobo @maxdeviant Release Notes: - Changed the behavior of `<tab>` at start of line when an inline completion (Copilot, Supermaven, ...) is visible. If the cursor is before the suggested indentation, `<tab>` now indents the line instead of accepting the visible completion. Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
9c0c853a2c
commit
142f949e73
2 changed files with 67 additions and 1 deletions
|
@ -4585,6 +4585,23 @@ impl Editor {
|
||||||
_: &AcceptInlineCompletion,
|
_: &AcceptInlineCompletion,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
let buffer = self.buffer.read(cx);
|
||||||
|
let snapshot = buffer.snapshot(cx);
|
||||||
|
let selection = self.selections.newest_adjusted(cx);
|
||||||
|
let cursor = selection.head();
|
||||||
|
let current_indent = snapshot.indent_size_for_line(MultiBufferRow(cursor.row));
|
||||||
|
let suggested_indents = snapshot.suggested_indents([cursor.row], cx);
|
||||||
|
if let Some(suggested_indent) = suggested_indents.get(&MultiBufferRow(cursor.row)).copied()
|
||||||
|
{
|
||||||
|
if cursor.column < suggested_indent.len
|
||||||
|
&& cursor.column <= current_indent.len
|
||||||
|
&& current_indent.len <= suggested_indent.len
|
||||||
|
{
|
||||||
|
self.tab(&Default::default(), cx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.show_inline_completions_in_menu(cx) {
|
if self.show_inline_completions_in_menu(cx) {
|
||||||
self.hide_context_menu(cx);
|
self.hide_context_menu(cx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use gpui::{prelude::*, Model};
|
use gpui::{prelude::*, Model};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use inline_completion::InlineCompletionProvider;
|
use inline_completion::InlineCompletionProvider;
|
||||||
|
use language::{Language, LanguageConfig};
|
||||||
use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint};
|
use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint};
|
||||||
use std::ops::Range;
|
use std::{num::NonZeroU32, ops::Range, sync::Arc};
|
||||||
use text::{Point, ToOffset};
|
use text::{Point, ToOffset};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -122,6 +123,54 @@ async fn test_inline_completion_jump_button(cx: &mut gpui::TestAppContext) {
|
||||||
"});
|
"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_indentation(cx: &mut gpui::TestAppContext) {
|
||||||
|
init_test(cx, |settings| {
|
||||||
|
settings.defaults.tab_size = NonZeroU32::new(4)
|
||||||
|
});
|
||||||
|
|
||||||
|
let language = Arc::new(
|
||||||
|
Language::new(
|
||||||
|
LanguageConfig::default(),
|
||||||
|
Some(tree_sitter_rust::LANGUAGE.into()),
|
||||||
|
)
|
||||||
|
.with_indents_query(r#"(_ "(" ")" @end) @indent"#)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut cx = EditorTestContext::new(cx).await;
|
||||||
|
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
|
||||||
|
let provider = cx.new_model(|_| FakeInlineCompletionProvider::default());
|
||||||
|
assign_editor_completion_provider(provider.clone(), &mut cx);
|
||||||
|
|
||||||
|
cx.set_state(indoc! {"
|
||||||
|
const a: A = (
|
||||||
|
ˇ
|
||||||
|
);
|
||||||
|
"});
|
||||||
|
|
||||||
|
propose_edits(
|
||||||
|
&provider,
|
||||||
|
vec![(Point::new(1, 0)..Point::new(1, 0), " const function()")],
|
||||||
|
&mut cx,
|
||||||
|
);
|
||||||
|
cx.update_editor(|editor, cx| editor.update_visible_inline_completion(cx));
|
||||||
|
|
||||||
|
assert_editor_active_edit_completion(&mut cx, |_, edits| {
|
||||||
|
assert_eq!(edits.len(), 1);
|
||||||
|
assert_eq!(edits[0].1.as_str(), " const function()");
|
||||||
|
});
|
||||||
|
|
||||||
|
// When the cursor is before the suggested indentation level, accepting a
|
||||||
|
// completion should just indent.
|
||||||
|
accept_completion(&mut cx);
|
||||||
|
cx.assert_editor_state(indoc! {"
|
||||||
|
const a: A = (
|
||||||
|
ˇ
|
||||||
|
);
|
||||||
|
"});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_inline_completion_invalidation_range(cx: &mut gpui::TestAppContext) {
|
async fn test_inline_completion_invalidation_range(cx: &mut gpui::TestAppContext) {
|
||||||
init_test(cx, |_| {});
|
init_test(cx, |_| {});
|
||||||
|
|
Loading…
Reference in a new issue