tab_switcher: Add support for tab switcher in assistant panel (#15475)

Additionally, I've generalized the implementation of tab switcher so
that - instead of explicitly listing panels it supports (at the time of
writing it was just the terminal panel and nothing else), it now relies
on Panel::pane trait method. As long as that's implemented, you get a
tab switcher support for free.

Release Notes:

- Added support for tab switcher in Assistant panel.
This commit is contained in:
Piotr Osiewicz 2024-07-30 13:32:13 +02:00 committed by GitHub
parent 0540291204
commit 530feecdaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 35 additions and 32 deletions

1
Cargo.lock generated
View file

@ -10760,7 +10760,6 @@ dependencies = [
"project", "project",
"serde", "serde",
"serde_json", "serde_json",
"terminal_view",
"theme", "theme",
"ui", "ui",
"util", "util",

View file

@ -686,13 +686,11 @@ impl AssistantPanel {
.focus_handle(cx) .focus_handle(cx)
.contains_focused(cx) .contains_focused(cx)
{ {
if let Some(terminal_view) = terminal_panel if let Some(terminal_view) = terminal_panel.read(cx).pane().and_then(|pane| {
.read(cx) pane.read(cx)
.pane() .active_item()
.read(cx) .and_then(|t| t.downcast::<TerminalView>())
.active_item() }) {
.and_then(|t| t.downcast::<TerminalView>())
{
return Some(InlineAssistTarget::Terminal(terminal_view)); return Some(InlineAssistTarget::Terminal(terminal_view));
} }
} }

View file

@ -9,7 +9,7 @@ use gpui::{AppContext, Task, WeakView};
use language::{CodeLabel, LspAdapterDelegate}; use language::{CodeLabel, LspAdapterDelegate};
use terminal_view::{terminal_panel::TerminalPanel, TerminalView}; use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
use ui::prelude::*; use ui::prelude::*;
use workspace::Workspace; use workspace::{dock::Panel, Workspace};
use super::create_label_for_command; use super::create_label_for_command;
@ -65,13 +65,11 @@ impl SlashCommand for TermSlashCommand {
let Some(terminal_panel) = workspace.read(cx).panel::<TerminalPanel>(cx) else { let Some(terminal_panel) = workspace.read(cx).panel::<TerminalPanel>(cx) else {
return Task::ready(Err(anyhow::anyhow!("no terminal panel open"))); return Task::ready(Err(anyhow::anyhow!("no terminal panel open")));
}; };
let Some(active_terminal) = terminal_panel let Some(active_terminal) = terminal_panel.read(cx).pane().and_then(|pane| {
.read(cx) pane.read(cx)
.pane() .active_item()
.read(cx) .and_then(|t| t.downcast::<TerminalView>())
.active_item() }) else {
.and_then(|t| t.downcast::<TerminalView>())
else {
return Task::ready(Err(anyhow::anyhow!("no active terminal"))); return Task::ready(Err(anyhow::anyhow!("no active terminal")));
}; };

View file

@ -18,7 +18,6 @@ gpui.workspace = true
menu.workspace = true menu.workspace = true
picker.workspace = true picker.workspace = true
serde.workspace = true serde.workspace = true
terminal_view.workspace = true
ui.workspace = true ui.workspace = true
util.workspace = true util.workspace = true
workspace.workspace = true workspace.workspace = true

View file

@ -57,16 +57,25 @@ impl TabSwitcher {
} }
fn open(action: &Toggle, workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) { fn open(action: &Toggle, workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
let terminal = workspace.panel::<terminal_view::terminal_panel::TerminalPanel>(cx); let mut weak_pane = workspace.active_pane().downgrade();
let terminal_pane = terminal.and_then(|terminal| { for dock in [
terminal workspace.left_dock(),
.focus_handle(cx) workspace.bottom_dock(),
.contains_focused(cx) workspace.right_dock(),
.then(|| terminal.read(cx).pane()) ] {
}); dock.update(cx, |this, cx| {
let weak_pane = terminal_pane let Some(panel) = this
.unwrap_or_else(|| workspace.active_pane()) .active_panel()
.downgrade(); .filter(|panel| panel.focus_handle(cx).contains_focused(cx))
else {
return;
};
if let Some(pane) = panel.pane(cx) {
weak_pane = pane.downgrade();
}
})
}
workspace.toggle_modal(cx, |cx| { workspace.toggle_modal(cx, |cx| {
let delegate = TabSwitcherDelegate::new(action, cx.view().downgrade(), weak_pane, cx); let delegate = TabSwitcherDelegate::new(action, cx.view().downgrade(), weak_pane, cx);
TabSwitcher::new(delegate, cx) TabSwitcher::new(delegate, cx)

View file

@ -171,7 +171,7 @@ impl TerminalPanel {
fn apply_tab_bar_buttons(&self, cx: &mut ViewContext<Self>) { fn apply_tab_bar_buttons(&self, cx: &mut ViewContext<Self>) {
let additional_buttons = self.additional_tab_bar_buttons.clone(); let additional_buttons = self.additional_tab_bar_buttons.clone();
self.pane().update(cx, |pane, cx| { self.pane.update(cx, |pane, cx| {
pane.set_render_tab_bar_buttons(cx, move |pane, cx| { pane.set_render_tab_bar_buttons(cx, move |pane, cx| {
h_flex() h_flex()
.gap_2() .gap_2()
@ -683,10 +683,6 @@ impl TerminalPanel {
Some(()) Some(())
} }
pub fn pane(&self) -> &View<Pane> {
&self.pane
}
fn has_no_terminals(&self, cx: &WindowContext) -> bool { fn has_no_terminals(&self, cx: &WindowContext) -> bool {
self.pane.read(cx).items_len() == 0 && self.pending_terminals_to_add == 0 self.pane.read(cx).items_len() == 0 && self.pending_terminals_to_add == 0
} }
@ -849,6 +845,10 @@ impl Panel for TerminalPanel {
fn toggle_action(&self) -> Box<dyn gpui::Action> { fn toggle_action(&self) -> Box<dyn gpui::Action> {
Box::new(ToggleFocus) Box::new(ToggleFocus)
} }
fn pane(&self) -> Option<View<Pane>> {
Some(self.pane.clone())
}
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]