Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session resurrection #2801

Merged
merged 135 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 132 commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
01e21e1
add necessary actions in server and utils
alekspickle Apr 12, 2023
ad4480c
update
alekspickle May 16, 2023
4025faa
Merge remote-tracking branch 'origin/main' into feat/saving-tab-layou…
alekspickle May 16, 2023
810a5eb
Merge branch 'main' into feat/saving-tab-layout-to-a-file
alekspickle Jun 28, 2023
a69604e
move all logic relevant to local default config directories to utils:…
alekspickle Jun 28, 2023
65da173
add debug statements for pane geom
alekspickle Jun 28, 2023
71cc15b
add tests; print resulting kdl
alekspickle Jun 29, 2023
a58c945
fix dumping custom layouts from setup; start fixing algorithm for sim…
alekspickle Jul 2, 2023
502fdc0
fix: fixed persistence code and tests to support flexible layouts
Aug 24, 2023
be52cb7
Merge pull request #1 from AlixBernard/feat/panegeom-partition-recons…
alekspickle Sep 17, 2023
09d36fe
fix(tab-bar,compact-bar): tab switching with mouse sometimes not work…
tlinford Jun 30, 2023
6265653
docs(changelog): plugins tab switching with mouse fix
tlinford Jun 30, 2023
b2e6fe6
feat(ui): new status bar mode (#2619)
imsnif Jul 12, 2023
a09b86e
docs(changelog): status-bar supermode
imsnif Jul 12, 2023
7e60a76
fix(rendering): occasional glitches while resizing (#2621)
imsnif Jul 12, 2023
e4ab2ec
docs(changelog): resize glitches fix
imsnif Jul 12, 2023
d71e994
chore(version): bump development version
imsnif Jul 12, 2023
62d6bdb
Fix colored pane frames in mirrored sessions (#2625)
har7an Jul 16, 2023
6ff71e1
fix(sessions): use custom lists of adjectives and nouns for generatin…
khs26 Jul 18, 2023
86e8a65
docs(changelog): generate session names with custom words list
tlinford Jul 18, 2023
ce0b594
feat(plugins): make plugins configurable (#2646)
imsnif Jul 25, 2023
d614f16
docs(changelog): configurable plugins
imsnif Jul 25, 2023
3d9154a
fix(terminal): properly handle resizes in alternate screen (#2654)
imsnif Jul 27, 2023
7c33947
docs(changelog): focus glitches
imsnif Jul 27, 2023
df40730
feat(plugins): utility functions to find active pane and tab (#2652)
Nacho114 Jul 28, 2023
7d4ef51
docs(changelog): plugin api utility functions
imsnif Jul 28, 2023
0fb4000
feat(ui): break pane to new tab and move panes between tabs (#2664)
imsnif Aug 2, 2023
65d361b
docs(changelog): break pane to new tab
imsnif Aug 2, 2023
4b9454f
fix(performance): plug memory leak (#2675)
imsnif Aug 4, 2023
9813418
docs(changelog): plug memory leak
imsnif Aug 4, 2023
4d498d4
feat(plugins): use protocol buffers for serializing across the wasm b…
imsnif Aug 9, 2023
be62683
docs(changelog): protobuffers
imsnif Aug 9, 2023
bff1adf
feat: add plugin permission system (#2624)
jaeheonji Aug 12, 2023
563098d
docs(changelog): permission system
imsnif Aug 12, 2023
2c78940
feat(sessions): add a session manager to switch between sessions, tab…
imsnif Aug 24, 2023
817dbf2
docs(changelog): session manager
imsnif Aug 24, 2023
a071f55
fix(ux): various ui/ux fixes (#2722)
imsnif Aug 24, 2023
c490f4e
docs(changelog): update ux fixes
imsnif Aug 24, 2023
8a0f74f
feat(plugins): optionally move plugin to focused tab (#2725)
imsnif Aug 25, 2023
7633b0e
docs(changelog): move plugin to focused tab
imsnif Aug 25, 2023
2a83633
fix(keybinds): add 'floating' and 'name' to the Run command keybindin…
imsnif Aug 25, 2023
c9cad25
docs(changelog): keybind run floating pane
imsnif Aug 25, 2023
080bbee
fix(plugins): make sure configuration is also part of the plugin keys…
imsnif Aug 25, 2023
65d4166
docs(changelog): fix plugin configuration uniqueness
imsnif Aug 25, 2023
23883ac
fix(plugins): remove protobuf duplications (#2729)
imsnif Aug 25, 2023
fd2075d
Update CHANGELOG.md
imsnif Aug 25, 2023
4be9b7a
fix(plugins): various ui fixes (#2731)
imsnif Aug 26, 2023
096a97b
Update CHANGELOG.md
imsnif Aug 26, 2023
f8ef61c
fix(panes): refocus pane properly on tab change (#2734)
imsnif Aug 27, 2023
d5d541b
docs(changelog): stacked pane focus glitch
imsnif Aug 27, 2023
52891a7
xtask/pipeline: Fix publish task (#2711)
har7an Aug 28, 2023
fc54970
chore(release): v0.38.0
imsnif Aug 28, 2023
fd6a0e9
chore(version): bump development version
imsnif Aug 28, 2023
bd7bb4b
refactor(server): remove unnecessary mut (#2735)
orhun Aug 28, 2023
7d047e1
docs(changelog): refactor server
jaeheonji Aug 28, 2023
bc8248a
chore(repo): update build instructions
imsnif Aug 28, 2023
a63094c
fix(status-bar): add break tab hints (#2748)
imsnif Aug 29, 2023
15f0385
Update CHANGELOG.md
imsnif Aug 29, 2023
f74d0cc
fix(reconnect): do not clear terminal state when entering alternate s…
imsnif Aug 30, 2023
0731232
docs(changelog): fix glitches on windows terminal
imsnif Aug 30, 2023
0efc535
fix(grid): memory leak with unfocused tabs (#2745)
tlinford Aug 30, 2023
35e51f5
docs(changelog): grid memory leak fix
tlinford Aug 30, 2023
a447e7b
fix(input): block input thread for newtiledpane and newfloatingpane a…
imsnif Aug 31, 2023
624900d
docs(changelog): input action new pane fix
imsnif Aug 31, 2023
4ad8d5c
chore(version): adjust version for release
imsnif Aug 31, 2023
182dff7
chore(release): v0.38.1
imsnif Aug 31, 2023
970a762
chore(version): bump development version
imsnif Aug 31, 2023
b4c7134
fix(terminal): wrap lines when adding characters in alternate screen …
imsnif Sep 15, 2023
d68e833
docs(changelog): line wrap bug
imsnif Sep 15, 2023
db0909f
chore(version): bump version for patch release
imsnif Sep 15, 2023
4af934d
chore(release): v0.38.2
imsnif Sep 15, 2023
b97ac0e
chore(version): bump development version
imsnif Sep 15, 2023
433fe96
fix(utils): validate session name (#2607)
deepsghimire Sep 16, 2023
a0c83e0
docs(changelog): fix validate session name
jaeheonji Sep 16, 2023
0959fd0
merge conflict fix
alekspickle Sep 17, 2023
e953fb7
Merge branch 'zellij-org:main' into feat/saving-tab-layout-to-a-file
alekspickle Sep 18, 2023
608bf86
feat(panes): in place run (#2795)
imsnif Sep 19, 2023
1adef73
docs
imsnif Sep 18, 2023
a6655b9
bring in commands to dumped layout
imsnif Sep 19, 2023
6fcda39
tidy up data structures
imsnif Sep 20, 2023
b6a13af
bring in plugins to dumped layout
imsnif Sep 20, 2023
8d4ac4c
Merge branch 'main' into session-resurrection
imsnif Sep 20, 2023
b2202fd
fix tests
imsnif Sep 21, 2023
708b4b6
style(fmt): rustfmt
imsnif Sep 21, 2023
84df41c
chore: rename file (#2803)
AlixBernard Sep 21, 2023
c36c419
bring in floating panes
imsnif Sep 21, 2023
52f4abb
bring in stacked panes
imsnif Sep 23, 2023
fe20094
style(fmt): rustfmt
imsnif Sep 23, 2023
f6ef55f
bring in new_tab_template
imsnif Sep 23, 2023
066caac
bring in swap layouts
imsnif Sep 25, 2023
e9958de
bring in edit panes, command panes and cwds
imsnif Sep 26, 2023
b672cf3
consolidate CWD common prefixes when possible
imsnif Sep 26, 2023
8a98304
filter out default shell
imsnif Sep 26, 2023
4098d6c
style(fmt): rustfmt
imsnif Sep 26, 2023
ada04cb
handle scrollback editor panes properly
imsnif Sep 27, 2023
14a2db0
handle in place panes properly
imsnif Sep 27, 2023
fed789d
bring in pane names
imsnif Sep 27, 2023
3e79a5a
style(fmt): rustfmt
imsnif Sep 27, 2023
2c65496
Merge branch 'main' into session-resurrection
imsnif Sep 28, 2023
ccd5124
style(fmt): rustfmt
imsnif Sep 28, 2023
d8ab551
dump layout action to terminal
imsnif Sep 28, 2023
91200d7
log session layout to HD periodically
imsnif Sep 28, 2023
b4b4366
resurrect dead sessions by attaching to them
imsnif Oct 2, 2023
f36eeb6
delete dead sessions
imsnif Oct 2, 2023
687478a
style(fmt): rustfmt
imsnif Oct 3, 2023
224aedf
start command panes as suspended by default
imsnif Oct 3, 2023
bb9eac6
style(fmt): rustfmt
imsnif Oct 3, 2023
26c6fe9
respect tab/pane focus
imsnif Oct 3, 2023
b3a76e4
improve dump performance
imsnif Oct 3, 2023
5ec1bf2
hide_floating_panes in layout and resurrection
imsnif Oct 4, 2023
6900600
show resurrectable sessions in zellij ls and include timestamps
imsnif Oct 4, 2023
2498574
style(fmt): rustfmt
imsnif Oct 4, 2023
1279743
allow disabling session serialization in config
imsnif Oct 5, 2023
ef949ac
style(fmt): rustfmt
imsnif Oct 5, 2023
05018ca
fix e2e tests
imsnif Oct 5, 2023
dd918cf
add e2e test
imsnif Oct 6, 2023
77b77fb
style(fmt): rustfmt
imsnif Oct 6, 2023
3fb2595
Merge branch 'main' into session-resurrection
imsnif Oct 6, 2023
2678f6c
style(fmt): rustfmt
imsnif Oct 6, 2023
0918bca
serialize and restore pane viewport
imsnif Oct 7, 2023
88c25be
fix e2e tests and add new one
imsnif Oct 9, 2023
1880984
style(fmt): rustfmt
imsnif Oct 9, 2023
5144b29
cleanups
imsnif Oct 9, 2023
6e90a1b
cleanups
imsnif Oct 9, 2023
c922130
more cleanups
imsnif Oct 9, 2023
9044b4d
refactor: move stuff around
imsnif Oct 10, 2023
1d793e1
fix e2e tests
imsnif Oct 10, 2023
641a03d
style(fmt): rustfmt
imsnif Oct 10, 2023
3825368
style(fmt): handle compilation warnings
imsnif Oct 11, 2023
9c040d5
add tests for new layout properties
imsnif Oct 11, 2023
4f24a98
fix current session name indication
imsnif Oct 11, 2023
9adf4c6
style(fmt): rustfmt
imsnif Oct 11, 2023
1e00585
adjust default config
imsnif Oct 12, 2023
76e3c2b
some cleanups
imsnif Oct 12, 2023
06e3f5f
go away clippy
imsnif Oct 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ pkg-fmt = "tgz"

[features]
# See remarks in zellij_utils/Cargo.toml
default = [ "zellij-utils/plugins_from_target" ]
disable_automatic_asset_installation = [ "zellij-utils/disable_automatic_asset_installation" ]
unstable = [ "zellij-client/unstable", "zellij-utils/unstable" ]
singlepass = [ "zellij-server/singlepass" ]
default = ["zellij-utils/plugins_from_target"]
disable_automatic_asset_installation = ["zellij-utils/disable_automatic_asset_installation"]
unstable = ["zellij-client/unstable", "zellij-utils/unstable"]
singlepass = ["zellij-server/singlepass"]

# uncomment this when developing plugins in the Zellij UI to make plugin compilation faster
# [profile.dev.package."*"]
Expand Down
1 change: 1 addition & 0 deletions docs/MANPAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ACTIONS
Right, Up, Down).
* __Clear__ - clears current screen.
* __DumpScreen: <File\>__ - dumps the screen in the specified file.
* __DumpLayout: <File\>__ - dumps the screen in the specified or default file.
* __EditScrollback__ - replaces the current pane with the scrollback buffer.
* __ScrollUp__ - scrolls up 1 line in the focused pane.
* __ScrollDown__ - scrolls down 1 line in the focused pane.
Expand Down
119 changes: 104 additions & 15 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use dialoguer::Confirm;
use std::{fs::File, io::prelude::*, path::PathBuf, process};
use std::{fs::File, io::prelude::*, path::PathBuf, process, time::Duration};

use crate::sessions::{
assert_session, assert_session_ne, get_active_session, get_name_generator, get_sessions,
assert_dead_session, assert_session, assert_session_ne, delete_session as delete_session_impl,
get_active_session, get_name_generator, get_resurrectable_sessions, get_sessions,
get_sessions_sorted_by_mtime, kill_session as kill_session_impl, match_session_name,
print_sessions, print_sessions_with_index, session_exists, ActiveSession, SessionNameMatch,
print_sessions, print_sessions_with_index, resurrection_layout, session_exists, ActiveSession,
SessionNameMatch,
};
use zellij_client::{
old_config_converter::{
Expand Down Expand Up @@ -49,7 +51,7 @@ pub(crate) fn kill_all_sessions(yes: bool) {
}
}
for session in &sessions {
kill_session_impl(session);
kill_session_impl(&session.0);
}
process::exit(0);
},
Expand All @@ -60,6 +62,39 @@ pub(crate) fn kill_all_sessions(yes: bool) {
}
}

pub(crate) fn delete_all_sessions(yes: bool, force: bool) {
let active_sessions: Vec<String> = get_sessions()
.unwrap_or_default()
.iter()
.map(|s| s.0.clone())
.collect();
let resurrectable_sessions = get_resurrectable_sessions();
let dead_sessions: Vec<_> = if force {
resurrectable_sessions
} else {
resurrectable_sessions
.iter()
.filter(|(name, _, _)| !active_sessions.contains(name))
.cloned()
.collect()
};
if !yes {
println!("WARNING: this action will delete all resurrectable sessions.");
if !Confirm::new()
.with_prompt("Do you want to continue?")
.interact()
.unwrap()
{
println!("Abort.");
process::exit(1);
}
}
for session in &dead_sessions {
delete_session_impl(&session.0, force);
}
process::exit(0);
}

pub(crate) fn kill_session(target_session: &Option<String>) {
match target_session {
Some(target_session) => {
Expand All @@ -74,6 +109,20 @@ pub(crate) fn kill_session(target_session: &Option<String>) {
}
}

pub(crate) fn delete_session(target_session: &Option<String>, force: bool) {
match target_session {
Some(target_session) => {
assert_dead_session(target_session, force);
delete_session_impl(target_session, force);
process::exit(0);
},
None => {
println!("Please specify the session name to delete.");
process::exit(1);
},
}
}

fn get_os_input<OsInputOutput>(
fn_get_os_input: fn() -> Result<OsInputOutput, nix::Error>,
) -> OsInputOutput {
Expand Down Expand Up @@ -117,6 +166,9 @@ fn find_indexed_session(
}
}

/// Client entrypoint for all [`zellij_utils::cli::CliAction`]
///
/// Checks session to send the action to and attaches with client
pub(crate) fn send_action_to_session(
cli_action: zellij_utils::cli::CliAction,
requested_session_name: Option<String>,
Expand All @@ -141,7 +193,11 @@ pub(crate) fn send_action_to_session(
attach_with_cli_client(cli_action, &session_name, config);
},
ActiveSession::Many => {
let existing_sessions = get_sessions().unwrap();
let existing_sessions: Vec<String> = get_sessions()
.unwrap_or_default()
.iter()
.map(|s| s.0.clone())
.collect();
if let Some(session_name) = requested_session_name {
if existing_sessions.contains(&session_name) {
attach_with_cli_client(cli_action, &session_name, config);
Expand All @@ -150,14 +206,14 @@ pub(crate) fn send_action_to_session(
"Session '{}' not found. The following sessions are active:",
session_name
);
print_sessions(existing_sessions);
list_sessions(false);
std::process::exit(1);
}
} else if let Ok(session_name) = envs::get_session_name() {
attach_with_cli_client(cli_action, &session_name, config);
} else {
eprintln!("Please specify the session name to send actions to. The following sessions are active:");
print_sessions(existing_sessions);
list_sessions(false);
std::process::exit(1);
}
},
Expand Down Expand Up @@ -293,7 +349,13 @@ fn attach_with_session_name(
"Ambiguous selection: multiple sessions names start with '{}':",
prefix
);
print_sessions(sessions);
print_sessions(
sessions
.iter()
.map(|s| (s.clone(), Duration::default(), false))
.collect(),
false,
);
process::exit(1);
},
SessionNameMatch::None => {
Expand All @@ -310,7 +372,7 @@ fn attach_with_session_name(
ActiveSession::One(session_name) => ClientInfo::Attach(session_name, config_options),
ActiveSession::Many => {
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());
list_sessions(false);
process::exit(1);
},
},
Expand Down Expand Up @@ -351,6 +413,7 @@ pub(crate) fn start_client(opts: CliArgs) {
opts.command = Some(Command::Sessions(Sessions::Attach {
session_name: reconnect_to_session.name.clone(),
create: true,
force_run_commands: false,
index: None,
options: None,
}));
Expand All @@ -369,6 +432,7 @@ pub(crate) fn start_client(opts: CliArgs) {
if let Some(Command::Sessions(Sessions::Attach {
session_name,
create,
force_run_commands,
index,
options,
})) = opts.command.clone()
Expand All @@ -387,10 +451,20 @@ pub(crate) fn start_client(opts: CliArgs) {
.as_ref()
.and_then(|s| session_exists(&s).ok())
.unwrap_or(false);
if create && !session_exists {
let resurrection_layout =
session_name.as_ref().and_then(|s| resurrection_layout(&s));
if create && !session_exists && resurrection_layout.is_none() {
session_name.clone().map(start_client_plan);
}
attach_with_session_name(session_name, config_options.clone(), create)
match (session_name.as_ref(), resurrection_layout) {
(Some(session_name), Some(mut resurrection_layout)) if !session_exists => {
if force_run_commands {
resurrection_layout.recursively_add_start_suspended(Some(false));
}
ClientInfo::Resurrect(session_name.clone(), resurrection_layout)
},
_ => attach_with_session_name(session_name, config_options.clone(), create),
}
};

if let Ok(val) = std::env::var(envs::SESSION_NAME_ENV_KEY) {
Expand All @@ -399,9 +473,12 @@ pub(crate) fn start_client(opts: CliArgs) {
}
}

let attach_layout = match client {
let attach_layout = match &client {
ClientInfo::Attach(_, _) => None,
ClientInfo::New(_) => Some(layout),
ClientInfo::Resurrect(_session_name, layout_to_resurrect) => {
Some(layout_to_resurrect.clone())
},
};

let tab_position_to_focus = reconnect_to_session
Expand Down Expand Up @@ -457,9 +534,12 @@ pub(crate) fn start_client(opts: CliArgs) {
config_options.clone(),
true,
);
let attach_layout = match client {
let attach_layout = match &client {
ClientInfo::Attach(_, _) => None,
ClientInfo::New(_) => Some(layout),
ClientInfo::Resurrect(_, resurrection_layout) => {
Some(resurrection_layout.clone())
},
};
reconnect_to_session = start_client_impl(
Box::new(os_input),
Expand Down Expand Up @@ -518,15 +598,24 @@ pub(crate) fn start_client(opts: CliArgs) {
}

fn generate_unique_session_name() -> String {
let sessions = get_sessions();
let sessions = get_sessions().map(|sessions| {
sessions
.iter()
.map(|s| s.0.clone())
.collect::<Vec<String>>()
});
let dead_sessions: Vec<String> = get_resurrectable_sessions()
.iter()
.map(|(s, _, _)| s.clone())
.collect();
let Ok(sessions) = sessions else {
eprintln!("Failed to list existing sessions: {:?}", sessions);
process::exit(1);
};

let name = get_name_generator()
.take(1000)
.find(|name| !sessions.contains(name));
.find(|name| !sessions.contains(name) && !dead_sessions.contains(name));

if let Some(name) = name {
return name;
Expand Down
13 changes: 11 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,23 @@ fn main() {
}
}

if let Some(Command::Sessions(Sessions::ListSessions)) = opts.command {
commands::list_sessions();
if let Some(Command::Sessions(Sessions::ListSessions { no_formatting })) = opts.command {
commands::list_sessions(no_formatting);
} else if let Some(Command::Sessions(Sessions::KillAllSessions { yes })) = opts.command {
commands::kill_all_sessions(yes);
} else if let Some(Command::Sessions(Sessions::KillSession { ref target_session })) =
opts.command
{
commands::kill_session(target_session);
} else if let Some(Command::Sessions(Sessions::DeleteAllSessions { yes, force })) = opts.command
{
commands::delete_all_sessions(yes, force);
} else if let Some(Command::Sessions(Sessions::DeleteSession {
ref target_session,
force,
})) = opts.command
{
commands::delete_session(target_session, force);
} else if let Some(path) = opts.server {
commands::start_server(path, opts.debug);
} else {
Expand Down
Loading