From 4d7e4055c7a30c983bb42b0a3c37aa7f07ef607f Mon Sep 17 00:00:00 2001
From: BZ
Date: Sun, 24 Sep 2023 21:24:36 +0200
Subject: [PATCH] update readme
---
README.md | 226 +++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 156 insertions(+), 70 deletions(-)
diff --git a/README.md b/README.md
index 7e78da1..e43347c 100644
--- a/README.md
+++ b/README.md
@@ -1,128 +1,214 @@
-AwesomeWM - Vim - Tmux Navigator
-==================
+# AwesomeWM - Vim - Tmux Navigator
Usually vim and tmux have their own dedicated keybinds for navigation.
-Christoomey's plugin [vim-tmux-navigator](https://github.com/christoomey/vim-tmux-navigator) allows you to the use the same keybinds for vim and tmux.
+Christoomey's plugin [vim-tmux-navigator](https://github.com/christoomey/vim-tmux-navigator) allows you to the use the same keybinds for both of them.
This might be sufficient for floating wm users, but when using a tiling wm like awesomewm we can do better and add another layer.
-`awesomewm-vim-tmux-navigator` lets you navigate seamlessly between system windows, vim splits and tmux panes by only using your awesomewm navigation keybinds (e.g. Mod4+hjkl).
-Every vim split and tmux pane is treated like a standalone system window, allowing you to forget your vim/tmux specific navigation hotkeys.
+`awesomewm-vim-tmux-navigator` lets you navigate seamlessly between system windows, (n)vim splits and tmux panes by only using your awesomewm navigation keybinds (e.g. Mod4+hjkl).
+Every split and pane is treated like a standalone system window, allowing you to forget your vim/tmux specific navigation hotkeys.
-How does it work
-------------
-It essentially works by sending the correct keypresses based on the context.
-Therefore the plugin has to detect whether the current focused application is vim, tmux or any other system window.
+## 💡 How does it work?
+
+It essentially works by emulating the correct keypresses based on the context.
+Therefore the plugin has to detect whether the current focused application is vim, tmux, vim inside tmux (etc.) or any other system window.
The plugin offers two methods of determining the focused application:
-1. By using dynamic titles. The plugin tries to change the title (`WM_NAME`) of your terminal in order to differentitate between applications. However, not every shell-terminal-stack supports dynamic titles or is configured correctly out of the box. Minimal configurations are provided for `zsh` and `bash`.
+1. By using dynamic titles. The plugin tries to change the title of your terminal in order to differentiate between applications. However, not every shell-terminal-stack supports dynamic titles or is configured correctly out of the box.
-2. By using `pstree`. This should theoretically work on every setup, but it might perform slower due to having an extra process to spawn. This method can be enabled by setting the `experimental` flag.
+2. By using `pstree`. This should theoretically work on every setup, but it might perform slightly slower due to having an extra process to spawn.
+By default the plugin uses awesomewm's builtin implementation (`root.fake_input`) to emulate keypresses.
-Installation
-------------
+## 📦 Installation
+
+The configuration of vim or tmux is optional if you only use one of them.
+
+### awesomewm:
+
+Clone the repo:
-### AwesomeWM
-Clone the repo.
```
git clone https://github.com/intrntbrn/awesomewm-vim-tmux-navigator ~/.config/awesome/awesomewm-vim-tmux-navigator
```
-It's not recommended to change the path since it's hardcoded in other configuration files.
-Add your preferred navigation (focus) keybinds to `rc.lua` (e.g. Mod4+arrows or Mod4+hjkl):
+Import and configure the module:
```
-require("awesomewm-vim-tmux-navigator") {
- up = {"Up", "k"},
- down = {"Down", "j"},
- left = {"Left", "h"},
- right = {"Right", "l"},
- mod = "Mod4",
- mod_keysym = "Super_L",
- --experimental = true
+require("awesomewm-vim-tmux-navigator")({
+ mod = "Mod4",
+ mod_keysym = "Super_L", -- comment out to autodetect
+ up = { "Up", "k" },
+ down = { "Down", "j" },
+ left = { "Left", "h" },
+ right = { "Right", "l" },
+
+ tmux = {
+ mods = { "Control_L" },
+ up = "Up",
+ down = "Down",
+ left = "Left",
+ right = "Right",
+ },
+
+ vim = {
+ mods = { "Control_L" },
+ up = "k",
+ down = "j",
+ left = "h",
+ right = "l",
+ },
+
+ -- focus = require("awful").client.focus.global_bydirection,
+ -- debug = print,
+
+ -- dont_restore_mods = true, -- prevent sticky mods (see troubleshooting)
+ -- use_pstree = true, -- detect app by using pstree instead of dynamic titles
+ -- use_xdotool = true, -- emulate keypresses using xdotool instead of builtin
+})
+```
+
+If the awesomewm navigation keybinds are already in use, you have to **remove them manually**
+in your `rc.lua`.
+
+The corresponding keysym names can be retrieved by running the terminal command `xev -event keyboard`.
+If `mod_keysym` is nil the plugin tries to detect your modifier.
+
+### vim:
+
+This plugin replaces `christoomey/vim-tmux-navigator`. Therefore you have to
+replace it in your plugin manager with `intrntbrn/awesomewm-vim-tmux-navigator`.
+However, both plugins share the same keybind commands, so it's not necessary to
+adjust already configured custom keybinds.
+Custom keybinds have to match your awesomewm configuration.
+
+lazy.nvim (lua):
+
+```lua
+ {
+ "intrntbrn/awesomewm-vim-tmux-navigator",
+ event = "VeryLazy",
+ build = "git -C ~/.config/awesome/awesomewm-vim-tmux-navigator/ pull",
+ keys = {
+ { mode = { "n" }, "", ":TmuxNavigateLeft", { noremap = true, silent = true } },
+ { mode = { "n" }, "", ":TmuxNavigateDown", { noremap = true, silent = true } },
+ { mode = { "n" }, "", ":TmuxNavigateUp", { noremap = true, silent = true } },
+ { mode = { "n" }, "", ":TmuxNavigateRight", { noremap = true, silent = true } },
+ },
+ config = function()
+ vim.g.tmux_navigator_no_mappings = 1
+ -- vim.g.tmux_navigator_no_dynamic_title = 1
+ -- vim.g.tmux_navigator_save_on_switch = 1
+ -- vim.g.tmux_navigator_disable_when_zoomed = 1
+ -- vim.g.tmux_navigator_preserve_zoom = 1
+ end,
}
```
-Please verify that `mod` and `mod_keysym` matches your actual awesomewm modifier key by using the terminal applications `xev` and `xmodmap`.
-For instance you might press the right super key and have to specify "Super_R" as your `mod_keysym`, or "Mod1" and "Alt_L" if you prefer to use the alt key.
+vim-plug (VimL):
-Don't forget to remove your previously used navigation keybinds (or other conflicting keybinds) in `rc.lua`.
+```viml
+Plug 'intrntbrn/awesomewm-vim-tmux-navigator', { do = 'git -C ~/.config/awesome/awesomewm-vim-tmux-navigator/ pull' }
-If you like to use your own custom directional focus function, you can do this by defining `focus`.
-Default is `awful.client.focus.global_bydirection`.
-
-### Vim
-Install using your favorite package manager, e.g. `vim-plug`:
-
-```vim
-Plug 'intrntbrn/awesomewm-vim-tmux-navigator'
+let g:tmux_navigator_no_mappings = 1
+noremap :TmuxNavigateLeft
+noremap :TmuxNavigateDown
+noremap :TmuxNavigateUp
+noremap :TmuxNavigateRight
+" let g:tmux_navigator_no_dynamic_title = 1
+" let g:tmux_navigator_save_on_switch = 1
+" let g:tmux_navigator_disable_when_zoomed = 1
+" let g:tmux_navigator_preserve_zoom = 1
```
-Remove `christoomey/vim-tmux-navigator` if you are using it.
+
-**Options:**
+### tmux:
-`let g:tmux_navigator_insert_mode = 1` to enable navigator keybinds in insert mode
+Add the following to your `tmux.conf`:
-### Tmux
-Add the following to your `tmux.conf` at the very bottom.
```tmux
-# Set title suffix to "- TMUX"
+# smart pane switching with awareness of vim splits and awesomewm windows
+is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
+bind-key -n 'C-Left' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"left\")" ' } { select-pane -L } }
+bind-key -n 'C-Right' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"right\")" ' } { select-pane -R } }
+bind-key -n 'C-Up' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"up\")" ' } { select-pane -T } }
+bind-key -n 'C-Down' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"down\")" ' } { select-pane -D } }
+bind-key -T copy-mode-vi 'C-Left' if-shell "$is_vim" { send-keys C-h } { if-shell -F '#{pane_at_left}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"left\")" ' } { select-pane -L } }
+bind-key -T copy-mode-vi 'C-Right' if-shell "$is_vim" { send-keys C-l } { if-shell -F '#{pane_at_right}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"right\")" ' } { select-pane -R } }
+bind-key -T copy-mode-vi 'C-Up' if-shell "$is_vim" { send-keys C-k } { if-shell -F '#{pane_at_top}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"up\")" ' } { select-pane -T } }
+bind-key -T copy-mode-vi 'C-Down' if-shell "$is_vim" { send-keys C-j } { if-shell -F '#{pane_at_bottom}' {run-shell 'awesome-client "awesome.emit_signal(\"navigator::focus\", \"down\")" ' } { select-pane -D } }
+
+# set title suffix to "- TMUX" (optional when using pstree method)
set-option -g set-titles on
set-option -g set-titles-string '#S: #W - TMUX'
-# Smart pane switching with awareness of vim splits and system windows
-is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
- | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
-bind -n C-Left if-shell "$is_vim" "send-keys C-h" "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh left'"
-bind -n C-Down if-shell "$is_vim" "send-keys C-j" "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh down'"
-bind -n C-Up if-shell "$is_vim" "send-keys C-k" "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh up'"
-bind -n C-Right if-shell "$is_vim" "send-keys C-l" "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh right'"
-bind-key -T copy-mode-vi 'C-Left' "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh left'"
-bind-key -T copy-mode-vi 'C-Down' "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh down'"
-bind-key -T copy-mode-vi 'C-Up' "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh up'"
-bind-key -T copy-mode-vi 'C-Right' "run-shell 'sh ~/.config/awesome/awesomewm-vim-tmux-navigator/tmux_focus.sh right'"
```
-Troubleshooting
----------------
-1. Make sure there are no conflicting keybindings.
+Custom keybinds have to match your awesomewm configuration.
-2. Check https://github.com/christoomey/vim-tmux-navigator#troubleshooting.
+## ❓ Troubleshooting
-3. Try to enable dynamic titles in your shell. Minimal configurations are provided for `zsh` and `bash`:
+### Setup:
+
+1. Enable debug mode:
+
+```lua
+debug = function(msg) require("naughty").notify({ text = msg }) end
+```
+
+2. Make sure there are no conflicting keybinds.
+ You can bypass conflicts in awesomewm by invoking the plugin from the terminal for verification:
+
+```bash
+echo "select a window" && sleep 2 && awesome-client 'awesome.emit_signal("navigator::navigate", "up")'
+```
+
+3. Verify if dynamic titles are working. The title of (n)vim and tmux
+ applications should end with "- (N)VIM" or "- TMUX" respectively.
+ If you don't have a titlebar, you can use the terminal command `xprop | grep WM_NAME`.
+ If dynamic titles are not working, set `use_pstree` to true or configure
+ your shell-terminal-stack correctly. Minimal configurations are provided for `zsh` and `bash`:
```
echo "source ~/.config/awesome/awesomewm-vim-tmux-navigator/dynamictitles.zsh" >> ~/.zshrc
```
-or
-
```
echo "source ~/.config/awesome/awesomewm-vim-tmux-navigator/dynamictitles.bash" >> ~/.bashrc
```
-After a correct installation the title of a tmux session should end with "- TMUX" and "- VIM" or "- NVIM" for vim or nvim sessions respectively.
-Check the title of the terminal client in your wm tasklist or by using the terminal application `xprop` (title is property `WM_NAME`).
+4. Check https://github.com/christoomey/vim-tmux-navigator#troubleshooting.
-In case your title does not change, your terminal and/or shell may not support dynamic titles. Try other.
+5. Create an issue.
-4. Set `experimental = true`. The experimental mode does not require dynamic titles, but might be a bit slower.
+### Sticky Mods:
-Integration
----------------
-This plugin can be used from everywhere and does not require any kind of import or reference.
+In order to emulate keypresses in vim/tmux, the plugin needs to release your wm
+modifier (e.g. mod4) temporarily and restore it afterwards.
+There is a race condition if the user was fast enough to release the modifier
+during this operation resulting in _sticky_ mods. This issue is very unlikely to be ever solved.
-Awesomewm: `awesome.emit_signal("navigator::navigate", "left")`
-
-Shell: `echo 'awesome.emit_signal("navigator::navigate", "up")' | awesome-client`
+Restoring mods can be disabled by setting the `dont_restore_mods` option.
+Please note that you can't hold the modifier down for consecutive actions using
+this option. However, this option works very well with combo-keybinds using custom keyboards (qmk similar software/firmware).
+## 📡 API
+- **navigate**: directional vim/tmux aware navigation
+- **focus**: regular directional system window navigation
+awesomewm:
+````lua
+w```
+shell:
+```bash
+awesome-client 'awesome.emit_signal("navigator::navigate", "up")'
+awesome-client 'awesome.emit_signal("navigator::focus", "down")'
+````