Implement attach --create subcommand flag to create session if one does not exist (#731)

* Implement attach --create

* fixup! Implement attach --create

* fixup! Implement attach --create

* fixup! Implement attach --create

* fixup! Implement attach --create
This commit is contained in:
GPery 2021-09-19 15:47:52 +03:00 committed by GitHub
parent eb22a6c171
commit b761a28702
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 25 deletions

View file

@ -4,7 +4,10 @@ mod sessions;
mod tests; mod tests;
use crate::install::populate_data_dir; use crate::install::populate_data_dir;
use sessions::{assert_session, assert_session_ne, get_active_session, list_sessions}; use sessions::{
assert_session, assert_session_ne, get_active_session, get_sessions, list_sessions,
print_sessions, session_exists, ActiveSession,
};
use std::process; use std::process;
use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo}; use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo};
use zellij_server::{os_input_output::get_server_os_input, start_server}; use zellij_server::{os_input_output::get_server_os_input, start_server};
@ -52,29 +55,75 @@ pub fn main() {
} }
}; };
if let Some(Command::Sessions(Sessions::Attach { if let Some(Command::Sessions(Sessions::Attach {
mut session_name, session_name,
force, force,
create,
options, options,
})) = opts.command.clone() })) = opts.command.clone()
{ {
if let Some(session) = session_name.as_ref() {
assert_session(session);
} else {
session_name = Some(get_active_session());
}
let config_options = match options { let config_options = match options {
Some(SessionCommand::Options(o)) => config_options.merge(o), Some(SessionCommand::Options(o)) => config_options.merge(o),
None => config_options, None => config_options,
}; };
let (client, attach_layout) = match session_name.as_ref() {
Some(session) => {
if create {
if !session_exists(session).unwrap() {
(ClientInfo::New(session_name.unwrap()), layout)
} else {
(
ClientInfo::Attach(
session_name.unwrap(),
force,
config_options.clone(),
),
None,
)
}
} else {
assert_session(session);
(
ClientInfo::Attach(
session_name.unwrap(),
force,
config_options.clone(),
),
None,
)
}
}
None => match get_active_session() {
ActiveSession::None => {
if create {
(
ClientInfo::New(names::Generator::default().next().unwrap()),
layout,
)
} else {
println!("No active zellij sessions found.");
process::exit(1);
}
}
ActiveSession::One(session_name) => (
ClientInfo::Attach(session_name, force, config_options.clone()),
None,
),
ActiveSession::Many => {
println!("Please specify the session name to attach to. The following sessions are active:");
print_sessions(get_sessions().unwrap());
process::exit(1);
}
},
};
start_client( start_client(
Box::new(os_input), Box::new(os_input),
opts, opts,
config, config,
config_options.clone(), config_options,
ClientInfo::Attach(session_name.unwrap(), force, config_options), client,
None, attach_layout,
); );
} else { } else {
let session_name = opts let session_name = opts

View file

@ -6,7 +6,7 @@ use zellij_utils::{
ipc::{ClientToServerMsg, IpcSenderWithContext}, ipc::{ClientToServerMsg, IpcSenderWithContext},
}; };
fn get_sessions() -> Result<Vec<String>, io::ErrorKind> { pub(crate) fn get_sessions() -> Result<Vec<String>, io::ErrorKind> {
match fs::read_dir(&*ZELLIJ_SOCK_DIR) { match fs::read_dir(&*ZELLIJ_SOCK_DIR) {
Ok(files) => { Ok(files) => {
let mut sessions = Vec::new(); let mut sessions = Vec::new();
@ -47,7 +47,7 @@ fn assert_socket(name: &str) -> bool {
} }
} }
fn print_sessions(sessions: Vec<String>) { pub(crate) fn print_sessions(sessions: Vec<String>) {
let curr_session = std::env::var("ZELLIJ_SESSION_NAME").unwrap_or_else(|_| "".into()); let curr_session = std::env::var("ZELLIJ_SESSION_NAME").unwrap_or_else(|_| "".into());
sessions.iter().for_each(|session| { sessions.iter().for_each(|session| {
let suffix = if curr_session == *session { let suffix = if curr_session == *session {
@ -59,23 +59,30 @@ fn print_sessions(sessions: Vec<String>) {
}) })
} }
pub(crate) fn get_active_session() -> String { pub(crate) enum ActiveSession {
None,
One(String),
Many,
}
pub(crate) fn get_active_session() -> ActiveSession {
match get_sessions() { match get_sessions() {
Ok(mut sessions) => { Ok(mut sessions) => {
if sessions.len() == 1 { if sessions.len() == 1 {
return sessions.pop().unwrap(); return ActiveSession::One(sessions.pop().unwrap());
} }
if sessions.is_empty() { if sessions.is_empty() {
println!("No active zellij sessions found."); ActiveSession::None
} else { } else {
println!("Please specify the session name to attach to. The following sessions are active:"); ActiveSession::Many
print_sessions(sessions);
} }
} }
Err(e) => eprintln!("Error occured: {:?}", e), Err(e) => {
} eprintln!("Error occured: {:?}", e);
process::exit(1); process::exit(1);
} }
}
}
pub(crate) fn list_sessions() { pub(crate) fn list_sessions() {
let exit_code = match get_sessions() { let exit_code = match get_sessions() {
@ -95,15 +102,30 @@ pub(crate) fn list_sessions() {
process::exit(exit_code); process::exit(exit_code);
} }
pub(crate) fn assert_session(name: &str) { pub(crate) fn session_exists(name: &str) -> Result<bool, io::ErrorKind> {
match get_sessions() { return match get_sessions() {
Ok(sessions) => { Ok(sessions) => {
if sessions.iter().any(|s| s == name) { if sessions.iter().any(|s| s == name) {
return; return Ok(true);
} }
Ok(false)
}
Err(e) => Err(e),
};
}
pub(crate) fn assert_session(name: &str) {
match session_exists(name) {
Ok(result) => {
if result {
return;
} else {
println!("No session named {:?} found.", name); println!("No session named {:?} found.", name);
} }
Err(e) => eprintln!("Error occured: {:?}", e), }
Err(e) => {
eprintln!("Error occured: {:?}", e);
}
}; };
process::exit(1); process::exit(1);
} }

View file

@ -85,6 +85,11 @@ pub enum Sessions {
/// zellij client (if any) and attach to this. /// zellij client (if any) and attach to this.
#[structopt(long, short)] #[structopt(long, short)]
force: bool, force: bool,
/// Create a session if one does not exist.
#[structopt(short, long)]
create: bool,
/// Change the behaviour of zellij /// Change the behaviour of zellij
#[structopt(subcommand, name = "options")] #[structopt(subcommand, name = "options")]
options: Option<SessionCommand>, options: Option<SessionCommand>,