Tmux plugin, Popup menus to help with managing your environment
Popup menus to help with managing your environment.
For tmux < 3.0 whiptail will be used instead of the tmux feature
display-menu
.
Not too hard to adapt to fit your needs. Items that some might find slightly redundant are included, easier to remove excess for more experienced users, then add more for newbies.
Some basic popup menus come as the default (See Configuration for how to disable them)
<prefix> <
displays some Windows handling options<prefix> >
displays some pane handling optionsRather lacking and since they're written as hard-to-read one-liners, a more integrated approach with navigation and adaptability seemed the way to go, also covering more than panes and windows.
Not solely meant for beginners, I use it myself all the time:
<prefix> : kill-ser <tab> <enter>
with the menus 5 keys: <prefix> \ A x y
Once installed, hit the trigger to get the main menu to pop up.
The default is <prefix> \
see Configuration below for how to change it.
The grey one is generated with whiptail, the rest by tmux built-in display-menu
Version | Notice |
---|---|
3.2 | Fully compatible |
3.0 - 3.1c | Menu centering is not supported, it's displayed top left if C is selected. |
1.8 - 2.9a | Only available using Whiptail, menu location setting ignored. |
1.7 | tpm is not available, so the plugin needs to be initialized by running [path to tmux-menus]/menus.tmux directly from the conf file |
The above table covers compatibility for the general tool. Each item has a min tmux version set, if the running tmux doesn't match this, that item will be skipped.
The easiest way to install tmux-menus
is via the Tmux Plugin
Manager.
Add plugin to the list of TPM plugins in .tmux.conf
:
set -g @plugin 'jaclu/tmux-menus'
Hit <prefix> + I
to install the plugin and activate it. You should
now be able to use the plugin.
Clone the repository
git clone https://github.com/jaclu/tmux-menus ~/clone/path
Add this line to the bottom of .tmux.conf
run-shell ~/clone/path/menus.tmux
Reload the tmux
environment
# type this inside tmux
$ tmux source-file ~/.tmux.conf
You should now be able to use tmux-menus
immediately.
These menus can also be displayed using Whiptail, be aware that in order to run whiptail dialogs via a shortcut, the current (if any) task is suspended, dialogs are run, and when done the suspended task is reactivated.
The downside of this is that if no current tasks were running in
the active pane, you will see fg: no current job
being printed when
the dialog is exited. This can be ignored.
The menu system works the same using Whiptail, however the menu shortcuts are not as convenient, since Whiptail does not differentiate between upper and lower case letters, and does not at all support special keys like 'Left' or 'Home'
If tmux is < 3.0 whiptail will automatically be used.
If you want to use Whiptail on modern tmuxes set this env variable:
export FORCE_WHIPTAIL_MENUS=1
The default trigger is <prefix> \
. The trigger is selected like this:
set -g @menus_trigger 'F9'
Please note that non-standard keys, like the default backslash need to
be noted in a specific way in order not to confuse tmux.
Either '\'
or without quotes as \\
. Quoting '\\'
won't make sense
for tmux and fail to bind the key.
If you want to trigger menus without first hitting <prefix>
set -g @menus_without_prefix 1
This param can be either 0 (the default) or 1
The default location is: P, compatible with tmux 3.0 and up
Locations can be one of:
set -g @menus_location_x 'C'
set -g @menus_location_y 'C'
By default all menus are cached, use this to disable caching.
set -g @menus_use_cache 'no'
In the main menu, you can request the config file to be reloaded. The defaults for this are:
When a reload is requested, the default will be printed and used if not manually changed.
set -g @menus_config_file "$XDG_CONFIG_HOME/tmux/tmux.conf"
To disable the rather limited default popup menus, you can add the following
unbind-key -n MouseDown3Pane
unbind-key -n M-MouseDown3Pane
unbind-key -n MouseDown3Status
unbind-key -n MouseDown3StatusLeft
unbind-key <
unbind-key >
tmux does not give any error if a menu doesn't fit the available screen. The only hint is that the menu is terminated instantaneously. For this reason, a menu that is closed right away is assumed to have failed due to lacking screen real estate, and then the required min screen size for this dialog is printed. Starting with tmux 3.2 menus will be shrunk to some extent to make them fit, so for later versions of tmux you might get away with a slightly narrower screen than the required size.
Not directly related to this plugin, but since it does have an option to trigger sync mode, and having it on unintendedly can ruin your day, this might be helpful. You can add this snippet to your status bar to make sync mode stand out, so that you never leave it turned on when not intended.
#[reverse,blink]#{?pane_synchronized,*** PANES SYNCED! ***,}#[default]
Each menu is a script, so you can edit a menu script, and once saved, the new content is displayed the next time you trigger that menu.
Rapid development with minimal fuzz.
If you are struggling with a menu edit, run that menu item in a pane of the tmux session you are working on, something like
./items/sessions.sh
This directly triggers that menu and displays any syntax errors on the command line.
In scripts/utils.sh
there is a function log_it and a variable log_file.
If log_file is defined, any call to log_it is printed there.
If not defined, nothing happens. log_it lines can be left in the code.
If you are triggering a menu from the command line, you can use direct echo,
but then you need to remove it before deploying since tmux sees any
script output as a potential error and display it in a scroll-back buffer.
If tailing a log file is unpractical, a more scalable way to achieve the
same result as echo would be to set log_file='/dev/stdout'
To trigger log output, add lines like:
log_it "foo is now [$foo]"
Each item consists of at least two params
Item types and their parameters
#!/bin/sh
#
# This script is assumed to have been placed in the items folder of
# this repo, if not, you will need to change the paths to the support
# scripts below.
#
static_content() {
menu_name="Simple Test"
req_win_width=39
req_win_height=23
#
# Be aware:
# The first 'set' to define a new menu segment should not use
# 'set -- "@" \', if that is done, it will just continue to build on
# what was defined in the previous menu segment!
# 'set -- \' creates a new set of parameters for menu_generate_part
#
set -- \
0.0 M Left "Back to Main menu <==" "main.sh" \
0.0 S \
0.0 T "Example of a line extending action" \
2.0 C "\$" "<P> Rename this session" "command-prompt -I '#S' \
'rename-session -- \"%%\"'" \
0.0 S \
0.0 T "Example of action reloading the menu" \
1.8 C z "<P> Zoom pane toggle" "resize-pane -Z $menu_reload"
menu_generate_part 1 "$@"
}
#===============================================================
#
# Main
#
#===============================================================
# Full path to tmux-menux plugin
D_TM_BASE_PATH="$(dirname "$(cd -- "$(dirname -- "$0")" && pwd)")"
# Source dialog handling script
# shellcheck disable=SC1091
. "$D_TM_BASE_PATH"/scripts/dialog_handling.sh
If whilst building the dialog, you need to take a break and check some
condition, you just pause the set --
param assignments, do the check
and then resume param assignment using set -- "$@"
Something like this:
...
1.8 C z "<P> Zoom pane toggle" "resize-pane -Z $menu_reload"
if tmux display-message -p '#{pane_marked_set}' | grep -q '1'; then
set -- "$@" \
1.7 C s "Swap current pane with marked" "swap-pane $menu_reload"
fi
set -- "$@" \
1.7 C "{" "<P> Swap pane with prev" "swap-pane -U $menu_reload" \
...
Contributions are welcome, and they're appreciated. Every little bit helps, and credit is always given.
The best way to send feedback is to file an issue