Vifm Launcher with Byobu

From Vifm Wiki
Jump to navigation Jump to search

This script automates the process of launching a byobu session with predefined windows (clash, scrcpy, and vifm) and ensures only one instance of the session is active. If the session already exists, it attaches to the existing session and switches to the vifm window.

Features[edit]

  • Automatically creates or attaches to a byobu session.
  • Configures multiple windows within the session as an example: clash, scrcpy, and vifm.
  • Ensures only one instance of the session is active.
  • Activates the session's terminal window and switches to the vifm window.
  • Logs execution details for debugging purposes.
  • Shortcut Integration: You can set up a keyboard shortcut (e.g., Win + E) in GNOME by configuring it to run: gnome-terminal -- /home/xxx/apps/vifm_launcher.sh

This allows you to activate the vifm window directly, similar to how applications are launched in Windows. When the shortcut is pressed:

  • If the session exists, it attaches to the session and switches to the vifm window.
  • If the session does not exist, it creates a new session and opens the predefined windows.

Configuration[edit]

Edit variables at the top.

Known issues[edit]

  • In find_existing_window, using grep -qi "byobu" might cause confusion if multiple byobu windows exist
  • When working with terminal tabs (where a new tab is opened in the same window) and the byobu tab isn't currently active, the script fails to reactivate the original byobu terminal tab and instead creates a new session

Code[edit]

#!/bin/bash

# Get the script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

LOG_FILE="$SCRIPT_DIR/vifm-launcher.log"

SESSION_NAME="my_session"
VIFM_WINDOW_NAME="vifm"
TERMINAL_CMD="gnome-terminal"

# windowname:cmd pairs that define configuration of a session
WINDOWS=(
    clash:$HOME/apps/clash-linux-amd64-v3
    scrcpy:$HOME/apps/scrcpy.sh
    $VIFM_WINDOW_NAME:vifm
)

fail() {
    echo "Error:" "$@"
    exit 1
}

# dependency checks
command -v xdotool >/dev/null 2>&1 ||
    fail "xdotool is not installed. Install it using 'sudo apt install xdotool' or alike."
command -v byobu >/dev/null 2>&1 ||
    fail "byobu is not installed. Install it using 'sudo apt install byobu' or alike."

detect_byobu_backend() {
    if grep -q "tmux" ~/.byobu/backend ~/.config/byobu/backend 2>/dev/null; then
        echo "tmux"
    else
        echo "screen"
    fi
}

# just check for byobu-tmux and use it instead?
byobu_backend=$(detect_byobu_backend)
echo "Detected byobu backend: $byobu_backend" >> "$LOG_FILE"
[ "$byobu_backend" = tmux ] ||
    fail "Only tmux backend is supported. Run 'byobu-select-profile' to switch."

find_existing_window() {
    local retries=5
    local delay=0.5

    for ((i = 0; i < retries; i++)); do
        window_id=$(xdotool search --onlyvisible --class "$TERMINAL_CMD" 2>/dev/null | while read -r id; do
            xdotool getwindowname "$id" 2>/dev/null | grep -qi "byobu" && echo "$id"
        done | head -n1)

        if [ -n "$window_id" ]; then
            echo "$window_id"
            return 0
        fi
        sleep "$delay"
    done

    return 1
}

activate_window() {
    local window_id="$1"

    if [ -z "$window_id" ]; then
        return 1
    fi

    xdotool windowmap "$window_id" 2>/dev/null
    xdotool windowactivate "$window_id" 2>/dev/null

    return 0
}

create_byobu_session() {
    if byobu has-session -t "$SESSION_NAME" 2>/dev/null; then
        echo "Session $SESSION_NAME already exists. Attaching..." >> "$LOG_FILE"
        byobu attach-session -t "$SESSION_NAME"
        return 0
    fi

    byobu new-session -d -s "$SESSION_NAME"

    local first=yes
    for id_cmd in "${WINDOWS[@]}"; do
        local id=${id_cmd%%:*}
        local cmd=${id_cmd#*:}

        if [ "$first" = yes ]; then
            byobu rename-window -t "$SESSION_NAME:0" "$id"
        else
            byobu new-window -t "$SESSION_NAME" -n "$id"
        fi
        byobu send-keys -t "${SESSION_NAME}:$id" "$cmd" Enter

        first=no
    done

    byobu attach-session -t "$SESSION_NAME"
}

main() {
    local window_id=$(find_existing_window)

    if [ -n "$window_id" ]; then
        if activate_window "$window_id"; then
            if byobu select-window -t "$SESSION_NAME:$VIFM_WINDOW_NAME" 2>/dev/null; then
                echo "Activated existing byobu terminal window and switched to vifm."
                return 0
            else
                fail "Failed switching to vifm window."
            fi
        else
            fail "Failed to activate existing window."
        fi
    fi

    if ! create_byobu_session; then
        echo "Failed to create a new byobu session." >> "$LOG_FILE"
        exit 1
    fi
}

main

echo "Script execution completed at $(date)" >> "$LOG_FILE"

Source[edit]

GitHub#1061 by wideweide