zellij
zellij copied to clipboard
Switch Session
Good day to you!
I have written script-binary for attaching session
#!/usr/bin/env zsh
Z_DIR=~/.config/zellij
SESSION=$(
FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS
--header='F1 - choose session
F2 - list active sessions
F3 - create session
'
"
[[ ! -z $1 ]] && (
echo $1
) || (
cd $Z_DIR/layouts
fd 'yaml' | sd '(.+)(\..+)' '$1' | fzf
)
)
LAYOUT_PATH="$Z_DIR/layouts/$SESSION.yaml"
# echo $LAYOUT_PATH
[[ -z $SESSION ]] && return 1
zellij --layout-path $LAYOUT_PATH
and mapped detaching
in Zellij.
To switch session, i'm detaching from curent session and execute script.
Is it possible to run script after detaching or is there action for switching session?
- action: [Detach, Run: {cmd: session-man}]
key: [Alt: 'D',]
Thank you!
Hey, thanks for taking the time in writing this issue.
This shouldn't be possible currently, since we don't handle the client once the session is detached.
A hack that would work currently would to specify, in a state directory before detaching, that you detached from the session. And wrap the calling of zellij, that runs the script if it detect a 1 at the location for example. Once it exits. This is super hacky.
I have started to collect some possible locations we would want to run actions on in
#851I do think on_attach
and on_detach
could be valuable points there.
It is also planned to integrate session switching directly in the UI at some point.
current workaround:
- create keybinding in shell (ctrl-z) for script-switching session
- and create keybinding for running wtype (xdotool-like for wayland) before detaching
- action:
[
Run:
{
cmd: setsid,
args: ["wtype", "-M", "ctrl", "-P", "z"],
},
Detach,
]
key: [Alt: "D"]
@a-kenji Is this work in progress? I want a session-switch interface just like tmux, but it seems has not. I need typing many words when I try to attach a session. just like this:
> zellij list-sessions
unequaled-flowers
calm-guide
hot-beam
> zellij attach hot-beam
And there has no completion for sessions.
@cathaysia,
This is not a wip yet. We would accept pr's for that.
And there has no completion for sessions.
This depends on the shell, if you use fish
, you should get these completions.
I need typing many words when I try to attach a session. just like this:
If you look at our integration section in the docs, you could already save a lot of typing by using one of the simplest shell scripts:
https://zellij.dev/documentation/integration.html#list-current-sessions
Obviously that is not as nice as tmux's session switching.
I borrowed the code from List current sessions and wrapped it around with loop, it almost works same like tmux session switch, except single session case is tricky.
instead of start zellij, you start this Z script
#!/usr/bin/env bash
while true; do
ZJ_SESSIONS=$(zellij list-sessions)
NO_SESSIONS=$(echo "${ZJ_SESSIONS}" wc -l)
if [ "${NO_SESSIONS}" -ge 2 ]; then
SESSION=$(echo "${ZJ_SESSIONS}" | fzf)
if [ $? -eq 0 ]; then
zellij attach $SESSION
else
exit 0
fi
else
SESSION=$ZJ_SESSIONS
zellij attach -c
fi
echo "detach/quit SESSION=$SESSION"
done
When you want to switch while inside zellij session, just detach (you can bind to tmux session switch key), then you will see fzf provide session list again, that you can select and switch to. And finally when you want to quit, just Ctrl-C/ESC on fzf selection screen. (or if zellij can provide different exit code for quit/detach, then we can detect and exit too w/o prompt list)
I did an ad-hoc one for personal usage: https://github.com/alex35mil/dotfiles/tree/master/user/bin/zellij/runner
https://user-images.githubusercontent.com/4244251/214125080-e106749d-b891-4f3f-ac81-e6b79ad89ab7.mp4
Even though the previous version worked, its UI was crap and not really pleasant to use. I rewrote it and abstracted away all (🤞) hardcoded stuff specific to my system. Published to the crates.io. Source is here.
https://user-images.githubusercontent.com/4244251/221366175-6c3ae4fd-985a-491b-9d26-255cdf03def5.mov
Even though the previous version worked, its UI was crap and not really pleasant to use. I rewrote it and abstracted away all (🤞) hardcoded stuff specific to my system. Published to the crates.io. Source is here.
This looks brutal 👍. Is there a way to install it other than using cargo? Like some executable or binary file which can be downloaded from github releases?
@mabasic Sorry, nope. I just cargo publish
it from the depths of my dotfiles
repo.
FWIW Installing Rust/Cargo is the breeziest experience unless you’re concerned with having Rust toolchain on your machine.
@mabasic Sorry, nope. I just
cargo publish
it from the depths of mydotfiles
repo.FWIW Installing Rust/Cargo is the breeziest experience unless you’re concerned with having Rust toolchain on your machine.
Have you tried installing Rust/Cargo on Windows xD (not wsl) You select the wrong option during the install and you get yourself whole Visual Studio installed cca 4GB. I have once managed to install it manually without having VS installed in the process 😄
It can be done but it is not a breeze. That is why I would have preferred a single binary instead, but never mind I will get around the issue.
Ah, sorry, not a windows user 😳
Similarly i have a "zellij runner" type code that loosely manages the sessions. Its mean to help to switch between different sessions, create new ones with zoxide results. I also have some code in my .zshrc that automatically connects to a default zellij session using this runner.
I'd love for this to be built in by default into zellij itself someday.
# connect to default zellij session if not already in one
if [ -z "$ZELLIJ_SESSION_NAME" ]; then
zr default
fi
function zr() {
# If a session name is provided as an argument, attach to or create it
if [[ -n $1 ]]; then
if zellij ls | grep -E -q "^$1( \(current\))?$"; then
# Attach to the specified session if it exists
zellij a "$1"
else
# Create a new session with the specified name if it doesn't exist
zellij -s "$1"
fi
fi
while true; do
local sessions_list=("New session" "Exit")
local existing_sessions=($(zellij ls | sed 's/ (current)//'))
if [[ ${#existing_sessions[@]} -gt 0 ]]; then
sessions_list=("${existing_sessions[@]}" "${sessions_list[@]}")
fi
local choice=$(printf '%s\n' "${sessions_list[@]}" | fzf --prompt="Select an option: ")
# If the choice is empty, assume the user wants to exit
if [[ -z $choice ]]; then
break
fi
case $choice in
"New session")
local dir_options=("No directory" "Exit")
local dirs=($(zoxide query -l))
if [[ ${#dirs[@]} -gt 0 ]]; then
dir_options=("${dirs[@]}" "${dir_options[@]}")
fi
local dir_choice=$(printf '%s\n' "${dir_options[@]}" | fzf --prompt="Select a directory or choose 'No directory': ")
# If the dir_choice is empty or invalid, continue to the next iteration of the loop
if [[ -z $dir_choice || $dir_choice == "Exit" ]]; then
continue
fi
case $dir_choice in
"No directory")
zellij
;;
*)
local session_name="$(basename $dir_choice)"
if [[ " ${existing_sessions[@]} " =~ " ${session_name} " ]]; then
# Attach to existing session
zellij a $session_name
else
# Create new session and change directory
(cd "$dir_choice" && zellij -s "$session_name")
fi
;;
esac
;;
"Exit")
break
;;
*)
zellij a $choice
;;
esac
done
}
@mabasic Sorry, nope. I just
cargo publish
it from the depths of mydotfiles
repo. FWIW Installing Rust/Cargo is the breeziest experience unless you’re concerned with having Rust toolchain on your machine.Have you tried installing Rust/Cargo on Windows xD (not wsl) You select the wrong option during the install and you get yourself whole Visual Studio installed cca 4GB. I have once managed to install it manually without having VS installed in the process 😄
It can be done but it is not a breeze. That is why I would have preferred a single binary instead, but never mind I will get around the issue.
But why would you want to install zellij-runner on windows (not WSL)? I thought zellij didn't compile on windows natively?
My version: zellij-sessionizer thanks to @ryanhuanli for inspiration https://github.com/zellij-org/zellij/issues/884#issuecomment-1250483279 here's my version for another use case:
- it's implementation of ThePrimeagen tmux-sessionizer https://github.com/ThePrimeagen/.dotfiles/blob/602019e902634188ab06ea31251c01c1a43d1621/bin/.local/scripts/tmux-sessionizer . I short, it allows to create sessions in predefined set of folders, like all children folders in
~/projects, ~/.config ~/work
. - so in select screen I need completely different approach, I don't show currently existing sessions or controls to create new empty session, who needs it anyway?
- not selecting anything (Esc or Ctrl-C): will restore previous session
difference from tmux-sessionizer comes from script running as a wrapper for zellij:
- obvious for those who read this thread:
- this script is zellij manager, user starts this script and it's running zellij for you
- to switch sessions, user just need to detach from current zellij session, instead of terminal he will see sessionizer menu to select folder for new session
- I'm adding menu item
Quit
that will terminate zellij-sessionizer - the only way to terminate script otherwise is to kill it.
#!/usr/bin/env bash
# set your own root folders, all children folders will become options for in sessionizer menu
root_folders="$HOME/projects $HOME/work $HOME/.config"
function attach_session() {
local session_root=$1
local session_name=$(basename "$session_root" | tr . _)
cd $session_root
zellij attach --create $session_name
}
quit_option="=== Quit sessionizer ==="
last_session=""
while true; do
selected_option=$( (echo $quit_option && find $root_folders -mindepth 1 -maxdepth 1 -type d) | fzf)
if [[ $selected_option == $quit_option ]]; then
exit 0
fi
if [[ -z $selected_option && -z $last_session ]]; then
exit 0
fi
if [[ -z $selected_option ]]; then
attach_session $last_session
else
last_session=$selected_option
attach_session $selected_option
fi
done
I don't have anything as sophisticated as the scripts above. but I wanted to add a functionality to my script where it could be executed within a zellij session, and if there was a session with the same name as SESSION_TITLE
the script would switch to that session.
but for that I would need some command line argument similar to tmux switch -t <session-name>
.
Are there any plans for something similar to be implemented?
#! /usr/bin/env sh
# select a directory using zoxide
ZOXIDE_RESULT=$(zoxide query --interactive)
# checks whether a directory has been selected
if [[ -z "$ZOXIDE_RESULT" ]]; then
# if there was no directory, select returns without executing
exit 0
fi
# extracts the directory name from the absolute path
SESSION_TITLE=$(echo "$ZOXIDE_RESULT" | sed 's#.*/##')
# get the list of sessions
SESSION_LIST=$(zellij list-sessions -n | awk '{print $1}')
# checks if SESSION_TITLE is in the session list
if echo "$SESSION_LIST" | grep -q "^${SESSION_TITLE}$"; then
# if so, attach to existing session
zellij attach "${SESSION_TITLE}"
else
# if not, create a new session
zellij attach -c "${SESSION_TITLE}"
fi
IMO, you suggestion is quite attractive and good. I think that will be a good workflow! I have a small question.
get the list of sessions
SESSION_LIST=$(zellij list-sessions -n | awk '{print $1}')
I just want to know the "-n" option in this scripts. In my machine, -n omit all the color of the output which is much easier for later process. Can you explain further what it means? Better to provide link in the doc. I searched and found nothing. Thank you!
I just want to know the "-n" option in this scripts. In my machine, -n omit all the color of the output which is much easier for later process. Can you explain further what it means? Better to provide link in the doc. I searched and found nothing. Thank you!
Type zellij list-sessions -h
and press enter. this will show information about the flags that can be passed to the list-sessions
command, including the -n
flag, which without abbreviation becomes --no-formatting
. All zellij commands have their own list of help information, which is very useful.