Compare commits

..

4 commits

Author SHA1 Message Date
796d8744c5 added nesting flag 2024-02-04 16:07:24 -05:00
2dd4e35600 moved help into its own module 2024-01-23 16:45:58 -05:00
f77f768416 added terminal check 2023-08-15 21:30:10 -04:00
808591fb9b made README libraries section clearer 2023-06-20 12:33:38 -04:00
7 changed files with 142 additions and 119 deletions

View file

@ -1,6 +1,6 @@
[package] [package]
name = "remux" name = "remux"
version = "0.1.1" version = "0.1.2"
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

View file

@ -35,5 +35,9 @@ remux d foo
``` ```
ReMux is built using the [tmux_interface](https://crates.io/crates/tmux_interface) and [pico_args](https://crates.io/crates/pico_args) crates. ## Libraries
- [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

View file

@ -10,98 +10,6 @@ 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();

View file

@ -30,9 +30,15 @@ pub fn missing_target() {
exit(4); exit(4);
} }
/// user declined nesting dialog /// non-terminal environment prevention; code 5
pub fn nest_declined() { pub fn not_terminal() {
println!("remux: session nesting declined by user"); println!("remux: not running from a terminal");
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 Normal file
View file

@ -0,0 +1,98 @@
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())
}
}

View file

@ -1,23 +1,43 @@
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"]) {
command::help(&mut args); 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")
=> command::help(&mut args), => help(&mut args),
Some("a" | "attach") Some("a" | "attach")
=> command::attach(&mut args), => command::attach(&mut args),
@ -38,5 +58,9 @@ fn main() {
_ _
=> error::no_subcommand(subcommand.unwrap()) => error::no_subcommand(subcommand.unwrap())
} }
if nesting {
set_var("TMUX", tmux_var.unwrap());
}
} }

View file

@ -1,10 +1,5 @@
use std::{ use std::{
env::{ set_var, var }, env::var,
io::{
self,
Read, Write
},
process::exit process::exit
}; };
@ -13,8 +8,6 @@ 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);
@ -29,18 +22,8 @@ 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() != "" {
// ask the user if they want to nest (default: no) println!("Sessions should be nested with care; unset TMUX or use the '-n' flag to allow.");
print!("Are you sure you want to nest sessions? (y/N) "); exit(1);
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", "");
} }
} }