Wire up keyboard interaction in code actions menu

This commit is contained in:
Antonio Scandurra 2023-11-10 15:40:23 +01:00
parent bf576d47b1
commit fb450e35f7
2 changed files with 123 additions and 109 deletions

View file

@ -40,10 +40,11 @@ use fuzzy::{StringMatch, StringMatchCandidate};
use git::diff_hunk_to_display; use git::diff_hunk_to_display;
use gpui::{ use gpui::{
action, actions, div, point, px, relative, rems, size, uniform_list, AnyElement, AppContext, action, actions, div, point, px, relative, rems, size, uniform_list, AnyElement, AppContext,
BackgroundExecutor, Bounds, ClipboardItem, Component, Context, DispatchContext, EventEmitter, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Component, Context,
FocusHandle, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, Model, DispatchContext, EventEmitter, FocusHandle, FontFeatures, FontStyle, FontWeight,
ParentElement, Pixels, Render, StatelessInteractive, Styled, Subscription, Task, TextStyle, HighlightStyle, Hsla, InputHandler, Model, ParentElement, Pixels, Render, StatelessInteractive,
UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View, ViewContext,
VisualContext, WeakView, WindowContext,
}; };
use highlight_matching_bracket::refresh_matching_bracket_highlights; use highlight_matching_bracket::refresh_matching_bracket_highlights;
use hover_popover::{hide_hover, HoverState}; use hover_popover::{hide_hover, HoverState};
@ -68,7 +69,7 @@ pub use multi_buffer::{
}; };
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use project::{FormatTrigger, Location, Project}; use project::{FormatTrigger, Location, Project, ProjectTransaction};
use rand::prelude::*; use rand::prelude::*;
use rpc::proto::*; use rpc::proto::*;
use scroll::{ use scroll::{
@ -3901,6 +3902,7 @@ impl Editor {
scroll_handle: UniformListScrollHandle::default(), scroll_handle: UniformListScrollHandle::default(),
deployed_from_indicator, deployed_from_indicator,
})); }));
cx.notify();
} }
} }
})?; })?;
@ -3910,117 +3912,121 @@ impl Editor {
.detach_and_log_err(cx); .detach_and_log_err(cx);
} }
// pub fn confirm_code_action( pub fn confirm_code_action(
// workspace: &mut Workspace, &mut self,
// action: &ConfirmCodeAction, action: &ConfirmCodeAction,
// cx: &mut ViewContext<Workspace>, cx: &mut ViewContext<Self>,
// ) -> Option<Task<Result<()>>> { ) -> Option<Task<Result<()>>> {
// let editor = workspace.active_item(cx)?.act_as::<Editor>(cx)?; let actions_menu = if let ContextMenu::CodeActions(menu) = self.hide_context_menu(cx)? {
// let actions_menu = if let ContextMenu::CodeActions(menu) = menu
// editor.update(cx, |editor, cx| editor.hide_context_menu(cx))? } else {
// { return None;
// menu };
// } else { let action_ix = action.item_ix.unwrap_or(actions_menu.selected_item);
// return None; let action = actions_menu.actions.get(action_ix)?.clone();
// }; let title = action.lsp_action.title.clone();
// let action_ix = action.item_ix.unwrap_or(actions_menu.selected_item); let buffer = actions_menu.buffer;
// let action = actions_menu.actions.get(action_ix)?.clone(); let workspace = self.workspace()?;
// let title = action.lsp_action.title.clone();
// let buffer = actions_menu.buffer;
// let apply_code_actions = workspace.project().clone().update(cx, |project, cx| { let apply_code_actions = workspace
// project.apply_code_action(buffer, action, true, cx) .read(cx)
// }); .project()
// let editor = editor.downgrade(); .clone()
// Some(cx.spawn(|workspace, cx| async move { .update(cx, |project, cx| {
// let project_transaction = apply_code_actions.await?; project.apply_code_action(buffer, action, true, cx)
// Self::open_project_transaction(&editor, workspace, project_transaction, title, cx).await });
// })) let workspace = workspace.downgrade();
// } Some(cx.spawn(|editor, cx| async move {
let project_transaction = apply_code_actions.await?;
Self::open_project_transaction(&editor, workspace, project_transaction, title, cx).await
}))
}
// async fn open_project_transaction( async fn open_project_transaction(
// this: &WeakViewHandle<Editor this: &WeakView<Editor>,
// workspace: WeakViewHandle<Workspace workspace: WeakView<Workspace>,
// transaction: ProjectTransaction, transaction: ProjectTransaction,
// title: String, title: String,
// mut cx: AsyncAppContext, mut cx: AsyncWindowContext,
// ) -> Result<()> { ) -> Result<()> {
// let replica_id = this.read_with(&cx, |this, cx| this.replica_id(cx))?; let replica_id = this.update(&mut cx, |this, cx| this.replica_id(cx))?;
// let mut entries = transaction.0.into_iter().collect::<Vec<_>>(); let mut entries = transaction.0.into_iter().collect::<Vec<_>>();
// entries.sort_unstable_by_key(|(buffer, _)| { cx.update(|_, cx| {
// buffer.read_with(&cx, |buffer, _| buffer.file().map(|f| f.path().clone())) entries.sort_unstable_by_key(|(buffer, _)| {
// }); buffer.read(cx).file().map(|f| f.path().clone())
});
})?;
// // If the project transaction's edits are all contained within this editor, then // If the project transaction's edits are all contained within this editor, then
// // avoid opening a new editor to display them. // avoid opening a new editor to display them.
// if let Some((buffer, transaction)) = entries.first() { if let Some((buffer, transaction)) = entries.first() {
// if entries.len() == 1 { if entries.len() == 1 {
// let excerpt = this.read_with(&cx, |editor, cx| { let excerpt = this.update(&mut cx, |editor, cx| {
// editor editor
// .buffer() .buffer()
// .read(cx) .read(cx)
// .excerpt_containing(editor.selections.newest_anchor().head(), cx) .excerpt_containing(editor.selections.newest_anchor().head(), cx)
// })?; })?;
// if let Some((_, excerpted_buffer, excerpt_range)) = excerpt { if let Some((_, excerpted_buffer, excerpt_range)) = excerpt {
// if excerpted_buffer == *buffer { if excerpted_buffer == *buffer {
// let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| { let all_edits_within_excerpt = buffer.read_with(&cx, |buffer, _| {
// let excerpt_range = excerpt_range.to_offset(buffer); let excerpt_range = excerpt_range.to_offset(buffer);
// buffer buffer
// .edited_ranges_for_transaction::<usize>(transaction) .edited_ranges_for_transaction::<usize>(transaction)
// .all(|range| { .all(|range| {
// excerpt_range.start <= range.start excerpt_range.start <= range.start
// && excerpt_range.end >= range.end && excerpt_range.end >= range.end
// }) })
// }); })?;
// if all_edits_within_excerpt { if all_edits_within_excerpt {
// return Ok(()); return Ok(());
// } }
// } }
// } }
// } }
// } else { } else {
// return Ok(()); return Ok(());
// } }
// let mut ranges_to_highlight = Vec::new(); let mut ranges_to_highlight = Vec::new();
// let excerpt_buffer = cx.build_model(|cx| { let excerpt_buffer = cx.build_model(|cx| {
// let mut multibuffer = MultiBuffer::new(replica_id).with_title(title); let mut multibuffer = MultiBuffer::new(replica_id).with_title(title);
// for (buffer_handle, transaction) in &entries { for (buffer_handle, transaction) in &entries {
// let buffer = buffer_handle.read(cx); let buffer = buffer_handle.read(cx);
// ranges_to_highlight.extend( ranges_to_highlight.extend(
// multibuffer.push_excerpts_with_context_lines( multibuffer.push_excerpts_with_context_lines(
// buffer_handle.clone(), buffer_handle.clone(),
// buffer buffer
// .edited_ranges_for_transaction::<usize>(transaction) .edited_ranges_for_transaction::<usize>(transaction)
// .collect(), .collect(),
// 1, 1,
// cx, cx,
// ), ),
// ); );
// } }
// multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)), cx); multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)), cx);
// multibuffer multibuffer
// }); })?;
// workspace.update(&mut cx, |workspace, cx| { workspace.update(&mut cx, |workspace, cx| {
// let project = workspace.project().clone(); let project = workspace.project().clone();
// let editor = let editor =
// cx.add_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx)); cx.build_view(|cx| Editor::for_multibuffer(excerpt_buffer, Some(project), cx));
// workspace.add_item(Box::new(editor.clone()), cx); workspace.add_item(Box::new(editor.clone()), cx);
// editor.update(cx, |editor, cx| { editor.update(cx, |editor, cx| {
// editor.highlight_background::<Self>( editor.highlight_background::<Self>(
// ranges_to_highlight, ranges_to_highlight,
// |theme| theme.editor.highlighted_line_background, |theme| theme.editor_highlighted_line_background,
// cx, cx,
// ); );
// }); });
// })?; })?;
// Ok(()) Ok(())
// } }
fn refresh_code_actions(&mut self, cx: &mut ViewContext<Self>) -> Option<()> { fn refresh_code_actions(&mut self, cx: &mut ViewContext<Self>) -> Option<()> {
let project = self.project.clone()?; let project = self.project.clone()?;

View file

@ -4126,7 +4126,7 @@ fn build_key_listeners(
build_action_listener(Editor::unfold_at), build_action_listener(Editor::unfold_at),
build_action_listener(Editor::fold_selected_ranges), build_action_listener(Editor::fold_selected_ranges),
build_action_listener(Editor::show_completions), build_action_listener(Editor::show_completions),
// build_action_listener(Editor::toggle_code_actions), todo!() build_action_listener(Editor::toggle_code_actions),
// build_action_listener(Editor::open_excerpts), todo!() // build_action_listener(Editor::open_excerpts), todo!()
build_action_listener(Editor::toggle_soft_wrap), build_action_listener(Editor::toggle_soft_wrap),
build_action_listener(Editor::toggle_inlay_hints), build_action_listener(Editor::toggle_inlay_hints),
@ -4142,13 +4142,21 @@ fn build_key_listeners(
build_action_listener(Editor::restart_language_server), build_action_listener(Editor::restart_language_server),
build_action_listener(Editor::show_character_palette), build_action_listener(Editor::show_character_palette),
// build_action_listener(Editor::confirm_completion), todo!() // build_action_listener(Editor::confirm_completion), todo!()
// build_action_listener(Editor::confirm_code_action), todo!() build_action_listener(|editor, action, cx| {
editor
.confirm_code_action(action, cx)
.map(|task| task.detach_and_log_err(cx));
}),
// build_action_listener(Editor::rename), todo!() // build_action_listener(Editor::rename), todo!()
// build_action_listener(Editor::confirm_rename), todo!() // build_action_listener(Editor::confirm_rename), todo!()
// build_action_listener(Editor::find_all_references), todo!() // build_action_listener(Editor::find_all_references), todo!()
build_action_listener(Editor::next_copilot_suggestion), build_action_listener(Editor::next_copilot_suggestion),
build_action_listener(Editor::previous_copilot_suggestion), build_action_listener(Editor::previous_copilot_suggestion),
build_action_listener(Editor::copilot_suggest), build_action_listener(Editor::copilot_suggest),
build_action_listener(Editor::context_menu_first),
build_action_listener(Editor::context_menu_prev),
build_action_listener(Editor::context_menu_next),
build_action_listener(Editor::context_menu_last),
build_key_listener( build_key_listener(
move |editor, key_down: &KeyDownEvent, dispatch_context, phase, cx| { move |editor, key_down: &KeyDownEvent, dispatch_context, phase, cx| {
if phase == DispatchPhase::Bubble { if phase == DispatchPhase::Bubble {