rwx/sh/tmux.sh

460 lines
13 KiB
Bash
Raw Normal View History

2025-06-28 04:36:16 +02:00
# ╭──────╮
# │ tmux │
# ╰──────╯
2025-07-25 23:02:35 +02:00
# ╭──────┬───────────┬────────╮
# │ tmux │ constants │ values │
# ╰──────┴───────────┴────────╯
2025-07-25 22:05:55 +02:00
2025-07-25 21:42:21 +02:00
RWX_TMUX_MAIN_BACKGROUND="#080808"
2025-07-25 22:05:55 +02:00
RWX_TMUX_MAIN_FOREGROUND="white"
2025-07-25 21:52:05 +02:00
RWX_TMUX_MESSAGE_BACKGROUND="red"
RWX_TMUX_MESSAGE_FOREGROUND="white"
2025-07-25 22:05:55 +02:00
2025-07-25 23:02:35 +02:00
# ╭──────┬───────────┬──────────╮
# │ tmux │ constants │ commands │
# ╰──────┴───────────┴──────────╯
RWX_TMUX_BORDER_BACKGROUND="#[bg=##181818]"
RWX_TMUX_ITEM_BACKGROUND="#[bg=##282828]"
RWX_TMUX_ITEM_FOREGROUND="#[fg=yellow]"
2025-07-25 22:56:16 +02:00
RWX_TMUX_PATH_FOREGROUND="#[fg=cyan]"
2025-07-25 21:49:06 +02:00
RWX_TMUX_PREFIX_CHARACTER="p"
2025-07-25 23:02:35 +02:00
RWX_TMUX_PREFIX_FOREGROUND="#[fg=red]"
2025-07-25 21:32:51 +02:00
2025-07-25 23:17:49 +02:00
RWX_TMUX_RESET="#[bg=default,fg=default]"
2025-07-25 22:42:31 +02:00
RWX_TMUX_SESSION_MANY="#[fg=red]"
RWX_TMUX_SESSION_ONE="#[fg=green]"
2025-07-25 21:32:51 +02:00
# ╭──────┬───────────╮
# │ tmux │ functions │
# ╰──────┴───────────╯
2025-07-06 07:32:55 +02:00
# attach
#= tma
rwx_tmux_attach() {
local server="${1}"
2025-07-06 15:59:31 +02:00
if [ -n "${server}" ]; then
2025-07-06 07:32:55 +02:00
tmux -L "${server}" attach-session
else
rwx_tmux_list
fi
}
2025-07-06 07:32:06 +02:00
# kill
#= tmk
rwx_tmux_kill() {
local server="${1}"
2025-07-06 15:59:31 +02:00
if [ -n "${server}" ]; then
2025-07-06 07:32:06 +02:00
tmux -L "${server}" kill-server 2>"/dev/null"
else
rwx_tmux_list
fi
}
2025-07-06 07:30:42 +02:00
# list
#= tml
rwx_tmux_list() {
2025-07-06 16:09:46 +02:00
local user_id
user_id="$(id --user)"
ls "/tmp/tmux-${user_id}"
2025-07-06 07:30:42 +02:00
}
2025-07-25 22:29:57 +02:00
# ╭──────┬──────╮
# │ tmux │ help │
# ╰──────┴──────╯
# display key bindings
2025-07-25 22:33:01 +02:00
#= tmh
2025-07-25 22:29:57 +02:00
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 │ │ │
╰───────────────────┴───────────┴─────────┴─────┴───────╯
"
}
2025-07-25 23:17:49 +02:00
# ╭──────┬──────╮
# │ tmux │ item │
# ╰──────┴──────╯
# ╭──────┬───────╮
# │ tmux │ setup │
# ╰──────┴───────╯
2025-07-25 23:17:49 +02:00
#= tms
rwx_tmux_setup() {
2025-06-30 00:28:33 +02:00
local file script
2025-07-02 15:18:47 +02:00
if rwx_root; then
file="/etc/tmux.conf"
script="/etc/tmux.sh"
else
file="${HOME}/.tmux.conf"
script="${HOME}/.tmux.sh"
fi
2025-06-30 00:28:33 +02:00
rwx_file_write "${script}" "\
rwx_tmux_server() {
basename \"\${TMUX}\" |
cut \\
--delimiter \",\" \\
--fields \"1\"
}
2025-06-30 01:08:26 +02:00
rwx_tmux_servers() {
2025-07-25 16:08:05 +02:00
local active name root sockets text user_id
2025-07-22 20:53:49 +02:00
active=\"\$(rwx_tmux_server)\"
2025-07-25 16:08:05 +02:00
user_id=\"\$(id -u)\"
root=\"/tmp/tmux-\${user_id}\"
2025-07-22 20:53:49 +02:00
sockets=\"\$(find \"\${root}\" -type s -printf \"%P\\n\")\"
while IFS= read -r name; do
2025-07-25 16:08:05 +02:00
if tmux -L \"\${name}\" list-sessions >/dev/null; then
2025-07-22 20:53:49 +02:00
text=\"\${text}\\
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \\
2025-06-30 03:40:04 +02:00
\"
2025-07-22 20:53:49 +02:00
if [ \"\${name}\" = \"\${active}\" ]; then
text=\"\${text}#[fg=green]\"
else
2025-07-25 22:14:22 +02:00
text=\"\${text}${RWX_TMUX_ITEM_FOREGROUND}\"
2025-07-22 20:53:49 +02:00
fi
text=\"\${text}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}\${name}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-06-30 03:40:04 +02:00
\"
2025-07-22 20:53:49 +02:00
fi
2025-07-04 07:50:19 +02:00
done <<EOF
2025-07-22 20:53:49 +02:00
\${sockets}
2025-07-04 07:50:19 +02:00
EOF
2025-06-30 02:10:17 +02:00
echo \"\${text}\"
2025-06-30 01:08:26 +02:00
}
2025-07-02 01:07:24 +02:00
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
2025-07-02 03:25:56 +02:00
tmux set-option -g status \"\${current}\"
2025-07-02 01:07:24 +02:00
}
2025-06-30 03:52:26 +02:00
rwx_tmux_uptime() {
local since=\"\$(uptime --since)\"
local date=\"\$(echo \"\${since}\" | awk '{print \$1}')\"
local time=\"\$(echo \"\${since}\" | awk '{print \$2}')\"
echo \"\\
2025-07-25 22:14:22 +02:00
${RWX_TMUX_ITEM_FOREGROUND}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}\${date}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \\
2025-07-25 22:14:22 +02:00
${RWX_TMUX_ITEM_FOREGROUND}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}\${time}\\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \\
2025-06-30 03:52:26 +02:00
\"
}
2025-06-30 00:28:33 +02:00
"
rwx_file_write "${file}" "\
# ╭────────╮
# │ option │
# ╰────────╯
# empty name for windows
set-option -g automatic-rename on
2025-07-20 18:25:44 +02:00
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
2025-07-25 21:52:05 +02:00
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 '\
2025-06-30 00:28:33 +02:00
#(sh -c \". ${script}; rwx_tmux_server\")\
2025-07-02 05:05:10 +02:00
/ \
#{session_name}\
2025-07-02 05:05:10 +02:00
/ \
2025-07-02 03:48:10 +02:00
#{window_name}\
2025-07-02 05:05:10 +02:00
/ \
2025-07-02 03:48:10 +02:00
#{pane_current_command}\
2025-07-02 05:05:10 +02:00
- \
#{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
2025-06-29 10:19:01 +02:00
set-option -g status 2
# background color
2025-07-25 21:42:21 +02:00
set-option -g status-bg '${RWX_TMUX_MAIN_BACKGROUND}'
# foreground color
2025-07-25 22:05:55 +02:00
set-option -g status-fg '${RWX_TMUX_MAIN_FOREGROUND}'
# line 1
set-option -g status-format[0] '\
#{W:\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND}#{?window_zoomed_flag,\
2025-07-19 20:23:15 +02:00
#{?pane_synchronized,#[fg=magenta][,#[fg=red][},#{?pane_synchronized,#[fg=blue][, }}\
#{?window_active,#[fg=green],\
2025-07-25 22:14:22 +02:00
#{?window_activity_flag,#[fg=red],${RWX_TMUX_ITEM_FOREGROUND}}}\
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}#{window_name}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND}#{?window_zoomed_flag,\
2025-07-19 20:23:15 +02:00
#{?pane_synchronized,#[fg=magenta]],#[fg=red]]},#{?pane_synchronized,#[fg=blue]], }}\
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-06-30 04:07:33 +02:00
} \
2025-06-30 05:27:22 +02:00
\
#[align=right]\
2025-07-25 22:14:22 +02:00
${RWX_TMUX_ITEM_FOREGROUND}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}%Y-%m-%d\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-07-25 22:14:22 +02:00
${RWX_TMUX_ITEM_FOREGROUND}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}%H:%M:%S\
2025-07-25 21:49:06 +02:00
${RWX_TMUX_BORDER_BACKGROUND}#{?client_prefix,\
${RWX_TMUX_PREFIX_FOREGROUND}${RWX_TMUX_PREFIX_CHARACTER}, }\
'
# line 2
set-option -g status-format[1] '\
#{S:\
2025-07-25 22:42:31 +02:00
#{?session_many_attached,${RWX_TMUX_SESSION_MANY},\
#{?session_attached,${RWX_TMUX_SESSION_ONE},${RWX_TMUX_ITEM_FOREGROUND}}}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}#{session_name}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-06-30 04:47:53 +02:00
} \
2025-06-30 05:27:22 +02:00
\
#[align=right]\
2025-06-30 04:42:15 +02:00
#(sh -c \". ${script}; rwx_tmux_servers\")\
'
# line 3
set-option -g status-format[2] '\
2025-07-25 22:56:16 +02:00
${RWX_TMUX_PATH_FOREGROUND}#{pane_current_path}\
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-06-30 05:27:22 +02:00
\
2025-06-30 03:40:04 +02:00
#[align=right]\
'
# line 4
set-option -g status-format[3] '\
#{P:\
2025-07-25 22:14:22 +02:00
#{?pane_active,#[fg=green],${RWX_TMUX_ITEM_FOREGROUND}}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}#{pane_current_command}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-06-30 04:07:33 +02:00
} \
2025-06-30 05:27:22 +02:00
\
2025-06-30 05:42:42 +02:00
#[align=right]\
'
# line 5
set-option -g status-format[4] '\
2025-06-29 22:32:47 +02:00
#{?uid,#[fg=green],#[fg=red]}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}#{user}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-07-25 22:14:22 +02:00
${RWX_TMUX_ITEM_FOREGROUND}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 21:32:51 +02:00
${RWX_TMUX_ITEM_BACKGROUND}#{host}\
2025-07-25 21:41:13 +02:00
${RWX_TMUX_BORDER_BACKGROUND} \
2025-07-25 23:17:49 +02:00
${RWX_TMUX_RESET} \
2025-07-02 05:17:29 +02:00
\
#[align=right]\
2025-07-02 05:18:57 +02:00
#(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
2025-06-16 15:25:26 +02:00
# new
bind-key -n S-M-Down new-session
bind-key -n S-M-Right new-window
2025-07-19 18:53:25 +02:00
# like byobu
bind-key -n F2 new-window
2025-07-20 00:00:09 +02:00
# 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
2025-06-16 14:33:48 +02:00
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
2025-07-02 01:07:24 +02:00
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
2025-06-30 11:40:58 +02:00
bind-key h split-window -c '#{pane_current_path}' -h
bind-key v split-window -c '#{pane_current_path}' -v
2025-06-29 10:11:44 +02:00
# kill server
bind-key k kill-server
# reload configuration
2025-07-19 18:36:06 +02:00
bind-key r source-file ${file} \
\\; display-message 'source-file ${file}'
2025-06-29 10:11:44 +02:00
# toggle mouse
2025-07-19 18:36:06 +02:00
bind-key M set-option -g mouse \
\\; display-message 'mouse = #{mouse}'
2025-06-29 10:11:44 +02:00
# swap window
bind-key M-Left swap-window -t -1
bind-key M-Right swap-window -t +1
2025-07-19 18:36:06 +02:00
# synchronize panes
bind-key S set-window-option synchronize-panes \
\\; display-message 'sync = #{synchronize-panes}'
"
}