Skip to content

Commit

Permalink
add zoom-pane subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
quantonganh committed Aug 28, 2023
1 parent a9c7d28 commit 0b5aa7d
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 3 deletions.
8 changes: 8 additions & 0 deletions mux/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,10 @@ impl Tab {
.lock()
.split_and_insert(pane_index, request, pane)
}

pub fn get_zoomed_pane(&self) -> Option<Arc<dyn Pane>> {
self.inner.lock().get_zoomed_pane()
}
}

impl TabInner {
Expand Down Expand Up @@ -2051,6 +2055,10 @@ impl TabInner {
pane_index
})
}

fn get_zoomed_pane(&self) -> Option<Arc<dyn Pane>> {
self.zoomed.clone()
}
}

/// This type is used directly by the codec, take care to bump
Expand Down
9 changes: 6 additions & 3 deletions wezterm-mux-server-impl/src/sessionhandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,11 @@ impl SessionHandler {
let tab = mux
.get_tab(containing_tab_id)
.ok_or_else(|| anyhow!("no such tab {}", containing_tab_id))?;
tab.set_active_pane(&pane);
tab.set_zoomed(zoomed);
tab.set_zoomed(false);
if zoomed {
tab.set_active_pane(&pane);
tab.set_zoomed(zoomed);
}
Ok(Pdu::UnitResponse(UnitResponse {}))
},
send_response,
Expand Down Expand Up @@ -1021,7 +1024,7 @@ async fn split_pane(split: SplitPane, client_id: Option<Arc<ClientId>>) -> anyho

Ok::<Pdu, anyhow::Error>(Pdu::SpawnResponse(SpawnResponse {
pane_id: pane.pane_id(),
tab_id: tab_id,
tab_id,
window_id,
size,
}))
Expand Down
6 changes: 6 additions & 0 deletions wezterm/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod set_window_title;
mod spawn_command;
mod split_pane;
mod tls_creds;
mod zoom_pane;

#[derive(Debug, Parser, Clone, Copy)]
enum CliOutputFormatKind {
Expand Down Expand Up @@ -159,6 +160,10 @@ Outputs the pane-id for the newly created pane on success"
/// Rename a workspace
#[command(name = "rename-workspace", rename_all = "kebab")]
RenameWorkspace(rename_workspace::RenameWorkspace),

/// Zoom, unzoom, or toggle zoom state
#[command(name = "zoom-pane", rename_all = "kebab")]
ZoomPane(zoom_pane::ZoomPane),
}

async fn run_cli_async(opts: &crate::Opt, cli: CliCommand) -> anyhow::Result<()> {
Expand Down Expand Up @@ -194,6 +199,7 @@ async fn run_cli_async(opts: &crate::Opt, cli: CliCommand) -> anyhow::Result<()>
CliSubCommand::SetTabTitle(cmd) => cmd.run(client).await,
CliSubCommand::SetWindowTitle(cmd) => cmd.run(client).await,
CliSubCommand::RenameWorkspace(cmd) => cmd.run(client).await,
CliSubCommand::ZoomPane(cmd) => cmd.run(client).await,
}
}

Expand Down
109 changes: 109 additions & 0 deletions wezterm/src/cli/zoom_pane.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use crate::cli::resolve_pane_id;
use anyhow::{anyhow, Result};
use clap::Parser;
use codec::SetPaneZoomed;
use mux::pane::PaneId;
use std::collections::HashMap;
use wezterm_client::client::Client;

#[derive(Debug, Parser, Clone)]
pub struct ZoomPane {
/// Specify the target pane.
/// The default is to use the current pane based on the
/// environment variable WEZTERM_PANE.
#[arg(long)]
pane_id: Option<PaneId>,

/// Zooms the pane if it wasn't already zoomed
#[arg(long, default_value = "true")]
zoom: bool,

/// Unzooms the pane if it was zoomed
#[arg(long)]
unzoom: bool,

/// Toggles the zoom state of the pane
#[arg(long)]
toggle: bool,
}

impl ZoomPane {
pub async fn run(&self, client: Client) -> Result<()> {
let panes = client.list_panes().await?;

let mut pane_id_to_tab_id = HashMap::new();
let mut tab_id_to_active_zoomed_pane_id = HashMap::new();

for tabroot in panes.tabs {
let mut cursor = tabroot.into_tree().cursor();

loop {
if let Some(entry) = cursor.leaf_mut() {
pane_id_to_tab_id.insert(entry.pane_id, entry.tab_id);
if entry.is_active_pane && entry.is_zoomed_pane {
tab_id_to_active_zoomed_pane_id.insert(entry.tab_id, entry.pane_id);
}
}
match cursor.preorder_next() {
Ok(c) => cursor = c,
Err(_) => break,
}
}
}

let pane_id = resolve_pane_id(&client, self.pane_id).await?;
let containing_tab_id = pane_id_to_tab_id
.get(&pane_id)
.copied()
.ok_or_else(|| anyhow!("unable to resolve current tab"))?;

if self.zoom {
client
.set_zoomed(SetPaneZoomed {
containing_tab_id,
pane_id,
zoomed: true,
})
.await?;
}

if self.unzoom {
client
.set_zoomed(SetPaneZoomed {
containing_tab_id,
pane_id,
zoomed: false,
})
.await?;
}

if self.toggle {
if tab_id_to_active_zoomed_pane_id.contains_key(&containing_tab_id) {
let target_pane = tab_id_to_active_zoomed_pane_id
.get(&containing_tab_id)
.copied()
.ok_or_else(|| {
anyhow!("could not determine which pane should be active for tab {containing_tab_id}")
})?;
if target_pane == pane_id {
client
.set_zoomed(SetPaneZoomed {
containing_tab_id,
pane_id,
zoomed: false,
})
.await?;
}
} else {
client
.set_zoomed(SetPaneZoomed {
containing_tab_id,
pane_id,
zoomed: true,
})
.await?;
}
}
Ok(())
}
}

0 comments on commit 0b5aa7d

Please sign in to comment.