rwx/sh/tmux.sh
2025-07-25 23:18:49 +02:00

460 lines
13 KiB
Bash

# ╭──────╮
# │ tmux │
# ╰──────╯
# ╭──────┬───────────┬────────╮
# │ tmux │ constants │ values │
# ╰──────┴───────────┴────────╯
RWX_TMUX_MAIN_BACKGROUND="#080808"
RWX_TMUX_MAIN_FOREGROUND="white"
RWX_TMUX_MESSAGE_BACKGROUND="red"
RWX_TMUX_MESSAGE_FOREGROUND="white"
# ╭──────┬───────────┬──────────╮
# │ tmux │ constants │ commands │
# ╰──────┴───────────┴──────────╯
RWX_TMUX_BORDER_BACKGROUND="#[bg=##181818]"
RWX_TMUX_ITEM_BACKGROUND="#[bg=##282828]"
RWX_TMUX_ITEM_FOREGROUND="#[fg=yellow]"
RWX_TMUX_PATH_FOREGROUND="#[fg=cyan]"
RWX_TMUX_PREFIX_CHARACTER="p"
RWX_TMUX_PREFIX_FOREGROUND="#[fg=red]"
RWX_TMUX_RESET="#[bg=default,fg=default]"
RWX_TMUX_SESSION_MANY="#[fg=red]"
RWX_TMUX_SESSION_ONE="#[fg=green]"
# ╭──────┬───────────╮
# │ tmux │ functions │
# ╰──────┴───────────╯
# attach
#= tma
rwx_tmux_attach() {
local server="${1}"
if [ -n "${server}" ]; then
tmux -L "${server}" attach-session
else
rwx_tmux_list
fi
}
# kill
#= tmk
rwx_tmux_kill() {
local server="${1}"
if [ -n "${server}" ]; then
tmux -L "${server}" kill-server 2>"/dev/null"
else
rwx_tmux_list
fi
}
# list
#= tml
rwx_tmux_list() {
local user_id
user_id="$(id --user)"
ls "/tmp/tmux-${user_id}"
}
# ╭──────┬──────╮
# │ tmux │ help │
# ╰──────┴──────╯
# display key bindings
#= tmh
rwx_tmux_help() {
# TODO pad constants
rwx_log "\
╭─────────────────────┬─────────────╮
│ rwx │ tmux │
├───────────┬─────────┼─────┬───────┤
│ -n │ F12 │ -n │ C-b │
╭───────────────────┼───────────┼─────────┼─────┼───────┤
│ command-prompt │ │ │ │ : │
│ copy-mode │ │ │ │ PPage │
│ detach-client │ F6 │ │ │ d │
│ kill-server │ │ k │ │ │
│ new-session │ S-M-Down │ │ │ │
│ new-window │ S-M-Right │ │ │ c │
│ next-window │ M-Right │ │ │ n │
│ previous-window │ M-Left │ │ │ p │
│ rename-session │ │ C-s │ │ │
│ rename-window │ │ C-w │ │ │
│ resize-pane -Z │ │ │ │ z │
│ select-layout -n │ M-Home │ │ │ │
│ select-layout -p │ M-End │ │ │ │
│ select-pane -D │ C-S-Down │ │ │ │
│ select-pane -L │ C-S-Left │ │ │ │
│ select-pane -R │ C-S-Right │ │ │ │
│ select-pane -U │ C-S-Up │ │ │ │
│ set -g mouse │ │ M │ │ │
│ set -g status off │ C-F6 │ │ │ │
│ set -g status on │ C-F1 │ │ │ │
│ set -g status 2 │ C-F2 │ │ │ │
│ set -g status 3 │ C-F3 │ │ │ │
│ set -g status 4 │ C-F4 │ │ │ │
│ set -g status 5 │ C-F5 │ │ │ │
│ source-file │ │ r │ │ │
│ split-window -h │ │ h │ │ % │
│ split-window -v │ │ v │ │ \" │
│ swap-window -t -1 │ │ M-Left │ │ │
│ swap-window -t +1 │ │ M-Right │ │ │
│ switch-client -n │ M-Down │ │ │ │
│ switch-client -p │ M-Up │ │ │ │
│ synchronize-panes │ │ S │ │ │
╰───────────────────┴───────────┴─────────┴─────┴───────╯
"
}
# ╭──────┬──────╮
# │ tmux │ item │
# ╰──────┴──────╯
# ╭──────┬───────╮
# │ tmux │ setup │
# ╰──────┴───────╯
#= tms
#/ tmux_setup
rwx_tmux_setup() {
local file script
if rwx_root; then
file="/etc/tmux.conf"
script="/etc/tmux.sh"
else
file="${HOME}/.tmux.conf"
script="${HOME}/.tmux.sh"
fi
rwx_file_write "${script}" "\
rwx_tmux_server() {
basename \"\${TMUX}\" |
cut \\
--delimiter \",\" \\
--fields \"1\"
}
rwx_tmux_servers() {
local active name root sockets text user_id
active=\"\$(rwx_tmux_server)\"
user_id=\"\$(id -u)\"
root=\"/tmp/tmux-\${user_id}\"
sockets=\"\$(find \"\${root}\" -type s -printf \"%P\\n\")\"
while IFS= read -r name; do
if tmux -L \"\${name}\" list-sessions >/dev/null; then
text=\"\${text}\\
${RWX_TMUX_RESET} \\
\"
if [ \"\${name}\" = \"\${active}\" ]; then
text=\"\${text}#[fg=green]\"
else
text=\"\${text}${RWX_TMUX_ITEM_FOREGROUND}\"
fi
text=\"\${text}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
${RWX_TMUX_ITEM_BACKGROUND}\${name}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
\"
fi
done <<EOF
\${sockets}
EOF
echo \"\${text}\"
}
rwx_tmux_status() {
local current=\"\${1}\"
local operand=\"\${2}\"
case \"\${operand}\" in
\"+\")
case \"\${current}\" in
\"off\") current=\"on\" ;;
\"on\") current=\"2\" ;;
\"2\") current=\"3\" ;;
\"3\") current=\"4\" ;;
\"4\") current=\"5\" ;;
*) ;;
esac
;;
\"-\")
case \"\${current}\" in
\"on\") current=\"off\" ;;
\"2\") current=\"on\" ;;
\"3\") current=\"2\" ;;
\"4\") current=\"3\" ;;
\"5\") current=\"4\" ;;
*) ;;
esac
;;
*) ;;
esac
tmux set-option -g status \"\${current}\"
}
rwx_tmux_uptime() {
local since=\"\$(uptime --since)\"
local date=\"\$(echo \"\${since}\" | awk '{print \$1}')\"
local time=\"\$(echo \"\${since}\" | awk '{print \$2}')\"
echo \"\\
${RWX_TMUX_ITEM_FOREGROUND}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
${RWX_TMUX_ITEM_BACKGROUND}\${date}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
${RWX_TMUX_RESET} \\
${RWX_TMUX_ITEM_FOREGROUND}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
${RWX_TMUX_ITEM_BACKGROUND}\${time}\\
${RWX_TMUX_BORDER_BACKGROUND} \\
\"
}
"
rwx_file_write "${file}" "\
# ╭────────╮
# │ option │
# ╰────────╯
# empty name for windows
set-option -g automatic-rename on
set-option -g automatic-rename-format '#{pane_current_command}'
# first index number
set-option -g base-index 1
# display duration
set-option -g display-time 1536
# extend history limit
set-option -g history-limit 1048576
# style for messages
set-option -g message-style '\
bg=${RWX_TMUX_MESSAGE_BACKGROUND},fg=${RWX_TMUX_MESSAGE_FOREGROUND}'
# activity monitoring
set-window-option -g monitor-activity on
# silence monitoring
set-window-option -g monitor-silence 0
# enable mouse actions
set-option -g mouse on
# prefix with ^B or F12
set-option -g prefix C-b
set-option -g prefix2 F12
# renumber windows after closing one
set-option -g renumber-windows on
# enable title
set-option -g set-titles on
# set title to working directory
set-option -g set-titles-string '\
#(sh -c \". ${script}; rwx_tmux_server\")\
/ \
#{session_name}\
/ \
#{window_name}\
/ \
#{pane_current_command}\
- \
#{window_width}×#{window_height}\
/ \
#{pane_width}×#{pane_height}\
'
# ╭────────┬──────╮
# │ option │ pane │
# ╰────────┴──────╯
# first index number
set-option -g pane-base-index 1
# ╭────────┬──────┬────────╮
# │ option │ pane │ border │
# ╰────────┴──────┴────────╯
# active style
set-option -g pane-active-border-style fg=green
# regular style
set-option -g pane-border-style fg=blue
# ╭────────┬────────╮
# │ option │ status │
# ╰────────┴────────╯
# status lines
set-option -g status 2
# background color
set-option -g status-bg '${RWX_TMUX_MAIN_BACKGROUND}'
# foreground color
set-option -g status-fg '${RWX_TMUX_MAIN_FOREGROUND}'
# line 1
set-option -g status-format[0] '\
#{W:\
${RWX_TMUX_BORDER_BACKGROUND}#{?window_zoomed_flag,\
#{?pane_synchronized,#[fg=magenta][,#[fg=red][},#{?pane_synchronized,#[fg=blue][, }}\
#{?window_active,#[fg=green],\
#{?window_activity_flag,#[fg=red],${RWX_TMUX_ITEM_FOREGROUND}}}\
${RWX_TMUX_ITEM_BACKGROUND}#{window_name}\
${RWX_TMUX_BORDER_BACKGROUND}#{?window_zoomed_flag,\
#{?pane_synchronized,#[fg=magenta]],#[fg=red]]},#{?pane_synchronized,#[fg=blue]], }}\
${RWX_TMUX_RESET} \
} \
\
#[align=right]\
${RWX_TMUX_ITEM_FOREGROUND}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}%Y-%m-%d\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_RESET} \
${RWX_TMUX_ITEM_FOREGROUND}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}%H:%M:%S\
${RWX_TMUX_BORDER_BACKGROUND}#{?client_prefix,\
${RWX_TMUX_PREFIX_FOREGROUND}${RWX_TMUX_PREFIX_CHARACTER}, }\
'
# line 2
set-option -g status-format[1] '\
#{S:\
#{?session_many_attached,${RWX_TMUX_SESSION_MANY},\
#{?session_attached,${RWX_TMUX_SESSION_ONE},${RWX_TMUX_ITEM_FOREGROUND}}}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}#{session_name}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_RESET} \
} \
\
#[align=right]\
#(sh -c \". ${script}; rwx_tmux_servers\")\
'
# line 3
set-option -g status-format[2] '\
${RWX_TMUX_PATH_FOREGROUND}#{pane_current_path}\
${RWX_TMUX_RESET} \
\
#[align=right]\
'
# line 4
set-option -g status-format[3] '\
#{P:\
#{?pane_active,#[fg=green],${RWX_TMUX_ITEM_FOREGROUND}}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}#{pane_current_command}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_RESET} \
} \
\
#[align=right]\
'
# line 5
set-option -g status-format[4] '\
#{?uid,#[fg=green],#[fg=red]}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}#{user}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_RESET} \
${RWX_TMUX_ITEM_FOREGROUND}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_ITEM_BACKGROUND}#{host}\
${RWX_TMUX_BORDER_BACKGROUND} \
${RWX_TMUX_RESET} \
\
#[align=right]\
#(sh -c \". ${script}; rwx_tmux_uptime\")\
'
# refresh period
set-option -g status-interval 1
# bar location
set-option -g status-position bottom
# ╭─────╮
# │ key │
# ╰─────╯
# detach client
bind-key -n F6 detach-client
# new
bind-key -n S-M-Down new-session
bind-key -n S-M-Right new-window
# like byobu
bind-key -n F2 new-window
# select layout
bind-key -n M-Home select-layout -n
bind-key -n M-End select-layout -p
# select pane
bind-key -n C-S-Down select-pane -D
bind-key -n C-S-Left select-pane -L
bind-key -n C-S-Right select-pane -R
bind-key -n C-S-Up select-pane -U
# status lines
bind-key -n C-F6 set-option -g status off
bind-key -n C-F1 set-option -g status on
bind-key -n C-F2 set-option -g status 2
bind-key -n C-F3 set-option -g status 3
bind-key -n C-F4 set-option -g status 4
bind-key -n C-F5 set-option -g status 5
bind-key -n M-NPage run-shell '. ${script}; rwx_tmux_status #{status} -'
bind-key -n M-PPage run-shell '. ${script}; rwx_tmux_status #{status} +'
# switch session
bind-key -n M-Down switch-client -n
bind-key -n M-Up switch-client -p
# switch window
bind-key -n M-Left previous-window
bind-key -n M-Right next-window
# ╭─────┬────────╮
# │ key │ prefix │
# ╰─────┴────────╯
# rename
bind-key C-s command-prompt { rename-session '%%' }
bind-key C-w command-prompt { rename-window '%%' }
# split window
bind-key h split-window -c '#{pane_current_path}' -h
bind-key v split-window -c '#{pane_current_path}' -v
# kill server
bind-key k kill-server
# reload configuration
bind-key r source-file ${file} \
\\; display-message 'source-file ${file}'
# toggle mouse
bind-key M set-option -g mouse \
\\; display-message 'mouse = #{mouse}'
# swap window
bind-key M-Left swap-window -t -1
bind-key M-Right swap-window -t +1
# synchronize panes
bind-key S set-window-option synchronize-panes \
\\; display-message 'sync = #{synchronize-panes}'
"
}