Compare commits
2 commits
796d8744c5
...
65e28327f1
Author | SHA1 | Date | |
---|---|---|---|
65e28327f1 | |||
70c7c325f9 |
7 changed files with 119 additions and 142 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "remux"
|
name = "remux"
|
||||||
version = "0.1.2"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
|
@ -35,9 +35,5 @@ remux d foo
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Libraries
|
ReMux is built using the [tmux_interface](https://crates.io/crates/tmux_interface) and [pico_args](https://crates.io/crates/pico_args) crates.
|
||||||
|
|
||||||
- [pico-args](https://crates.io/crates/pico_args) — argument parsing
|
|
||||||
- [tmux_interface](https://crates.io/crates/tmux_interface) — tmux communication
|
|
||||||
- [termion](https://crates.io/crates/termion) — ANSI formatting
|
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,98 @@ use tmux_interface::TmuxCommand;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
|
pub fn help(pargs: &mut Arguments) {
|
||||||
|
let topic = pargs.subcommand().unwrap();
|
||||||
|
|
||||||
|
match topic.as_deref() {
|
||||||
|
None => {
|
||||||
|
println!("remux v{}", env!("CARGO_PKG_VERSION"));
|
||||||
|
println!("Valerie Wolfe <sleeplessval@gmail.com>");
|
||||||
|
println!("A command wrapper for tmux written in Rust.\n");
|
||||||
|
|
||||||
|
println!("usage: remux <command> [<args>]\n");
|
||||||
|
|
||||||
|
println!("Commands:");
|
||||||
|
println!(" help Show help text for remux or a specific command");
|
||||||
|
println!(" attach Attach to an existing tmux session");
|
||||||
|
println!(" detach Detach clients from a tmux session");
|
||||||
|
println!(" has Check if a tmux session exists");
|
||||||
|
println!(" list Pretty-print all tmux sessions");
|
||||||
|
println!(" new Create a new tmux session");
|
||||||
|
|
||||||
|
println!("\nUse 'remux help <command>' to see detailed help text for each command.");
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
Some("a" | "attach")
|
||||||
|
=> {
|
||||||
|
println!("remux attach");
|
||||||
|
println!("Attach to an existing session.\n");
|
||||||
|
|
||||||
|
println!("usage: remux attach [flags] <session> [window]\n");
|
||||||
|
|
||||||
|
println!("args:");
|
||||||
|
println!(" <session> The session to attach to");
|
||||||
|
println!(" [window] Optionally focus a window in the given session\n");
|
||||||
|
|
||||||
|
println!("flags:");
|
||||||
|
println!(" -d, --detach Detach other attached clients from the session");
|
||||||
|
println!(" -r, --readonly Attach the session as read-only");
|
||||||
|
},
|
||||||
|
|
||||||
|
Some("d" | "detach")
|
||||||
|
=> {
|
||||||
|
println!("remux detach");
|
||||||
|
println!("Detach all clients from a session.\n");
|
||||||
|
|
||||||
|
println!("usage: remux detach <session>\n");
|
||||||
|
|
||||||
|
println!("args:");
|
||||||
|
println!(" <session> The session name to detach clients from");
|
||||||
|
},
|
||||||
|
|
||||||
|
Some("has")
|
||||||
|
=> {
|
||||||
|
println!("remux has");
|
||||||
|
println!("Check if the target session exists.\n");
|
||||||
|
|
||||||
|
println!("usage: remux has [flags] <session>\n");
|
||||||
|
|
||||||
|
println!("args:");
|
||||||
|
println!(" <session> The session to check for\n");
|
||||||
|
|
||||||
|
println!("flags:");
|
||||||
|
println!(" -q, --quiet Display no text; exit code only");
|
||||||
|
},
|
||||||
|
|
||||||
|
Some("l" | "ls" | "list")
|
||||||
|
=> {
|
||||||
|
println!("remux list");
|
||||||
|
println!("Pretty-print all tmux sessions.\n");
|
||||||
|
|
||||||
|
println!("usage: remux list");
|
||||||
|
},
|
||||||
|
|
||||||
|
Some("n" | "new")
|
||||||
|
=> {
|
||||||
|
println!("remux new");
|
||||||
|
println!("Create a new tmux session.\n");
|
||||||
|
|
||||||
|
println!("usage: remux new [flags] <title> [command]\n");
|
||||||
|
|
||||||
|
println!("args:");
|
||||||
|
println!(" <title> The title of the new session");
|
||||||
|
println!(" [command] The shell command to run\n");
|
||||||
|
|
||||||
|
println!("flags:");
|
||||||
|
println!(" -t, --target <dir> Sets the target directory for the new session.");
|
||||||
|
},
|
||||||
|
|
||||||
|
// not found
|
||||||
|
_ => error::no_help(topic.unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn attach(pargs: &mut Arguments) {
|
pub fn attach(pargs: &mut Arguments) {
|
||||||
util::prevent_nest();
|
util::prevent_nest();
|
||||||
|
|
||||||
|
|
12
src/error.rs
12
src/error.rs
|
@ -30,15 +30,9 @@ pub fn missing_target() {
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// non-terminal environment prevention; code 5
|
/// user declined nesting dialog
|
||||||
pub fn not_terminal() {
|
pub fn nest_declined() {
|
||||||
println!("remux: not running from a terminal");
|
println!("remux: session nesting declined by user");
|
||||||
exit(5);
|
exit(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// tried to nest while not in a session; code 6
|
|
||||||
pub fn not_nesting() {
|
|
||||||
println!("remux: cannot use nesting flag outside a TMUX session");
|
|
||||||
exit(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
98
src/help.rs
98
src/help.rs
|
@ -1,98 +0,0 @@
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
use pico_args::Arguments;
|
|
||||||
|
|
||||||
use crate::error;
|
|
||||||
|
|
||||||
pub fn help(pargs: &mut Arguments) {
|
|
||||||
let topic = pargs.subcommand().unwrap();
|
|
||||||
|
|
||||||
match topic.as_deref() {
|
|
||||||
None => {
|
|
||||||
println!("remux v{}", env!("CARGO_PKG_VERSION"));
|
|
||||||
println!("Valerie Wolfe <sleeplessval@gmail.com>");
|
|
||||||
println!("A command wrapper for tmux written in Rust.\n");
|
|
||||||
|
|
||||||
println!("usage: remux <command> [<args>]\n");
|
|
||||||
|
|
||||||
println!("Commands:");
|
|
||||||
println!(" help Show help text for remux or a specific command");
|
|
||||||
println!(" attach Attach to an existing tmux session");
|
|
||||||
println!(" detach Detach clients from a tmux session");
|
|
||||||
println!(" has Check if a tmux session exists");
|
|
||||||
println!(" list Pretty-print all tmux sessions");
|
|
||||||
println!(" new Create a new tmux session");
|
|
||||||
|
|
||||||
println!("\nUse 'remux help <command>' to see detailed help text for each command.");
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
Some("a" | "attach")
|
|
||||||
=> {
|
|
||||||
println!("remux attach");
|
|
||||||
println!("Attach to an existing session.\n");
|
|
||||||
|
|
||||||
println!("usage: remux attach [flags] <session> [window]\n");
|
|
||||||
|
|
||||||
println!("args:");
|
|
||||||
println!(" <session> The session to attach to");
|
|
||||||
println!(" [window] Optionally focus a window in the given session\n");
|
|
||||||
|
|
||||||
println!("flags:");
|
|
||||||
println!(" -d, --detach Detach other attached clients from the session");
|
|
||||||
println!(" -r, --readonly Attach the session as read-only");
|
|
||||||
},
|
|
||||||
|
|
||||||
Some("d" | "detach")
|
|
||||||
=> {
|
|
||||||
println!("remux detach");
|
|
||||||
println!("Detach all clients from a session.\n");
|
|
||||||
|
|
||||||
println!("usage: remux detach <session>\n");
|
|
||||||
|
|
||||||
println!("args:");
|
|
||||||
println!(" <session> The session name to detach clients from");
|
|
||||||
},
|
|
||||||
|
|
||||||
Some("has")
|
|
||||||
=> {
|
|
||||||
println!("remux has");
|
|
||||||
println!("Check if the target session exists.\n");
|
|
||||||
|
|
||||||
println!("usage: remux has [flags] <session>\n");
|
|
||||||
|
|
||||||
println!("args:");
|
|
||||||
println!(" <session> The session to check for\n");
|
|
||||||
|
|
||||||
println!("flags:");
|
|
||||||
println!(" -q, --quiet Display no text; exit code only");
|
|
||||||
},
|
|
||||||
|
|
||||||
Some("l" | "ls" | "list")
|
|
||||||
=> {
|
|
||||||
println!("remux list");
|
|
||||||
println!("Pretty-print all tmux sessions.\n");
|
|
||||||
|
|
||||||
println!("usage: remux list");
|
|
||||||
},
|
|
||||||
|
|
||||||
Some("n" | "new")
|
|
||||||
=> {
|
|
||||||
println!("remux new");
|
|
||||||
println!("Create a new tmux session.\n");
|
|
||||||
|
|
||||||
println!("usage: remux new [flags] <title> [command]\n");
|
|
||||||
|
|
||||||
println!("args:");
|
|
||||||
println!(" <title> The title of the new session");
|
|
||||||
println!(" [command] The shell command to run\n");
|
|
||||||
|
|
||||||
println!("flags:");
|
|
||||||
println!(" -t, --target <dir> Sets the target directory for the new session.");
|
|
||||||
},
|
|
||||||
|
|
||||||
// not found
|
|
||||||
_ => error::no_help(topic.unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
28
src/main.rs
28
src/main.rs
|
@ -1,43 +1,23 @@
|
||||||
use std::{
|
|
||||||
env::{ set_var, var },
|
|
||||||
io::{ stdout, IsTerminal }
|
|
||||||
};
|
|
||||||
|
|
||||||
use pico_args::Arguments;
|
use pico_args::Arguments;
|
||||||
|
|
||||||
mod command;
|
mod command;
|
||||||
mod error;
|
mod error;
|
||||||
mod help;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use help::help;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// collect args
|
|
||||||
let mut args = Arguments::from_env();
|
let mut args = Arguments::from_env();
|
||||||
|
|
||||||
// consume flags
|
|
||||||
if args.contains(["-h", "--help"]) {
|
if args.contains(["-h", "--help"]) {
|
||||||
help(&mut args);
|
command::help(&mut args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let nesting = args.contains(["-n", "--nest"]);
|
|
||||||
let tmux_var = var("TMUX").ok();
|
|
||||||
if nesting {
|
|
||||||
if tmux_var.is_none() {
|
|
||||||
error::not_nesting();
|
|
||||||
}
|
|
||||||
set_var("TMUX", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if !stdout().is_terminal() { error::not_terminal(); }
|
|
||||||
|
|
||||||
let subcommand = args.subcommand().unwrap();
|
let subcommand = args.subcommand().unwrap();
|
||||||
|
|
||||||
// invoke subcommand function
|
|
||||||
match subcommand.as_deref() {
|
match subcommand.as_deref() {
|
||||||
Some("h" | "help")
|
Some("h" | "help")
|
||||||
=> help(&mut args),
|
=> command::help(&mut args),
|
||||||
|
|
||||||
Some("a" | "attach")
|
Some("a" | "attach")
|
||||||
=> command::attach(&mut args),
|
=> command::attach(&mut args),
|
||||||
|
@ -58,9 +38,5 @@ fn main() {
|
||||||
_
|
_
|
||||||
=> error::no_subcommand(subcommand.unwrap())
|
=> error::no_subcommand(subcommand.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
if nesting {
|
|
||||||
set_var("TMUX", tmux_var.unwrap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/util.rs
23
src/util.rs
|
@ -1,5 +1,10 @@
|
||||||
use std::{
|
use std::{
|
||||||
env::var,
|
env::{ set_var, var },
|
||||||
|
io::{
|
||||||
|
self,
|
||||||
|
|
||||||
|
Read, Write
|
||||||
|
},
|
||||||
process::exit
|
process::exit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +13,8 @@ use tmux_interface::{
|
||||||
variables::session::session::SESSION_ALL
|
variables::session::session::SESSION_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error;
|
||||||
|
|
||||||
/// return a Vec of all sessions or None
|
/// return a Vec of all sessions or None
|
||||||
pub fn get_sessions() -> Option<Vec<Session>> {
|
pub fn get_sessions() -> Option<Vec<Session>> {
|
||||||
let i_sessions = Sessions::get(SESSION_ALL);
|
let i_sessions = Sessions::get(SESSION_ALL);
|
||||||
|
@ -22,8 +29,18 @@ pub fn get_sessions() -> Option<Vec<Session>> {
|
||||||
pub fn prevent_nest() {
|
pub fn prevent_nest() {
|
||||||
let tmux = var("TMUX").ok();
|
let tmux = var("TMUX").ok();
|
||||||
if tmux.is_some() && tmux.unwrap() != "" {
|
if tmux.is_some() && tmux.unwrap() != "" {
|
||||||
println!("Sessions should be nested with care; unset TMUX or use the '-n' flag to allow.");
|
// ask the user if they want to nest (default: no)
|
||||||
exit(1);
|
print!("Are you sure you want to nest sessions? (y/N) ");
|
||||||
|
let _ = io::stdout().flush();
|
||||||
|
|
||||||
|
let mut input = [0];
|
||||||
|
let _ = io::stdin().read(&mut input);
|
||||||
|
match input[0] as char {
|
||||||
|
'y' | 'Y'
|
||||||
|
=> {},
|
||||||
|
_ => error::nest_declined()
|
||||||
|
}
|
||||||
|
set_var("TMUX", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue