Require alt-tab
for AcceptEditPrediction
when tab
inserting whitespace is desired (#24705)
Moves tab whitespace insertion logic out of `AcceptEditPrediction` handler. `edit_prediction_requires_modifier` context will now be true when on a line with leading whitespace, so that `alt-tab` is used to accept predictions in this case. This way leading indentation can be typed when edit predictions are visible Release Notes: - N/A Co-authored-by: Ben <ben@zed.dev> Co-authored-by: Joao <joao@zed.dev>
This commit is contained in:
parent
2e7a89c5e3
commit
498bb518ff
3 changed files with 27 additions and 69 deletions
|
@ -709,6 +709,7 @@ pub struct Editor {
|
||||||
/// Used to prevent flickering as the user types while the menu is open
|
/// Used to prevent flickering as the user types while the menu is open
|
||||||
stale_inline_completion_in_menu: Option<InlineCompletionState>,
|
stale_inline_completion_in_menu: Option<InlineCompletionState>,
|
||||||
edit_prediction_settings: EditPredictionSettings,
|
edit_prediction_settings: EditPredictionSettings,
|
||||||
|
edit_prediction_cursor_on_leading_whitespace: bool,
|
||||||
inline_completions_hidden_for_vim_mode: bool,
|
inline_completions_hidden_for_vim_mode: bool,
|
||||||
show_inline_completions_override: Option<bool>,
|
show_inline_completions_override: Option<bool>,
|
||||||
menu_inline_completions_policy: MenuInlineCompletionsPolicy,
|
menu_inline_completions_policy: MenuInlineCompletionsPolicy,
|
||||||
|
@ -1423,6 +1424,7 @@ impl Editor {
|
||||||
show_inline_completions_override: None,
|
show_inline_completions_override: None,
|
||||||
menu_inline_completions_policy: MenuInlineCompletionsPolicy::ByProvider,
|
menu_inline_completions_policy: MenuInlineCompletionsPolicy::ByProvider,
|
||||||
edit_prediction_settings: EditPredictionSettings::Disabled,
|
edit_prediction_settings: EditPredictionSettings::Disabled,
|
||||||
|
edit_prediction_cursor_on_leading_whitespace: false,
|
||||||
custom_context_menu: None,
|
custom_context_menu: None,
|
||||||
show_git_blame_gutter: false,
|
show_git_blame_gutter: false,
|
||||||
show_git_blame_inline: false,
|
show_git_blame_inline: false,
|
||||||
|
@ -1567,8 +1569,12 @@ impl Editor {
|
||||||
if has_active_edit_prediction {
|
if has_active_edit_prediction {
|
||||||
key_context.add("copilot_suggestion");
|
key_context.add("copilot_suggestion");
|
||||||
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||||
|
if showing_completions
|
||||||
if showing_completions || self.edit_prediction_requires_modifier() {
|
|| self.edit_prediction_requires_modifier()
|
||||||
|
// Require modifier key when the cursor is on leading whitespace, to allow `tab`
|
||||||
|
// bindings to insert tab characters.
|
||||||
|
|| self.edit_prediction_cursor_on_leading_whitespace
|
||||||
|
{
|
||||||
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4931,23 +4937,6 @@ impl Editor {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<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(), window, cx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.show_edit_predictions_in_menu() {
|
if self.show_edit_predictions_in_menu() {
|
||||||
self.hide_context_menu(window, cx);
|
self.hide_context_menu(window, cx);
|
||||||
}
|
}
|
||||||
|
@ -5298,6 +5287,9 @@ impl Editor {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.edit_prediction_cursor_on_leading_whitespace =
|
||||||
|
multibuffer.is_line_whitespace_upto(cursor);
|
||||||
|
|
||||||
let inline_completion = provider.suggest(&buffer, cursor_buffer_position, cx)?;
|
let inline_completion = provider.suggest(&buffer, cursor_buffer_position, cx)?;
|
||||||
let edits = inline_completion
|
let edits = inline_completion
|
||||||
.edits
|
.edits
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use gpui::{prelude::*, Entity};
|
use gpui::{prelude::*, Entity};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use inline_completion::EditPredictionProvider;
|
use inline_completion::EditPredictionProvider;
|
||||||
use language::{Language, LanguageConfig};
|
|
||||||
use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint};
|
use multi_buffer::{Anchor, MultiBufferSnapshot, ToPoint};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use std::{num::NonZeroU32, ops::Range, sync::Arc};
|
use std::ops::Range;
|
||||||
use text::{Point, ToOffset};
|
use text::{Point, ToOffset};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -124,54 +123,6 @@ 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(|_| 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, window, cx| editor.update_visible_inline_completion(window, 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, |_| {});
|
||||||
|
|
|
@ -4236,6 +4236,21 @@ impl MultiBufferSnapshot {
|
||||||
indent
|
indent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_line_whitespace_upto<T>(&self, position: T) -> bool
|
||||||
|
where
|
||||||
|
T: ToOffset,
|
||||||
|
{
|
||||||
|
for char in self.reversed_chars_at(position) {
|
||||||
|
if !char.is_whitespace() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if char == '\n' {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn prev_non_blank_row(&self, mut row: MultiBufferRow) -> Option<MultiBufferRow> {
|
pub fn prev_non_blank_row(&self, mut row: MultiBufferRow) -> Option<MultiBufferRow> {
|
||||||
while row.0 > 0 {
|
while row.0 > 0 {
|
||||||
row.0 -= 1;
|
row.0 -= 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue