diff options
| author | Ken Matsui <26405363+ken-matsui@users.noreply.github.com> | 2021-11-01 03:14:12 +0900 |
|---|---|---|
| committer | Ken Matsui <26405363+ken-matsui@users.noreply.github.com> | 2021-11-06 05:15:09 +0900 |
| commit | 4acb2458d2e0da1d0459114f45123841e2fca741 (patch) | |
| tree | 50a81760d29440580eabdb5e4f691db038e4bb8d /src | |
| parent | docs(changelog): fix link (diff) | |
| download | sl0ppij-4acb2458d2e0da1d0459114f45123841e2fca741.tar.gz sl0ppij-4acb2458d2e0da1d0459114f45123841e2fca741.tar.xz sl0ppij-4acb2458d2e0da1d0459114f45123841e2fca741.zip | |
feat(attach): Support `--index` option to choose specific session by provided number in active sessions ordered by creation date, resolve #823
feat(attach): Support `--first` option for `attach` sub-command to let zellij choose the alphabetically first session; resolve #823
fix(attach-first): Fix `--first` option to choose the first created session in the existent sessions
feat(attach): Support `--index` option to choose the session indexed by provided number like -t option of tmux
feat(attach): Support listing active sessions with index when a provided number is not found in the active sessions
feat(attach): Support listing active sessions with index when a provided number is not found in the active sessions
feat: Add anyhow to uniformly treat error types and avoid panics
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 119 | ||||
| -rw-r--r-- | src/sessions.rs | 53 |
2 files changed, 132 insertions, 40 deletions
diff --git a/src/main.rs b/src/main.rs index 0cacc375..f12eb010 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,8 +5,9 @@ mod tests; use crate::install::populate_data_dir; use sessions::{ - assert_session, assert_session_ne, get_active_session, get_sessions, kill_session, - list_sessions, print_sessions, session_exists, ActiveSession, + assert_session, assert_session_ne, get_active_session, get_sessions, + get_sessions_sorted_by_creation_date, kill_session, list_sessions, print_sessions, + print_sessions_with_index, session_exists, ActiveSession, }; use std::process; use zellij_client::{os_input_output::get_client_os_input, start_client, ClientInfo}; @@ -62,7 +63,7 @@ pub fn main() { } } Err(e) => { - eprintln!("Error occured: {:?}", e); + eprintln!("Error occurred: {:?}", e); process::exit(1); } } @@ -111,6 +112,7 @@ pub fn main() { if let Some(Command::Sessions(Sessions::Attach { session_name, create, + index, options, })) = opts.command.clone() { @@ -119,47 +121,94 @@ pub fn main() { 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) + let (client, attach_layout) = if let Some(idx) = index { + // Ignore session_name when `--index` is provided + match get_sessions_sorted_by_creation_date() { + Ok(sessions) => { + if sessions.is_empty() { + if create { + ( + ClientInfo::New(names::Generator::default().next().unwrap()), + layout, + ) + } else { + println!("No active zellij sessions found."); + process::exit(1); + } } else { - ( - ClientInfo::Attach(session_name.unwrap(), config_options.clone()), - None, - ) + match sessions.get(idx) { + Some(session) => ( + ClientInfo::Attach(session.clone(), config_options.clone()), + None, + ), + None => { + if create { + ( + ClientInfo::New( + names::Generator::default().next().unwrap(), + ), + layout, + ) + } else { + println!("No session indexed by {} found. The following sessions are active:", idx); + print_sessions_with_index(sessions); + process::exit(1); + } + } + } } - } else { - assert_session(session); - ( - ClientInfo::Attach(session_name.unwrap(), config_options.clone()), - None, - ) + } + Err(e) => { + eprintln!("Error occurred: {:?}", e); + process::exit(1); } } - None => match get_active_session() { - ActiveSession::None => { + } else { + 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(), + config_options.clone(), + ), + None, + ) + } + } else { + assert_session(session); ( - ClientInfo::New(names::Generator::default().next().unwrap()), - layout, + ClientInfo::Attach(session_name.unwrap(), config_options.clone()), + None, ) - } else { - println!("No active zellij sessions found."); - process::exit(1); } } - ActiveSession::One(session_name) => ( - ClientInfo::Attach(session_name, 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); - } - }, + 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, 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( diff --git a/src/sessions.rs b/src/sessions.rs index c2d8afea..bf44d088 100644 --- a/src/sessions.rs +++ b/src/sessions.rs @@ -1,4 +1,5 @@ use std::os::unix::fs::FileTypeExt; +use std::time::SystemTime; use std::{fs, io, process}; use zellij_utils::{ consts::ZELLIJ_SOCK_DIR, @@ -29,6 +30,36 @@ pub(crate) fn get_sessions() -> Result<Vec<String>, io::ErrorKind> { } } +pub(crate) fn get_sessions_sorted_by_creation_date() -> anyhow::Result<Vec<String>> { + match fs::read_dir(&*ZELLIJ_SOCK_DIR) { + Ok(files) => { + let mut sessions_with_creation_date: Vec<(String, SystemTime)> = Vec::new(); + for file in files { + let file = file?; + let file_name = file.file_name().into_string().unwrap(); + let file_created_at = file.metadata()?.created()?; + if file.file_type()?.is_socket() && assert_socket(&file_name) { + sessions_with_creation_date.push((file_name, file_created_at)); + } + } + sessions_with_creation_date.sort_by_key(|x| x.1); // the oldest one will be the first + + let sessions = sessions_with_creation_date + .iter() + .map(|x| x.0.clone()) + .collect(); + Ok(sessions) + } + Err(err) => { + if let io::ErrorKind::NotFound = err.kind() { + Ok(Vec::with_capacity(0)) + } else { + Err(err.into()) + } + } + } +} + fn assert_socket(name: &str) -> bool { let path = &*ZELLIJ_SOCK_DIR.join(name); match LocalSocketStream::connect(path) { @@ -59,6 +90,18 @@ pub(crate) fn print_sessions(sessions: Vec<String>) { }) } +pub(crate) fn print_sessions_with_index(sessions: Vec<String>) { + let curr_session = std::env::var("ZELLIJ_SESSION_NAME").unwrap_or_else(|_| "".into()); + for (i, session) in sessions.iter().enumerate() { + let suffix = if curr_session == *session { + " (current)" + } else { + "" + }; + println!("{}: {}{}", i, session, suffix); + } +} + pub(crate) enum ActiveSession { None, One(String), @@ -78,7 +121,7 @@ pub(crate) fn get_active_session() -> ActiveSession { } } Err(e) => { - eprintln!("Error occured: {:?}", e); + eprintln!("Error occurred: {:?}", e); process::exit(1); } } @@ -91,7 +134,7 @@ pub(crate) fn kill_session(name: &str) { IpcSenderWithContext::new(stream).send(ClientToServerMsg::KillSession); } Err(e) => { - eprintln!("Error occured: {:?}", e); + eprintln!("Error occurred: {:?}", e); process::exit(1); } }; @@ -108,7 +151,7 @@ pub(crate) fn list_sessions() { 0 } Err(e) => { - eprintln!("Error occured: {:?}", e); + eprintln!("Error occurred: {:?}", e); 1 } }; @@ -137,7 +180,7 @@ pub(crate) fn assert_session(name: &str) { } } Err(e) => { - eprintln!("Error occured: {:?}", e); + eprintln!("Error occurred: {:?}", e); } }; process::exit(1); @@ -151,7 +194,7 @@ pub(crate) fn assert_session_ne(name: &str) { } println!("Session with name {:?} aleady exists. Use attach command to connect to it or specify a different name.", name); } - Err(e) => eprintln!("Error occured: {:?}", e), + Err(e) => eprintln!("Error occurred: {:?}", e), }; process::exit(1); } |
