Skip to content

Commit

Permalink
feat(tmux): concurrent async comm with tmux
Browse files Browse the repository at this point in the history
  • Loading branch information
graelo committed Aug 18, 2022
1 parent cfd2e35 commit 4381b70
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 62 deletions.
33 changes: 0 additions & 33 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ edition = "2018"

[dependencies]
regex = "1.4"
duct = "0.13"
futures = "0.3"
tokio = { version = "1.4", features = ["fs", "macros", "process", "rt-multi-thread"] }
37 changes: 22 additions & 15 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,31 @@ use tokio::fs;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;

async fn app() -> Result<()> {
println!("Hello, world!");
let mut handles = Vec::new();

println!("---- sessions ----");
let sessions = tmux::session::available_sessions()?;
for session in sessions {
println!("{:?}", session);
}

println!("---- windows ----");
let windows = tmux::window::available_windows()?;
for window in windows {
println!("{:?}", window);
}
let handle = tokio::spawn(async move {
println!("---- sessions ----");
let sessions = tmux::session::available_sessions().await.unwrap();
for session in sessions {
println!("{:?}", session);
}
Ok(())
});
handles.push(handle);

let handle = tokio::spawn(async move {
println!("---- windows ----");
let windows = tmux::window::available_windows().await.unwrap();
for window in windows {
println!("{:?}", window);
}
Ok(())
});
handles.push(handle);

println!("---- panes ----");
let panes = tmux::pane::available_panes()?;
let panes = tmux::pane::available_panes().await?;

let mut handles = Vec::new();
for pane in panes {
let handle = tokio::spawn(async move {
let output = pane.capture().await.unwrap();
Expand All @@ -48,7 +55,7 @@ fn main() {
let rt = tokio::runtime::Runtime::new().unwrap();

match rt.block_on(app()) {
Ok(_) => println!("Done"),
Ok(_) => println!("✅ sessions persisted."),
Err(e) => println!("An error ocurred: {}", e),
};
}
19 changes: 12 additions & 7 deletions src/tmux/pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
use std::path::PathBuf;
use std::str::FromStr;

use tokio::process;

use super::pane_id::PaneId;
use crate::error;

Expand Down Expand Up @@ -144,14 +142,17 @@ impl Pane {
"-",
];

let output = process::Command::new("tmux").args(&args).output().await?;
// let text = String::from_utf8(output.stdout)?;
let output = tokio::process::Command::new("tmux")
.args(&args)
.output()
.await?;

Ok(output.stdout)
}
}

/// Returns a list of all `Pane` from all sessions.
pub fn available_panes() -> Result<Vec<Pane>, error::ParseError> {
pub async fn available_panes() -> Result<Vec<Pane>, error::ParseError> {
let args = vec![
"list-panes",
"-a",
Expand All @@ -166,11 +167,15 @@ pub fn available_panes() -> Result<Vec<Pane>, error::ParseError> {
:#{pane_current_command}",
];

let output = duct::cmd("tmux", &args).read()?;
let output = tokio::process::Command::new("tmux")
.args(&args)
.output()
.await?;
let buffer = String::from_utf8(output.stdout)?;

// Each call to `Pane::parse` returns a `Result<Pane, _>`. All results
// are collected into a Result<Vec<Pane>, _>, thanks to `collect()`.
let result: Result<Vec<Pane>, error::ParseError> = output
let result: Result<Vec<Pane>, error::ParseError> = buffer
.trim_end() // trim last '\n' as it would create an empty line
.split('\n')
.map(|line| Pane::from_str(line))
Expand Down
10 changes: 7 additions & 3 deletions src/tmux/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,18 @@ impl FromStr for Session {
}

/// Returns a list of all `Session` from the current tmux session.
pub fn available_sessions() -> Result<Vec<Session>, ParseError> {
pub async fn available_sessions() -> Result<Vec<Session>, ParseError> {
let args = vec!["list-sessions", "-F", "#{session_id}:#{session_name}"];

let output = duct::cmd("tmux", &args).read()?;
let output = tokio::process::Command::new("tmux")
.args(&args)
.output()
.await?;
let buffer = String::from_utf8(output.stdout)?;

// Each call to `Session::parse` returns a `Result<Session, _>`. All results
// are collected into a Result<Vec<Session>, _>, thanks to `collect()`.
let result: Result<Vec<Session>, ParseError> = output
let result: Result<Vec<Session>, ParseError> = buffer
.trim_end() // trim last '\n' as it would create an empty line
.split('\n')
.map(|line| Session::from_str(line))
Expand Down
10 changes: 7 additions & 3 deletions src/tmux/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl FromStr for Window {
}

/// Returns a list of all `Window` from all sessions.
pub fn available_windows() -> Result<Vec<Window>, ParseError> {
pub async fn available_windows() -> Result<Vec<Window>, ParseError> {
let args = vec![
"list-windows",
"-a",
Expand All @@ -102,11 +102,15 @@ pub fn available_windows() -> Result<Vec<Window>, ParseError> {
:#{window_linked_sessions_list}",
];

let output = duct::cmd("tmux", &args).read()?;
let output = tokio::process::Command::new("tmux")
.args(&args)
.output()
.await?;
let buffer = String::from_utf8(output.stdout)?;

// Each call to `Window::parse` returns a `Result<Window, _>`. All results
// are collected into a Result<Vec<Window>, _>, thanks to `collect()`.
let result: Result<Vec<Window>, ParseError> = output
let result: Result<Vec<Window>, ParseError> = buffer
.trim_end() // trim last '\n' as it would create an empty line
.split('\n')
.map(|line| Window::from_str(line))
Expand Down

0 comments on commit 4381b70

Please sign in to comment.