aboutsummaryrefslogtreecommitdiff
path: root/linux/home/.config/tmux
diff options
context:
space:
mode:
Diffstat (limited to 'linux/home/.config/tmux')
-rwxr-xr-xlinux/home/.config/tmux/file_manager.sh108
-rwxr-xr-xlinux/home/.config/tmux/fzf-menu.sh60
-rwxr-xr-xlinux/home/.config/tmux/left-status.sh25
-rwxr-xr-xlinux/home/.config/tmux/notes.sh113
-rwxr-xr-xlinux/home/.config/tmux/right-status.sh27
-rwxr-xr-xlinux/home/.config/tmux/tmux-popup-pane-manager.sh152
-rwxr-xr-xlinux/home/.config/tmux/tmux-toggle-option.sh27
-rw-r--r--linux/home/.config/tmux/tmux.conf835
-rwxr-xr-xlinux/home/.config/tmux/tmux_number.sh11
9 files changed, 1358 insertions, 0 deletions
diff --git a/linux/home/.config/tmux/file_manager.sh b/linux/home/.config/tmux/file_manager.sh
new file mode 100755
index 0000000..b3a70a5
--- /dev/null
+++ b/linux/home/.config/tmux/file_manager.sh
@@ -0,0 +1,108 @@
+#!/usr/bin/env bash
+# tmux file opener with fallback file manager (no preview)
+
+# Mark this pane as the file manager immediately
+tmux select-pane -T "FILE_MANAGER"
+# Also set the option as backup
+tmux set-option -pq @file_manager 1
+
+orig_pane="$1"
+chooser_file="$HOME/.cache/tmux-fm-selected"
+rm -f "$chooser_file"
+
+# Function: pick available file manager
+pick_fm() {
+ if command -v lf >/dev/null 2>&1; then
+ echo "lf"
+ elif command -v nnn >/dev/null 2>&1; then
+ echo "nnn"
+ elif command -v ranger >/dev/null 2>&1; then
+ echo "ranger"
+ else
+ echo ""
+ fi
+}
+
+fm=$(pick_fm)
+if [[ -z "$fm" ]]; then
+ echo "No file manager found (lf, nnn, ranger)." >&2
+ cleanup
+ exit 1
+fi
+
+# Cleanup function to reset both title and option
+cleanup() {
+ tmux select-pane -T ""
+ tmux set-option -puq @file_manager
+ rm -f "$chooser_file"
+}
+
+# Set trap to cleanup on exit (including when user presses 'q')
+trap cleanup EXIT INT TERM
+
+# Launch the chosen file manager with no preview where possible
+case "$fm" in
+ nnn)
+ # Disable preview completely and use picker mode
+ # -A: disable dir auto-select, -e: open text files in editor
+ # -o: open files with opener, -x: show only selection
+ NNN_OPENER="tee \"$chooser_file\"" nnn -Axo
+ ;;
+ lf)
+ # Disable preview and set selection path
+ lf -command 'set preview false' -selection-path="$chooser_file"
+ ;;
+ ranger)
+ # Disable all previews
+ ranger --choosefile="$chooser_file" \
+ --cmd='set preview_files false' \
+ --cmd='set preview_directories false' \
+ --cmd='set preview_images false'
+ ;;
+esac
+
+# Exit if no file chosen (user pressed 'q' or cancelled)
+if [[ ! -s "$chooser_file" ]]; then
+ exit 0
+fi
+
+file="$(head -n 1 "$chooser_file")"
+rm -f "$chooser_file"
+
+# Restrict to current window panes and exclude the file manager pane
+current_window=$(tmux display-message -p '#I')
+mapfile -t panes < <(
+ tmux list-panes -t "$current_window" -F '#S:#I.#P' |
+ grep -v "^$(tmux display-message -p '#S:#I').$(tmux display-message -p '#P')$"
+)
+
+# Choose target pane
+if [[ ${#panes[@]} -eq 0 ]]; then
+ exit 1
+elif [[ ${#panes[@]} -eq 1 ]]; then
+ target="${panes[0]}"
+else
+ echo "Select target pane:"
+ for i in "${!panes[@]}"; do
+ letter=$(printf "\\$(printf '%03o' $((97 + i)))") # a, b, c...
+ echo "$letter) ${panes[$i]}"
+ done
+ read -n 1 -p "Choice: " choice
+ echo
+ idx=$(( $(printf "%d" "'$choice") - 97 ))
+ if [[ $idx -ge 0 && $idx -lt ${#panes[@]} ]]; then
+ target="${panes[$idx]}"
+ else
+ exit 1
+ fi
+fi
+
+# Decide if file is text or binary
+if file --mime-type "$file" 2>/dev/null | grep -q 'text/'; then
+ opener="${EDITOR:-$(command -v nvim || command -v vim || echo 'vi')}"
+else
+ opener="$(command -v xdg-open || command -v open || echo 'cat')"
+fi
+
+# Send open command to target pane
+tmux send-keys -t "$target" "$opener \"$file\"" C-m
diff --git a/linux/home/.config/tmux/fzf-menu.sh b/linux/home/.config/tmux/fzf-menu.sh
new file mode 100755
index 0000000..d7863d9
--- /dev/null
+++ b/linux/home/.config/tmux/fzf-menu.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+# fzf session name
+FZF_SESSION_NAME="fzf"
+
+# Print error messages
+error() {
+ echo "Error: $1" >&2
+}
+
+# Check if tmux is installed
+if ! command -v tmux >/dev/null 2>&1; then
+ error "tmux is not installed."
+ exit 1
+fi
+
+# Function to handle file or directory opening
+open_selected_item() {
+ # Use fzf to select a file from the specified directory
+ SELECTED_FILE=$(find ~ -type f | fzf --preview "bat --style=numbers --color=always --line-range=:500 {}" \
+ --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi)
+
+ if [ "$SELECTED_FILE" != "" ]; then
+ # Ask whether to open the file or its directory
+ read -p "Open file (f) or directory (d)? " choice
+ case "$choice" in
+ f | F)
+ # Open the selected file in nvim
+ nvim "$SELECTED_FILE"
+ ;;
+ d | D)
+ # Change to the directory containing the selected file
+ cd "$(dirname "$SELECTED_FILE")"
+ ;;
+ *)
+ echo "Invalid choice. Please enter 'f' for file or 'd' for directory."
+ ;;
+ esac
+ else
+ echo "No file selected."
+ fi
+}
+
+# Check if the fzf session exists
+if tmux has-session -t "$FZF_SESSION_NAME" 2>/dev/null; then
+ # Get the current tmux session name
+ CURRENT_SESSION=$(tmux display-message -p '#S')
+
+ # If currently in the fzf session, detach; otherwise, attach to it
+ if [ "$CURRENT_SESSION" = "$FZF_SESSION_NAME" ]; then
+ tmux detach-client
+ else
+ tmux set -gF '@last_session_name' '#S' # Store the current session name
+ tmux display-popup -E -x200% -y0 -w50% -h99% "tmux attach-session -t $FZF_SESSION_NAME"
+ fi
+else
+ # If the fzf session doesn't exist, create it and run file selection logic in a popup
+ tmux set -gF '@last_session_name' '#S' # Store the current session name
+ tmux display-popup -E -w100% -h100% -y0 -x0 "tmux new-session -A -s fzf '$0 open_selected_item'"
+fi
diff --git a/linux/home/.config/tmux/left-status.sh b/linux/home/.config/tmux/left-status.sh
new file mode 100755
index 0000000..e4a8c49
--- /dev/null
+++ b/linux/home/.config/tmux/left-status.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+function ip-address() {
+ # Loop through the interfaces and check for the interface that is up.
+ for file in /sys/class/net/*; do
+ iface=$(basename $file);
+ read status < $file/operstate;
+ [ "$status" == "up" ] && ip addr show $iface | awk '/inet /{printf $2""}'
+ done
+}
+
+function vpn-connection() {
+ # Check for tun0 interface.
+ [ -d /sys/class/net/tun0 ] && printf "%s " 'VPN*'
+}
+
+function main() {
+ # Comment out any function you do not need.
+ ip-address
+ vpn-connection
+}
+
+# Calling the main function which will call the other functions.
+main
+
diff --git a/linux/home/.config/tmux/notes.sh b/linux/home/.config/tmux/notes.sh
new file mode 100755
index 0000000..71a8dc7
--- /dev/null
+++ b/linux/home/.config/tmux/notes.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+# Notes/TODO management & quick search engine via tmux
+
+NOTES_DIR="$HOME/documents/main"
+TODO_FILE="$NOTES_DIR/inbox/tasks/TODO.md"
+EDITOR="nvim"
+NOTE_SESSION_NAME="note"
+BROWSER_PREFERENCES=("firefox" "chromium" "google-chrome" "brave-browser" "chrome")
+SEARCH_URL="https://www.google.com/search?q="
+
+# simple error printing
+error() {
+ echo "Error: $1" >&2
+}
+
+# add a TODO entry with timestamp
+add_todo() {
+ local todo_text="$1"
+ [ -z "$todo_text" ] && return 1
+
+ [ ! -f "$TODO_FILE" ] && echo -e "# TODO List\n" > "$TODO_FILE"
+
+ echo "- [ ] $todo_text ($(date '+%Y-%m-%d %H:%M'))" >> "$TODO_FILE"
+ tmux display-message "Added TODO: $todo_text"
+}
+
+# open a web search
+search_web() {
+ local query="$1"
+ [ -z "$query" ] && return 1
+
+ local encoded_query=$(printf '%s' "$query" | sed 's/ /+/g' | sed 's/[^a-zA-Z0-9+._-]//g')
+ local search_url="${SEARCH_URL}${encoded_query}"
+
+ if command -v xdg-open >/dev/null 2>&1; then
+ xdg-open "$search_url" >/dev/null 2>&1 &
+ else
+ for browser in "${BROWSER_PREFERENCES[@]}"; do
+ command -v "$browser" >/dev/null 2>&1 && $browser "$search_url" >/dev/null 2>&1 & break
+ done
+ fi
+
+ tmux display-message "Opening search for: $query"
+}
+
+# display the notes menu (in-editor or popup)
+open_menu() {
+ tmux set -gF '@last_session_name' '#S'
+
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null && tmux list-panes -t "$NOTE_SESSION_NAME" -F "#{pane_current_command}" | grep -q "^nvim$"; then
+ # menu for active nvim session
+ tmux display-menu -T "#[align=center] Notes (nvim-mode)" \
+ "New note" n "command-prompt -p 'Enter note title:' 'send-keys -t $NOTE_SESSION_NAME \":e $NOTES_DIR/%%.md\" Enter'" \
+ "Open note" o "send-keys -t $NOTE_SESSION_NAME \":cd $NOTES_DIR | FzfLua files\" Enter" \
+ "TODO List" t "send-keys -t $NOTE_SESSION_NAME \":e $TODO_FILE\" Enter" \
+ "Add Quick TODO" T "command-prompt -p 'Enter TODO:' 'run-shell \"$0 --add-todo %%\"'" \
+ "Grep/find patterns" g "send-keys -t $NOTE_SESSION_NAME \":cd $NOTES_DIR | FzfLua live_grep\" Enter" \
+ "Web Search" s "command-prompt -p 'Search query:' 'run-shell \"$0 --search %%\"'" \
+ "Quit (q)" q ""
+ else
+ # popup menu outside of nvim
+ tmux display-menu -T "#[align=center] Notes (popup-mode)" \
+ "New note" n "command-prompt -p 'Enter note title:' \"display-popup -w 100% -h 100% -E 'tmux new-session -A -s $NOTE_SESSION_NAME \\\"$EDITOR $NOTES_DIR/%%.md\\\"'\"" \
+ "Open note" o "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME 'fzf --preview \\\"bat --style=numbers --color=always --line-range=:500 {}\\\" --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi < <(find $NOTES_DIR -type f -name \\\"*.md\\\") | xargs -r $EDITOR'\"" \
+ "TODO List" t "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME \\\"$EDITOR $TODO_FILE\\\"\"" \
+ "Add Quick TODO" T "command-prompt -p 'Enter TODO:' 'run-shell \"$0 --add-todo %%\"'" \
+ "Grep/find patterns" g "display-popup -w 100% -h 100% -E \"tmux new-session -A -s $NOTE_SESSION_NAME 'rg --color=always --line-number --no-heading --smart-case . $NOTES_DIR | fzf --delimiter=: --preview \\\"bat --style=numbers --color=always --line-range=:500 {1}\\\" --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi | cut -d ':' -f 1 | xargs -r $EDITOR'\"" \
+ "Web Search" s "command-prompt -p 'Search query:' 'run-shell \"$0 --search %%\"'" \
+ "Quit (q)" q ""
+ fi
+}
+
+# make sure tmux is installed
+command -v tmux >/dev/null 2>&1 || { error "tmux is not installed."; exit 1; }
+
+# handle CLI arguments
+if [ "$1" = "--add-todo" ]; then
+ shift
+ add_todo "$*"
+ exit 0
+fi
+
+if [ "$1" = "--search" ]; then
+ shift
+ search_web "$*"
+ exit 0
+fi
+
+if [ "$1" = "--new" ]; then
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null; then
+ # reuse existing session
+ tmux display-popup -w 100% -h 100% -E "
+ FILE=\$(find $NOTES_DIR -type f -name '*.md' \
+ | fzf --preview 'bat --style=numbers --color=always --line-range=:500 {}' \
+ --preview-window=up:60% --height=90% --layout=reverse --border=sharp --ansi)
+ [ -n \"\$FILE\" ] && tmux send-keys -t $NOTE_SESSION_NAME \":e \$FILE\" Enter
+ "
+ else
+ open_menu
+ fi
+ exit 0
+fi
+
+# default behavior: toggle or open menu
+if [ -z "$1" ]; then
+ if tmux has-session -t "$NOTE_SESSION_NAME" 2>/dev/null; then
+ CURRENT_SESSION=$(tmux display-message -p '#S')
+ [ "$CURRENT_SESSION" = "$NOTE_SESSION_NAME" ] && tmux detach-client || tmux display-popup -E -x200% -y0 -w50% -h99% "tmux attach-session -t $NOTE_SESSION_NAME"
+ else
+ open_menu
+ fi
+fi
diff --git a/linux/home/.config/tmux/right-status.sh b/linux/home/.config/tmux/right-status.sh
new file mode 100755
index 0000000..a14bbe3
--- /dev/null
+++ b/linux/home/.config/tmux/right-status.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Get CPU average
+getCPU=$[100-$(vmstat 1 2|tail -1|awk '{print $15}')]
+
+# Grab the second line of the ouput produced by the command: free -g (displays output in Gb)
+getMem=$(free -h | sed -n '2p')
+getMemPct=$(free -g | sed -n '2p')
+
+# Split the string in secondLine into an array
+read -ra ADDR <<< "$getMem"
+read -ra ADDRPct <<< "$getMemPct"
+
+# Get the total RAM from arrays
+totalRam="${ADDR[1]//[^0-9.0-9]/}"
+totalRamPct="${ADDRPct[1]}"
+
+# Get the used RAM from arrays
+usedRam="${ADDR[2]//[^0-9.0-9]/}"
+usedRamPct="${ADDRPct[2]}"
+
+# Calculate and display the percentages
+pct="$(($usedRamPct*100/$totalRamPct))"
+usage="$usedRam/$totalRam"
+#echo "cpu:$getCPU% | mem:$pct% ($usage""G)"
+echo "Cpu:$getCPU% | Mem:$pct% |"
+
diff --git a/linux/home/.config/tmux/tmux-popup-pane-manager.sh b/linux/home/.config/tmux/tmux-popup-pane-manager.sh
new file mode 100755
index 0000000..bb0cfef
--- /dev/null
+++ b/linux/home/.config/tmux/tmux-popup-pane-manager.sh
@@ -0,0 +1,152 @@
+#!/usr/bin/bash
+# tmux-popup-pane-manager.sh - menu driven tmux pane activities
+# github repo: https://github.com/pl643/tmux-scripts
+# resize, selection, syncronize, layout, splits, kill, break
+
+# sample tmux.conf binding:
+# bind-key -n M-p tmux-popup-pane-manager.sh
+
+[ "$TMUX" = "" ] && echo "NOTE: needs to be run inside a tmux sessions" && exit 1
+
+run_after_popup="/tmp/.run_after_popup"
+realpath="$(realpath "$0")"
+if [ "$1" != "--no-popup" ]; then
+ tmux popup -E -T "────────────── Pane Manager ─────" -w 46 -h 35 "$realpath --no-popup"
+
+ [ -f "$run_after_popup" ] && bash "$run_after_popup" && rm "$run_after_popup"
+ exit 0
+fi
+
+pane_border_status="off"
+display_menu() {
+ clear
+ tmux list-windows | grep active | awk '{print $2}' | tail -c2 | grep -q Z && zoom_status="on" || zoom_status="off"
+ tmux show-options -w | grep -q 'synchronize-panes.*on' && synchronize_panes="on" || synchronize_panes="off"
+ tmux show-options -w | grep -q 'pane-border-status.*top' && pane_border_status="top"
+ tmux show-options -w | grep -q 'pane-border-status.*bottom' && pane_border_status="bottom"
+ printf "
+ Resize
+
+ hjkl x 5 HJKL x 1
+ 1 - 9 | x 10%% ! - ) ─ x 10%%
+ = equally | + equally ─
+
+ Split
+
+ s - spilt - v | spilt |
+
+ Navigation
+
+ n p next/prev pane
+ N P next/prev layout
+ u d swap pane up/down
+
+ Toggles
+
+ b border [ %s ]
+ S syncronize [ %s ]
+ z zoom [ %s ]
+
+ Misc
+
+ B break (make pane into window)
+ o join this pane to window
+ D send C-d
+ e display panes / exit
+ t rename pane
+ X kill (no confirm!)
+ q quit" "$pane_border_status" "$synchronize_panes" "$zoom_status"
+}
+display_menu
+
+# https://www.reddit.com/r/tmux/comments/g9nr01/how_to_show_message_or_effect_when/
+# Uncomment this setting if want status of pane sync on the status bar
+tmux set -ag status-right '#{?pane_synchronized, #[fg=red]IN_SYNC#[default],}'
+
+# https://www.reddit.com/r/tmux/comments/dfj5ye/rename_pane_not_window_is_there_a_builtin/
+tmux set -g pane-border-format " [ ###P #T ] "
+
+# If C-c is press in the while [ true ] loop, a run runaway process occurs, limiting
+# it to 20 will cause the loop to exit after 20 loops. Modify MAXNUMLOOP if you
+# need more keys presses.
+MAXNUMLOOP=100
+COUNTER=0
+while [ "$COUNTER" -lt "$MAXNUMLOOP" ]; do
+
+ read -sn1 c || exit
+
+ # Resize x 1
+ [ "$c" = "H" ] && tmux resize-pane -L 1
+ [ "$c" = "L" ] && tmux resize-pane -R 1
+ [ "$c" = "J" ] && tmux resize-pane -D 1
+ [ "$c" = "K" ] && tmux resize-pane -U 1
+
+ # Resize x 5
+ [ "$c" = "h" ] && tmux resize-pane -L 5
+ [ "$c" = "l" ] && tmux resize-pane -R 5
+ [ "$c" = "j" ] && tmux resize-pane -D 5
+ [ "$c" = "k" ] && tmux resize-pane -U 5
+
+ # Resize X percent
+ [ "$c" = "1" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 10 / 100))
+ [ "$c" = "2" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 20 / 100))
+ [ "$c" = "3" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 30 / 100))
+ [ "$c" = "4" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 40 / 100))
+ [ "$c" = "5" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 50 / 100))
+ [ "$c" = "6" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 60 / 100))
+ [ "$c" = "7" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 70 / 100))
+ [ "$c" = "8" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 80 / 100))
+ [ "$c" = "9" ] && tmux resize-pane -x $(($(tmux display-message -p "#{window_width}") * 90 / 100))
+
+ # Resize Y percent
+ [ "$c" = "!" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 10 / 100))
+ [ "$c" = "@" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 20 / 100))
+ [ "$c" = "#" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 30 / 100))
+ [ "$c" = "$" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 40 / 100))
+ [ "$c" = "%" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 50 / 100))
+ [ "$c" = "^" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 60 / 100))
+ [ "$c" = "&" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 70 / 100))
+ [ "$c" = "*" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 80 / 100))
+ [ "$c" = "(" ] && tmux resize-pane -y $(($(tmux display-message -p "#{window_height}") * 90 / 100))
+
+ # Pane layout cycle
+ [ "$c" = "N" ] || [ "$c" = " " ] && tmux next-layout
+ [ "$c" = "P" ] && tmux previous-layout
+
+ # Pane selection cycle
+ [ "$c" = "n" ] && tmux select-pane -t :.+
+ [ "$c" = "p" ] && tmux select-pane -t :.-
+
+ # Pane layout selection even horizontal/vertical
+ [ "$c" = "=" ] && tmux select-layout even-horizontal
+ [ "$c" = "+" ] && tmux select-layout even-vertical
+
+ # Rotate pane
+ [ "$c" = "u" ] && tmux swap-pane -U
+ [ "$c" = "d" ] && tmux swap-pane -D
+
+ # Syncronize pane
+ [ "$c" = "S" ] && tmux setw synchronize-pane && display_menu
+
+ # border status ( 3 toggle off, top, bottom )
+ [ "$c" = "b" ] && [ "$pane_border_status" = "off" ] && tmux set pane-border-status && display_menu && continue
+ [ "$c" = "b" ] && [ "$pane_border_status" = "top" ] && tmux set pane-border-status bottom && display_menu && continue
+ [ "$c" = "b" ] && [ "$pane_border_status" = "bottom" ] && tmux set pane-border-status off &&
+ pane_border_status="off" && display_menu && continue
+
+ # Split panes
+ [ "$c" = "s" ] || [ "$c" = "-" ] && tmux split -v
+ [ "$c" = "v" ] || [ "$c" = "|" ] && tmux split -h
+
+ # Misc
+ [ "$c" = "B" ] && tmux break-pane
+ [ "$c" = "o" ] && printf "\n\n join window: " && read window && tmux join-pane -t "$window"
+ [ "$c" = "X" ] && tmux kill-pane
+ [ "$c" = "D" ] && tmux send-key C-d
+ display_menu
+ [ "$c" = "q" ] && exit
+ [ "$c" = "e" ] && echo tmux display-panes >"$run_after_popup" && exit
+ [ "$c" = "z" ] && tmux resize-pane -Z && display_menu
+ [ "$c" = "t" ] && printf "\n\n pane name: " && read pane_name && tmux select-pane -T "$pane_name" && display_menu
+ let COUNTER=COUNTER+1
+done
diff --git a/linux/home/.config/tmux/tmux-toggle-option.sh b/linux/home/.config/tmux/tmux-toggle-option.sh
new file mode 100755
index 0000000..52d5fdb
--- /dev/null
+++ b/linux/home/.config/tmux/tmux-toggle-option.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/bash
+
+#USAGE="USAGE: $0 OPTION_NAME ON_STATE OFF_STATE"
+
+#OPTION_NAME=$1
+#ON_STATE=$2
+#OFF_STATE=$3
+#
+#if [[ "$#" != 3 ]]; then
+# echo $USAGE
+# exit 1
+#fi
+#
+#if [[ `tmux show-option -w | grep "$OPTION_NAME $ON_STATE"` ]]; then
+# OPTION_VALUE=$OFF_STATE
+#else
+# OPTION_VALUE=$ON_STATE
+#fi
+#
+#tmux display-message "monitor activity: $OPTION_NAME $OPTION_VALUE"
+#tmux set-option -w $OPTION_NAME $OPTION_VALUE > /dev/null
+
+if [ $(tmux show-option -A status-left) != 'status-left* "#[fg=#50fa7b,bg=default] #[bg=#50fa7b,fg=black]❐ #S #[fg=#50fa7b,bg=default]"' ]; then
+ tmux set -g status-left "#[fg=#50fa7b,bg=default] #[bg=#50fa7b,fg=black]❐ #S #[fg=#50fa7b,bg=default] ";
+else
+ tmux set -g status-left "#[fg=#50fa7b,bg=default]#[bg=#50fa7b,fg=black] ❐ #S #( ~/.config/tmux/left-status.sh ) #[fg=#50fa7b,bg=default]" && tmux set -g status-right "#[fg=#50fa7b,bg=default] #{?client_prefix,#[reverse] Prefix #[noreverse] ,}#[bg=default,fg=#50fa7b]#[bg=#50fa7b,fg=black] #( ~/.config/tmux/right-status.sh ) %d-%b-%y | %H:%M #[bg=default,fg=#50fa7b]";
+fi
diff --git a/linux/home/.config/tmux/tmux.conf b/linux/home/.config/tmux/tmux.conf
new file mode 100644
index 0000000..a62e3e3
--- /dev/null
+++ b/linux/home/.config/tmux/tmux.conf
@@ -0,0 +1,835 @@
+# ████████╗███╗ ███╗██╗ ██╗██╗ ██╗
+# ╚══██╔══╝████╗ ████║██║ ██║╚██╗██╔╝
+# ██║ ██╔████╔██║██║ ██║ ╚███╔╝
+# ██║ ██║╚██╔╝██║██║ ██║ ██╔██╗
+# ██║ ██║ ╚═╝ ██║╚██████╔╝██╔╝ ██╗
+# ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Options ###
+
+# Setting the Prefix from Ctrl+b to Ctrl+s
+unbind C-b
+set -g prefix C-s
+#set -g prefix M-Space
+
+# Ensure that we can send Ctrl+s to other apps
+bind C-s send-prefix
+
+# Check if in (n)vim
+is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
+
+# Send the prefix to client inside window (nested tmux)
+#bind-key -n C-a send-prefix
+bind -n C-a if-shell "$is_vim" "send-keys C-a" "send-prefix"
+
+# Disable local tmux keys (nested tmux)
+bind -T root F12 \
+ set prefix None \;\
+ set key-table off \;\
+ if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\
+ refresh-client -S \;\
+
+bind -T off F12 \
+ set -u prefix \;\
+ set -u key-table \;\
+ refresh-client -S
+
+# Toggle Sync Panes
+bind C-y set-window-option synchronize-panes\; display-message "Synchronize-Panes is now #{?pane_synchronized,on,off}"
+
+# Setting the delay between Prefix and Command
+set -sg escape-time 10
+#set-option -sg escape-time 10
+
+# Reload tmux with <Prefix>r
+bind r source-file ~/.config/tmux/tmux.conf \; display "Reloaded!"
+
+# Use <Prefix>L to clear terminal
+bind -r L send-keys "clear" Enter
+
+# Rename current window (Ctrl + A, A)
+bind R rename-window '' \; \
+ command-prompt -I "#W" "rename-window -- '%%'"
+
+# Auto rename pane
+set -wg automatic-rename on
+set -g automatic-rename-format "#{pane_current_command}"
+
+# Renumber all windows when one is killed
+set -g renumber-windows on
+
+# Mouse
+set -g mouse on
+
+# Right Click Menu
+bind -n MouseDown3Pane \
+ if-shell -F "#{||:#{match:#{pane_current_command},nvim},#{match:#{pane_current_command},vim}}" \
+ "send-keys -M" \
+ "display-menu -t= -xM -yM -T '#[align=centre]#{pane_index} (#{pane_id})' \
+ 'Vim' v 'send-keys \"vi\" Enter' \
+ 'File-manager' f 'send-keys \"yazi\" Enter' \
+ '' \
+ 'Horizontal Split' '\\\\' 'split-window -h -c \"#{pane_current_path}\"' \
+ 'Vertical Split' '-' 'split-window -v -c \"#{pane_current_path}\"' \
+ '' \
+ 'Copy Mode' 'C' 'copy-mode -e' \
+ 'Paste' 'p' {send-keys C-v} \
+ 'Open with xdg-open' 'o' 'send-keys \"xdg-open #{pane_current_path}\"' \
+ 'Enter' 'e' 'send-keys Enter' \
+ '' \
+ 'Go To Top' '↑' 'copy-mode -e; send-keys gg' \
+ 'Go To Bottom' '↓' 'copy-mode -e; send-keys G' \
+ '' \
+ 'Break Pane' 't' 'break-pane' \
+ 'Join Pane' 'j' 'choose-window \"join-pane -h -s %%\"' \
+ '#{?pane_marked,Unmark,Mark}' 'm' 'select-pane -m' \
+ '#{?#{>:#{window_panes},1},,-}Swap Up' 'u' 'swap-pane -U' \
+ '#{?#{>:#{window_panes},1},,-}Swap Down' 'd' 'swap-pane -D' \
+ '' \
+ 'New Window' 'n' 'new-window' \
+ 'Previous Window' '🡠' 'previous-window' \
+ 'Next Window' '🡢' 'next-window' \
+ 'Swap Window Left' '<' 'swap-window -t -1' \
+ 'Swap Window Right' '>' 'swap-window -t +1' \
+ '' \
+ 'Kill' 'X' 'kill-pane' \
+ 'Respawn' 'R' 'respawn-pane -k' \
+ 'Interrupt (Ctrl+C)' 'c' 'send-keys C-c' \
+ '#{?#{>:#{window_panes},1},,-}#{?window_zoomed_flag,Unzoom,Zoom}' 'z' 'resize-pane -Z'"
+
+
+# Disable copy on primary selection (prevents auto-copy on mouse drag release)
+unbind -T root MouseDrag1Pane
+unbind -T copy-mode MouseDragEnd1Pane
+unbind -T copy-mode-vi MouseDragEnd1Pane
+
+# Left-click to select a pane (no copy mode)
+bind -T root MouseDown1Pane {
+ select-pane -t= # Select pane under mouse
+ send-keys -M # Enable mouse interaction in pane
+}
+
+# Don't go into copy-mode on first click/drag
+bind -T root MouseDrag1Pane if-shell '[ "#{mouse_flags}" = "drag" ]' {
+ if-shell '[ "#{pane_id}" = "#{mouse_pane}" ]' {
+ copy-mode
+ send-keys -X begin-selection
+ } {
+ select-pane -t=
+ send-keys -M
+ }
+} {
+ select-pane -t=
+ send-keys -M
+}
+
+# Left-click to start selection in copy-mode
+bind -T root DoubleClick1Pane {
+ copy-mode
+ send-keys -X begin-selection
+}
+
+# Left-click to start selection in copy-mode
+bind -T copy-mode-vi MouseDown1Pane {
+ send-keys -X cancel-selection
+ send-keys -X begin-selection
+}
+
+# Left-click drag to start selection in copy-mode
+bind -T copy-mode-vi MouseDown1Pane {
+ send-keys -X begin-selection
+}
+
+# Right click to copy the selected text and exit copy mode
+bind -T copy-mode-vi MouseDown3Pane {
+ send-keys -X copy-pipe-no-clear
+ send-keys -X end-selection
+ send-keys Escape
+}
+
+# Middle click exit copy mode without copying (cancel the selection)
+bind -T copy-mode-vi MouseDown2Pane {
+ send-keys -X end-selection
+ send-keys Escape
+}
+
+# Middle click paste if not in copy-mode
+# Conditional behavior for MouseDown2Pane
+if-shell '[ "$CTRL_V_PASTE" = "true" ]' \
+ "bind -T root MouseDown2Pane send-keys C-v" \
+ "bind -T root MouseDown2Pane send-keys C-S-v"
+
+## Right-click drag to exit copy mode without selecting text
+#bind -T copy-mode-vi MouseDragEnd3Pane {
+# send-keys -X end-selection # End selection
+# send-keys Escape # Exit copy mode
+#}
+
+# Make mouse-drag work only with Ctrl
+#unbind -T root MouseDrag1Pane
+#unbind -T copy-mode-vi MouseDrag1Pane
+#bind -n C-MouseDrag1Pane if -Ft= \
+#'#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" send-keys -X \"send-keys -M\"' 'copy-mode -M'
+#bind -T copy-mode-vi C-MouseDrag1Pane send-keys -X begin-selection
+
+# Exiting copy mode without copying (Left-click to exit)
+#bind -T copy-mode-vi MouseDown1Pane {
+# select-pane -t= # Deselect pane
+# send-keys Escape # Exit copy mode
+#}
+
+
+# Scrollback
+set -g history-limit 10000
+
+# Sane scrolling
+set -g terminal-overrides 'xterm*:smcup@:rmcup@'
+
+# Sane scrolling
+bind -n WheelUpPane {
+ if -F '#{==:#{window_name},nvim}' {
+ #send-keys -M
+ send-keys Up
+ } {
+ copy-mode -e
+ }
+}
+bind -n WheelDownPane {
+ if -F '#{==:#{window_name},nvim}' {
+ #send-keys -M
+ send-keys Down
+ } {
+ copy-mode -e
+ }
+}
+
+# Focus events, allow supported requests from applications to passthrough/run in tmux
+set-option -g focus-events on
+
+# Update the TERM variable of terminal emulator when creating a new session or attaching a existing session
+set -g update-environment 'DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY TERM'
+
+# New session
+#bind -n M-N new-session
+
+
+# Lock
+#set-option -g lock-command "vlock -c"
+#set -g lock-after-time 910 # Seconds; 0 = never
+#bind -n M-Escape lock-session
+
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Window Movement/Control ###
+
+# Aggressive resizing, useful when using "grouped sessions" and multi-monitor setup
+setw -g aggressive-resize on
+
+# Menu
+bind-key -n M-m display-menu -x W -y S \
+ "New Session" S "command-prompt -p \"New Session:\" \"new-session -A -s '%%'\"" \
+ "Kill Session" x "kill-session" \
+ "Kill Other Session(s)" X "kill-session -a" \
+ "" \
+ "New Window" ␍ new-window \
+ "Kill Window" k "killw" \
+ "Choose Window" w choose-window \
+ "Previous Window" 🡠 previous-window \
+ "Next Window" 🡢 next-window \
+ "Swap Window Right" ↑ "swap-window -t -1" \
+ "Swap Window Left" ↓ "swap-window -t +1" \
+ "Horizontal Split" v "split-window -h" \
+ "Vertical Split" s "split-window -v" \
+ "" \
+ "Layout Horizontal" h "select-layout even-horizontal" \
+ "Layout Vertical" k "select-layout even-horizontal" \
+ "" \
+ "Swap Pane Up" < "swap-pane -U" \
+ "Swap Pane Down" > "swap-pane -D" \
+ "Break Pane" t break-pane \
+ "Join Pane" j "choose-window 'join-pane -h -s \"%%\"'" \
+ "#{?window_zoomed_flag,Unzoom,Zoom}" z "resize-pane -Z"
+
+
+# Popup Pane Manager
+bind-key -n M-/ run-shell ~/.config/tmux/tmux-popup-pane-manager.sh
+
+# List sessions
+
+#bind M-q display-popup -E -w 75% -h 75% "\
+# tmux list-sessions -F '#{?session_attached,,#{session_name}}' |\
+# sed '/^$/d' |\
+# fzf --reverse --header jump-to-session --preview 'tmux capture-pane -pt {}' |\
+# xargs tmux switch-client -t"
+
+# Kill sessions
+bind M-q display-popup -E "\
+ tmux list-sessions -F '#{?session_attached,,#{session_name}}' |\
+ fzf --reverse -m --header=kill-session |\
+ xargs -I {} tmux kill-session -t {}"
+
+# List sessions
+bind -n M-Space display-popup -E "\
+ tmux list-sessions -F '#{?session_attached,,#{session_name}}' |\
+ sed '/^$/d' |\
+ fzf --reverse --header jump-to-session --preview 'tmux capture-pane -pt {}' |\
+ xargs tmux switch-client -t"
+
+# Session chooser
+#bind -n M-q choose-tree -Zs -O time
+
+# Quick window select
+bind -n M-? list-keys
+bind -n M-0 select-window -t :=0
+bind -n M-1 select-window -t :=1
+bind -n M-2 select-window -t :=2
+bind -n M-3 select-window -t :=3
+bind -n M-4 select-window -t :=4
+bind -n M-5 select-window -t :=5
+bind -n M-6 select-window -t :=6
+bind -n M-7 select-window -t :=7
+bind -n M-8 select-window -t :=8
+bind -n M-9 select-window -t :=9
+
+# move pane to existing window or create it
+bind-key -n M-! run -C '#{?#{m:*|1|*,|#{W:#I|}},joinp -ht :1,breakp -t :1}'
+bind-key -n M-@ run -C '#{?#{m:*|2|*,|#{W:#I|}},joinp -ht :2,breakp -t :2}'
+bind-key -n M-# run -C '#{?#{m:*|3|*,|#{W:#I|}},joinp -ht :3,breakp -t :3}'
+bind-key -n M-$ run -C '#{?#{m:*|4|*,|#{W:#I|}},joinp -ht :4,breakp -t :4}'
+bind-key -n M-% run -C '#{?#{m:*|5|*,|#{W:#I|}},joinp -ht :5,breakp -t :5}'
+bind-key -n M-^ run -C '#{?#{m:*|6|*,|#{W:#I|}},joinp -ht :6,breakp -t :6}'
+bind-key -n M-& run -C '#{?#{m:*|7|*,|#{W:#I|}},joinp -ht :7,breakp -t :7}'
+bind-key -n M-* run -C '#{?#{m:*|8|*,|#{W:#I|}},joinp -ht :8,breakp -t :8}'
+bind-key -n M-( run -C '#{?#{m:*|9|*,|#{W:#I|}},joinp -ht :9,breakp -t :9}'
+bind-key -n M-) run -C '#{?#{m:*|0|*,|#{W:#I|}},joinp -ht :0,breakp -t :0}'
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Pane Movement/Control ###
+
+# Smart pane switching with awareness of Vim splits.
+# See: https://github.com/christoomey/vim-tmux-navigator
+# Navigate across tmux-vim
+
+# {{{ keybinds: select-pane
+#bind -Tnav h select-pane -L
+#bind h select-pane -L
+#bind -Tnav C-h select-pane -L
+#bind C-h select-pane -L
+#bind -Tnav j select-pane -D
+#bind j select-pane -D
+#bind -Tnav C-j select-pane -D
+#bind C-j select-pane -D
+#bind -Tnav k select-pane -U
+#bind k select-pane -U
+#bind -Tnav C-k select-pane -U
+#bind C-k select-pane -U
+#bind -Tnav l select-pane -R
+#bind l select-pane -R
+#bind -Tnav C-l select-pane -R
+#bind C-l select-pane -R
+
+# {{{ keybinds: select-pane
+# Smart pane switching with Vim awareness
+is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(n?vim|vimx?)'"
+
+bind -n C-h if-shell "$is_vim" "send-keys C-\\ C-n C-h" "select-pane -L"
+bind -n C-j if-shell "$is_vim" "send-keys C-\\ C-n C-j" "select-pane -D"
+bind -n C-k if-shell "$is_vim" "send-keys C-\\ C-n C-k" "select-pane -U"
+bind -n C-l if-shell "$is_vim" "send-keys C-\\ C-n C-l" "select-pane -R"
+# keybinds: select-pane }}}
+
+# {{{ keybinds: split-window
+bind -Tnav "\\" split-window -h -c "#{pane_current_path}" # vertical
+bind "\\" split-window -h -c "#{pane_current_path}" # vertical
+bind -Tnav "|" split-window -fh -c "#{pane_current_path}" # full vertical
+bind "|" split-window -fh -c "#{pane_current_path}" # full vertical
+bind -Tnav "-" split-window -v -c "#{pane_current_path}" # horizontal
+bind "-" split-window -v -c "#{pane_current_path}" # horizontal
+bind -Tnav "_" split-window -fv -c "#{pane_current_path}" # full horizontal
+bind "_" split-window -fv -c "#{pane_current_path}" # full horizontal
+# keybinds: split-window }}}
+
+# {{{ keybinds: resize-pane
+bind -r -Tnav M-h resize-pane -L 10
+bind -r M-h resize-pane -L 10
+bind -r -Tnav M-j resize-pane -D 5
+bind -r M-j resize-pane -D 5
+bind -r -Tnav M-k resize-pane -U 5
+bind -r M-k resize-pane -U 5
+bind -r -Tnav M-l resize-pane -R 10
+bind -r M-l resize-pane -R 10
+# keybinds: resize-pane }}}
+
+# Hide a pane and bring it back with <Prefix>! and <Prefix>@ respectively
+bind-key ! break-pane -d -n _hidden_pane
+bind-key @ join-pane -s $.0
+
+# Send Pane to another session/window with <Prefix>=
+bind-key = command-prompt -p "send pane to:" "join-pane -t '%%'"
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Popup ###
+
+# Toggle popup "term" session
+set -g @term_session_name "term"
+bind -n M-t if-shell -F '#{==:#{session_name},term}' {
+ detach-client
+ } {
+ if-shell "tmux has-session -t term" {
+ set -gF '@last_session_name' '#S' # Store the current session name
+ display-popup -E -xC -yC -w60% -h60% "tmux attach-session -t term"
+ } {
+ set -gF '@last_session_name' '#S' # Store the current session name
+ display-popup -E -xC -yC -w60% -h60% "tmux new-session -d -c '#{pane_current_path}' -s term && tmux set-option -t term status off && tmux attach-session -t term"
+ }
+}
+
+
+## Toggle popup "note" session
+bind-key -n M-n if-shell -F "#{client_in_popup}" \
+ "detach-client -P" \
+ "run-shell ~/.config/tmux/notes.sh"
+
+bind-key -n M-N run-shell "~/.config/tmux/notes.sh --new"
+
+# Toggle popup "pack" session
+bind-key -n M-p if-shell -F '#{==:#{session_name},pack}' {
+ detach-client
+} {
+ set -gF '@last_session_name' '#S' # Store the current session name
+ #display-popup -w 80% -h 80% -E "tmux new-session -A -s pack"
+ display-popup -E -x200% -y0 -w50% -h99% "tmux new-session -A -s pack"
+}
+
+# M-T → Open TODO.md in popup
+bind-key -n M-o if-shell -F '#{==:#{session_name},todo}' {
+
+ detach-client
+} {
+ set -gF '@last_session_name' '#S'
+ display-popup -E -x200% -y0 -w50% -h99% "tmux new-session -A -s todo 'nvim ~/documents/main/inbox/tasks/TODO.md'"
+}
+
+# M-y → Toggle VM popup (starts/attaches session "virt" inside popup)
+bind-key -n M-y if-shell -F '#{==:#{session_name},virt}' {
+ detach-client -P
+} {
+ set -gF '@last_session_name' '#S'
+ display-popup -E -x200% -y0 -w40% -h60% "tmux new-session -A -s virt bash -lc 'echo \"### VM Manager ###\"; echo; echo \"Available VM scripts:\"; ls -1 ~/.scripts/env/virt/ 2>/dev/null || echo \"No scripts found in ~/.scripts/env/virt/\"; echo; echo \"Run your VM by typing its script name (e.g., ubuntu, fedora, win11).\"; exec \$SHELL'"
+}
+
+# M-H → Open history in popup
+bind-key -n M-H if-shell -F '#{==:#{session_name},hist}' {
+ detach-client
+} {
+ set -gF '@last_session_name' '#S'
+ display-popup -E -x200% -y0 -w50% -h99% "tmux new-session -A -s hist \"bash -c \'
+ shell=\\\$(basename \\\$SHELL)
+ if [[ \\\$shell == zsh ]]; then
+ if [[ -f \\\$HOME/.config/zsh/.zhistory ]]; then
+ nvim \\\$HOME/.config/zsh/.zhistory
+ elif [[ -f \\\$HOME/.zhistory ]]; then
+ nvim \\\$HOME/.zhistory
+ else
+ echo \\\"No Zsh history found\\\"; sleep 5
+ fi
+ elif [[ \\\$shell == bash ]]; then
+ if [[ -f \\\$HOME/.bash_history ]]; then
+ nvim \\\$HOME/.bash_history
+ else
+ echo \\\"No Bash history found\\\"; sleep 5
+ fi
+ else
+ echo \\\"Unknown shell: \\\$shell\\\"; sleep 5
+ fi
+ \'\""
+}
+
+# Move popup session (note, term, or pack) to scratchpad (tmux)/last session or back to respective popup
+bind -n M-x run-shell '
+ current_session=$(tmux display-message -p "#S");
+
+ # Check if the current session is one of the popups (note, term, pack)
+ if [ "$current_session" = "note" ] || [ "$current_session" = "term" ] || [ "$current_session" = "pack" ]; then
+ # Detach, break the pane out of the popup, and join it to the last session
+ tmux detach-client;
+ tmux break-pane;
+ last_session=$(tmux show -gvq @last_session_name || echo tmux);
+ tmux set -g @last_popup_session "$current_session"; # Save which popup it was
+ tmux join-pane -s "$current_session" -t "$last_session" -h;
+ else
+ # If not in one of the popups, move the last popup session back to its popup
+ last_popup=$(tmux show -gqv @last_popup_session);
+
+ if [ "$last_popup" = "note" ]; then
+ if ! tmux has-session -t note; then
+ # Spawn note session in detached mode without blocking
+ tmux new-session -d -s note;
+ fi
+ tmux join-pane -s $(tmux display-message -p "#P") -t note;
+ tmux kill-pane -a -t note:0;
+ elif [ "$last_popup" = "term" ]; then
+ if ! tmux has-session -t term; then
+ tmux new-session -d -s term;
+ fi
+ tmux join-pane -s $(tmux display-message -p "#P") -t term;
+ tmux kill-pane -a -t term:0;
+ elif [ "$last_popup" = "pack" ]; then
+ if ! tmux has-session -t pack; then
+ tmux new-session -d -s pack;
+ fi
+ tmux join-pane -s $(tmux display-message -p "#P") -t pack;
+ tmux kill-pane -a -t pack:0;
+ fi
+ fi'
+# TODO: add keybinding that will allow going across the dipslay popup and main tmux session
+# TODO: add keybinding for toggling the display popup size to/from fullscreen and it's original size
+
+# Toggle popup "fzf" session
+#bind-key -n M-o run-shell ~/.config/tmux/fzf-menu.sh
+
+# Toggle popup "htop" session
+bind -n M-i if-shell -F '#{==:#{session_name},htop}' {
+ detach-client
+ } {
+ if-shell "tmux has-session -t HUD" {
+ display-popup -E -x200% -y0 -w40% -h40% "tmux new-session -A -s HUD"
+ } {
+ display-popup -E -x200% -y0 -w40% -h40% "tmux new-session -A -s htop 'htop'"
+ }
+}
+
+# Toggle popup "lazygit" session
+bind-key -n M-g if-shell -F '#{==:#{session_name},lazygit}' {
+ detach-client
+} {
+ display-popup -w 90% -h 90% -E "tmux new-session -A -s lazygit 'lazygit'"
+}
+
+## Toggle popup "yazi" session
+#bind-key -n M-f if-shell -F '#{==:#{session_name},yazi}' {
+# detach-client
+#} {
+# display-popup -w 90% -h 90% -E "tmux new-session -A -s yazi 'yazi'"
+#}
+#tmux split-window -h -p 30 \
+# "NNN_OPENER=~/.config/tmux/file_manager.sh nnn"
+
+#bind-key -n M-f run-shell 'tmux split-window -hb -p 30 "~/.config/tmux/file_manager.sh $(tmux display-message -p "#I.#P")"'
+
+# Robust file manager toggle - checks both title and option
+bind-key -n M-f run-shell "\
+fm_pane_title=\$(tmux list-panes -F '#{pane_id} #{pane_title}' | awk '\$2==\"FILE_MANAGER\" {print \$1}'); \
+fm_pane_option=\$(tmux list-panes -F '#{pane_id} #{@file_manager}' | awk '\$2==\"1\" {print \$1}'); \
+fm_pane=\${fm_pane_title:-\$fm_pane_option}; \
+if [ -n \"\$fm_pane\" ]; then \
+ tmux kill-pane -t \"\$fm_pane\"; \
+else \
+ current_pane=\$(tmux display-message -p '#{session_name}:#{window_index}.#{pane_index}'); \
+ tmux split-window -hb -p 30 \"~/.config/tmux/file_manager.sh \$current_pane\"; \
+fi"
+
+## Toggle popup "speedtest" session
+#bind-key -n M-s if-shell -F '#{==:#{session_name},speedtest}' {
+# detach-client
+#} {
+# display-popup -E "tmux new-session -A -s speedtest 'speedtest'"
+#}
+
+
+# Toggle popup "nvim" session
+bind-key -n M-v if-shell -F '#{==:#{session_name},edit}' {
+ detach-client
+} {
+ display-popup -w 100% -h 100% -E "tmux new-session -A -s edit 'cd && nvim'"
+}
+
+
+# Toggle popup "ssh" session
+bind-key -n M-s if-shell -F '#{==:#{session_name},ssh}' {
+ detach-client
+} {
+ display-popup -w 40% -h 50% -E "tmux new-session -A -s ssh"
+}
+
+# Toggle popup session to fullscreen
+bind-key -n M-F run-shell '
+ popup_session=$(tmux display-message -p "#{session_name}");
+ if [[ "$popup_session" == "term" || "$popup_session" == "note" || "$popup_session" == "lazygit" || "$popup_session" == "yazi" || "$popup_session" == "speedtest" || "$popup_session" == "nvim" || "$popup_session" == "ssh" || "$popup_session" == "pack" || "$popup_session" == "htop" ]]; then
+ tmux detach-client
+ sleep 0.1
+ tmux display-popup -E -w 100% -h 100% "tmux new-session -A -s $popup_session"
+ fi
+'
+
+bind -n M-L lock-session
+
+#bind-key -n M-o display-popup -E nvim -c ":ObsidianNew"
+#bind-key -n M-/ display-popup -w "90%" -h "85%" -E nvim -c ":ObsidianSearch"
+
+
+#proc
+#netw
+#ssh
+
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Copy Mode (Copy/Paste) ###
+
+# Set Vi copy mode, use <prefix>[ to enter copy mode
+setw -g mode-keys vi # `<prefix>:list-keys -T copy-mode-vi` to confirm
+
+# super fast way to reach copy-mode and search upwards
+bind-key / copy-mode \; send-key ?
+
+# Alt + Space copy-mode without prefix
+bind-key -n M-c copy-mode
+
+# Shift up/down copy-mode without prefix
+bind-key -n S-Up copy-mode \; send-key Up
+bind-key -n S-Down copy-mode \; send-key Down
+bind-key -n Pageup copy-mode \; send-key Pageup
+bind-key -n Pagedown copy-mode \; send-key Pagedown
+#bind -n Pageup if-shell "$is_vim" "send-keys Pageup" "copy-mode -u"
+#bind -n S-Pageup if-shell "$is_vim" "send-keys Pageup" "copy-mode -u"
+bind -n Pageup if-shell "$is_vim" "send-keys Pageup"
+bind -n S-Pageup if-shell "$is_vim" "send-keys Pageup"
+bind -n S-Pagedown send-keys Pagedown
+
+# Change selection <space> and enter to vi keybinding
+bind-key -T copy-mode-vi 'v' send -X begin-selection
+bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
+bind -T copy-mode-vi Escape send -X cancel
+bind -T copy-mode-vi C-c send -X clear-selection
+bind -T copy-mode-vi C-v send -X begin-selection \; send-keys -X rectangle-toggle
+
+# Unbind any previous 'y' in copy-mode-vi to prevent conflicts
+unbind -T copy-mode-vi 'y'
+
+# Clipboard copy for X11/XWayland
+if-shell -b '[ "$DISPLAY" ] && command -v xclip >/dev/null' "\
+ bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel 'xclip -in -selection clipboard > /dev/null 2>&1'"
+
+# Clipboard copy for Wayland
+if-shell -b '[ \"$WAYLAND_DISPLAY\" ] && command -v wl-copy >/dev/null' "\
+ bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel 'wl-copy --foreground --type text/plain > /dev/null 2>&1'"
+
+# macOS clipboard copy
+if-shell -b '[ \"$(uname -s)\" = \"Darwin\" ] && command -v pbcopy >/dev/null' "\
+ bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel 'pbcopy'"
+
+# Windows (WSL) clipboard copy
+if-shell -b 'uname -r | grep -qi microsoft && command -v clip.exe >/dev/null' "\
+ bind-key -T copy-mode-vi 'y' send-keys -X copy-pipe-and-cancel 'clip.exe > /dev/null 2>&1'"
+
+# For OSC-Yank in vim to work over ssh
+# https://github.com/ojroques/vim-oscyank
+#set -s set-clipboard on
+#set -g set-clipboard on
+#set -g terminal-overrides 'xterm*:paste:Ctrl+Shift+V'
+
+set -g allow-passthrough on
+set extended-keys on
+
+# notify when a window has activity
+set-window-option -g monitor-activity on
+
+# Copy mode search with a simple shortcut (@see https://superuser.com/a/1253137)
+bind-key / copy-mode \; send-key ?
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Colors ###
+
+## Assume external terminal supports the 256 colors palette (when TERM=xterm-256color)
+#set -sa terminal-features ",xterm-256color:256"
+## Assume external terminal supports RGB colors (when TERM=xterm-256color)
+#set -sa terminal-features ",xterm-256color:RGB"
+#
+## Set TERM for proper colors
+#set -g default-terminal "tmux-256color"
+#set -g default-terminal "xterm-256color"
+
+# Set 256 color terminal
+#set-option -sa terminal-overrides ",tmux-256color:Tc"
+#set-option -sa terminal-overrides ",xterm*:Tc,alacritty*:Tc"
+
+# Colors for pane borders(default)
+setw -g pane-border-style fg=white
+setw -g pane-active-border-style fg=green
+
+# Active pane normal, other shaded out
+setw -g window-style fg=colour240
+setw -g window-active-style fg=white
+
+# Popup border
+set -g popup-border-lines rounded
+
+#
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Status ###
+
+set -g status-position bottom # [top, bottom]
+set -g status on
+#set -g status-interval 1
+set -g status-interval 500
+#set -g status-style fg=#50fa7b,bg=default
+
+# Toggle status
+bind T set status
+
+# Inactive windows
+set -g status-style bg=default
+set -g window-status-activity-style noreverse
+set -g window-status-format "#[fg=#ffffff,bg=default]#I: #W"
+
+## Left
+set -g status-left ""
+set -g status-left-length 60
+
+## Center
+set -g status-justify absolute-centre
+
+## Right
+set -g status-right-length 60
+set-option -g status-right ""
+
+
+### Status Style
+set -g status-style "bg=default,fg=#CDD6F4"
+#set -g status-left-length 100
+#set -g status-right-length 150
+
+### Left
+set -g status-left '#( \
+ if fc-list | grep -qi nerd; then \
+ cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[fg=#39BAE6]#[bg=default]#[bg=#39BAE6,fg=#000000] ❐ #S #[fg=#39BAE6,bg=default]"} \
+ /-- INSERT --/ {print "#[fg=#50fa7b]#[bg=default]#[bg=#50fa7b,fg=#000000] ❐ #S #[fg=#50fa7b,bg=default]"}'\''; \
+ else \
+ cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[bg=default,fg=#39BAE6] #S "} \
+ /-- INSERT --/ {print "#[bg=default,fg=#50fa7b] #S "}'\''; \
+ fi \
+)'
+
+### Center
+set -g window-status-current-format '#( \
+ if fc-list | grep -qi nerd; then \
+ cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[fg=#39BAE6]#[bg=default]#[fg=#000000,bg=#39BAE6] #I:#W #[bg=default,fg=#39BAE6]"} \
+ /-- INSERT --/ {print "#[fg=#50fa7b]#[bg=default]#[fg=#000000,bg=#50fa7b] #I:#W #[bg=default,fg=#50fa7b]"}'\''; \
+ else \
+ cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[fg=#39BAE6,bg=default] #I:#W "} \
+ /-- INSERT --/ {print "#[fg=#50fa7b,bg=default] #I:#W "}'\''; \
+ fi \
+)'
+
+### Right
+set -g status-right '#( \
+ key_off="#[fg=#50fa7b,bg=default]#([ $(tmux show-option -qv key-table) = off ] && echo KEYS\ OFF)#[default]"; \
+ vi_segment=$(cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[fg=#50fa7b,bg=default] #[fg=#39BAE6]#[bg=#39BAE6,fg=#000000] %H:%M #[bg=default,fg=#39BAE6]"} \
+ /-- INSERT --/ {print "#[fg=#39BAE6,bg=default] #[fg=#50fa7b]#[bg=#50fa7b,fg=#000000] %H:%M #[bg=default,fg=#50fa7b]"}'\'')
+
+ if fc-list | grep -qi nerd; then \
+ echo "$key_off $vi_segment"; \
+ else \
+ cat ~/.vi-mode | awk '\''/-- NORMAL --/ {print "#[fg=#50fa7b,bg=default] #[fg=#39BAE6] %H:%M "} \
+ /-- INSERT --/ {print "#[fg=#39BAE6,bg=default] #[fg=#50fa7b] %H:%M "}'\''; \
+ fi \
+)'
+
+# Force refresh after session creation
+#set-hook -g after-new-session 'source-file ~/.tmux.conf'
+#set-hook -g client-attached 'source-file ~/.tmux.conf'
+
+
+# Set environment variable from script output
+#run-shell 'tmux set-environment -g NERD_FONT_DETECTED "$(~/.config/tmux/detect_nerd_font)"'
+
+## Reload Status with IP addr, Cpu, Mem and Date
+bind a run-shell ~/.config/tmux/tmux-toggle-option.sh
+
+## Numbers
+bind < command-prompt -p index "run-shell '~/.config/tmux/tmux_number.sh %%'"
+
+## Reload Config/Status silently
+bind b source-file ~/.config/tmux/tmux.conf
+
+set-option -g default-shell "/usr/bin/zsh"
+
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Plugin Install ###
+
+set -g @plugin "tmux-plugins/tpm"
+set -g @plugin "tmux-plugins/tmux-sensible"
+set -g @plugin "tmux-plugins/tmux-resurrect"
+set -g @plugin "tmux-plugins/tmux-continuum"
+#set -g @plugin "loichyan/tmux-toggle-popup"
+set -g @plugin "christoomey/vim-tmux-navigator"
+#set -g @plugin "tmux-plugins/tmux-yank"
+#set -g @plugin 'srdusr/tmux-vi-mode'
+#set -g @plugin 'vi-mode ~/.config/tmux/plugins/vi-mode.sh'
+
+
+set -g @plugin 'catppuccin/tmux'
+set -g @plugin 'tmux-plugins/tmux-online-status'
+set -g @plugin 'tmux-plugins/tmux-battery'
+
+#――――――――――――――――――――――――――――――――――――――――――
+
+### Plugins Settings ###
+
+# Plugin to save and restore tmux sessions after restart
+# * Save with: <Prefix> + Ctrl-s
+# * Restore with: <Prefix> + Ctlr-r
+# Change default save and restore keybindings
+ set -g @resurrect-save "W" # <Prefix> + W
+ set -g @resurrect-restore "E" # <Prefix> + E
+
+# Restore vim and nvim sessions as well
+# For vim:
+ set -g @resurrect-strategy-vim "session"
+# For neovim:
+ set -g @resurrect-strategy-nvim "session"
+
+# Automatic restore
+ #set -g @continuum-restore "on"
+ #set -g @continuum-boot "on"
+
+# Restore Panes
+# set -g @resurrect-capture-pane-contents "on"
+
+# This is a hook for tmux-resurrect which tells it to kill session 0 before restoring the panels
+ set -g @resurrect-hook-pre-restore-pane-processes "tmux switch-client -n && tmux kill-session -t=0"
+
+# Tmux navigation
+ #set -g @plugin 'christoomey/vim-tmux-navigator'
+# Plugin uninstall
+ # Delete or comment out the plugin in .tmux.conf.
+ # Press <prefix> + alt + u to remove the plugin.
+
+# >>>>> CATPPUCCIN CONFIGS <<<<<
+
+# Configure Catppuccin
+set -g @catppuccin_flavor "mocha"
+set -g @catppuccin_status_background "none"
+set -g @catppuccin_window_status_style "none"
+set -g @catppuccin_pane_status_enabled "off"
+set -g @catppuccin_pane_border_status "off"
+
+# Configure Online status
+set -g @online_icon "ok"
+set -g @offline_icon "nok"
+
+# TMUX plugin manager (keep at the bottom of tmux.conf)
+ #run "~/.config/tmux/plugins/tpm/tpm"
+ if "test ! -d ~/.config/tmux/plugins/tpm" \
+ "run 'git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm && ~/.config/tmux/plugins/tpm/bin/install_plugins'"
+run -b "~/.config/tmux/plugins/tpm/tpm"
diff --git a/linux/home/.config/tmux/tmux_number.sh b/linux/home/.config/tmux/tmux_number.sh
new file mode 100755
index 0000000..5d239d0
--- /dev/null
+++ b/linux/home/.config/tmux/tmux_number.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -x
+dest="$1"
+[ "x""$dest" != "x" ]
+tmux list-windows -F "#{window_index}" | grep "^${dest}$" 2>&1 >/dev/null
+ret="$?"
+if [ "x""$ret" = "x0" ]; then
+ tmux swap-window -t ":${dest}"
+else
+ tmux move-window -t ":${dest}"
+fi