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

feat(ui): Implement 'attach --create' so attach would never fail #588

Closed
wants to merge 2 commits into from

Conversation

ottok
Copy link

@ottok ottok commented Jun 27, 2021

Add support for --create in subcommand attach to enable similar use as in tmux new-session -A -s Foo where attaching a session will always result in a session, either re-using the old or creating a new.

This allows me to have a Zellij session open "forever", even across remote host reboots when the session otherwise dies. For example I can have while ! ssh host -t 'zellij attach --create workspace'; do echo $?; sleep 3; done and that window will forever be an open terminal to my remote machine with my previous session open as far as possible.

Closes: #541

zellij-attach-create

@ottok
Copy link
Author

ottok commented Jun 27, 2021

PS. This is my first Rust project, so feel free to nitpick about all the things I am doing wrong so that I can learn.

@imsnif imsnif requested a review from kunalmohan June 29, 2021 12:54
@imsnif
Copy link
Member

imsnif commented Jun 29, 2021

Hey @ottok - thanks for opening this PR, but unfortunately there's already one in the works for this: #587
I'd be very happy if you'd like to maybe pick up a different issue and work on it? We can make sure to mark that you're working on it so no one can take it away. Would also be happy to give it my personal attention and nitpick the code as much as you want :)

@ottok
Copy link
Author

ottok commented Jul 10, 2021

First-time contributors need a maintainer to approve running workflows.

Could you please approve workflows so I can see if this PR would have passed tests even if I would decide to discard it?

@kunalmohan
Copy link
Member

Hi @ottok! Looks like the author of #587 will be busy for some time (#587 (comment)). So I'll review this and if this is ready before the other one, we can go ahead and merge this.

Copy link
Member

@kunalmohan kunalmohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ottok! Thank you for the PR. This mostly looks good. There are a couple of changes that need to be done to handle all the cases correctly and a few other suggestions regarding the code. And make sure to fix the fmt and clippy lint errors. Feel free to ping me if you need any help 🙂

if sessions.len() == 1 {
// If a session name was omitted but there is only one session, attach it
session_name = sessions.pop();
println!("Attaching session {:?}", session_name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need the println!() statements.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have them at least now while developing, otherwise I don't get any feedback from Zellij on what code path it took.

// If a session name was omitted, but --create was used, attach to new session
// with random name
start_new_session = true;
println!("Creating a new session to attach");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

src/main.rs Outdated
// If a session name was given, but does not exist while --create was used,
// attach a new session using that name
start_new_session = true;
println!("Creating new session {:?} to attach", session_name.clone().unwrap());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same. We don't need this.

@@ -20,11 +20,39 @@ use zellij_utils::{
structopt::StructOpt,
};

fn start_new_session_name(opts: &CliArgs) -> String {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have this function to accept just the opts.session.as_ref(). So the parameter would be session_name: Option<&String>.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But session_name might be empty. I'll think about something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the session_name is empty, the parameter session_name will be None. So, you can then operate on it the same way you do now:

fn start_new_session_name(name: Option<&String>) -> String {
    let session_name = name
        .map_or_else(|| names::Generator::default().next().unwrap(), |s| s.clone());
    assert_session_ne(&session_name);
    return session_name;
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to get this working in various ways, but always every avenue I took ended up in failures. I guess I don't yet fully master the Rust ownership and types. Could you please show me what exactly I should have in the calling function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see kunalmohan@ec464a2 for the relevant changes. Feel free to reach out in case there's any confusion.

@@ -47,7 +47,17 @@ fn assert_socket(name: &str) -> bool {
}
}

fn print_sessions(sessions: Vec<String>) {
pub(crate) fn get_sessions() -> Vec<String> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function looks redundant to me now. We can simply unwrap() on the result returned by read_sessions() to get the same behaviour.

// If a session name was omitted but there is only one session, attach it
session_name = sessions.pop();
println!("Attaching session {:?}", session_name);
} else if create {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be checked only if there are no active sessions. If there is only one active session, we attach to it. If there are more than one active sessions we exit with a message. If there are no active sessions, we create one if create flag was passed, otherwise exit.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this is how tmux does it to allow one to create a new fresh session if the previous one had died. I think this is useful.

If we wan't the <name> to be compulsory for zellij attach --create <name> then that should maybe be checked already in the command-line argument parsing phase.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we should allow users to create a fresh session if one does not exist. But this case here is the one where the user does not mention the session name. Since there is no session name, we will create a new session only if there are no active sessions. Otherwise, zellij attach --create will keep on creating a new session each time even though there are more than 1 active sessions and the user might want to attach to one of those.

IMO this is the behaviour that zellij should have with --create flag:

  1. If session name is specified:
  • If a session with name <session_name> is present, attach to it.
  • If a session with name <session_name> does not exist, create a new session.
  1. If no session name is specified:
  • If only a single session exists, attach to it.
  • If more than one session exists, exit with a message (and list the sessions).
  • If no session exists, create a new one with a random name

Do you have something else in mind?

Add support for --create in subcommand attach to enable similar use
as in 'tmux new-session -A -s Foo' where attaching a session will always
result in a session, either re-using the old or creating a new.

Closes: zellij-org#541
@ottok ottok force-pushed the feature/attach-create branch from e74ddee to 9ade2ce Compare July 18, 2021 19:02
@ottok
Copy link
Author

ottok commented Jul 18, 2021

Apparently the workflows don't run when I refresh the PR. Which I did to make sure CI passes. But now I can't know if it does for sure..

@kunalmohan
Copy link
Member

Hi @ottok! Are you still working on this? This is an important feature and we would like to have it in main branch as soon as possible. In case you're busy, I'll be more than happy to take it off your hands :)

@ottok
Copy link
Author

ottok commented Aug 2, 2021 via email

@kunalmohan
Copy link
Member

Did you have any follow-up comments to my responses?

I had replied to them in the inline comments themselves. Are there more concerns?

@a-kenji
Copy link
Contributor

a-kenji commented Sep 19, 2021

Thank you for the work on this feature!
It has now been implemented by #731.

@a-kenji a-kenji closed this Sep 19, 2021
@jeffschwartz
Copy link

Please update cli help to reflect new feature.

@ottok
Copy link
Author

ottok commented Mar 1, 2024

It is already in the cli:

± zellij attach --help
zellij-attach 
Attach to a session

USAGE:
    zellij attach [OPTIONS] [SESSION_NAME] [SUBCOMMAND]

ARGS:
    <SESSION_NAME>    Name of the session to attach to

OPTIONS:
    -c, --create                Create a session if one does not exist
    -f, --force-run-commands    If resurrecting a dead session, immediately run all its commands on
                                startup
    -h, --help                  Print help information
        --index <INDEX>         Number of the session index in the active sessions ordered creation
                                date

SUBCOMMANDS:
    help       Print this message or the help of the given subcommand(s)
    options    Change the behaviour of zellij

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: zellij attach --create
5 participants