mirror of
https://github.com/TECHNOFAB11/tmux-copyrat.git
synced 2025-12-12 16:10:07 +01:00
refactor: capture as method on Pane
This commit is contained in:
parent
34f05e1fae
commit
8924af3c51
2 changed files with 52 additions and 55 deletions
|
|
@ -9,14 +9,14 @@ fn main() -> Result<(), error::ParseError> {
|
|||
let config = ConfigExt::initialize()?;
|
||||
|
||||
// Identify active pane and capture its content.
|
||||
let panes: Vec<tmux::Pane> = tmux::list_panes()?;
|
||||
let panes: Vec<tmux::Pane> = tmux::available_panes()?;
|
||||
|
||||
let active_pane = panes
|
||||
.into_iter()
|
||||
.find(|p| p.is_active)
|
||||
.expect("Exactly one tmux pane should be active in the current window.");
|
||||
|
||||
let buffer = tmux::capture_pane(&active_pane, &config.capture_region)?;
|
||||
let buffer = active_pane.capture(&config.capture_region)?;
|
||||
let lines = buffer.split('\n').collect::<Vec<_>>();
|
||||
|
||||
// We have to dance a little with Panes, because this process' i/o streams
|
||||
|
|
|
|||
103
src/tmux.rs
103
src/tmux.rs
|
|
@ -53,11 +53,6 @@ impl FromStr for Pane {
|
|||
// Pane id must be start with '%' followed by a `u32`
|
||||
let id_str = iter.next().unwrap();
|
||||
let id = PaneId::from_str(id_str)?;
|
||||
// if !id_str.starts_with('%') {
|
||||
// return Err(ParseError::ExpectedPaneIdMarker);
|
||||
// }
|
||||
// let id = id_str[1..].parse::<u32>()?;
|
||||
// let id = format!("%{}", id);
|
||||
|
||||
let is_copy_mode = iter.next().unwrap().parse::<bool>()?;
|
||||
|
||||
|
|
@ -83,6 +78,53 @@ impl FromStr for Pane {
|
|||
}
|
||||
}
|
||||
|
||||
impl Pane {
|
||||
/// Returns the entire Pane content as a `String`.
|
||||
///
|
||||
/// The provided `region` specifies if the visible area is captured, or the
|
||||
/// entire history.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// In Tmux, the start line is the line at the top of the pane. The end line
|
||||
/// is the last line at the bottom of the pane.
|
||||
///
|
||||
/// - In normal mode, the index of the start line is always 0. The index of
|
||||
/// the end line is always the pane's height minus one. These do not need to
|
||||
/// be specified when capturing the pane's content.
|
||||
///
|
||||
/// - If navigating history in copy mode, the index of the start line is the
|
||||
/// opposite of the pane's scroll position. For instance a pane of 40 lines,
|
||||
/// scrolled up by 3 lines. It is necessarily in copy mode. Its start line
|
||||
/// index is `-3`. The index of the last line is `(40-1) - 3 = 36`.
|
||||
///
|
||||
pub fn capture(&self, region: &CaptureRegion) -> Result<String, ParseError> {
|
||||
let mut args_str = format!("capture-pane -t {pane_id} -J -p", pane_id = self.id);
|
||||
|
||||
let region_str = match region {
|
||||
CaptureRegion::VisibleArea => {
|
||||
if self.is_copy_mode && self.scroll_position > 0 {
|
||||
format!(
|
||||
" -S {start} -E {end}",
|
||||
start = -self.scroll_position,
|
||||
end = self.height - self.scroll_position - 1
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
CaptureRegion::EntireHistory => String::from(" -S - -E -"),
|
||||
};
|
||||
|
||||
args_str.push_str(®ion_str);
|
||||
|
||||
let args: Vec<&str> = args_str.split(' ').collect();
|
||||
|
||||
let output = duct::cmd("tmux", &args).read()?;
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct PaneId(String);
|
||||
|
||||
|
|
@ -90,12 +132,12 @@ impl FromStr for PaneId {
|
|||
type Err = ParseError;
|
||||
|
||||
/// Parse into PaneId. The `&str` must be start with '%'
|
||||
/// followed by a `u32`.
|
||||
/// followed by a `u16`.
|
||||
fn from_str(src: &str) -> Result<Self, Self::Err> {
|
||||
if !src.starts_with('%') {
|
||||
return Err(ParseError::ExpectedPaneIdMarker);
|
||||
}
|
||||
let id = src[1..].parse::<u32>()?;
|
||||
let id = src[1..].parse::<u16>()?;
|
||||
let id = format!("%{}", id);
|
||||
Ok(PaneId(id))
|
||||
}
|
||||
|
|
@ -114,7 +156,7 @@ impl fmt::Display for PaneId {
|
|||
}
|
||||
|
||||
/// Returns a list of `Pane` from the current tmux session.
|
||||
pub fn list_panes() -> Result<Vec<Pane>, ParseError> {
|
||||
pub fn available_panes() -> Result<Vec<Pane>, ParseError> {
|
||||
let args = vec![
|
||||
"list-panes",
|
||||
"-F",
|
||||
|
|
@ -162,51 +204,6 @@ pub fn get_options(prefix: &str) -> Result<HashMap<String, String>, ParseError>
|
|||
Ok(args)
|
||||
}
|
||||
|
||||
/// Returns the entire Pane content as a `String`.
|
||||
///
|
||||
/// The provided `region` specifies if the visible area is captured, or the
|
||||
/// entire history.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// In Tmux, the start line is the line at the top of the pane. The end line
|
||||
/// is the last line at the bottom of the pane.
|
||||
///
|
||||
/// - In normal mode, the index of the start line is always 0. The index of
|
||||
/// the end line is always the pane's height minus one. These do not need to
|
||||
/// be specified when capturing the pane's content.
|
||||
///
|
||||
/// - If navigating history in copy mode, the index of the start line is the
|
||||
/// opposite of the pane's scroll position. For instance a pane of 40 lines,
|
||||
/// scrolled up by 3 lines. It is necessarily in copy mode. Its start line
|
||||
/// index is `-3`. The index of the last line is `(40-1) - 3 = 36`.
|
||||
///
|
||||
pub fn capture_pane(pane: &Pane, region: &CaptureRegion) -> Result<String, ParseError> {
|
||||
let mut args_str = format!("capture-pane -t {pane_id} -J -p", pane_id = pane.id);
|
||||
|
||||
let region_str = match region {
|
||||
CaptureRegion::VisibleArea => {
|
||||
if pane.is_copy_mode && pane.scroll_position > 0 {
|
||||
format!(
|
||||
" -S {start} -E {end}",
|
||||
start = -pane.scroll_position,
|
||||
end = pane.height - pane.scroll_position - 1
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
CaptureRegion::EntireHistory => String::from(" -S - -E -"),
|
||||
};
|
||||
|
||||
args_str.push_str(®ion_str);
|
||||
|
||||
let args: Vec<&str> = args_str.split(' ').collect();
|
||||
|
||||
let output = duct::cmd("tmux", &args).read()?;
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
/// Ask tmux to swap the current Pane with the target_pane (uses Tmux format).
|
||||
pub fn swap_pane_with(target_pane: &str) -> Result<(), ParseError> {
|
||||
// -Z: keep the window zoomed if it was zoomed.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue