Skip to content

Tmux persistent sessions

Source: Notion | Last edited: 2024-11-06 | ID: 1302d2dc-3ef...


It’s more powerful than the screen Ubuntu: screen - How to Keep a Process Running After Logging Out

Step by step guide to use Tmux + Cursor / VSCode

Section titled “Step by step guide to use Tmux + Cursor / VSCode”
  1. Ask LLM on how to install Tmux on your Linux workstation; and install Tmux on your Linux. Or if you’re on Ubuntu, simply run sudo apt update && sudo apt install tmux
  2. Install fzf, too: sudo apt install fzf
  3. Add additional content snippet to the settings.json under the .vscode folder of your project directory in your Cursor / VScode IDE
  4. Follow the instruction on the ~7min long video to find out how to use the Tmux to persist your terminal sessions.

Video file

The settings.json snippet described in the video above:

Section titled “The settings.json snippet described in the video above:”

@Anonymous @Anonymous New fixes.

2024-11-01 bug fixes for tmux-create-named-session so that the mouse scroll would scroll the terminal windows but not the prompt history log; add detailed docstrings

2024-10-31 bug fixes for tmux-wipe-all; no more errors popping up. Compatible with different OS(s). Terminal tab title is more elegantly displaying the SHELL and folder name.

{
"terminal.integrated.profiles.linux": { // NOTE: Ensure to modify 'linux' to your OS ('windows' or 'osx') in the profile name! If using SSH, the OS refers to the remote system.
/**
* Creates a new tmux session with a user-defined or timestamp-based name.
*
* Workflow:
* - Checks if tmux is already running.
* - If not, prompts the user to enter a session name.
* - Defaults to a timestamp if no name is provided.
* - Initiates a new tmux session with mouse support and specific terminal overrides.
* - If tmux is already active, notifies the user.
*/
"tmux-create-named-session": {
"path": "${env:SHELL}",
"args": ["-c", "if [ -z \"$TMUX\" ]; then timestamp=$(date '+%y%m%d-%H%M'); echo 'Creating new tmux session...'; echo 'Default name will be: '$timestamp; read '?Enter session name (Enter for default): ' name; session_name=${name:-$timestamp}; final_name=$timestamp'_'${session_name// /_}; echo 'Starting session: '$final_name; tmux new -s \"$final_name\" \\; set -g mouse on \\; set -g terminal-overrides 'xterm*:smcup@:rmcup@' \\; set-environment TERM_PROGRAM tmux || echo 'Failed to create session'; else echo 'Already in tmux session'; fi; $SHELL"],
"icon": "rocket"
},
/**
* Switches to an existing tmux session selected by the user via fzf.
*
* Workflow:
* - Verifies if fzf is installed.
* - Checks for active tmux sessions.
* - Presents a selection menu using fzf for the user to choose a session.
* - Attaches to the selected session or switches the client if already in tmux.
* - Handles scenarios where no session is selected or if switching fails.
*/
"tmux-switch": {
"path": "${env:SHELL}",
"args": ["-c", "if command -v fzf >/dev/null 2>&1; then if tmux ls >/dev/null 2>&1; then selected=$(tmux list-sessions -F '#{session_name}' | fzf --height=40% --reverse --header='Select session to attach (ESC to cancel):') && if [ -n \"$selected\" ]; then if [ -z \"$TMUX\" ]; then tmux attach -t \"$selected\" || echo 'Failed to attach to session'; else tmux switch-client -t \"$selected\" || echo 'Failed to switch session'; fi; else echo 'No session selected'; fi; else echo 'No tmux sessions running'; fi; else echo 'Please install fzf using your package manager'; fi; $SHELL"],
"icon": "split-horizontal"
},
/**
* Kills a selected tmux session chosen by the user via fzf.
*
* Workflow:
* - Checks if fzf is installed.
* - Verifies the existence of active tmux sessions.
* - Utilizes fzf to present a selection menu for session termination.
* - Attempts to kill the selected session and notifies the user of the outcome.
* - Handles cases where no session is selected or if killing fails.
*/
"tmux-wipe-a-selected": {
"path": "${env:SHELL}",
"args": ["-c", "if command -v fzf >/dev/null 2>&1; then if tmux ls >/dev/null 2>&1; then selected=$(tmux list-sessions -F '#{session_name}' | fzf --height=40% --reverse --header='Select session to kill (ESC to cancel):') && if [ -n \"$selected\" ]; then tmux kill-session -t \"$selected\" && echo \"Killed session: $selected\" || echo 'Failed to kill session'; else echo 'No session selected'; fi; else echo 'No tmux sessions running'; fi; else echo 'Please install fzf using your package manager'; fi; $SHELL"],
"icon": "chrome-close"
},
/**
* Terminates all running tmux sessions and cleans up related processes.
*
* Workflow:
* - Checks if any tmux processes are active.
* - Attempts to kill the tmux server, suppressing errors.
* - Notifies the user of successful or failed termination.
* - Cleans up any lingering tmux-related processes by matching specific command patterns.
* - Restarts the shell session.
*/
"tmux-wipe-all": {
"path": "${env:SHELL}",
"args": ["-c", "if pgrep tmux >/dev/null 2>&1; then (tmux kill-server 2>/dev/null || true) && echo 'All sessions cleaned' || echo 'Failed to kill all sessions'; pkill -f 'tmux.*create-named-session' 2>/dev/null; pkill -f 'tmux.*switch' 2>/dev/null; pkill -f 'tmux.*wipe' 2>/dev/null; else echo 'No tmux sessions running'; fi && exec $SHELL"],
"icon": "clear-all"
}
},
"terminal.integrated.defaultProfile.windows": "cmd", // Change to your preferred shell on Windows (e.g., "cmd", "git-bash", "pwsh", "PowerShell")
"terminal.integrated.defaultProfile.linux": "bash", // Change to your preferred shell on Linux (e.g., "zsh", "fish", "sh", "ksh")
"terminal.integrated.defaultProfile.osx": "zsh", // Change to your preferred shell on macOS (e.g., "bash", "fish", "tcsh")
"terminal.integrated.tabs.enabled": true,
"terminal.integrated.tabs.location": "right",
"terminal.integrated.scrollback": 100000000,
"terminal.integrated.allowChords": false,
"terminal.integrated.persistentSessionReviveProcess": "never",
"terminal.integrated.enablePersistentSessions": true,
"terminal.integrated.tabs.title": "${process}${separator}${workspaceFolder}",
"terminal.integrated.tabs.description": "${local}${separator}${cwdFolder}",
"terminal.integrated.tabs.showActiveTerminal": "always",
"terminal.integrated.tabs.separator": " - ",
"terminal.integrated.tabs.hideCondition": "never"
}

The demo SHELL script for long session running:

#!/bin/bash
LOG_FILE="~/scripts/progress.log"
SCRIPT_NAME=$(basename "$0")
# Color definitions
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
echo -e "${BLUE}[${MAGENTA}${SCRIPT_NAME}${BLUE}]${NC} Starting long-running process at $(date)" | tee -a "$LOG_FILE"
for i in {1..100}; do
PERCENT="${YELLOW}${i}${NC}"
echo -e "${BLUE}[${MAGENTA}${SCRIPT_NAME}${BLUE}]${NC} ${CYAN}Iteration ${PERCENT}${GREEN} (Progress: ${PERCENT}%)${NC} at $(date)" | tee -a "$LOG_FILE"
sleep 8
done
echo -e "${BLUE}[${MAGENTA}${SCRIPT_NAME}${BLUE}]${NC} ${GREEN}Process completed at $(date)${NC}" | tee -a "$LOG_FILE"