Ecosyste.ms: Awesome

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

Awesome Lists | Featured Topics | Projects

https://github.com/jabirali/tmux-tilish

Plugin which makes tmux work and feel like i3wm
https://github.com/jabirali/tmux-tilish

dwm i3 i3wm sway swaywm tmux tmux-plugins

Last synced: 3 months ago
JSON representation

Plugin which makes tmux work and feel like i3wm

Awesome Lists containing this project

README

        

# Tmux Tilish

This is a plugin that makes [`tmux`][6] behave more like a typical
[dynamic window manager][7]. It is heavily inspired by [`i3wm`][8], and
most keybindings are taken [directly from there][1]. However, I have made
some adjustments to make these keybindings more consistent with `vim`:
using hjkl instead of
jkl; for directions, and
using `vim`'s definitions of "split" and "vsplit". There is also an
"easy mode" available for non-`vim` users, which uses arrow keys
instead of hjkl.

The plugin has been verified to work on `tmux` v1.9, v2.6, v2.7, v2.9, and v3.0.
Some features are only available on newer versions of `tmux` (currently v2.7+),
but I hope to provide at least basic support for most `tmux` versions in active use.
If you encounter any problems, please file an issue and I'll try to look into it.

[1]: https://i3wm.org/docs/refcard.html
[6]: https://github.com/tmux/tmux/wiki/Getting-Started
[7]: https://en.wikipedia.org/wiki/Dynamic_window_manager
[8]: https://i3wm.org/docs/

## Why?

Okay, so who is this plugin for anyway? You may be interested in this if:

- You're using or interested in using `tmux`, but find the default keybindings
a bit clunky. This lets you try out an alternative keybinding paradigm,
which uses a modifier key (Alt) instead of a prefix key
(Ctrl + b). The plugin also makes it easier to do
automatic tiling via `tmux` layouts, as opposed to splitting panes manually.
- You use `i3wm`, but also do remote work over `ssh` + `tmux`. This lets
you use similar keybindings in both contexts.
- You also use other platforms like Gnome, Mac, or WSL. You want to take
your `i3wm` muscle memory with you via `tmux`.
- You're not really using `i3wm` anymore, but you did like how it handled
terminals and workspaces. You'd like to keep working that way in terminals,
without using `i3wm` or `sway` for your whole desktop.
- You use a window manager that is similar to `i3wm`, e.g. [`dwm`][9],
and want to have that workflow in `tmux` too.

[9]: https://dwm.suckless.org/tutorial/

## Quickstart

The easiest way to install this plugin is via the [Tmux Plugin Manager][2].
Just add the following to `~/.tmux.conf`, then press Ctrl + b
followed by Shift + i to install it (assuming default prefix key):

set -g @plugin 'jabirali/tmux-tilish'

For `tmux` v2.7+, you can customize which layout is used as default for new workspaces.
To do so, add this to `~/.tmux.conf`:

set -g @tilish-default 'main-vertical'

Just replace `main-vertical` with one of the layouts from the `tmux` `man` page:

| Description | Name |
| ----------------- | ----------------- |
| split then vsplit | `main-horizontal` |
| only split | `even-vertical` |
| vsplit then split | `main-vertical` |
| only vsplit | `even-horizontal` |
| fully tiled | `tiled` |

The words "split" and "vsplit" refer to the layouts you get in `vim` when
running `:split` and `:vsplit`, respectively. (Unfortunately, what is called
a "vertical" and "horizontal" split varies between programs.)
If you do not set this option, `tilish` will not autoselect any layout; you
can still choose layouts manually using the keybindings listed below.

After performing the steps above, you should read the [list of keybindings](#keybindings).
For further configuration options:

- If you use `nvim` or `vim`, consider [integrating it with `tilish`](#integration-with-vim).
- If you do not use `vim` or `kak`, consider activating [easy mode](#easy-mode).
- If you use `kak` or `emacs`, consider activating [prefix mode](#prefix-mode).
- If you use `tmux` within `i3wm` or `sway`, see [this section](#usage-inside-i3wm).
- If you like `dmenu`, check out the [application launcher](#application-launcher).
- If it doesn't work, check your [terminal settings](#terminal-compatibility).

It is also recommended that you add the following to the top of your `.tmux.conf`:

set -s escape-time 0
set -g base-index 1

The first line prevents e.g. Esc + h from triggering the
Alt + h keybinding, preventing common misbehavior when
using `vim` in `tmux`. This option is automatically set by [tmux-sensible][4], if
you use that. The second line makes workspace numbers go from 1-10 instead of 0-9,
which makes more sense on a keyboard where the number row starts at 1. However,
`tilish` explicitly checks this setting when mapping keys, and works fine without it.

[2]: https://github.com/tmux-plugins/tpm
[4]: https://github.com/tmux-plugins/tmux-sensible

## Keybindings

Finally, here is a list of the actual keybindings. Most are [taken from `i3wm`][1].
Below, a "workspace" is what `tmux` would call a "window" and `vim` would call a "tab",
while a "pane" is what `i3wm` would call a "window" and `vim` would call a "split".

| Keybinding | Description |
| ---------- | ----------- |
| Alt + 0-9 | Switch to workspace number 0-9 |
| Alt + Shift + 0-9 | Move pane to workspace 0-9 |
| Alt + hjkl | Move focus left/down/up/right |
| Alt + Shift + hjkl | Move pane left/down/up/right |
| Alt + o | Move focus to next pane |
| Alt + Enter | Create a new pane at "the end" of the current layout |
| Alt + s | Switch to layout: split then vsplit |
| Alt + Shift + s | Switch to layout: only split |
| Alt + v | Switch to layout: vsplit then split |
| Alt + Shift + v | Switch to layout: only vsplit |
| Alt + t | Switch to layout: fully tiled |
| Alt + z | Switch to layout: zoom (fullscreen) |
| Alt + r | Refresh current layout |
| Alt + n | Name current workspace |
| Alt + Shift + q | Quit (close) pane |
| Alt + Shift + e | Exit (detach) `tmux` |
| Alt + Shift + c | Reload config |

The Alt + 0 and Alt + Shift + 0
bindings are "smart": depending on `base-index`, they either act on workspace 0 or 10.

The keybindings that move panes between workspaces assume a US keyboard layout.
However, you can configure `tilish` for international keyboards by providing a string
`@tilish-shiftnum` prepared by pressing Shift +
1234567890.
For instance, for a UK keyboard, you would configure it as follows:

set -g @tilish-shiftnum '!"£$%^&*()'

Your terminal must support sending keycodes like `M-£` for the above to work.
For instance, a UK keyboard layout works fine on `urxvt`, but does not work
by default on `kitty` or `alacritty`, which may require additional configuration.

## Easy mode

To make the plugin more accessible for people who do not use `vim` as well,
there is also an "easy mode" available, which uses arrow keys instead of
the `vim`-style hjkl keys.
This mode can be activated by putting this in your `.tmux.conf`:

set -g @tilish-easymode 'on'

The revised keybindings for the pane focus and movement then become:

| Keybinding | Description |
| ---------- | ----------- |
| Alt + | Move focus left/down/up/right |
| Alt + Shift + | Move pane left/down/up/right |

## Prefix mode
Note that this feature is currently only available in `tmux` v2.4+.
The "prefix mode" uses a prefix key instead of Alt, and
may be particularly interesting for users of editors like `kak` and
`emacs` that use Alt key a lot. To activate this mode, you
define a prefix keybinding in your `tmux.conf`. For instance, to use
Alt + Space as your `tilish` prefix, add:

set -g @tilish-prefix 'M-space'

Actions that would usually be done by Alt + key
are now accomplished by pressing the prefix and then key.
For example, opening a split is usually Alt + Enter,
but with the above prefix this becomes Alt + Space
then Enter. Note that the `tilish` prefix is different from
the `tmux` prefix, and should generally be bound to a different key.
For the prefix key, you can choose basically any keybinding that `tmux`
supports, e.g. `F12` or `C-s` or anything else you may prefer.

All these keybindings are `repeat`'able, so you do not have to press the
prefix key again if you type multiple commands fast enough. Thus, pressing
Alt + Space followed by hj would
move to the left and then down, without requiring another prefix activation.
The `tmux` option `repeat-time` can be used to customize this timeout.
Personally, I find the default 500ms timeout somewhat short, and would
recommend that you increase this to at least a second if you use `tilish`:

set -g repeat-time 1000

## Application launcher

In `i3wm`, the keybinding Alt+d is by default mapped to
the application launcher `dmenu`, which can be practical to quickly open apps.
If you have [`fzf`][5] available on your system, `tilish` can offer a similar
application launcher using the same keyboard shortcut. To enable this
functionality, add the following to your `~/.tmux.conf`:

set -g @tilish-dmenu 'on'

Basically, pressing Alt+d will then pop up a split
that lets you fuzzy-search through all executables in your system `$PATH`.
Selecting an executable runs the command in that split. When you want
to start an interactive process, this can be more convenient than
using Alt+Enter and typing the command name.
This is currently only available in `tmux` v2.7+.

[5]: https://github.com/junegunn/fzf

## Terminal compatibility

Not all terminals support all keybindings. The plugin has been verified
to work well with: `iTerm2` and `Terminal.app` on macOS; `alacritty`, `kitty`,
`terminator`, `gnome-terminal`, and `urxvt` on Linux; `wsltty` and `alacritty`
on Windows. Some of these terminals bind Alt+Enter to
fullscreen, so you have to disable that for the `tilish` "new pane" binding to
work. Moreover, `gnome-terminal` steals the "switch workspace" keybindings
Alt+0-9 *if* you open multiple tabs. If you
use macOS, you likely want to configure the `Option` key to send either `Esc+`
(`iTerm2`) or `Meta` (`Terminal.app`) under the keyboard settings of the app.

It is also worth noting that `iTerm2` allows you to swap the `Cmd` and `Option`
keys in the terminal app. I recommend giving this a try if you're on macOS,
since the `Cmd` is more ergonomic than the `Option` key for extended use.

If you use `xterm`, almost none of the Alt keys work by default.
That can be fixed by adding this to `~/.Xresources`:

XTerm*eightBitControl: false
XTerm*eightBitInput: false
XTerm.omitTranslation: fullscreen
XTerm*fullscreen: never

The same issue affects Alacritty on macOS; see
[this issue](https://github.com/alacritty/alacritty/issues/93#issuecomment-353489475)
for a proposed solution.

## Usage inside i3wm

If you use `tilish` inside `i3wm` or `sway`, keybindings like
Alt+Enter may spawn a new terminal in your window manager
instead of a new terminal pane inside `tmux`. The window manager always takes
priority — so if both `i3wm` and `tilish` define the same keybinding,
`i3wm` will intercept the keybinding before `tmux` sees it.

The best way to solve this is perhaps to change your window manager modifier key
to Super, also known as the "Windows key". As described
[in the `i3wm` user guide](https://i3wm.org/docs/userguide.html#_using_i3), this can
be done by changing `$mod` to `Mod4` in your `i3wm` config. That way, pressing e.g.
Alt+Enter opens a new terminal pane inside `tmux`, while
Super+Enter opens a new terminal in `i3wm`.

Alternatively, `tilish` also supports a [Prefix mode](#prefix-mode). This is in my opinion
less ergonomic than the default `tilish` keybindings. However, it does not require the use
of Alt, and is therefore compatible with the default `i3wm` keybindings.

## Integration with vim

There are two great plugins [tmux-navigate][10] and [vim-tmux-navigator][3],
which both allow seamless navigation between `vim` splits and `tmux` splits.
The former has an advantage that it also works over `ssh` connections, and that
it plays better with zooming (Alt+z). If you use either
plugin, you can tell `tilish` to make it setup the keybindings for you. (If you
don't, `tilish` will use fallback keybindings that don't integrate with `vim`.)

### Navigate

It is perhaps easiest to setup `tmux-navigate`. Just load `navigate` *after* `tilish`
in your `tmux.conf`, and set the option `@tilish-navigate` to `on` to integrate them.
Thus a full working minimal example of a `tpm`-based `tmux.conf` would be:

# List of plugins.
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'jabirali/tmux-tilish'
set -g @plugin 'sunaku/tmux-navigate'

# Plugin options.
set -g @tilish-navigate 'on'

# Install `tpm` if needed.
if "test ! -d ~/.tmux/plugins/tpm" \
"run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"

# Activate the plugins.
run -b "~/.tmux/plugins/tpm/tpm"

No further setup is required; `tilish` sets up the keybindings, and `navigate`
handles seamless navigation of `vim`/`nvim` splits. However, if you also want
this seamless navigation over `ssh` connections, you should install
the accompanying `vim` plugin; see [their website for more information][10].

### Navigator

To install `vim-tmux-navigator`, you should first install the plugin for `vim`
or `nvim`, as described on [their website][3]. Then place this in your
`~/.config/nvim/init.vim` (`nvim`) or `~/.vimrc` (`vim`):

noremap :TmuxNavigateLeft
noremap :TmuxNavigateDown
noremap :TmuxNavigateUp
noremap :TmuxNavigateRight

You then just have to tell `tilish` that you want the integration:

set -g @tilish-navigator 'on'

A minimal working example of a `~/.tmux.conf` with `tpm` would then be:

# List of plugins.
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'jabirali/tmux-tilish'

# Plugin options.
set -g @tilish-navigator 'on'

# Install `tpm` if needed.
if "test ! -d ~/.tmux/plugins/tpm" \
"run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"

# Activate the plugins.
run -b "~/.tmux/plugins/tpm/tpm"

[3]: https://github.com/christoomey/vim-tmux-navigator
[10]: https://github.com/sunaku/tmux-navigate

# Related projects

- [3mux](https://github.com/aaronjanse/3mux)
- [tmux-navigate](https://github.com/sunaku/tmux-navigate)
- [vim-tmux-navigator](https://github.com/christoomey/vim-tmux-navigator)
- [vim-i3wm-tmux-navigator](https://github.com/fogine/vim-i3wm-tmux-navigator)