zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
21.96k stars 667 forks source link

Feature request: nested zellij instances (e.g. over ssh) #387

Open alxhub opened 3 years ago

alxhub commented 3 years ago

Currently, running zellij inside zellij does work, but is not specially handled. A really good experience could be provided though, especially in combination with ssh:

  1. I'm inside a tab in zellij on my local machine.
  2. I ssh to a remote machine.
  3. I launch zellij on the remote machine.

Rather than running an independent instance of zellij that's tricky to control as it requires escape sequences to operate, zellij could instead recognize that it's running inside another instance and coordinate. It would be possible to:

a-kenji commented 3 years ago

Good idea! Thanks for taking the time in writing this out.

Lillecarl commented 2 years ago

There's a really cool thing that Zellij could do that'd "remove" the need for running Zellij on the remote machine.

The terminal emulator Wezterm supports running SSH through it, and then you can spawn new wezterm tabs they'll be in the same SSH session because of something called SSH channels, Wezterm is also written in rust and uses libssh2 for this so i guess quite a bit of code could be reused from that project (both WezTerm and Zellij are MIT licensed too so copypasta is cool)

This would kinda imply adding a command mode to zellij to be able to run the ssh command, or if there's a way for the zellij binary to know which pane it runs in, which then can be used to instruct the zellij server to initiate an ssh connection in that pane. Think zellij ssh user@host.

When i saw this feature in Wezterm my jaw dropped, it's such an obviously awesome feature.

ssh2 = {version="0.9.3", features=["openssl-on-win32"]}
libssh-rs = {version="0.1.1", features=["vendored"]}

https://wezfurlong.org/wezterm/ssh.html

raphCode commented 2 years ago

There's a really cool thing that Zellij could do that'd "remove" the need for running Zellij on the remote machine.

Running zellij or any other terminal multiplexer provides session persistence, so that the programs continue to run after the ssh connection drops. To me, this is an important feature, especially for long running tasks. If I understand correctly, multiplexed ssh sessions a la wezterm do not provide this?

Lillecarl commented 2 years ago

@raphCode true, my suggestion complements another issue regarding nested zellij instances.

milanglacier commented 1 year ago

Both tmux and zellij treats nested session as is...

But most of the time, nested tmux works just fine because its keybinding scheme is centered around the prefix key. Say if you want to control the nesteed tmux session, you just need to press Control b twice to send the real Control b to the terminal which then forwards to the nesteed tmux session.

In zellij, you need to firstly lock the outer level session by C-g and then you are able to send keys like C-p, C-n into the inner level zellij session, which then controls the pane/tab/layout of the nested zellij session. But here comes the problem, you can never send a real C-p, C-n stuffs into the nested tmux session because you can never really lock the nested zellij session as you can never send a real C-g into the terminal.

Here's my workaround config to fix the problem (that is, tweaking the keymaps to have ability to send a real C-g into the terminal), note that I used Alt g as my lock mode key instead of Ctrl g but they should work the same.

    locked {
        bind "Alt g" { SwitchToMode "Normal"; }
    }

    normal {
        bind "Alt g" { SwitchToMode "Locked"; }
    }

    shared_except "locked" {
        bind "Ctrl a" { SwitchToMode "Tmux"; }
        bind "Alt p" { SwitchToMode "Pane"; }
        bind "Alt r" { SwitchToMode "Resize"; }
        bind "Alt s" { SwitchToMode "Scroll"; }
        bind "Alt o" { SwitchToMode "Session"; }
        bind "Alt t" { SwitchToMode "Tab"; }
        bind "Alt m" { SwitchToMode "Move"; }
        bind "Alt g" { Write 27 7015; SwitchToMode "Normal"; } // send a real Alt+g to the terminal
    }

In this way, you are able to send the real Alt g to the terminal and then you are able to lock the nested zellij session. In this setup, nested zellij works like nested tmux, controlling the nested session is a little verbose than controlling the outer level session, but it is doable, you just need to press one more keystroke (Ctrl a, Alt p, or whatever).

I also have the following keymaps to make things easier:


    tab {
        bind "Alt t" { Write 27 7028; SwitchToMode "Normal"; } // send a real Alt+t to the terminal
    }

    session {
        bind "Alt o" { Write 27 7023; SwitchToMode "Normal"; } // send a real Alt+o to the terminal
    }

    pane {
        bind "Alt p" { Write 27 7024; SwitchToMode "Normal"; } // send a real Alt+p to the terminal
    }

In this way, pressing Alt t twice will activate the tab mode in the nested zellij session, so you do not need to lock the outer level zellij session for entering the tab mode of the nested zellij session. To send a real A-t into the nested zellij session, firstly press A-g to lock the outlevel session, and then press A-t twice.

bruno-robert commented 7 months ago

@milanglacier In your example you are using Alt as a modfier, so sending Alt+t would be Write 27 7028. How would one come up with the bytes to send for an arbitrary keypress, say Ctrl+t for example?

adriangalilea commented 4 months ago

My ideal scenario would be:

Instead of having a zellij inside a zellij, with conflicting keybinds and so on, I would love to be able to directly let my main zellij instance wormhole into the remote zellij instance in a way that I would simply experience the remote zellij instance until I close it and then I would be back up in the main zellij instance.

Commands: zellij ssh bob@foo zellij

Then I'd see only a zellij instance in the remote machine but zellij notes that this is indeed a wormholed instance.

This may not be feasible or be very complex, just sharing my thoughts :)

P.S.: I love zellij

rsniezek commented 3 weeks ago

My ideal scenario would be:

Instead of having a zellij inside a zellij, with conflicting keybinds and so on, I would love to be able to directly let my main zellij instance wormhole into the remote zellij instance in a way that I would simply experience the remote zellij instance until I close it and then I would be back up in the main zellij instance.

Commands: zellij ssh bob@foo zellij

Then I'd see only a zellij instance in the remote machine but zellij notes that this is indeed a wormholed instance.

This may not be feasible or be very complex, just sharing my thoughts :)

P.S.: I love zellij

I'd also love to be able to simply connect my local zellij to a remote session. E.g. via session manager, simply selecting remote session would switch to it like to a local one so that the usage is identical to working locally. I'm willing to pay for having the session be local only or remote only if I can avoid nesting and have great UX thanks to the session manager. With this one could still pretty much use current nesting with lock mode or any improvements that are to come but remote session attach would work independently of that