* feat: Attach sessions by unique name prefix (#1169) This makes attaching to sessions more convenient since only the first character(s) of the session name must be typed. If this prefix matches multiple sessions and is therefore ambiguous, zellij will complain and show all sessions names starting with these characters. If any session name matches the given string exact, it is attached immediately, therefore it is always possible to attach to every session, even if the set of session names is not prefix-free. * Add feature to changelog * Try to fix flaky e2e test
This commit is contained in:
parent
e487537472
commit
7b0a46f812
4 changed files with 56 additions and 11 deletions
|
|
@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
* fix: right and middle clicks creating selection (https://github.com/zellij-org/zellij/pull/1372)
|
* fix: right and middle clicks creating selection (https://github.com/zellij-org/zellij/pull/1372)
|
||||||
|
* feat: Attach to sessions more conveniently by only typing their name's first character(s) (https://github.com/zellij-org/zellij/pull/1360)
|
||||||
|
|
||||||
## [0.29.1] - 2022-05-02
|
## [0.29.1] - 2022-05-02
|
||||||
* fix: forward mouse events to plugin panes (https://github.com/zellij-org/zellij/pull/1369)
|
* fix: forward mouse events to plugin panes (https://github.com/zellij-org/zellij/pull/1369)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ use crate::install::populate_data_dir;
|
||||||
use crate::sessions::kill_session as kill_session_impl;
|
use crate::sessions::kill_session as kill_session_impl;
|
||||||
use crate::sessions::{
|
use crate::sessions::{
|
||||||
assert_session, assert_session_ne, get_active_session, get_sessions,
|
assert_session, assert_session_ne, get_active_session, get_sessions,
|
||||||
get_sessions_sorted_by_mtime, print_sessions, print_sessions_with_index, session_exists,
|
get_sessions_sorted_by_mtime, match_session_name, print_sessions, print_sessions_with_index,
|
||||||
ActiveSession,
|
session_exists, ActiveSession, SessionNameMatch,
|
||||||
};
|
};
|
||||||
use dialoguer::Confirm;
|
use dialoguer::Confirm;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -144,10 +144,23 @@ fn attach_with_session_name(
|
||||||
ClientInfo::Attach(session_name.unwrap(), config_options)
|
ClientInfo::Attach(session_name.unwrap(), config_options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(session) => {
|
Some(prefix) => match match_session_name(prefix).unwrap() {
|
||||||
assert_session(session);
|
SessionNameMatch::UniquePrefix(s) | SessionNameMatch::Exact(s) => {
|
||||||
ClientInfo::Attach(session_name.unwrap(), config_options)
|
ClientInfo::Attach(s, config_options)
|
||||||
}
|
}
|
||||||
|
SessionNameMatch::AmbiguousPrefix(sessions) => {
|
||||||
|
println!(
|
||||||
|
"Ambiguous selection: multiple sessions names start with '{}':",
|
||||||
|
prefix
|
||||||
|
);
|
||||||
|
print_sessions(sessions);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
SessionNameMatch::None => {
|
||||||
|
eprintln!("No session with the name '{}' found!", prefix);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
None => match get_active_session() {
|
None => match get_active_session() {
|
||||||
ActiveSession::None if create => create_new_client(),
|
ActiveSession::None if create => create_new_client(),
|
||||||
ActiveSession::None => {
|
ActiveSession::None => {
|
||||||
|
|
@ -156,7 +169,7 @@ fn attach_with_session_name(
|
||||||
}
|
}
|
||||||
ActiveSession::One(session_name) => ClientInfo::Attach(session_name, config_options),
|
ActiveSession::One(session_name) => ClientInfo::Attach(session_name, config_options),
|
||||||
ActiveSession::Many => {
|
ActiveSession::Many => {
|
||||||
println!("Please specify the session name to attach to. The following sessions are active:");
|
println!("Please specify the session to attach to, either by using the full name or a unique prefix.\nThe following sessions are active:");
|
||||||
print_sessions(get_sessions().unwrap());
|
print_sessions(get_sessions().unwrap());
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,14 +144,43 @@ pub(crate) fn list_sessions() {
|
||||||
process::exit(exit_code);
|
process::exit(exit_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn session_exists(name: &str) -> Result<bool, io::ErrorKind> {
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum SessionNameMatch {
|
||||||
|
AmbiguousPrefix(Vec<String>),
|
||||||
|
UniquePrefix(String),
|
||||||
|
Exact(String),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn match_session_name(prefix: &str) -> Result<SessionNameMatch, io::ErrorKind> {
|
||||||
return match get_sessions() {
|
return match get_sessions() {
|
||||||
Ok(sessions) if sessions.iter().any(|s| s == name) => Ok(true),
|
Ok(sessions) => Ok({
|
||||||
Ok(_) => Ok(false),
|
let filtered_sessions: Vec<String> = sessions
|
||||||
|
.iter()
|
||||||
|
.filter(|s| s.starts_with(prefix))
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
if filtered_sessions.iter().any(|s| s == prefix) {
|
||||||
|
return Ok(SessionNameMatch::Exact(prefix.to_string()));
|
||||||
|
}
|
||||||
|
match &filtered_sessions[..] {
|
||||||
|
[] => SessionNameMatch::None,
|
||||||
|
[s] => SessionNameMatch::UniquePrefix(s.to_string()),
|
||||||
|
_ => SessionNameMatch::AmbiguousPrefix(filtered_sessions),
|
||||||
|
}
|
||||||
|
}),
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn session_exists(name: &str) -> Result<bool, io::ErrorKind> {
|
||||||
|
match match_session_name(name) {
|
||||||
|
Ok(SessionNameMatch::Exact(_)) => Ok(true),
|
||||||
|
Ok(_) => Ok(false),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn assert_session(name: &str) {
|
pub(crate) fn assert_session(name: &str) {
|
||||||
match session_exists(name) {
|
match session_exists(name) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
|
|
|
||||||
|
|
@ -950,7 +950,8 @@ pub fn detach_and_attach_session() {
|
||||||
name: "Wait for session to be attached",
|
name: "Wait for session to be attached",
|
||||||
instruction: |remote_terminal: RemoteTerminal| -> bool {
|
instruction: |remote_terminal: RemoteTerminal| -> bool {
|
||||||
let mut step_is_complete = false;
|
let mut step_is_complete = false;
|
||||||
if remote_terminal.cursor_position_is(3, 2) {
|
if remote_terminal.status_bar_appears() && remote_terminal.cursor_position_is(3, 2)
|
||||||
|
{
|
||||||
// we're back inside the session
|
// we're back inside the session
|
||||||
step_is_complete = true;
|
step_is_complete = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue