Zsh-Undo-Dir
May 10, 2026 ยท View on GitHub
Undo and redo current working directory changes

How to Install
Manually:
-
Change your directory to wherever you would like to install the plugin
Example:
cd ~/.zsh/plugins -
Run these commands:
git clone https://github.com/allisnulll/zsh-undo-dir echo "source $PWD/zsh-undo-dir/zsh-undo-dir.plugin.zsh" >> $HOME/.zshrc(All this does is clone the repository and source the script at the end of your
.zshrcfile)
With a Plugin Manager:
Zinit
-
Source
zinit.zshat the start of your.zshrc(This will depend on where you installed Zinit)source /usr/share/zinit/zinit.zsh -
Use Zinit to add the plugin by adding this line to the end of your
.zshrc
zinit light allisnulll/zsh-undo-dir
Keybinds:
bindkey -M emacs "^o" undo_dir
bindkey -M vicmd "^o" undo_dir
bindkey -M viins "^o" undo_dir
bindkey -M emacs "^[[1;2P" redo_dir
bindkey -M vicmd "^[[1;2P" redo_dir
bindkey -M viins "^[[1;2P" redo_dir
The default keybinds are meant to be similar to the keymaps for jumplists in Vim, but can be mapped to whatever you want.
How to make the default keybinds work
Terminal emulators interpret Ctrl-I to be the same key as Tab. This is a problem when you want to retain the functionality of the Tab key while also binding Ctrl-I to something else. The way that I circumvent this is by having my terminal remap Ctrl-I to F13 and to map redo_dir to F13 instead.
You can run cat and press the desired key to see what characters the terminal receives. As long as it receives different characters for Tab and Ctrl-I, then they can act separately.
Example Wezterm Config:
local wezterm = require("wezterm")
local config = wezterm.config_builder()
config.keys = {{
key = "i",
mods = "CTRL",
action = wezterm.action.SendString("\x1b[1;2P"),
}}
return config