Add Code Actions to the Toolbar (#31236)

Closes issue #31120.


https://github.com/user-attachments/assets/a4b3c86d-7358-49ac-b8d9-e9af50daf671

Release Notes:

- Added a code actions icon to the toolbar. This icon can be disabled by
setting `toolbar.code_actions` to `false`.
This commit is contained in:
smit 2025-05-23 16:55:29 +05:30 committed by GitHub
parent fbc922ad46
commit 1cad1cbbfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 167 additions and 50 deletions

View file

@ -15,7 +15,7 @@
pub mod actions;
mod blink_manager;
mod clangd_ext;
mod code_context_menus;
pub mod code_context_menus;
pub mod display_map;
mod editor_settings;
mod editor_settings_controls;
@ -777,7 +777,7 @@ impl RunnableTasks {
}
#[derive(Clone)]
struct ResolvedTasks {
pub struct ResolvedTasks {
templates: SmallVec<[(TaskSourceKind, ResolvedTask); 1]>,
position: Anchor,
}
@ -5375,7 +5375,7 @@ impl Editor {
let quick_launch = action.quick_launch;
let mut context_menu = self.context_menu.borrow_mut();
if let Some(CodeContextMenu::CodeActions(code_actions)) = context_menu.as_ref() {
if code_actions.deployed_from_indicator == action.deployed_from_indicator {
if code_actions.deployed_from == action.deployed_from {
// Toggle if we're selecting the same one
*context_menu = None;
cx.notify();
@ -5388,7 +5388,7 @@ impl Editor {
}
drop(context_menu);
let snapshot = self.snapshot(window, cx);
let deployed_from_indicator = action.deployed_from_indicator;
let deployed_from = action.deployed_from.clone();
let mut task = self.code_actions_task.take();
let action = action.clone();
cx.spawn_in(window, async move |editor, cx| {
@ -5399,10 +5399,12 @@ impl Editor {
let spawned_test_task = editor.update_in(cx, |editor, window, cx| {
if editor.focus_handle.is_focused(window) {
let multibuffer_point = action
.deployed_from_indicator
.map(|row| DisplayPoint::new(row, 0).to_point(&snapshot))
.unwrap_or_else(|| editor.selections.newest::<Point>(cx).head());
let multibuffer_point = match &action.deployed_from {
Some(CodeActionSource::Indicator(row)) => {
DisplayPoint::new(*row, 0).to_point(&snapshot)
}
_ => editor.selections.newest::<Point>(cx).head(),
};
let (buffer, buffer_row) = snapshot
.buffer_snapshot
.buffer_line_for_row(MultiBufferRow(multibuffer_point.row))
@ -5526,7 +5528,7 @@ impl Editor {
),
selected_item: Default::default(),
scroll_handle: UniformListScrollHandle::default(),
deployed_from_indicator,
deployed_from,
}));
if spawn_straight_away {
if let Some(task) = editor.confirm_code_action(
@ -5746,6 +5748,21 @@ impl Editor {
self.refresh_code_actions(window, cx);
}
pub fn code_actions_enabled(&self, cx: &App) -> bool {
!self.code_action_providers.is_empty()
&& EditorSettings::get_global(cx).toolbar.code_actions
}
pub fn has_available_code_actions(&self) -> bool {
self.available_code_actions
.as_ref()
.is_some_and(|(_, actions)| !actions.is_empty())
}
pub fn context_menu(&self) -> &RefCell<Option<CodeContextMenu>> {
&self.context_menu
}
fn refresh_code_actions(&mut self, window: &mut Window, cx: &mut Context<Self>) -> Option<()> {
let newest_selection = self.selections.newest_anchor().clone();
let newest_selection_adjusted = self.selections.newest_adjusted(cx).clone();
@ -7498,7 +7515,7 @@ impl Editor {
window.focus(&editor.focus_handle(cx));
editor.toggle_code_actions(
&ToggleCodeActions {
deployed_from_indicator: Some(row),
deployed_from: Some(CodeActionSource::Indicator(row)),
quick_launch,
},
window,
@ -7519,7 +7536,7 @@ impl Editor {
.map_or(false, |menu| menu.visible())
}
fn context_menu_origin(&self) -> Option<ContextMenuOrigin> {
pub fn context_menu_origin(&self) -> Option<ContextMenuOrigin> {
self.context_menu
.borrow()
.as_ref()
@ -8538,7 +8555,7 @@ impl Editor {
}
}
fn render_context_menu(
pub fn render_context_menu(
&self,
style: &EditorStyle,
max_height_in_lines: u32,