plugins/tmux-navigator: port to mkVimPlugin

Add missing settings:
- preserve_zoom
- no_mappings

Include upstream's documentation.

Deprecate old option names.
This commit is contained in:
Matt Sturgeon 2024-03-19 20:17:57 +00:00 committed by Gaétan Lepage
parent 822ec15646
commit 9dc094489a
3 changed files with 179 additions and 31 deletions

View file

@ -12,4 +12,14 @@
githubId = 1176328; githubId = 1176328;
name = "Alison Jenkins"; name = "Alison Jenkins";
}; };
MattSturgeon = {
email = "matt@sturgeon.me.uk";
matrix = "@mattsturg:matrix.org";
github = "MattSturgeon";
githubId = 5046562;
name = "Matt Sturgeon";
keys = [
{fingerprint = "7082 22EA 1808 E39A 83AC 8B18 4F91 844C ED1A 8299";}
];
};
} }

View file

@ -6,37 +6,173 @@
... ...
}: }:
with lib; let with lib; let
cfg = config.plugins.tmux-navigator; # TODO: Introduced 2024-03-19, remove on 2024-05-19
in { deprecations = let
options.plugins.tmux-navigator = { pluginPath = ["plugins" "tmux-navigator"];
enable = mkEnableOption "Tmux-Navigator (see https://github.com/christoomey/vim-tmux-navigator for tmux installation instruction)"; option = s: pluginPath ++ [s];
setting = s: pluginPath ++ ["settings" s];
settingStr = s: concatStringsSep "." (setting s);
in [
(
mkRenamedOptionModule
(option "tmuxNavigatorSaveOnSwitch")
(setting "save_on_switch")
)
(
mkRemovedOptionModule
(option "tmuxNavigatorDisableWhenZoomed")
"Use `${settingStr "disable_when_zoomed"}` option."
)
(
mkRemovedOptionModule
(option "tmuxNavigatorNoWrap")
"Use `${settingStr "no_wrap"}` option."
)
];
in
helpers.vim-plugin.mkVimPlugin config {
name = "tmux-navigator";
originalName = "vim-tmux-navigator";
defaultPackage = pkgs.vimPlugins.tmux-navigator;
globalPrefix = "tmux_navigator_";
package = helpers.mkPackageOption "tmux-navigator" pkgs.vimPlugins.tmux-navigator; maintainers = [helpers.maintainers.MattSturgeon];
description = ''
When combined with a set of tmux key bindings, the plugin will allow you to navigate seamlessly between vim splits and tmux panes using a consistent set of hotkeys.
**WARNING:** to work correctly, you must configure tmux separately.
## Usage
This plugin provides the following mappings which allow you to move between vim splits and tmux panes seamlessly.
- `<ctrl-h>` => Left
- `<ctrl-j>` => Down
- `<ctrl-k>` => Up
- `<ctrl-l>` => Right
- `<ctrl-\>` => Previous split
To use alternative key mappings, see [`plugins.tmux-navigator.settings.no_mappings`][no_mappings].
## Configure tmux
There are two main ways to configure tmux. Either install the `tmuxPlugins.vim-tmux-navigator` plugin or add a snippet to your tmux config:
```shell
# Smart pane switching with awareness of vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l' 'select-pane -R'
# Forwarding <C-\\> needs different syntax, depending on tmux version
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\' 'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
"bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\' 'select-pane -l'"
bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l
```
See the [upstream docs] for more info.
[no_mappings]: ./settings.html#pluginstmux-navigatorsettingsno_mappings
[upstream docs]: https://github.com/christoomey/vim-tmux-navigator#installation
'';
imports = deprecations;
settingsOptions = {
save_on_switch = helpers.mkNullOrOption (types.enum [1 2]) ''
You can configure the plugin to write the current buffer, or all buffers, when navigating from vim to tmux.
tmuxNavigatorSaveOnSwitch = helpers.mkNullOrOption (lib.types.enum [1 2]) ''
null: don't save on switch (default value) null: don't save on switch (default value)
1: update (write the current buffer, but only if changed) 1: `:update` (write the current buffer, but only if changed)
2: wall (write all buffers) 2: `:wall` (write all buffers)
''; '';
tmuxNavigatorDisableWhenZoomed = helpers.mkNullOrOption (lib.types.enum [1]) '' disable_when_zoomed = helpers.defaultNullOpts.mkBool false ''
null: unzoom when moving from Vim to another pane (default value) By default, if you zoom the tmux pane running vim and then attempt to navigate "past" the edge of the vim session, tmux will unzoom the pane.
1: If the tmux window is zoomed, keep it zoomed when moving from Vim to another pane This is the default tmux behavior, but may be confusing if you've become accustomed to navigation "wrapping" around the sides due to this plugin.
This option disables the unzooming behavior, keeping all navigation within vim until the tmux pane is explicitly unzoomed.
''; '';
tmuxNavigatorNoWrap = helpers.mkNullOrOption (lib.types.enum [1]) '' preserve_zoom = helpers.defaultNullOpts.mkBool false ''
null: move past the edge of the screen, tmux/vim will wrap around to the opposite side (default value) As noted in `disable_when_zoomed`, navigating from a vim pane to another tmux pane normally causes the window to be unzoomed.
1: disable wrap Some users may prefer the behavior of tmux's `-Z` option to `select-pane`, which keeps the window zoomed if it was zoomed.
This option enables that behavior.
Naturally, if `disable_when_zoomed` is enabled, this option will have no effect.
'';
no_wrap = helpers.defaultNullOpts.mkBool false ''
By default, if you try to move past the edge of the screen, tmux/vim will "wrap" around to the opposite side.
This option disables "wrapping" in vim, but tmux will need to be configured separately.
Tmux doesn't have a "no_wrap" option, so whatever key bindings you have need to conditionally wrap based on position on screen:
```shell
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
| grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}' {} { select-pane -L } }
bind-key -n 'C-j' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {} { select-pane -D } }
bind-key -n 'C-k' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}' {} { select-pane -U } }
bind-key -n 'C-l' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}' {} { select-pane -R } }
bind-key -T copy-mode-vi 'C-h' if-shell -F '#{pane_at_left}' {} { select-pane -L }
bind-key -T copy-mode-vi 'C-j' if-shell -F '#{pane_at_bottom}' {} { select-pane -D }
bind-key -T copy-mode-vi 'C-k' if-shell -F '#{pane_at_top}' {} { select-pane -U }
bind-key -T copy-mode-vi 'C-l' if-shell -F '#{pane_at_right}' {} { select-pane -R }
```
'';
no_mappings = helpers.defaultNullOpts.mkBool false ''
By default `<C-h>`, `<C-j>`, `<C-k>`, `<C-l>`, & `<C-\\>` are mapped to navigating left, down, up, right, & previous, respectively.
This option disables those default mappings being created.
You can use the plugin's five commands to define your own custom mappings:
```nix
keymaps = [
{
key = "<C-w>h";
action = "<cmd>TmuxNavigateLeft<cr>";
}
{
key = "<C-w>j";
action = "<cmd>TmuxNavigateDown<cr>";
}
{
key = "<C-w>k";
action = "<cmd>TmuxNavigateUp<cr>";
}
{
key = "<C-w>l";
action = "<cmd>TmuxNavigateRight<cr>";
}
{
key = "<C-w>\\";
action = "<cmd>TmuxNavigatePrevious<cr>";
}
];
```
You will also need to update your tmux bindings to match.
''; '';
}; };
}
config = mkIf cfg.enable {
extraPlugins = [cfg.package];
globals = {
tmux_navigator_save_on_switch = cfg.tmuxNavigatorSaveOnSwitch;
tmux_navigator_disable_when_zoomed = cfg.tmuxNavigatorDisableWhenZoomed;
tmux_navigator_no_wrap = cfg.tmuxNavigatorNoWrap;
};
};
}

View file

@ -9,11 +9,13 @@
plugins.tmux-navigator = { plugins.tmux-navigator = {
enable = true; enable = true;
tmuxNavigatorSaveOnSwitch = 2; settings = {
save_on_switch = 2;
tmuxNavigatorDisableWhenZoomed = 1; disable_when_zoomed = true;
preserve_zoom = true;
tmuxNavigatorNoWrap = 1; no_wrap = true;
no_mappings = true;
};
}; };
}; };
} }