cmdlog.nvim · Debug & inspect · vimdoc
:help cmdlog
Interactive command-line history viewer for Neovim
doc/cmdlog.txt — rendered from the plugin's own vimdoc
*cmdlog.txt* Interactive command-line history viewer for Neovim *cmdlog.nvim*
CMDLOG
cmdlog.nvim is a lightweight Neovim plugin that provides interactive access to Neovim command-line (:) history and shell history using a fuzzy picker UI. It integrates with Telescope.nvim or fzf-lua and allows searching, previewing, favoriting, and reusing past commands. This plugin focuses on inspection and reuse of existing history entries. Commands are inserted into the command-line but are never executed automatically.
FEATURES
- Interactive listing of Neovim command-line (:) history - Optional integration of shell history (bash, zsh, fish, nu, ksh, csh, PowerShell) - Picker backend selection: - Telescope.nvim (default, with previews) - fzf-lua (minimal, fast; previews on POSIX only, none on Windows) - Favorites system with persistent storage, plus custom tags - Favorites: undo the last toggle, and manually reorder entries - Favorites export/import (:Cmdlog export/import), for backup or migrating between machines - Privacy filter (redact_patterns): commands matching a pattern (password, token, Bearer, ...) are never recorded to disk - extra_files: fold your own plain-text command files into the pickers as additional read-only history sources - Origin labels (nvim/shell/extra) in the combined pickers - Rotate between pickers without leaving the prompt (mappings.cycle_source), keeping whatever you've typed so far - Generated key legend in the Telescope picker title - Project-local history, scoped to the current Git root - Dedicated Lua-mode history view - Command usage stats (frequency, last used) - Known-error highlighting (Telescope only) - Risky-command highlighting, with :Cmdlog risky test to tune the patterns - Optional which-key.nvim integration for user-defined keymaps - Non-destructive command reuse (insert only, no auto-exec) - Extensible picker infrastructure for custom pickers
REQUIREMENTS
Required plugins:
- lib.nvim (required: the :Cmdlog command layer is built on
lib.nvim.bindings.usercmd.composer; also supplies the
cross-platform fs/notify/job helpers)
- telescope.nvim (required when picker = "telescope")
- fzf-lua (required when picker = "fzf")
SETUP
The plugin is configured via a setup() call.
Example:
lua require("cmdlog").setup({
picker = "telescope",
keymaps = {
[""] = "<leader>ch",
favorites = "<leader>cf",
},
})
Options are validated before the merge: an unknown key (top level, or
inside extra_files/project_scoped/mappings/shell_history) is dropped with a
did-you-mean hint rather than silently surviving as a dead field, and a
non-table value for one of those four falls back to its default. A known
key with a value outside its accepted range (currently just picker)
likewise falls back to its default instead of being used as-is. All three
are reported via vim.notify and again by :checkhealth cmdlog.
Available options:
picker Picker backend to use.
Values: "telescope" (default), "fzf", "fzf-lua"
("fzf-lua" is an alias for "fzf")
track_commands Record every ':' command via a single CmdlineLeave
autocmd, feeding project history, usage stats and
error tracking. Default: true
redact_patterns Lua patterns (string.find, like risky_patterns).
Commands matching any of these are never recorded
by track_commands -- not to project history, stats,
or the error log. Security feature: those files are
plaintext under stdpath("data").
Default: { "password", "secret", "token", "Bearer",
"api[-_]?key" }. Set to false/{} to disable.
extra_files { history = {...}, all = {...} } lists of extra
plain-text command files (one command per line,
read-only). history entries are folded into the
Neovim-history-based pickers and the combined
pickers; all entries only into the latter.
Default: { history = {}, all = {} }
keymaps Map of :Cmdlog subcommand name ("" for bare
:Cmdlog) to a normal-mode lhs. Registered with
vim.keymap.set and, when which-key.nvim is
installed, also passed to its add() so
descriptions show up there. Default: {} (none)
mappings Keys bound inside a picker (Telescope only; the
fzf-lua backend binds <CR> and nothing else).
Set any entry to false to disable it, or
mappings.enabled = false to disable all of them.
Defaults: select <CR>, toggle_favorite <Tab>,
refresh <C-r>, delete <C-x>, toggle_selection
<C-Space>, tag <C-t>, cycle_source <C-s>,
undo_favorite <C-z>, move_favorite_up <C-Up>,
move_favorite_down <C-Down>.
project_scoped { enabled = false }. When enabled, favorites are
kept in a separate file per Git project instead of
one global file. Outside a Git repository the
global file is used either way.
shell_history { parse, matches } escape hatch for a shell-history
format the built-in parsers cannot read. Both
halves belong together: setting parse without
matches makes deletion refuse rather than let the
built-in matcher guess. Default: {} (built-ins).
preview_execute Whether a picker's preview may run an entry.
Default: false -- see |cmdlog-previews|.
highlight_risky Highlight commands matching risky_patterns with
the CmdlogRiskyCommand group. Default: true.
risky_patterns Lua patterns naming destructive commands (rm -rf,
git reset --hard, git push --force, qa!, ...).
Set to false or {} to disable. Test a pattern with
|:Cmdlog-risky-test|.
favorites_path Path to the favorites JSON file.
favorite_tags_path Path to the favorite-tags JSON file.
project_history_path Path to the per-project history JSON file.
stats_path Path to the usage-stats JSON file.
errors_path Path to the known-error-commands JSON file.
COMMANDS
One command, :Cmdlog [subcommand], built via lib.nvim.bindings.usercmd.composer (https://github.com/StefanBartl/lib.nvim) with <Tab> completion on the subcommand. :Cmdlog *:Cmdlog* Bare invocation (no subcommand). Show favorites and history combined. Only unique commands are shown; duplicates are removed. :Cmdlog favorites *:Cmdlog-favorites* Show only commands marked as favorites. :Cmdlog full *:Cmdlog-full* Show favorites and full history. Duplicate commands are allowed. :Cmdlog nvim *:Cmdlog-nvim* Show only Neovim (:) commands. Only unique commands are shown; the latest occurrence is kept. :Cmdlog nvim-full *:Cmdlog-nvim-full* Show full Neovim (:) command history, including duplicates. :Cmdlog shell *:Cmdlog-shell* Show shell history entries. Only unique commands are shown; the latest occurrence is kept. :Cmdlog shell-full *:Cmdlog-shell-full* Show full shell history, including duplicates. :Cmdlog project *:Cmdlog-project* Show command history recorded while working inside the current Git project (deduplicated). Only commands run since track_commands was enabled are recorded. Requires being inside a Git repository. :Cmdlog lua *:Cmdlog-lua* Show only Lua-mode command history (:lua, :lua=, :=), deduplicated. :Cmdlog stats *:Cmdlog-stats* Show commands sorted by usage frequency (most-used first), annotated with "used Nx, last <date>". :Cmdlog risky test {command} *:Cmdlog-risky-test* Not a picker. Report which of the configuredrisky_patternsmatch {command}, so the list can be tuned without guessing from picker colours. The whole rest of the line is the command under test, not a quoted argument. Matching ignoreshighlight_risky(which gates display, not evaluation) and the output says so when it is off. :Cmdlog export [{path}] *:Cmdlog-export* Export favorites to a JSON file. {path} defaults to the favorites file's own path with a ".export.json" suffix. :Cmdlog import {path} *:Cmdlog-import* Import favorites from a JSON file, merging with the current list (existing favorites kept, new ones appended, deduplicated).
PICKER USAGE
Inside the picker, the following mappings are available (Telescope
insert mode; a generated legend of the active ones also shows in the
prompt title). All are configurable via mappings -- see |cmdlog-setup|.
These keys are Telescope's. Under picker = "fzf" exactly one action is
bound, <CR>, and it runs the selected command instead of inserting it;
no favorite toggle, no tag, no delete.
<CR> Insert the selected command into the command-line.
The command is not executed automatically.
<Tab> Toggle favorite status for the selected command.
<C-r> Refresh the picker contents.
<C-x> Delete the selected entry -- or every marked one -- from its
underlying history: Neovim's ':' history via histdel(), or
the shell history file, which is rewritten on disk after a
confirmation prompt. mappings.delete.
<C-Space> Mark/unmark an entry for a batch delete, then move down. A
batch asks once instead of once per command.
mappings.toggle_selection.
<C-t> (favorites picker only) Prompt for a tag and attach it to
the selected command. mappings.tag.
<C-s> Rotate to the next picker (nvim -> shell -> favorites ->
project -> nvim ...), keeping whatever you've typed so far.
mappings.cycle_source.
<C-z> Undo the most recent favorite toggle. mappings.undo_favorite.
<C-Up> (favorites picker only) Move the selected favorite one slot
up in the persisted order. mappings.move_favorite_up.
<C-Down> (favorites picker only) Move the selected favorite one slot
down in the persisted order. mappings.move_favorite_down.
COMMAND PREVIEWS
Previews depend on the command, and onpreview_execute: :edit {file} Shows a preview of the file if it is readable. Always available -- reading is not running. Everything below needspreview_execute = true, which is off by default. With it off, the preview shows the command line and a note saying why it was not run. The default is off because previewing is a browse action -- moving the cursor down a list -- and the entries are not necessarily your own: shell history andextra_filesare folded in. :!{shell-command} Simulates shell command output for supported shells. :term[inal] [{cmd}] Runs {cmd} and shows its output; with no argument, notes that the command opens an interactive terminal buffer with no static preview. :help {topic} Renders the help page via a headless Neovim instance. :lua {expr} Evaluates {expr} in-process (no subprocess) and shows the result. Two things are refused even withpreview_execute = true: an entry matchingrisky_patterns, and an argument that could end the command it is interpolated into (a '|' in a :help topic was a working injection). When using fzf-lua, the same previews are available on POSIX systems (Linux/macOS); Windows has no fzf-lua preview, since its preview mechanism runs an external shell command that has no reliable Windows equivalent.
KNOWN-ERROR HIGHLIGHTING
When a command's last execution set a non-empty v:errmsg, it is recorded (core/errors.lua) and subsequently shown with a leading marker and an ErrorMsg highlight in the Telescope backend. Not available in the fzf-lua backend, since fzf-lua entries double as the value fed back to actions.
FAVORITE TAGS
Favorites can be tagged with free-form labels, stored separately from favorites.json so the favorites format itself never changes. Tags are shown next to each favorite in the picker. See core/tags.lua.
WHICH-KEY INTEGRATION
Set the keymaps setup option to register normal-mode keymaps for any
:Cmdlog subcommand. When which-key.nvim is installed, the same mappings
are also passed to its add() so their descriptions appear there.
See lua/cmdlog/integrations/which_key.lua.
FAVORITES
Favorites are stored persistently on disk.
Default location:
~/.local/share/cmdlog/favorites.json
On Windows, the path resolves via stdpath("data").
Favorites are shared across all Neovim sessions.
Undo the most recent toggle with <C-z> (mappings.undo_favorite). In the
favorites picker, reorder entries manually with <C-Up>/<C-Down>
(mappings.move_favorite_up/down) -- the persisted list order is what
determines display order there.
Use :Cmdlog export [path] / :Cmdlog import path to back up favorites or
move them between machines; see |:Cmdlog-export| and |:Cmdlog-import|.
SHELL HISTORY
Shell history is read from standard history files, depending on the shell: - zsh ~/.zsh_history - bash ~/.bash_history - fish ~/.local/share/fish/fish_history - nu ~/.config/nushell/history.txt - ksh ~/.ksh_history - csh ~/.history - pwsh %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt The plugin only reads these files and never modifies them.
EXTRA FILES
Set theextra_filesoption to fold your own plain-text command files (one command per line) into the pickers as additional read-only history sources -- no favorites/tags/delete support, just listed alongside Neovim/shell history: lua require("cmdlog").setup({ extra_files = { history = { "~/my_global_history.txt" }, all = { "~/my_favs.txt" }, }, })historyentries are combined into the Neovim-history-based pickers (:Cmdlog nvim[-full]) and the combined pickers (:Cmdlog, :Cmdlog full);allentries only into the latter. In the combined pickers, entries from either list are labelled "extra" (see |cmdlog-origin-labels|).
ORIGIN LABELS
The combined pickers (:Cmdlog, :Cmdlog full) show where each non-favorite
entry came from -- "nvim", "shell", or "extra" (from extra_files) --
next to the command, using picker_utils' opts.label hook. Favorites are
already distinguished by the ★ marker and carry no origin label.
PRIVACY FILTER
redact_patterns(Lua patterns, same shape asrisky_patterns) is checked in core/tracker.lua before anything is written: a command matching any pattern is never recorded to project history, usage stats, or the error log. Those files are plaintext JSON under stdpath("data"), so this matters for e.g.:!curl -H "Authorization: Bearer ...". Default patterns: "password", "secret", "token", "Bearer", "api[-_]?key". Setredact_patterns = false(or{}) to disable.
EXTENDING
cmdlog.nvim is designed to be extensible. Utility helpers are provided in picker_utils.lua to simplify the creation of custom pickers. Custom pickers can reuse sorting, preview, and action logic without reimplementing common behavior. See the /docs directory in the repository for developer-oriented guides.
Run `:checkhealth cmdlog` to verify dependencies (telescope.nvim/fzf-lua
depending on picker) and shell-history detection.
NOTES
- cmdlog.nvim relies on Neovim's persisted command-line history (shada).
Ensure that the 'shada' option includes ':' to enable command history
persistence.
- Commands are never executed automatically by this plugin.
- Multiple concurrent Neovim instances may affect history ordering.
AUTHOR
Stefan Bartl