mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 05:12:40 +03:00
expose the tty name associated with a pane
This commit is contained in:
parent
889390a448
commit
0ca050e09d
@ -431,7 +431,7 @@ macro_rules! pdu {
|
||||
/// The overall version of the codec.
|
||||
/// This must be bumped when backwards incompatible changes
|
||||
/// are made to the types and protocol.
|
||||
pub const CODEC_VERSION: usize = 40;
|
||||
pub const CODEC_VERSION: usize = 41;
|
||||
|
||||
// Defines the Pdu enum.
|
||||
// Each struct has an explicit identifying number.
|
||||
|
@ -64,6 +64,9 @@ As features stabilize some brief notes about them will accumulate here.
|
||||
* [wezterm cli rename-workspace](cli/cli/rename-workspace.md). #2787
|
||||
* [wezterm.mux.rename_workspace](config/lua/wezterm.mux/rename_workspace.md). #2787
|
||||
* [wezterm cli get-pane-direction](cli/cli/get-pane-direction.md)
|
||||
* [pane:get_tty_name()](config/lua/pane/get_tty_name.md) and
|
||||
[PaneInformation.tty_name](config/lua/PaneInformation.md) to reason about the
|
||||
tty name on local unix systems.
|
||||
|
||||
#### Fixed
|
||||
* mux: Stale remote window mapping could prevent spawning new tabs in remote domain. #2759
|
||||
|
@ -126,3 +126,7 @@ end)
|
||||
return config
|
||||
```
|
||||
|
||||
{{since('nightly')}}
|
||||
|
||||
The `tty_name` field returns the tty name with the same constraints as described
|
||||
in [pane:get_tty_name()](../pane/get_tty_name.md).
|
||||
|
27
docs/config/lua/pane/get_tty_name.md
Normal file
27
docs/config/lua/pane/get_tty_name.md
Normal file
@ -0,0 +1,27 @@
|
||||
# `pane:get_tty_name()`
|
||||
|
||||
{{since('nightly')}}
|
||||
|
||||
Returns the tty device name, or `nil` if the name is unavailable.
|
||||
|
||||
* This information is only available for local panes. Multiplexer panes do not report this information. Similarly, if you are using eg: `ssh` to connect to a remote host, you won't be able to access the name of the remote process that is running.
|
||||
* This information is only available on unix systems. Windows systems do not have an equivalent concept.
|
||||
|
||||
This example sets the right status to show the tty name:
|
||||
|
||||
```lua
|
||||
local wezterm = require 'wezterm'
|
||||
|
||||
wezterm.on('update-status', function(window, pane)
|
||||
local tty = pane:get_tty_name()
|
||||
if tty then
|
||||
window:set_right_status(tty)
|
||||
else
|
||||
window:set_right_status ''
|
||||
end
|
||||
end)
|
||||
|
||||
return {}
|
||||
```
|
||||
|
||||
|
@ -403,6 +403,12 @@ impl UserData for MuxPane {
|
||||
tab.set_active_pane(&pane);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method("get_tty_name", move |_lua, this, ()| {
|
||||
let mux = Mux::get();
|
||||
let pane = this.resolve(&mux)?;
|
||||
Ok(pane.tty_name())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,6 +457,11 @@ impl Pane for LocalPane {
|
||||
.or_else(|| self.divine_current_working_dir())
|
||||
}
|
||||
|
||||
fn tty_name(&self) -> Option<String> {
|
||||
let name = self.pty.lock().tty_name()?;
|
||||
Some(name.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
fn get_foreground_process_info(&self) -> Option<LocalProcessInfo> {
|
||||
#[cfg(unix)]
|
||||
if let Some(pid) = self.pty.lock().process_group_leader() {
|
||||
|
@ -345,6 +345,10 @@ pub trait Pane: Downcast + Send + Sync {
|
||||
None
|
||||
}
|
||||
|
||||
fn tty_name(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn trickle_paste(&self, text: String) -> anyhow::Result<()> {
|
||||
if text.len() <= PASTE_CHUNK_SIZE {
|
||||
// Send it all now
|
||||
|
@ -996,6 +996,11 @@ impl portable_pty::MasterPty for WrappedSshPty {
|
||||
fn as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn tty_name(&self) -> Option<std::path::PathBuf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl std::io::Write for PtyWriter {
|
||||
|
@ -277,6 +277,7 @@ fn pane_tree(
|
||||
physical_top: dims.physical_top,
|
||||
left_col,
|
||||
top_row,
|
||||
tty_name: pane.tty_name(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2110,6 +2111,7 @@ pub struct PaneEntry {
|
||||
pub physical_top: StableRowIndex,
|
||||
pub top_row: usize,
|
||||
pub left_col: usize,
|
||||
pub tty_name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Serialize, PartialEq, Debug)]
|
||||
|
@ -161,4 +161,9 @@ impl MasterPty for TmuxPty {
|
||||
fn as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn tty_name(&self) -> Option<std::path::PathBuf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,9 @@ pub trait MasterPty {
|
||||
#[cfg(unix)]
|
||||
fn as_raw_fd(&self) -> Option<unix::RawFd>;
|
||||
|
||||
#[cfg(unix)]
|
||||
fn tty_name(&self) -> Option<std::path::PathBuf>;
|
||||
|
||||
/// If applicable to the type of the tty, return the termios
|
||||
/// associated with the stream
|
||||
#[cfg(unix)]
|
||||
|
@ -17,6 +17,7 @@ use serial::{
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::io::{Read, Result as IoResult, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -245,6 +246,11 @@ impl MasterPty for Master {
|
||||
fn as_raw_fd(&self) -> Option<crate::unix::RawFd> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn tty_name(&self) -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
struct Reader {
|
||||
|
@ -5,9 +5,12 @@ use anyhow::{bail, Error};
|
||||
use filedescriptor::FileDescriptor;
|
||||
use libc::{self, winsize};
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsStr;
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, mem, ptr};
|
||||
|
||||
pub use std::os::unix::io::RawFd;
|
||||
@ -42,9 +45,12 @@ fn openpty(size: PtySize) -> anyhow::Result<(UnixMasterPty, UnixSlavePty)> {
|
||||
bail!("failed to openpty: {:?}", io::Error::last_os_error());
|
||||
}
|
||||
|
||||
let tty_name = tty_name(slave);
|
||||
|
||||
let master = UnixMasterPty {
|
||||
fd: PtyFd(unsafe { FileDescriptor::from_raw_fd(master) }),
|
||||
took_writer: RefCell::new(false),
|
||||
tty_name,
|
||||
};
|
||||
let slave = UnixSlavePty {
|
||||
fd: PtyFd(unsafe { FileDescriptor::from_raw_fd(slave) }),
|
||||
@ -98,6 +104,33 @@ impl Read for PtyFd {
|
||||
}
|
||||
}
|
||||
|
||||
fn tty_name(fd: RawFd) -> Option<PathBuf> {
|
||||
let mut buf = vec![0 as std::ffi::c_char; 128];
|
||||
|
||||
loop {
|
||||
let res = unsafe { libc::ttyname_r(fd, buf.as_mut_ptr(), buf.len()) };
|
||||
|
||||
if res == libc::ERANGE {
|
||||
if buf.len() > 64 * 1024 {
|
||||
// on macOS, if the buf is "too big", ttyname_r can
|
||||
// return ERANGE, even though that is supposed to
|
||||
// indicate buf is "too small".
|
||||
return None;
|
||||
}
|
||||
buf.resize(buf.len() * 2, 0 as std::ffi::c_char);
|
||||
continue;
|
||||
}
|
||||
|
||||
return if res == 0 {
|
||||
let cstr = unsafe { std::ffi::CStr::from_ptr(buf.as_ptr()) };
|
||||
let osstr = OsStr::from_bytes(cstr.to_bytes());
|
||||
Some(PathBuf::from(osstr))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// On Big Sur, Cocoa leaks various file descriptors to child processes,
|
||||
/// so we need to make a pass through the open descriptors beyond just the
|
||||
/// stdio descriptors and close them all out.
|
||||
@ -269,6 +302,7 @@ impl PtyFd {
|
||||
struct UnixMasterPty {
|
||||
fd: PtyFd,
|
||||
took_writer: RefCell<bool>,
|
||||
tty_name: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Represents the slave end of a pty.
|
||||
@ -332,6 +366,10 @@ impl MasterPty for UnixMasterPty {
|
||||
Some(self.fd.0.as_raw_fd())
|
||||
}
|
||||
|
||||
fn tty_name(&self) -> Option<PathBuf> {
|
||||
self.tty_name.clone()
|
||||
}
|
||||
|
||||
fn process_group_leader(&self) -> Option<libc::pid_t> {
|
||||
match unsafe { libc::tcgetpgrp(self.fd.0.as_raw_fd()) } {
|
||||
pid if pid > 0 => Some(pid),
|
||||
|
@ -289,6 +289,15 @@ impl UserData for PaneInformation {
|
||||
None => Ok("".to_string()),
|
||||
}
|
||||
});
|
||||
fields.add_field_method_get("tty_name", |_, this| {
|
||||
let mut name = None;
|
||||
if let Some(mux) = Mux::try_get() {
|
||||
if let Some(pane) = mux.get_pane(this.pane_id) {
|
||||
name = pane.tty_name();
|
||||
}
|
||||
}
|
||||
Ok(name)
|
||||
});
|
||||
fields.add_field_method_get("current_working_dir", |_, this| {
|
||||
let mut name = None;
|
||||
if let Some(mux) = Mux::try_get() {
|
||||
|
@ -82,6 +82,11 @@ impl portable_pty::MasterPty for SshPty {
|
||||
fn as_raw_fd(&self) -> Option<std::os::fd::RawFd> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn tty_name(&self) -> Option<std::path::PathBuf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -138,6 +138,7 @@ struct CliListResultItem {
|
||||
window_title: String,
|
||||
is_active: bool,
|
||||
is_zoomed: bool,
|
||||
tty_name: Option<String>,
|
||||
}
|
||||
|
||||
impl CliListResultItem {
|
||||
@ -155,6 +156,7 @@ impl CliListResultItem {
|
||||
top_row,
|
||||
is_active_pane,
|
||||
is_zoomed_pane,
|
||||
tty_name,
|
||||
size:
|
||||
TerminalSize {
|
||||
rows,
|
||||
@ -194,6 +196,7 @@ impl CliListResultItem {
|
||||
window_title: window_title.to_string(),
|
||||
is_active: is_active_pane,
|
||||
is_zoomed: is_zoomed_pane,
|
||||
tty_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user