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*

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 *cmdlog-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 *cmdlog-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 *cmdlog-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 *cmdlog-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 configured risky_patterns match
    {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 ignores highlight_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 *cmdlog-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 *cmdlog-previews*

Previews depend on the command, and on preview_execute:

:edit {file}
    Shows a preview of the file if it is readable. Always available --
    reading is not running.

Everything below needs preview_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 and extra_files are 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 with preview_execute = true: an entry
matching risky_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 *cmdlog-error-highlight*

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 *cmdlog-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 *cmdlog-which-key*

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 *cmdlog-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 *cmdlog-shell*

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 *cmdlog-extra-files*

Set the extra_files option 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" },
      },
    })

history entries are combined into the Neovim-history-based pickers
(:Cmdlog nvim[-full]) and the combined pickers (:Cmdlog, :Cmdlog full);
all entries only into the latter. In the combined pickers, entries from
either list are labelled "extra" (see |cmdlog-origin-labels|).

ORIGIN LABELS *cmdlog-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 *cmdlog-privacy*

redact_patterns (Lua patterns, same shape as risky_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".
Set redact_patterns = false (or {}) to disable.

EXTENDING *cmdlog-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-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 *cmdlog-author*

Stefan Bartl