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

Switch Session #884

Open
fedoranvar opened this issue Nov 19, 2021 · 17 comments
Open

Switch Session #884

fedoranvar opened this issue Nov 19, 2021 · 17 comments
Labels
action Issues related to actions

Comments

@fedoranvar
Copy link

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!

@a-kenji
Copy link
Contributor

a-kenji commented Nov 19, 2021

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.

@fedoranvar
Copy link
Author

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"]

@cathaysia
Copy link

@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.
图片

@a-kenji
Copy link
Contributor

a-kenji commented Apr 27, 2022

@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.
image

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.

@ryanhuanli
Copy link

ryanhuanli commented Sep 19, 2022

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)

@alex35mil
Copy link

I did an ad-hoc one for personal usage: https://github.com/alex35mil/dotfiles/tree/master/user/bin/zellij/runner

zellij-runner.mp4

@alex35mil
Copy link

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.

zellij-runner.mov

@mabasic
Copy link

mabasic commented Feb 25, 2023

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?

@alex35mil
Copy link

@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
Copy link

mabasic commented Feb 26, 2023

@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.

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.

@alex35mil
Copy link

Ah, sorry, not a windows user 😳

@arnm
Copy link

arnm commented Apr 24, 2023

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
}

@KSaiAkshit
Copy link

@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.

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?

@aimestereo
Copy link

aimestereo commented Aug 5, 2023

My version: zellij-sessionizer
thanks to @ryanhuanli for inspiration #884 (comment)
here's my version for another use case:

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.

zellij-sessionizer:

#!/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

@emersonfbarros
Copy link

emersonfbarros commented Dec 12, 2023

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

@meicale
Copy link

meicale commented Feb 5, 2024

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!

@emersonfbarros
Copy link

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.

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

No branches or pull requests