feat: allow sync to save the histdb path

This commit is contained in:
Viktor Varland 2026-02-17 11:51:56 +01:00
parent 010104b2dd
commit 8b34f5d367
No known key found for this signature in database
GPG key ID: 991E991EBEC46432
4 changed files with 30 additions and 39 deletions

View file

@ -11,7 +11,8 @@ mkdir histdb
cd shell-history
go build -o verbatim .
sudo install verbatim /usr/local/bin/
install verbatim ~/bin
```
## Migrate from log files
@ -42,37 +43,8 @@ _add_history() {
}
add-zsh-hook precmd _add_history
hsup() { verbatim sync "$histdb_dir" }
hs() {
local copy_cmd=
case "$(uname -s)" in
Darwin) copy_cmd="pbcopy" ;;
*)
case "$XDG_SESSION_TYPE" in
x11) copy_cmd="xsel --clipboard" ;;
wayland) copy_cmd="wl-copy --trim-newline" ;;
*) echo "Session type not detected."; return ;;
esac ;;
esac
local entry="$(
verbatim search --compact --reverse --limit 10000 "$@" | \
fzf --ansi --disabled --query "${*:-}" \
--bind "start:reload:verbatim search --compact --reverse --limit 10000 {q}" \
--bind "change:reload:sleep 0.1; verbatim search --compact --reverse --limit 10000 {q} || true" \
--bind "ctrl-a:reload:verbatim search --compact --reverse {q}" \
--header "ctrl-a: search all"
)"
local entry_cmd="$(<<<$entry sed 's/\x1b\[[0-9;]*m//g' | awk '{ print substr($0, index($0, $5)) }')"
entry_cmd="${entry_cmd//\\n/$'\n'}"
if [[ "$entry" ]]; then
eval $copy_cmd <<< "$entry_cmd" >/dev/null
echo "Copied to clipboard." >&2
fi
}
# install hs (interactive search + copy to clipboard)
install scripts/hs ~/bin
```
## Usage
@ -80,7 +52,7 @@ hs() {
```
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] sync [DIR]
verbatim [--db PATH] import DIR
verbatim [--db PATH] stats
```

View file

@ -8,7 +8,14 @@ import (
func Run(d *sql.DB) error {
var total int
d.QueryRow("SELECT COUNT(*) FROM history").Scan(&total)
fmt.Printf("Total commands: %d\n\n", total)
fmt.Printf("Total commands: %d\n", total)
var lastSync sql.NullString
d.QueryRow(`SELECT value FROM sync_meta WHERE key = 'last_sync_time'`).Scan(&lastSync)
if lastSync.Valid {
fmt.Printf("Last sync: %s\n", lastSync.String)
}
fmt.Println()
fmt.Println("Commands per host:")
rows, err := d.Query("SELECT hostname, COUNT(*) as cnt FROM history GROUP BY hostname ORDER BY cnt DESC")

View file

@ -14,11 +14,20 @@ import (
)
func Run(d *sql.DB, args []string) error {
if len(args) < 1 {
fmt.Fprintln(os.Stderr, "usage: verbatim sync DIR")
os.Exit(1)
var gitDir string
if len(args) > 0 {
gitDir = args[0]
// Store git_dir for future use
d.Exec(`INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('git_dir', ?)`, gitDir)
} else {
// Try to read stored git_dir
err := d.QueryRow(`SELECT value FROM sync_meta WHERE key = 'git_dir'`).Scan(&gitDir)
if err != nil {
fmt.Fprintln(os.Stderr, "usage: verbatim sync [DIR]")
fmt.Fprintln(os.Stderr, " DIR must be provided on first run")
os.Exit(1)
}
}
gitDir := args[0]
if err := export(d, gitDir); err != nil {
return fmt.Errorf("export: %w", err)
@ -32,6 +41,9 @@ func Run(d *sql.DB, args []string) error {
return fmt.Errorf("import: %w", err)
}
// Record last sync time
d.Exec(`INSERT OR REPLACE INTO sync_meta (key, value) VALUES ('last_sync_time', datetime('now'))`)
fmt.Println("Sync complete.")
return nil
}

View file

@ -70,7 +70,7 @@ func usage() {
commands:
add record a command
search search history
sync export, git sync, import
sync export, git sync, import (remembers DIR)
import one-time import from log files
stats show statistics`)
os.Exit(1)