simple multi-computer shell history backed by git
  • Go 79.8%
  • Shell 16.8%
  • Just 3.4%
Find a file
Claudia 0e7ca1dfac
All checks were successful
ci/woodpecker/push/build Pipeline was successful
ci: revert the changelog path filter
A workflow-level `path` condition stopped tag pipelines from being created at
all in Woodpecker 3.16 — not skipped, not errored, absent. The documentation
says path conditions are ignored for tag events; the only CI difference between
the release that built and the one that did not was this block.

It was not even doing its job: Woodpecker 3.x returns an empty changed-files
list (woodpecker-ci/woodpecker#4788) and `on_empty` defaults to true, so the
condition matched everything and the changelog commit built anyway.

Releasing is worth more than a duplicate build. The next attempt gets tried on
one repo and watched before it goes near twelve.
2026-08-06 23:57:38 +02:00
.just feat: install to the XDG bin dir 2026-08-01 23:42:51 +02:00
.woodpecker ci: revert the changelog path filter 2026-08-06 23:57:38 +02:00
internal fix: correct module path to git.meatbag.se/varl/verbatim 2026-06-25 09:28:40 +02:00
scripts docs: update wrangle regeneration command to wrangle init 2026-06-26 09:20:14 +02:00
.gitignore chore: ignore local agent settings 2026-08-01 23:55:36 +02:00
CHANGELOG.md docs: changelog for v1.2.0 2026-08-02 12:13:10 +02:00
go.mod feat: add shell completion command 2026-06-25 11:43:19 +02:00
go.sum feat: add shell completion command 2026-06-25 11:43:19 +02:00
justfile feat: install to the XDG bin dir 2026-08-01 23:42:51 +02:00
main.go feat(completion): complete search --host/--dir from history 2026-06-25 12:57:38 +02:00
README.md feat: install to the XDG bin dir 2026-08-01 23:42:51 +02:00
search.sh fix: use pbcopy on macos 2026-05-30 09:08:36 +02:00
sync.sh fix: use git union merge driver 2026-02-06 08:54:09 +01:00

verbatim

Shell history stored in SQLite, synced via git.

TODO

  • More ergonomic search hook into the shell. Currently I like having Ctrl-R as stock, and running hs when I need to go cross-machine or fuzzy searching.

Install

cd $HOME/dev/vlv
git clone git.meatbag.se:varl/verbatim.git verbatim
mkdir histdb

cd verbatim
just install    # builds and copies verbatim + scripts/hs to
                # ~/.local/bin ($XDG_BIN_HOME)

Or build manually:

go build -o verbatim .
install -d ~/.local/bin
install verbatim scripts/hs ~/.local/bin/

Migrate from log files

verbatim import ~/dev/vlv/histdb/

zsh

~/.zshrc:

autoload -Uz compinit promptinit add-zsh-hook

histdb_dir="$HOME/dev/vlv/histdb"

_add_history() {
    if test "$(id -u)" -ne 0; then
        local cmd=$(fc -ln -1)
        cmd=${cmd//$'\n'/\\n}
        verbatim add \
            --timestamp "$(date -u +%Y-%m-%dT%H:%M:%S+00:00)" \
            --hostname "$(hostname)" \
            --dir "$(pwd)" \
            -- "$cmd"
    fi
}
add-zsh-hook precmd _add_history

# install hs (interactive search)
install scripts/hs ~/bin

# bind ctrl-r to verbatim search
source /path/to/verbatim/scripts/verbatim-widget.zsh

Usage

verbatim [--db PATH] add --timestamp T --hostname H --dir D -- COMMAND...
verbatim [--db PATH] search [--host H] [--dir D] [--after T] [--before T] [--limit N] [QUERY...]
verbatim [--db PATH] sync [DIR]
verbatim [--db PATH] import DIR
verbatim [--db PATH] stats

Default --db: ~/.local/share/verbatim/history.db

Alternatives

Of course, there are many other shell history tools that are more mature, have more features, solve the same problem in a different way, etc:

Those are my favourites of the ones I considered before settling on the two legacy shell scripts (later ported to Go -- and expanded on) was the fact that I want to rely on git for syncing, and I don't want to rely on a single server.

And it's hard to beat the <1ms speed of a kernel level >> for appending a command to a file. I've accepted the trade-off of verbatim taking ~2ms to add a record to SQLite.

With Git I can choose to pull from a specific machine, or a centralised forge depending on what I feel like, so I use that for sync.

Legacy

The old shell scripts (search.sh, sync.sh) are kept for backward compatibility during migration. They continue to work with the log files in the git repo.