mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +03:00
refactor: move split_pane logic from mux server to mux
This commit is contained in:
parent
3947014bad
commit
31c754f6e4
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2306,6 +2306,7 @@ dependencies = [
|
||||
"metrics",
|
||||
"mlua",
|
||||
"ntapi",
|
||||
"percent-encoding",
|
||||
"portable-pty",
|
||||
"procinfo",
|
||||
"promise",
|
||||
@ -4833,7 +4834,6 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"mux",
|
||||
"percent-encoding",
|
||||
"portable-pty",
|
||||
"promise",
|
||||
"rangeset",
|
||||
|
@ -23,6 +23,7 @@ log = "0.4"
|
||||
luahelper = { path = "../luahelper" }
|
||||
metrics = { version="0.17", features=["std"]}
|
||||
mlua = "0.7"
|
||||
percent-encoding = "2"
|
||||
portable-pty = { path = "../pty", features = ["serde_support"]}
|
||||
procinfo = { path = "../procinfo" }
|
||||
promise = { path = "../promise" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::client::{ClientId, ClientInfo};
|
||||
use crate::pane::{Pane, PaneId};
|
||||
use crate::tab::{Tab, TabId};
|
||||
use crate::tab::{SplitDirection, Tab, TabId};
|
||||
use crate::window::{Window, WindowId};
|
||||
use anyhow::{anyhow, Context, Error};
|
||||
use config::keyassignment::SpawnTabDomain;
|
||||
@ -11,6 +11,7 @@ use filedescriptor::{socketpair, AsRawSocketDescriptor, FileDescriptor};
|
||||
use libc::{SOL_SOCKET, SO_RCVBUF, SO_SNDBUF};
|
||||
use log::error;
|
||||
use metrics::histogram;
|
||||
use percent_encoding::percent_decode_str;
|
||||
use portable_pty::{CommandBuilder, ExitStatus, PtySize};
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
@ -700,6 +701,80 @@ impl Mux {
|
||||
*self.banner.borrow_mut() = banner;
|
||||
}
|
||||
|
||||
pub async fn split_pane(
|
||||
&self,
|
||||
// TODO: disambiguate with TabId
|
||||
pane_id: PaneId,
|
||||
direction: SplitDirection,
|
||||
command: Option<CommandBuilder>,
|
||||
command_dir: Option<String>,
|
||||
domain: config::keyassignment::SpawnTabDomain,
|
||||
) -> anyhow::Result<(Rc<dyn Pane>, PtySize)> {
|
||||
let (pane_domain_id, _window_id, tab_id) = self
|
||||
.resolve_pane_id(pane_id)
|
||||
.ok_or_else(|| anyhow!("pane_id {} invalid", pane_id))?;
|
||||
|
||||
let domain = match domain {
|
||||
SpawnTabDomain::DefaultDomain => self.default_domain(),
|
||||
SpawnTabDomain::CurrentPaneDomain => self
|
||||
.get_domain(pane_domain_id)
|
||||
.expect("resolve_pane_id to give valid domain_id"),
|
||||
SpawnTabDomain::DomainId(domain_id) => self
|
||||
.get_domain(domain_id)
|
||||
.ok_or_else(|| anyhow!("domain id {} is invalid", domain_id))?,
|
||||
SpawnTabDomain::DomainName(name) => self
|
||||
.get_domain_by_name(&name)
|
||||
.ok_or_else(|| anyhow!("domain name {} is invalid", name))?,
|
||||
};
|
||||
|
||||
let current_pane = self
|
||||
.get_pane(pane_id)
|
||||
.ok_or_else(|| anyhow!("pane_id {} is invalid", pane_id))?;
|
||||
let term_config = current_pane.get_config();
|
||||
|
||||
let cwd = command_dir.or_else(|| {
|
||||
self.get_pane(pane_id)
|
||||
.and_then(|pane| pane.get_current_working_dir())
|
||||
.and_then(|url| {
|
||||
percent_decode_str(url.path())
|
||||
.decode_utf8()
|
||||
.ok()
|
||||
.map(|path| path.into_owned())
|
||||
})
|
||||
.map(|path| {
|
||||
// On Windows the file URI can produce a path like:
|
||||
// `/C:\Users` which is valid in a file URI, but the leading slash
|
||||
// is not liked by the windows file APIs, so we strip it off here.
|
||||
let bytes = path.as_bytes();
|
||||
if bytes.len() > 2 && bytes[0] == b'/' && bytes[2] == b':' {
|
||||
path[1..].to_owned()
|
||||
} else {
|
||||
path
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let pane = domain
|
||||
.split_pane(command, cwd, tab_id, pane_id, direction)
|
||||
.await?;
|
||||
if let Some(config) = term_config {
|
||||
pane.set_config(config);
|
||||
}
|
||||
|
||||
// FIXME: clipboard
|
||||
|
||||
let dims = pane.get_dimensions();
|
||||
|
||||
let size = PtySize {
|
||||
cols: dims.cols as u16,
|
||||
rows: dims.viewport_rows as u16,
|
||||
pixel_height: 0, // FIXME: split pane pixel dimensions
|
||||
pixel_width: 0,
|
||||
};
|
||||
|
||||
Ok((pane, size))
|
||||
}
|
||||
|
||||
pub async fn spawn_tab_or_window(
|
||||
&self,
|
||||
window_id: Option<WindowId>,
|
||||
|
@ -16,7 +16,6 @@ hostname = "0.3"
|
||||
lazy_static = "1.4"
|
||||
log = "0.4"
|
||||
mux = { path = "../mux" }
|
||||
percent-encoding = "2"
|
||||
portable-pty = { path = "../pty", features = ["serde_support"]}
|
||||
promise = { path = "../promise" }
|
||||
rangeset = { path = "../rangeset" }
|
||||
|
@ -1,14 +1,11 @@
|
||||
use crate::PKI;
|
||||
use anyhow::{anyhow, Context};
|
||||
use codec::*;
|
||||
use config::keyassignment::SpawnTabDomain;
|
||||
use mux::client::ClientId;
|
||||
use mux::pane::{Pane, PaneId};
|
||||
use mux::renderable::{RenderableDimensions, StableCursorPosition};
|
||||
use mux::tab::TabId;
|
||||
use mux::Mux;
|
||||
use percent_encoding::percent_decode_str;
|
||||
use portable_pty::PtySize;
|
||||
use promise::spawn::spawn_into_main_thread;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
@ -698,70 +695,25 @@ impl Clipboard for RemoteClipboard {
|
||||
|
||||
async fn split_pane(split: SplitPane, sender: PduSender) -> anyhow::Result<Pdu> {
|
||||
let mux = Mux::get().unwrap();
|
||||
let (pane_domain_id, window_id, tab_id) = mux
|
||||
let (_pane_domain_id, window_id, tab_id) = mux
|
||||
.resolve_pane_id(split.pane_id)
|
||||
.ok_or_else(|| anyhow!("pane_id {} invalid", split.pane_id))?;
|
||||
|
||||
let domain = match split.domain {
|
||||
SpawnTabDomain::DefaultDomain => mux.default_domain(),
|
||||
SpawnTabDomain::CurrentPaneDomain => mux
|
||||
.get_domain(pane_domain_id)
|
||||
.expect("resolve_pane_id to give valid domain_id"),
|
||||
SpawnTabDomain::DomainId(domain_id) => mux
|
||||
.get_domain(domain_id)
|
||||
.ok_or_else(|| anyhow!("domain id {} is invalid", domain_id))?,
|
||||
SpawnTabDomain::DomainName(name) => mux
|
||||
.get_domain_by_name(&name)
|
||||
.ok_or_else(|| anyhow!("domain name {} is invalid", name))?,
|
||||
};
|
||||
|
||||
let pane_id = split.pane_id;
|
||||
let current_pane = mux
|
||||
.get_pane(pane_id)
|
||||
.ok_or_else(|| anyhow!("pane_id {} is invalid", pane_id))?;
|
||||
let term_config = current_pane.get_config();
|
||||
|
||||
let cwd = split.command_dir.or_else(|| {
|
||||
mux.get_pane(pane_id)
|
||||
.and_then(|pane| pane.get_current_working_dir())
|
||||
.and_then(|url| {
|
||||
percent_decode_str(url.path())
|
||||
.decode_utf8()
|
||||
.ok()
|
||||
.map(|path| path.into_owned())
|
||||
})
|
||||
.map(|path| {
|
||||
// On Windows the file URI can produce a path like:
|
||||
// `/C:\Users` which is valid in a file URI, but the leading slash
|
||||
// is not liked by the windows file APIs, so we strip it off here.
|
||||
let bytes = path.as_bytes();
|
||||
if bytes.len() > 2 && bytes[0] == b'/' && bytes[2] == b':' {
|
||||
path[1..].to_owned()
|
||||
} else {
|
||||
path
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let pane = domain
|
||||
.split_pane(split.command, cwd, tab_id, split.pane_id, split.direction)
|
||||
let (pane, size) = mux
|
||||
.split_pane(
|
||||
split.pane_id,
|
||||
split.direction,
|
||||
split.command,
|
||||
split.command_dir,
|
||||
split.domain,
|
||||
)
|
||||
.await?;
|
||||
let dims = pane.get_dimensions();
|
||||
let size = PtySize {
|
||||
cols: dims.cols as u16,
|
||||
rows: dims.viewport_rows as u16,
|
||||
pixel_height: 0,
|
||||
pixel_width: 0,
|
||||
};
|
||||
|
||||
let clip: Arc<dyn Clipboard> = Arc::new(RemoteClipboard {
|
||||
pane_id: pane.pane_id(),
|
||||
sender,
|
||||
});
|
||||
pane.set_clipboard(&clip);
|
||||
if let Some(config) = term_config {
|
||||
pane.set_config(config);
|
||||
}
|
||||
|
||||
Ok::<Pdu, anyhow::Error>(Pdu::SpawnResponse(SpawnResponse {
|
||||
pane_id: pane.pane_id(),
|
||||
|
Loading…
Reference in New Issue
Block a user