MLFlexer/modal.wezterm
{ "createdAt": "2024-04-17T17:13:36Z", "defaultBranch": "main", "description": "Vim-like modal keybindings for your terminal! ✌️", "fullName": "MLFlexer/modal.wezterm", "homepage": "", "language": "Lua", "name": "modal.wezterm", "pushedAt": "2025-06-30T13:32:49Z", "stargazersCount": 99, "topics": [ "keybind", "keybindings", "modal", "plugin", "vim", "wezterm" ], "updatedAt": "2025-11-24T03:21:41Z", "url": "https://github.com/MLFlexer/modal.wezterm"}modal.wezterm
Section titled “modal.wezterm”Vim-like modal keybindings for your terminal! ✌️
Overview
Section titled “Overview”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.
Default Copy/Visual/Search mode
Section titled “Default Copy/Visual/Search mode”Improvements to Wezterms CopyMode with vim keybindings
Default UI mode
Section titled “Default UI mode”Default modes
Section titled “Default modes”I have included some default modes which are opt-in as to improve performance for all users.
Copy mode, with Search and Visual submodes
Section titled “Copy mode, with Search and Visual submodes”
UI mode
Section titled “UI mode”UI mode has vim-like bindings to navigate and modify panes, tabs and other UI elements.
Scroll mode
Section titled “Scroll mode”In scroll mode you can scroll with familiar vim bindings.
It is recommended to do the setup with some [Customization]!(#Customization). However if you just want to try it out you can follow the [Preset]!(#Preset)
Preset
Section titled “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)modal.set_default_keys(config)This will add the keybindings to enter and exit modes:
ALT-uto enter UI mode from normal modeALT-cto enter Copy mode from normal modevto enter visual mode from Copy mode/to enter search mode from Copy modeALT-nto enter Scroll mode from normal modeescorCTRL-cto leave current non-normal mode
Checkout the [keybinding descriptions]!(/defaults/keybinds.md)
Customization
Section titled “Customization”- 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 tablelocal 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 textlocal 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)Configuration
Section titled “Configuration”Enabling default modes
Section titled “Enabling default modes”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 directorylocal 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_tablesCheckout the specific lua files to see the keybindings and what functionality each mode exports
Adding custom right status text
Section titled “Adding custom right status text”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
Update right status on mode change
Section titled “Update right status on mode change”Recommended: Using enter and exit events
Section titled “Recommended: Using enter and exit events”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)Using the wezterm.on(“update-right-status”, …) event
Section titled “Using the wezterm.on(“update-right-status”, …) event”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 endend)Credits
Section titled “Credits”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.