major refactor; parameters are handled by a state struct
This commit is contained in:
parent
a915bfd9c5
commit
ace9627b79
8 changed files with 188 additions and 89 deletions
|
@ -1,26 +1,41 @@
|
||||||
//! commands accessible from within a session
|
//! commands accessible from within a session
|
||||||
use std::fs::read_to_string;
|
|
||||||
|
|
||||||
use pico_args::Arguments;
|
|
||||||
use tmux_interface::{
|
use tmux_interface::{
|
||||||
Tmux,
|
Tmux,
|
||||||
commands
|
commands
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{ error, flag, util };
|
use crate::{
|
||||||
|
error,
|
||||||
|
state::State,
|
||||||
|
util
|
||||||
|
};
|
||||||
|
|
||||||
const TMP_ROOT: &str = "/tmp/remux_path";
|
pub fn path(state: &mut State) {
|
||||||
|
state.session_enforce("path");
|
||||||
|
|
||||||
pub fn switch(pargs: &mut Arguments) {
|
let message = commands::DisplayMessage::new().print().message("#{session_path}");
|
||||||
|
|
||||||
|
let result = Tmux::new().add_command(message).output().unwrap();
|
||||||
|
let text = String::from_utf8(result.0.stdout);
|
||||||
|
|
||||||
|
if let Ok(output) = text {
|
||||||
|
// trim the trailing line break
|
||||||
|
let target = output.len() - 1;
|
||||||
|
println!("{}", &output[0..target]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch(state: &mut State) {
|
||||||
util::terminal_enforce();
|
util::terminal_enforce();
|
||||||
// refuse to run outside a session
|
// refuse to run outside a session
|
||||||
util::session_enforce("switch");
|
state.session_enforce("switch");
|
||||||
|
|
||||||
// consume optional flags
|
// consume optional flags
|
||||||
let read_only = pargs.contains(flag::READ_ONLY);
|
let read_only = state.flags.read_only;
|
||||||
//TODO: -d flag handling needs to be done manually
|
//TODO: -d flag handling needs to be done manually
|
||||||
|
|
||||||
let args = pargs.clone().finish();
|
let args = state.args.clone().finish();
|
||||||
if args.len() < 1 { error::missing_target(); }
|
if args.len() < 1 { error::missing_target(); }
|
||||||
let target = args.get(0).unwrap().to_string_lossy().to_string();
|
let target = args.get(0).unwrap().to_string_lossy().to_string();
|
||||||
|
|
||||||
|
@ -36,17 +51,8 @@ pub fn switch(pargs: &mut Arguments) {
|
||||||
.output().ok();
|
.output().ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path() {
|
pub fn which(state: State) {
|
||||||
util::session_enforce("path");
|
state.session_enforce("which");
|
||||||
|
if let Some(title) = state.title { println!("{title}"); }
|
||||||
let exec = commands::Run::new().shell_command("printf '#{session_path}' > ".to_string() + TMP_ROOT);
|
|
||||||
Tmux::new()
|
|
||||||
.add_command(exec)
|
|
||||||
.output().ok();
|
|
||||||
|
|
||||||
if let Ok(text) = read_to_string(TMP_ROOT) {
|
|
||||||
println!("{text}");
|
|
||||||
std::fs::remove_file(TMP_ROOT).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,20 +15,19 @@ use crate::{
|
||||||
env::{ self, env_var },
|
env::{ self, env_var },
|
||||||
error,
|
error,
|
||||||
flag,
|
flag,
|
||||||
|
state::State,
|
||||||
util
|
util
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn attach(pargs: &mut Arguments) {
|
pub fn attach(state: &mut State) {
|
||||||
// must be run from terminal
|
|
||||||
util::terminal_enforce();
|
util::terminal_enforce();
|
||||||
// don't allow unflagged nests
|
state.nest_init();
|
||||||
util::prevent_nest();
|
|
||||||
|
|
||||||
// consume optional flags
|
// consume optional flags
|
||||||
let read_only = pargs.contains(flag::READ_ONLY);
|
let read_only = state.flags.read_only;
|
||||||
let detach_other = pargs.contains(flag::DETACH);
|
let detach_other = state.flags.detached;
|
||||||
|
|
||||||
let args = pargs.clone().finish();
|
let args = state.args.clone().finish();
|
||||||
let target: String;
|
let target: String;
|
||||||
let window: Option<&OsString>;
|
let window: Option<&OsString>;
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
|
@ -41,6 +40,9 @@ pub fn attach(pargs: &mut Arguments) {
|
||||||
window = args.get(1);
|
window = args.get(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do not allow attaching to the same session
|
||||||
|
if state.session && target == state.title.clone().unwrap() { error::same_session(); }
|
||||||
|
|
||||||
// make sure the session exists
|
// make sure the session exists
|
||||||
let exists = util::session_exists(target.clone());
|
let exists = util::session_exists(target.clone());
|
||||||
if !exists { error::no_target(target.clone()); }
|
if !exists { error::no_target(target.clone()); }
|
||||||
|
@ -62,17 +64,20 @@ pub fn attach(pargs: &mut Arguments) {
|
||||||
let mut tmux = Tmux::new().add_command(attach);
|
let mut tmux = Tmux::new().add_command(attach);
|
||||||
if let Some(select_window) = select_window { tmux = tmux.add_command(select_window); }
|
if let Some(select_window) = select_window { tmux = tmux.add_command(select_window); }
|
||||||
tmux.output().ok();
|
tmux.output().ok();
|
||||||
|
|
||||||
|
state.nest_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_action() {
|
pub fn context_action(state: &State) {
|
||||||
let repo = util::repo_root(std::env::current_dir().unwrap());
|
let repo = util::repo_root(std::env::current_dir().unwrap());
|
||||||
if !env::tmux() && repo.is_some() {
|
if !state.session && repo.is_some() {
|
||||||
let target = util::repo_fallback();
|
let target = util::repo_fallback();
|
||||||
let mut args = Arguments::from_vec( vec![(&target).into()] );
|
let mut args = Arguments::from_vec( vec![(&target).into()] );
|
||||||
|
let mut substate = State::new(&mut args);
|
||||||
if util::session_exists(&target) {
|
if util::session_exists(&target) {
|
||||||
attach(&mut args);
|
attach(&mut substate);
|
||||||
} else {
|
} else {
|
||||||
new(&mut args);
|
new(&mut substate);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -81,10 +86,10 @@ pub fn context_action() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn detach(pargs: &mut Arguments) {
|
pub fn detach(state: &mut State) {
|
||||||
util::terminal_enforce();
|
util::terminal_enforce();
|
||||||
// get target or fallback
|
// get target or fallback
|
||||||
let args = pargs.clone().finish();
|
let args = state.args.clone().finish();
|
||||||
let target: String;
|
let target: String;
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
target = util::repo_fallback();
|
target = util::repo_fallback();
|
||||||
|
@ -104,12 +109,12 @@ pub fn detach(pargs: &mut Arguments) {
|
||||||
.disable_echo().output().ok();
|
.disable_echo().output().ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has(pargs: &mut Arguments) {
|
pub fn has(state: &mut State) {
|
||||||
// consume optional flags
|
// consume optional flags
|
||||||
let quiet = pargs.contains(flag::QUIET);
|
let quiet = state.flags.quiet;
|
||||||
|
|
||||||
// get target or fallback
|
// get target or fallback
|
||||||
let args = pargs.clone().finish();
|
let args = state.args.clone().finish();
|
||||||
let target: String;
|
let target: String;
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
target = util::repo_fallback();
|
target = util::repo_fallback();
|
||||||
|
@ -148,12 +153,12 @@ pub fn list() {
|
||||||
// pretty print session list
|
// pretty print session list
|
||||||
println!("sessions:");
|
println!("sessions:");
|
||||||
for session in sessions.into_iter() {
|
for session in sessions.into_iter() {
|
||||||
let group = session.group.unwrap_or("[untitled]".to_string());
|
let name = session.name.unwrap_or("[untitled]".to_string());
|
||||||
let id = session.id.unwrap();
|
let id = session.id.unwrap();
|
||||||
let attached = session.attached.unwrap_or(0) > 0;
|
let attached = session.attached.unwrap_or(0) > 0;
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
" {group} ({bold}{blue}{id}{reset}) {bold}{green}{attach}{reset}",
|
" {name} ({bold}{blue}{id}{reset}) {bold}{green}{attach}{reset}",
|
||||||
// values
|
// values
|
||||||
attach = if attached { attach_symbol.clone() } else { "".to_string() },
|
attach = if attached { attach_symbol.clone() } else { "".to_string() },
|
||||||
// formatting
|
// formatting
|
||||||
|
@ -165,20 +170,19 @@ pub fn list() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(pargs: &mut Arguments) {
|
pub fn new(state: &mut State) {
|
||||||
util::terminal_enforce();
|
util::terminal_enforce();
|
||||||
// don't allow unflagged nesting
|
state.nest_init();
|
||||||
util::prevent_nest();
|
|
||||||
|
|
||||||
// get optional flags
|
// get optional flags
|
||||||
let detached = pargs.contains(flag::DETACH);
|
let detached = state.flags.detached;
|
||||||
let target_dir: Result<String, Error> = pargs.value_from_str(flag::TARGET);
|
let target_dir: Result<String, Error> = state.args.value_from_str(flag::TARGET);
|
||||||
|
|
||||||
// get environment variables
|
// get environment variables
|
||||||
let window_name = env_var(env::NEW_WINDOW_NAME);
|
let window_name = env_var(env::NEW_WINDOW_NAME);
|
||||||
|
|
||||||
// get target or fallback
|
// get target or fallback
|
||||||
let args = pargs.clone().finish();
|
let args = state.args.clone().finish();
|
||||||
let title: String;
|
let title: String;
|
||||||
let command: Option<&OsString>;
|
let command: Option<&OsString>;
|
||||||
if args.len() < 1 {
|
if args.len() < 1 {
|
||||||
|
@ -191,7 +195,7 @@ pub fn new(pargs: &mut Arguments) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new = commands::NewSession::new();
|
let mut new = commands::NewSession::new();
|
||||||
new = new.group_name(title);
|
new = new.session_name(title);
|
||||||
if let Some(command) = command { new.shell_command = Some(command.to_string_lossy()); }
|
if let Some(command) = command { new.shell_command = Some(command.to_string_lossy()); }
|
||||||
if detached { new.detached = true; }
|
if detached { new.detached = true; }
|
||||||
if let Ok(target_dir) = target_dir { new = new.start_directory(target_dir); }
|
if let Ok(target_dir) = target_dir { new = new.start_directory(target_dir); }
|
||||||
|
|
|
@ -5,9 +5,10 @@ pub type EnvVar = (&'static str, &'static str);
|
||||||
pub static ATTACH_SYMBOL: EnvVar = ("REMUX_ATTACH_SYMBOL", "*");
|
pub static ATTACH_SYMBOL: EnvVar = ("REMUX_ATTACH_SYMBOL", "*");
|
||||||
pub static NEW_WINDOW_NAME: EnvVar = ("REMUX_NEW_WINDOW", "");
|
pub static NEW_WINDOW_NAME: EnvVar = ("REMUX_NEW_WINDOW", "");
|
||||||
|
|
||||||
|
pub static TMUX: &str = "TMUX";
|
||||||
|
|
||||||
|
/// get or default an environment variable
|
||||||
pub fn env_var(envvar: EnvVar) -> String {
|
pub fn env_var(envvar: EnvVar) -> String {
|
||||||
var(envvar.0).unwrap_or(envvar.1.to_string())
|
var(envvar.0).unwrap_or(envvar.1.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tmux() -> bool { !var("TMUX").unwrap_or("".to_string()).is_empty() }
|
|
||||||
|
|
||||||
|
|
11
src/error.rs
11
src/error.rs
|
@ -25,6 +25,12 @@ pub fn missing_target() {
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// refuse to attach to current session; code 4
|
||||||
|
pub fn same_session() {
|
||||||
|
println!("remux: cannot attach to same session");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
/// non-terminal environment prevention; code 5
|
/// non-terminal environment prevention; code 5
|
||||||
pub fn not_terminal() {
|
pub fn not_terminal() {
|
||||||
println!("remux: not running from a terminal");
|
println!("remux: not running from a terminal");
|
||||||
|
@ -37,6 +43,11 @@ pub fn not_nesting() {
|
||||||
exit(6);
|
exit(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn prevent_nest() {
|
||||||
|
println!("remux: cannot nest sessions without the nest flag ('-n')");
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
|
||||||
/// tried to run a session command outside a session; code 7
|
/// tried to run a session command outside a session; code 7
|
||||||
pub fn not_in_session(cmd: &'static str) {
|
pub fn not_in_session(cmd: &'static str) {
|
||||||
println!("remux: '{cmd}' must be run from within a session");
|
println!("remux: '{cmd}' must be run from within a session");
|
||||||
|
|
30
src/flag.rs
30
src/flag.rs
|
@ -1,4 +1,6 @@
|
||||||
|
|
||||||
|
use pico_args::Arguments;
|
||||||
|
|
||||||
type Flag = [&'static str;2];
|
type Flag = [&'static str;2];
|
||||||
|
|
||||||
pub static DETACH: Flag = ["-d", "--detach"];
|
pub static DETACH: Flag = ["-d", "--detach"];
|
||||||
|
@ -9,3 +11,31 @@ pub static READ_ONLY: Flag = ["-r", "--read-only"];
|
||||||
pub static TARGET: Flag = ["-t", "--target"];
|
pub static TARGET: Flag = ["-t", "--target"];
|
||||||
pub static VERSION: Flag = ["-v", "--version"];
|
pub static VERSION: Flag = ["-v", "--version"];
|
||||||
|
|
||||||
|
pub struct Flags {
|
||||||
|
pub detached: bool,
|
||||||
|
pub nested: bool,
|
||||||
|
pub quiet: bool,
|
||||||
|
pub read_only: bool,
|
||||||
|
pub target: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flags {
|
||||||
|
|
||||||
|
pub fn from(args: &mut Arguments) -> Flags {
|
||||||
|
let detached = args.contains(DETACH);
|
||||||
|
let nested = args.contains(NEST);
|
||||||
|
let quiet = args.contains(QUIET);
|
||||||
|
let read_only = args.contains(READ_ONLY);
|
||||||
|
let target = args.value_from_str(TARGET).ok();
|
||||||
|
|
||||||
|
Flags {
|
||||||
|
detached,
|
||||||
|
nested,
|
||||||
|
quiet,
|
||||||
|
read_only,
|
||||||
|
target
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -1,4 +1,3 @@
|
||||||
use std::env::{ set_var, var };
|
|
||||||
|
|
||||||
use pico_args::Arguments;
|
use pico_args::Arguments;
|
||||||
|
|
||||||
|
@ -7,9 +6,12 @@ mod env;
|
||||||
mod error;
|
mod error;
|
||||||
mod flag;
|
mod flag;
|
||||||
mod help;
|
mod help;
|
||||||
|
mod script;
|
||||||
|
mod state;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use help::{ help, version };
|
use help::{ help, version };
|
||||||
|
use state::State;
|
||||||
|
|
||||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
@ -28,52 +30,44 @@ fn main() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nesting = args.contains(flag::NEST);
|
let mut state = State::new(&mut args);
|
||||||
let tmux_var = var("TMUX").ok();
|
|
||||||
if nesting {
|
|
||||||
if tmux_var.is_none() {
|
|
||||||
error::not_nesting();
|
|
||||||
}
|
|
||||||
set_var("TMUX", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
let subcommand = args.subcommand().unwrap();
|
let target = state.target();
|
||||||
|
|
||||||
// invoke subcommand function
|
// invoke subcommand function
|
||||||
match subcommand.as_deref() {
|
match target.as_deref() {
|
||||||
Some("help")
|
Some("help")
|
||||||
=> help(&mut args),
|
=> help(&mut args),
|
||||||
None
|
None
|
||||||
=> command::share::context_action(),
|
=> command::share::context_action(&state),
|
||||||
|
|
||||||
Some("a" | "attach")
|
Some("a" | "attach")
|
||||||
=> command::share::attach(&mut args),
|
=> command::share::attach(&mut state),
|
||||||
|
|
||||||
Some("d" | "detach")
|
Some("d" | "detach")
|
||||||
=> command::share::detach(&mut args),
|
=> command::share::detach(&mut state),
|
||||||
|
|
||||||
Some("h" | "has")
|
Some("h" | "has")
|
||||||
=> command::share::has(&mut args),
|
=> command::share::has(&mut state),
|
||||||
|
|
||||||
Some("l" | "ls" | "list")
|
Some("l" | "ls" | "list")
|
||||||
=> command::share::list(),
|
=> command::share::list(),
|
||||||
|
|
||||||
Some("n" | "new")
|
Some("n" | "new")
|
||||||
=> command::share::new(&mut args),
|
=> command::share::new(&mut state),
|
||||||
|
|
||||||
Some("p" | "path")
|
Some("p" | "path")
|
||||||
=> command::session::path(),
|
=> command::session::path(&mut state),
|
||||||
|
|
||||||
Some("s" | "switch")
|
Some("s" | "switch")
|
||||||
=> command::session::switch(&mut args),
|
=> command::session::switch(&mut state),
|
||||||
|
|
||||||
|
Some("w" | "which" | "title")
|
||||||
|
=> command::session::which(state),
|
||||||
|
|
||||||
_
|
_
|
||||||
=> error::no_subcommand(subcommand.unwrap())
|
=> error::no_subcommand(target.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-set TMUX var if we unset it for nest mode
|
|
||||||
if nesting {
|
|
||||||
set_var("TMUX", tmux_var.unwrap());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
58
src/state.rs
Normal file
58
src/state.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use pico_args::Arguments;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
env::TMUX,
|
||||||
|
error,
|
||||||
|
flag::Flags,
|
||||||
|
util::session_name
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct State<'a> {
|
||||||
|
pub args: &'a mut Arguments,
|
||||||
|
pub flags: Flags,
|
||||||
|
|
||||||
|
pub session: bool,
|
||||||
|
tmux_var: Option<String>,
|
||||||
|
pub title: Option<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State<'_> {
|
||||||
|
|
||||||
|
pub fn new(args: &mut Arguments) -> State {
|
||||||
|
let flags = Flags::from(args);
|
||||||
|
let tmux_var = env::var(TMUX).ok();
|
||||||
|
let session = tmux_var.is_some();
|
||||||
|
let title = if session { session_name() } else { None };
|
||||||
|
|
||||||
|
State {
|
||||||
|
args,
|
||||||
|
flags,
|
||||||
|
session,
|
||||||
|
tmux_var,
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nest_init(&self) {
|
||||||
|
if self.flags.nested {
|
||||||
|
if self.session { env::set_var(TMUX, ""); } // nesting & session => ok
|
||||||
|
else { error::not_nesting(); } // nesting & !session => error
|
||||||
|
} else if self.session { error::prevent_nest(); } // !nesting & session => error
|
||||||
|
// !nesting & !session => ok
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nest_deinit(&self) {
|
||||||
|
if self.flags.nested && self.session {
|
||||||
|
env::set_var(TMUX, self.tmux_var.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn session_enforce(&self, cmd: &'static str) {
|
||||||
|
if !self.session { error::not_in_session(cmd); }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn target(&mut self) -> Option<String> { self.args.subcommand().unwrap_or(None) }
|
||||||
|
}
|
||||||
|
|
33
src/util.rs
33
src/util.rs
|
@ -1,8 +1,7 @@
|
||||||
use std::{
|
use std::{
|
||||||
env::current_dir,
|
env::current_dir,
|
||||||
io::{ stdout, IsTerminal },
|
io::{ stdout, IsTerminal },
|
||||||
path::PathBuf,
|
path::PathBuf
|
||||||
process::exit
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use tmux_interface::{
|
use tmux_interface::{
|
||||||
|
@ -12,10 +11,19 @@ use tmux_interface::{
|
||||||
variables::session::SessionsCtl
|
variables::session::SessionsCtl
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::error;
|
||||||
env,
|
|
||||||
error
|
pub fn session_name() -> Option<String> {
|
||||||
};
|
let message = commands::DisplayMessage::new().print().message("#{session_name}");
|
||||||
|
|
||||||
|
let result = Tmux::new().add_command(message).output();
|
||||||
|
if let Ok(output) = result {
|
||||||
|
let text = String::from_utf8(output.0.stdout);
|
||||||
|
if let Ok(title) = text {
|
||||||
|
Some(title[0..title.len() - 1].to_owned())
|
||||||
|
} else { None }
|
||||||
|
} else { None }
|
||||||
|
}
|
||||||
|
|
||||||
/// 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>> {
|
||||||
|
@ -25,19 +33,6 @@ pub fn get_sessions() -> Option<Vec<Session>> {
|
||||||
} else { return None; }
|
} else { return None; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// show the tmux nest text if env var is not unset
|
|
||||||
pub fn prevent_nest() {
|
|
||||||
if env::tmux() {
|
|
||||||
println!("To nest sessions, use the -n flag.");
|
|
||||||
exit(6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// enforce a command is being used in-session
|
|
||||||
pub fn session_enforce(cmd: &'static str) {
|
|
||||||
if !env::tmux() { error::not_in_session(cmd); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// check whether a target session exists
|
/// check whether a target session exists
|
||||||
pub fn session_exists<S: Into<String>>(target: S) -> bool {
|
pub fn session_exists<S: Into<String>>(target: S) -> bool {
|
||||||
let has_session = commands::HasSession::new()
|
let has_session = commands::HasSession::new()
|
||||||
|
|
Loading…
Reference in a new issue