editor: Add ToggleFocus action (#34495)
Smit Barmase
and
Danilo Leal
created 4 months ago
This PR adds action `editor: toggle focus` which focuses to last active
editor pane item in workspace.
Release Notes:
- Added `editor: toggle focus` action, which focuses to last active
editor pane item.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Change summary
crates/editor/src/actions.rs | 2 ++
crates/editor/src/editor.rs | 13 +++++++++++++
crates/workspace/src/workspace.rs | 21 +++++++++++++++++++++
3 files changed, 36 insertions(+)
Detailed changes
@@ -425,6 +425,8 @@ actions!(
FoldRecursive,
/// Folds the selected ranges.
FoldSelectedRanges,
+ /// Toggles focus back to the last active buffer.
+ ToggleFocus,
/// Toggles folding at the current position.
ToggleFold,
/// Toggles recursive folding at the current position.
@@ -356,6 +356,7 @@ pub fn init(cx: &mut App) {
workspace.register_action(Editor::new_file_vertical);
workspace.register_action(Editor::new_file_horizontal);
workspace.register_action(Editor::cancel_language_server_work);
+ workspace.register_action(Editor::toggle_focus);
},
)
.detach();
@@ -16954,6 +16955,18 @@ impl Editor {
cx.notify();
}
+ pub fn toggle_focus(
+ workspace: &mut Workspace,
+ _: &actions::ToggleFocus,
+ window: &mut Window,
+ cx: &mut Context<Workspace>,
+ ) {
+ let Some(item) = workspace.recent_active_item_by_type::<Self>(cx) else {
+ return;
+ };
+ workspace.activate_item(&item, true, true, window, cx);
+ }
+
pub fn toggle_fold(
&mut self,
_: &actions::ToggleFold,
@@ -1711,6 +1711,27 @@ impl Workspace {
history
}
+ pub fn recent_active_item_by_type<T: 'static>(&self, cx: &App) -> Option<Entity<T>> {
+ let mut recent_item: Option<Entity<T>> = None;
+ let mut recent_timestamp = 0;
+ for pane_handle in &self.panes {
+ let pane = pane_handle.read(cx);
+ let item_map: HashMap<EntityId, &Box<dyn ItemHandle>> =
+ pane.items().map(|item| (item.item_id(), item)).collect();
+ for entry in pane.activation_history() {
+ if entry.timestamp > recent_timestamp {
+ if let Some(&item) = item_map.get(&entry.entity_id) {
+ if let Some(typed_item) = item.act_as::<T>(cx) {
+ recent_timestamp = entry.timestamp;
+ recent_item = Some(typed_item);
+ }
+ }
+ }
+ }
+ }
+ recent_item
+ }
+
pub fn recent_navigation_history_iter(
&self,
cx: &App,