mirror of
https://github.com/wez/wezterm.git
synced 2024-12-28 07:55:03 +03:00
170 lines
4.5 KiB
Rust
170 lines
4.5 KiB
Rust
use crate::tmux::{RefTmuxRemotePane, TmuxCmdQueue, TmuxDomainState};
|
|
use crate::tmux_commands::{Resize, SendKeys};
|
|
use crate::DomainId;
|
|
use filedescriptor::FileDescriptor;
|
|
use parking_lot::{Condvar, Mutex};
|
|
use portable_pty::{Child, ChildKiller, ExitStatus, MasterPty};
|
|
use std::io::{Read, Write};
|
|
use std::sync::Arc;
|
|
|
|
/// A local tmux pane(tab) based on a tmux pty
|
|
#[derive(Debug)]
|
|
pub(crate) struct TmuxPty {
|
|
pub domain_id: DomainId,
|
|
pub master_pane: RefTmuxRemotePane,
|
|
pub reader: FileDescriptor,
|
|
pub cmd_queue: Arc<Mutex<TmuxCmdQueue>>,
|
|
}
|
|
|
|
struct TmuxPtyWriter {
|
|
domain_id: DomainId,
|
|
master_pane: RefTmuxRemotePane,
|
|
cmd_queue: Arc<Mutex<TmuxCmdQueue>>,
|
|
}
|
|
|
|
impl Write for TmuxPtyWriter {
|
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
|
let pane_id = {
|
|
let pane_lock = self.master_pane.lock();
|
|
pane_lock.pane_id
|
|
};
|
|
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
|
|
let mut cmd_queue = self.cmd_queue.lock();
|
|
cmd_queue.push_back(Box::new(SendKeys {
|
|
pane: pane_id,
|
|
keys: buf.to_vec(),
|
|
}));
|
|
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
|
Ok(0)
|
|
}
|
|
|
|
fn flush(&mut self) -> std::io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Write for TmuxPty {
|
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
|
let pane_id = {
|
|
let pane_lock = self.master_pane.lock();
|
|
pane_lock.pane_id
|
|
};
|
|
log::trace!("pane:{}, content:{:?}", &pane_id, buf);
|
|
let mut cmd_queue = self.cmd_queue.lock();
|
|
cmd_queue.push_back(Box::new(SendKeys {
|
|
pane: pane_id,
|
|
keys: buf.to_vec(),
|
|
}));
|
|
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
|
Ok(0)
|
|
}
|
|
|
|
fn flush(&mut self) -> std::io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub(crate) struct TmuxChild {
|
|
pub active_lock: Arc<(Mutex<bool>, Condvar)>,
|
|
}
|
|
|
|
impl Child for TmuxChild {
|
|
fn try_wait(&mut self) -> std::io::Result<Option<portable_pty::ExitStatus>> {
|
|
todo!()
|
|
}
|
|
|
|
fn wait(&mut self) -> std::io::Result<portable_pty::ExitStatus> {
|
|
let &(ref lock, ref var) = &*self.active_lock;
|
|
let mut released = lock.lock();
|
|
while !*released {
|
|
var.wait(&mut released);
|
|
}
|
|
return Ok(ExitStatus::with_exit_code(0));
|
|
}
|
|
|
|
fn process_id(&self) -> Option<u32> {
|
|
Some(0)
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn as_raw_handle(&self) -> Option<std::os::windows::io::RawHandle> {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
struct TmuxChildKiller {}
|
|
|
|
impl ChildKiller for TmuxChildKiller {
|
|
fn kill(&mut self) -> std::io::Result<()> {
|
|
Err(std::io::Error::new(
|
|
std::io::ErrorKind::Other,
|
|
"TmuxChildKiller: kill not implemented!",
|
|
))
|
|
}
|
|
|
|
fn clone_killer(&self) -> Box<dyn ChildKiller + Send + Sync> {
|
|
Box::new(self.clone())
|
|
}
|
|
}
|
|
|
|
impl ChildKiller for TmuxChild {
|
|
fn kill(&mut self) -> std::io::Result<()> {
|
|
Err(std::io::Error::new(
|
|
std::io::ErrorKind::Other,
|
|
"TmuxPty: kill not implemented!",
|
|
))
|
|
}
|
|
|
|
fn clone_killer(&self) -> Box<dyn ChildKiller + Send + Sync> {
|
|
Box::new(TmuxChildKiller {})
|
|
}
|
|
}
|
|
|
|
impl MasterPty for TmuxPty {
|
|
fn resize(&self, size: portable_pty::PtySize) -> Result<(), anyhow::Error> {
|
|
let mut cmd_queue = self.cmd_queue.lock();
|
|
cmd_queue.push_back(Box::new(Resize { size }));
|
|
TmuxDomainState::schedule_send_next_command(self.domain_id);
|
|
Ok(())
|
|
}
|
|
|
|
fn get_size(&self) -> Result<portable_pty::PtySize, anyhow::Error> {
|
|
let pane = self.master_pane.lock();
|
|
Ok(portable_pty::PtySize {
|
|
rows: pane.pane_height as u16,
|
|
cols: pane.pane_width as u16,
|
|
pixel_width: 0,
|
|
pixel_height: 0,
|
|
})
|
|
}
|
|
|
|
fn try_clone_reader(&self) -> Result<Box<dyn Read + Send>, anyhow::Error> {
|
|
Ok(Box::new(self.reader.try_clone()?))
|
|
}
|
|
|
|
fn take_writer(&self) -> Result<Box<dyn Write + Send>, anyhow::Error> {
|
|
Ok(Box::new(TmuxPtyWriter {
|
|
domain_id: self.domain_id,
|
|
master_pane: self.master_pane.clone(),
|
|
cmd_queue: self.cmd_queue.clone(),
|
|
}))
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn process_group_leader(&self) -> Option<libc::pid_t> {
|
|
return None;
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
|
|
None
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn tty_name(&self) -> Option<std::path::PathBuf> {
|
|
None
|
|
}
|
|
}
|