Vim-like modal keybindings for your terminal! ✌️
Add keybindings which operate with vim-like modal bindings to accelerate your workflow. This plugin adds great opt-in default modes along with optional visual indicators and hints for the keybindings.
Improvements to Wezterms CopyMode with vim keybindings
I have included some default modes which are opt-in as to improve performance for all users.
UI mode has vim-like bindings to navigate and modify panes, tabs and other UI elements.
In scroll mode you can scroll with familiar vim bindings.
It is recommended to do the setup with some Customization. However if you just want to try it out you can follow the Preset
Add the following to the bottom of your config:
local wezterm = require("wezterm")
local modal = wezterm.plugin.require("https://github.com/MLFlexer/modal.wezterm")
modal.apply_to_config(config)
This will add the keybindings to enter and exit modes:
ALT-u
to enter UI mode from normal modeALT-c
to enter Copy mode from normal modev
to enter visual mode from Copy mode/
to enter search mode from Copy modeALT-n
to enter Scroll mode from normal modeesc
orCTRL-c
to leave current non-normal mode
Checkout the keybinding descriptions
- Require the plugin:
local wezterm = require("wezterm")
local modal = wezterm.plugin.require("https://github.com/MLFlexer/modal.wezterm")
- Add your own mode
There are more examples of key tables and status texts with and without hints in the /defaults
directory.
-- example key table
local key_table = {
{ key = "Escape", action = modal.exit_mode("mode_name") },
{ key = "c", mods = "CTRL", action = modal.exit_mode("mode_name") },
{ key = "z", action = wezterm.action.TogglePaneZoomState },
}
-- example right status text
local status_text = wezterm.format({
{ Attribute = { Intensity = "Bold" } },
{ Foreground = { Color = "Red" } },
{ Text = wezterm.nerdfonts.ple_left_half_circle_thick },
{ Foreground = { Color = "Black" } },
{ Background = { Color = "Red" } },
{ Text = "MODE NAME " },
})
modal.add_mode("mode_name", key_table, status_text)
- Add you keybind to enter the mode
config.keys = {
-- ...
-- your other keybindings
{
key = "m",
mods = "ALT",
action = activate_mode("mode_name"),
}
}
- Add the modes to your config
config.key_tables = modal.key_tables
- Change right status text when entering/leaving mode
wezterm.on("update-right-status", function(window, _)
modal.set_right_status(window)
end)
If you want to enable a default mode, then you can add the following:
modal.enable_defaults("https://github.com/MLFlexer/modal.wezterm")
-- "ui_mode" can be replaced by any filename from the /defaults directory
local key_table = require("ui_mode").key_table
local icons = {
left_seperator = wezterm.nerdfonts.ple_left_half_circle_thick,
key_hint_seperator = " | ",
mod_seperator = "-",
}
local hint_colors = {
key_hint_seperator = "Yellow",
key = "Green",
hint = "Red",
bg = "Black",
left_bg = "Gray",
}
local mode_colors = { bg = "Red", fg = "Black" }
local status_text = require("ui_mode").get_hint_status_text(icons, hint_colors, mode_colors)
modal.add_mode("UI", key_table, status_text)
config.keys = {
-- ...
-- your other keybindings
{
key = "u",
mods = "ALT",
action = activate_mode("UI"),
}
}
config.key_tables = modal.key_tables
Checkout the specific lua files to see the keybindings and what functionality each mode exports
To add a custom right status you can use the wezterm.format() function to create a formatted string. You can then add it as an argument when you add your mode:
local custom_status = wezterm.format({
{ Attribute = { Intensity = "Bold" } },
{ Foreground = { Color = bg } },
{ Text = wezterm.nerdfonts.ple_left_half_circle_thick },
{ Foreground = { Color = fg } },
{ Background = { Color = bg } },
{ Text = "Some custom text " },
})
modal.add_mode("mode_name", key_table, custom_status)
You should then add the text to your right status by following the steps in the next paragraph
You can use the modal.enter
and modal.exit
events to set the right status:
wezterm.on("modal.enter", function(name, window, pane)
modal.set_right_status(window, name)
modal.set_window_title(pane, name)
end)
wezterm.on("modal.exit", function(name, window, pane)
window:set_right_status("NOT IN A MODE")
modal.reset_window_title(pane)
end)
Alternatively you can show some other text in the right status by making a simple if statement in your wezterm.on
function:
wezterm.on("update-right-status", function(window, _)
if modal.get_mode(window) then -- is nil if you are not in a mode
modal.set_right_status(window)
else
-- your other status
end
end)
Thanks to github.com/twilsoft/wezmode for the inspiration to make this plugin. I have created this plugin as a lua alternative to wezmode, as I wanted to extend wezmode, but with lua instead of typescript.