An open API service indexing awesome lists of open source software.

https://github.com/jaclu/tmux-menus

Tmux plugin, Popup menus to help with managing your environment
https://github.com/jaclu/tmux-menus

popup-dialog tmux tmux-plugin tmux-plugins

Last synced: 6 months ago
JSON representation

Tmux plugin, Popup menus to help with managing your environment

Awesome Lists containing this project

README

          

# Tmux-Menus

main
main-styled

## Summary

Popup menus to help with managing the tmux environment. If so desired,
[styling](docs/Styling.md) can be used.

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.

Recent Changes

## Recent Changes

- Prevent tmux variables from being expanded in `Display Menu Commands`
- Moved Layouts and Split window into Windows menu
- Main menu help displays kind of an about box info, about what version of the
plugin is used
- `Display menu commands` Rotates between displaying commands and all matching
prefix and root binds.
- Added parameter `@menus_border_type` for Styling

Purpose

## Purpose

Tmux provides a few basic popup menus by default, but they're quite limited and
difficult to extend due to their complex, mouse-based one-liner implementations.
A more integrated, user-friendly approach with better navigation and flexibility
seemed like the right solution.

Not solely meant for beginners, I use it myself all the time:

- Using `Display menu commands` as a reminder of shortcuts for common tasks
- When connecting using terminals without much support for Meta or even lacking arrows,
this gives access to all the actions that aren't available with the
regular shortcuts. For instance, when running the built in Terminal on
MacOS the console keyboard is pretty limited.
- Tasks that would need external scripts to avoid hard-to-read
complex bind one-liners, such as killing the current session without getting
disconnected.
- When direct typing would be much longer.
Example: Kill the server directly with 12 keys:
` : kill-ser `
with the menus 5 keys: ` \ A x y`

Usage

## Usage

Once installed, hit the trigger to get the main menu to pop up.
The default is ` \` see Configuration below for how to change it.

Screenshots of some menus

## Screenshots

The white one is generated with whiptail, as can be seen whiptail menus use a lot
more screen real estate. However if they don't fit they are scrollable unlike
the tmux menus, if they don't fit, they are just not displayed.
The rest are generated by the tmux built-in `display-menu`

Handling Pane
Handling Window
Help summary
Missing Keys
Missing Keys-whiptail

Dependencies & Compatibility

## Dependencies & Compatibility

| Version | Notice |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| 3.4 | Styling can be used. |
| 3.2 | Menu location fully available. |
| 3.0 - 3.1c | Menu centering is not supported, it's displayed top left if C is selected. |
| < 3.0 | Needs `whiptail` or `dialog` (see below). Menu location and styling settings are ignored. |
| 1.8 | 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. Some menu items
has a min tmux version set, if the running tmux doesn't match this,
that item will be skipped. If it turns out that incorrect limits have been set
on some feature, please let me know!

Installing

## Via TPM (recommended)

The easiest way to install `tmux-menus` is via the [Tmux Plugin
Manager](https://github.com/tmux-plugins/tpm).

1. Add plugin to the list of TPM plugins in `.tmux.conf`:

```tmux
set -g @plugin 'jaclu/tmux-menus'
```

2. Hit ` + I` to install the plugin and activate it. The plugin should now
be usable.

## Manual Installation

1. Clone the repository

```sh
git clone https://github.com/jaclu/tmux-menus ~/clone/path
```

2. Add this line to the bottom of `.tmux.conf`

```tmux
run-shell ~/clone/path/menus.tmux
```

3. Reload the `tmux` environment

```sh
# type this inside tmux
$ tmux source-file ~/.tmux.conf
```

The plugin should now be activated.

Configuration

## Configuration

### Boolean parameters

All boolean parameters accept the following values:

- `Yes` `True` `1`
- `No` `False` `0`

This is case-insensitive, meaning any combination of uppercase and lowercase
letters is accepted.

### Display menus

The default trigger is ` \` The trigger is configured like this:

```tmux
set -g @menus_trigger 'Space'
```

Note: Non-standard keys, such as the default backslash (`\`), must be prefixed with `\`
(e.g., `\\`) to prevent confusion in tmux.

Handling special keys becomes more complex when using quotes:

- Inside single quotes, both `'\'` and `'\\'` work.
- Inside double quotes, only `"\\"` is valid.

To avoid unexpected errors when switching between quoting styles, it's recommended
to always prefix special keys with `\` inside both single and double quotes,
as well as when not using quotes.

### Display without using prefix

```tmux
set -g @menus_without_prefix 'Yes'
```

This boolean parameter defaults to `No`

Use this in order to trigger menus without first hitting ``

### Pointer to the config file

```tmux
set -g @menus_config_file '~/.configs/tmux.conf'
```

In the main menu, the tmux config file to be reloaded.
The default location for this is:

1. `@menus_config_file` - if this is defined in the tmux config file, it will be used.
2. `$TMUX_CONF` - if this is present in the environment, it will be used.
3. `$XDG_CONFIG_HOME/tmux/tmux.conf` - if `$XDG_CONFIG_HOME` is defined.
4. `~/.tmux.conf` - Default if none of the above are set.

When a reload is requested, the conf file will be prompted for, defaulting
to the first match above. It can be manually changed.

### Menu location

The default locations are: `C` for tmux >= 3.2 `P` otherwise. If whiptail/dialog
is used, menu location is ignored

```tmux
set -g @menus_location_x 'W'
set -g @menus_location_y 'S'
```

For all location options see the tmux man page, search for `display-menu`.
The basic options are:

| Value | Flag | Meaning |
| ----- | ---- | ---------------------------------------------- |
| C | Both | The centre of the terminal (tmux 3.2 or newer) |
| R | -x | The right side of the terminal |
| P | Both | The bottom left of the pane |
| M | Both | The mouse position |
| W | Both | The window position on the status line |
| S | -y | The line above or below the status line |

### Disable caching

```tmux
set -g @menus_use_cache 'No'
```

This boolean parameter defaults to `Yes`

By default menu items are cached.

Disabling caching also disables the Custom Menus feature.

To be more precise, items listed inside `static_content()` are cached.
Some items need to be freshly generated each time a menu is displayed,
those items are defines in `dynamic_content()` see
[scripts/pane_move.sh](items/pane_move.sh) for an example of this. In that case,
"Swap current pane with marked" is only displayed if there is a marked pane.

The plugin remembers what tmux version was used last time.
If another version is detected as the plugin is initialized, the entire
cache is dropped, so that the right version dependent items can be
selected as the cache is re-populated.
Same if a menu script is changed, if the script is newer than the cache,
that cache item is regenerated.

### Use Hint Overlays

```tmux
set -g @menus_use_hint_overlays 'No'
```

This boolean parameter defaults to `Yes`

This feature is not available when whiptail / dialog is used.

Some menu items will display tmux dialogs, where each have their own rather complex
set of special key bindings - choose-buffer, choose-client, choose-tree and
customize-mode

When entering such a dialog, per default an overlay will first be presented lisitng
the keys available for that dialog, if it fits on screen.

Use this setting to disable the overlay feature.

If `@menus_use_hint_overlays` is enabled, there is a support option
`@menus_show_key_hints` (defaults to 'No') that also can be toggled.
If `@menus_use_hint_overlays` is disabled, `@menus_show_key_hints` is ignored.

#### Show Key Hints

```tmux
set -g @menus_show_key_hints 'Yes'
```

This boolean parameter defaults to `No`

Related to `@menus_use_hint_overlays` Since those key-listings tend to be rather long
they might not fit on screen, and thus be silently skipped.
Enabling this will offer an extra option `Key Hints` on each menu featuring an
alternative that will display such a dialog, and mentioning which item on that
menu it is related to.

This Key Hint will display the dialog the normal way, giving a warning if the
screen is to small, mentioning required screen size.

It will also serve as a hint as to what menu entries are expected to display an overlay.

### Logging

Per default logging is disabled. If this is desired, provide a log file name
like this:

```tmux
set -g @menus_log_file '~/tmp/tmux-menus.log'
```

### Display menu commands

```tmux
set -g @menus_display_commands 'Yes'
```

This boolean parameter defaults to `No`

This feature is not available when whiptail / dialog is used or caching is disabled.

If set to true each menu will include an extra item `Display Commands` with the
shortcut `!`

Pressing this will display what commands are used for each action.

Pressing this again will display all matching prefix and root binds.
If multiple key binds matches, all of them will be listed.

Be aware that the menu will be taller when using this, so make sure the screen is
large enough to handle it!

If this is defined, there is a support setting that can be used:

```tmux
set -g @menus_display_cmds_cols 160
```

This is the maximum line length that will be used to display commands.
It defaults to `75` but can be changed if the display is really wide or narrow.

If the displayed command doesn't fit on one line, it will be split in chunks, if
possible it will be split on the last white space before `@menus_display_cmds_cols`
length. If no white space is found, the cmd will be split at the indicated max length.

In case this is set too wide, and the line doesn't fit on the display, tmux will
cut the line ending it with `>`.

Such lines are truncated. And the entire command was not displayed.

If commands end with `>` it is recommended to use a narrower setting for
`@menus_display_cmds_cols`

Screen might be too small

## Screen might be too small

tmux does not give any error if a menu doesn't fit the available screen,
it just does not display the menu.

The only hint is that the menu is terminated instantaneously.

Since this test is far from perfect, and some computers are really slow,
the current assumption is that if it was displayed < 0.1 seconds,
it was likely due to screen size.
On really slow systems, the cut-off is 0.5 seconds, since they would typically
need > 0.1 just to process the menu.
In that case this error will be displayed on the status-bar:

```tmux
tmux-menus ERROR: Screen might be too small
```

It will also be displayed if the menu is closed right away intentionally
or unintentionally, so there will no doubt sometimes be false positives.
If it doesn't happen the next time the menu is attempted, it can be ignored.

Using Styling for menus

## Using Styling for menus

See [docs/Styling.md](docs/Styling.md)

Custom menus

## Custom Menus

While the initial assumption was that users wanting to modify the menus would fork
the repository and make changes directly, a feature was added to allow menus to
be added dynamically based on user requests.

For details on how to use this feature, see the documentation:
[docs/CustomMenus.md](docs/CustomMenus.md)

whiptail / dialog

## whiptail / dialog - alternate tools for displaying menus

For tmux < 3.0 the tmux feature`display-menu` is not available.

If found `whiptail` or `dialog` will be used to display menus.

The preferred option is whiptail, but if not found dialog will be used instead.
If neither is available, this plugin will abort displaying an error message.

Since these are full-screen apps, when either is used, the current (if any)
task is suspended, dialogs are run, and when done the suspended task is reactivated.

The menu system works the same using external menu handlers, however the menu
shortcuts are not as convenient, since they do not differentiate between upper
and lower case letters,
and does not at all support special keys like 'Left' or 'Home'

To use external dialog handling on modern tmuxes set this env variable:

- for `whiptail` use `export TMUX_MENUS_HANDLER=1`
- for `dialog` use `export TMUX_MENUS_HANDLER=2`

In most cases whiptail is installed by default on Linux distros. If not, install
it using the package manager.
One gotcha is that in the Red Hat universe the package is not called whiptail,
the package containing whiptail is called `newt`.

MacOS does not come with whiptail, but it is available in the Homebrew package `newt`.

Modifications

## Modifications

Each menu is a standalone script, making it easy to edit. Once saved,
the updated content will be displayed the next time the menu is triggered.

**Fast development with minimal hassle!**

If an edited menu fails to load, you can run it directly from the command
line to check for syntax errors:

```bash
./items/sessions.sh
```

This will immediately execute the menu and display any errors in the terminal.

If `@menus_log_file` is set—either in the tmux configuration or hardcoded in
`scripts/helpers_minimal.sh` (around line 355, look for assignment of cfg_log_file)
logging can be used within menus:

```bash
log_it "foo is now [$foo]"
```

If monitoring a log file in a separate terminal is impractical,
you can set the log file to `/dev/stderr` to make `log_it` behave like `echo`.

Using `/dev/stderr` instead of `/dev/stdout` prevents unintended errors if
`log_it` is called during string assignments.

Menu building

## Menu building

Each item consists of at least two parameters

- min tmux version for this item, set to 0.0 if assumed to always work
- Type of menu item, see below
- Additional parameters depending on the item type

Item types and their parameters

- M - Open another menu
- shortcut for this item, or "" if none wanted
- label
- menu script
- C - run tmux Command
- shortcut for this item, or "" if none wanted
- label
- tmux command
- E - run External command
- shortcut for this item, or "" if none wanted
- label
- external command
- T - Display text line
- text to display. Any initial "-" (making it unselectable in tmux menus)
will be skipped if whiptail is used, since a leading "-" would cause it to crash.
- S - Separator/Spacer line line
- no parameters

### Sample script

```shell
#!/bin/sh

static_content() {
# Be aware:
# 'set -- \' creates a new set of parameters for menu_generate_part
# 'set -- "$@" \' should be used when appending parameters

set -- \
0.0 M Left "Back to Main menu $nav_home" "main.sh" \
0.0 S \
0.0 T "Example of a line extending action" \
2.0 C "r" "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" "Zoom pane toggle" "resize-pane -Z $menu_reload"

menu_generate_part 1 "$@"
}

menu_name="Simple Test"

# Full path to tmux-menux plugin
# This script is assumed to have been placed in the items folder of
# this repo, if not, D_TM_BASE_PATH needs to bechanged the path of the repo
D_TM_BASE_PATH="$(dirname -- "$(dirname -- "$(realpath "$0")")")"

# shellcheck source=scripts/dialog_handling.sh
. "$D_TM_BASE_PATH"/scripts/dialog_handling.sh

```

### Complex param building for menu items

If whilst building the dialog, a break is needed, to check somecondition, just
pause the `set --` param assignments, do the check and then resume param assignment
using `set -- "$@"`

Something like this:

```shell
...
1.8 C z "Zoom pane toggle" "resize-pane -Z $menu_reload"

if tmux display-message -p '#{pane_marked_set}' | grep -q '1'; then
set -- "$@" \
2.1 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

## Contributions

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](https://github.com/jaclu/tmux-menus/issues)

## Thanks to

- [cmon1701](https://github.com/cmon1701) For notifying me that the plugin listing
used hardcoded path assumptions - Addressed i release 2.1.3
- [sumskyi](https://github.com/sumskyi) for notifying me that the boolean check
error message for invalid values lacked the significant info about what variable
contained the incorrect value. Addressed in release 2.0.2
- [GaikwadPratik](https://github.com/GaikwadPratik) for notifying me that the
Disable caching feature was broken
- [Tony Soloveyv](https://github.com/tony-sol) for spotting an unintentional
shortcut change in the main menu
- [JuanGarcia345](https://github.com/JuanGarcia345) for suggesting to make
menu-cache optional.
- [phdoerfler](https://github.com/phdoerfler) for noticing TMUX_BIN was often not set,
I had it defined in my .tmux.conf, so totally missed such errors, in future testing I
will make sure not to rely on env variables.
- [giddie](https://github.com/giddie) for suggesting "Re-spawn current pane"
- [wilddog64](https://github.com/wilddog64) for suggesting adding a prefix
to the curl that probes public IP

## License

[MIT](LICENSE)