Editor end of input context (#40735)
This is needed for #38914 and seems generally useful to have for contextual keybindings. Release Notes: - N/A --------- Co-authored-by: David Kleingeld <davidsk@zed.dev>
This commit is contained in:
co-authored by
David Kleingeld
parent
62516e8f1f
commit
267052f891
@@ -2466,15 +2466,15 @@ impl Editor {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn key_context(&self, window: &Window, cx: &App) -> KeyContext {
|
||||
pub fn key_context(&self, window: &mut Window, cx: &mut App) -> KeyContext {
|
||||
self.key_context_internal(self.has_active_edit_prediction(), window, cx)
|
||||
}
|
||||
|
||||
fn key_context_internal(
|
||||
&self,
|
||||
has_active_edit_prediction: bool,
|
||||
window: &Window,
|
||||
cx: &App,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> KeyContext {
|
||||
let mut key_context = KeyContext::new_with_defaults();
|
||||
key_context.add("Editor");
|
||||
@@ -2551,6 +2551,17 @@ impl Editor {
|
||||
key_context.add("selection_mode");
|
||||
}
|
||||
|
||||
let disjoint = self.selections.disjoint_anchors();
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let snapshot = snapshot.buffer_snapshot();
|
||||
if self.mode == EditorMode::SingleLine
|
||||
&& let [selection] = disjoint
|
||||
&& selection.start == selection.end
|
||||
&& selection.end.to_offset(snapshot) == snapshot.len()
|
||||
{
|
||||
key_context.add("end_of_input");
|
||||
}
|
||||
|
||||
key_context
|
||||
}
|
||||
|
||||
@@ -2604,8 +2615,8 @@ impl Editor {
|
||||
pub fn accept_edit_prediction_keybind(
|
||||
&self,
|
||||
accept_partial: bool,
|
||||
window: &Window,
|
||||
cx: &App,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AcceptEditPredictionBinding {
|
||||
let key_context = self.key_context_internal(true, window, cx);
|
||||
let in_conflict = self.edit_prediction_in_conflict();
|
||||
@@ -2747,7 +2758,7 @@ impl Editor {
|
||||
self.buffer().read(cx).title(cx)
|
||||
}
|
||||
|
||||
pub fn snapshot(&self, window: &mut Window, cx: &mut App) -> EditorSnapshot {
|
||||
pub fn snapshot(&self, window: &Window, cx: &mut App) -> EditorSnapshot {
|
||||
let git_blame_gutter_max_author_length = self
|
||||
.render_git_blame_gutter(cx)
|
||||
.then(|| {
|
||||
@@ -9285,7 +9296,7 @@ impl Editor {
|
||||
fn render_edit_prediction_accept_keybind(
|
||||
&self,
|
||||
window: &mut Window,
|
||||
cx: &App,
|
||||
cx: &mut App,
|
||||
) -> Option<AnyElement> {
|
||||
let accept_binding = self.accept_edit_prediction_keybind(false, window, cx);
|
||||
let accept_keystroke = accept_binding.keystroke()?;
|
||||
@@ -9331,7 +9342,7 @@ impl Editor {
|
||||
label: impl Into<SharedString>,
|
||||
icon: Option<IconName>,
|
||||
window: &mut Window,
|
||||
cx: &App,
|
||||
cx: &mut App,
|
||||
) -> Stateful<Div> {
|
||||
let padding_right = if icon.is_some() { px(4.) } else { px(8.) };
|
||||
|
||||
|
||||
@@ -26838,3 +26838,24 @@ async fn test_copy_line_without_trailing_newline(cx: &mut TestAppContext) {
|
||||
|
||||
cx.assert_editor_state("line1\nline2\nˇ");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_end_of_editor_context(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
cx.set_state("line1\nline2ˇ");
|
||||
cx.update_editor(|e, window, cx| {
|
||||
e.set_mode(EditorMode::SingleLine);
|
||||
assert!(e.key_context(window, cx).contains("end_of_input"));
|
||||
});
|
||||
cx.set_state("ˇline1\nline2");
|
||||
cx.update_editor(|e, window, cx| {
|
||||
assert!(!e.key_context(window, cx).contains("end_of_input"));
|
||||
});
|
||||
cx.set_state("line1ˇ\nline2");
|
||||
cx.update_editor(|e, window, cx| {
|
||||
assert!(!e.key_context(window, cx).contains("end_of_input"));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user