Show HN: Smarter Shell History for Zsh

overflowy1 pts0 comments

GitHub - overflowy/zhist: Smarter shell history for zsh · GitHub

/" data-turbo-transient="true" />

Skip to content

Type / to search

Sign in<br>Sign upAppearance settings

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

overflowy

zhist

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>30 Commits<br>30 Commits

.github/workflows

.github/workflows

.gitignore

.gitignore

LICENSE

LICENSE

README.md

README.md

go.mod

go.mod

main.go

main.go

store.go

store.go

store_test.go

store_test.go

View all files

Repository files navigation

zhist

A shell history tool for zsh, written in Go. It records every command with its<br>working directory and exit status. It replaces the zsh history file as the<br>persistent store.

zhist.mp4

Purpose

Native zsh history stores a command and a timestamp, nothing else. zhist stores<br>context: where you ran a command and whether it failed. The fzf picker uses<br>that context. Failed commands show in red. One key toggles between global<br>history and the current directory's history.

Install

go install github.com/overflowy/zhist@latest

Requires fzf 0.45 or newer for the picker.

Setup

Add to .zshrc:

eval "$(zhist init)"

Import existing history once:

zhist import ~/.zsh_history

Imported entries have no directory or exit status. They show a blank directory<br>and never render red.

Keys

Key<br>Action

ctrl-r<br>Open the history picker

up / down<br>Open the picker on an empty line; otherwise step line history

ctrl-g<br>Toggle global / current-directory history

ctrl-d<br>Delete the selected entry

ctrl-x<br>Delete all entries with the same command

tab<br>Accept and leave the command on the line

Ignoring commands

Define a HIST_EXCLUDE array in .zshrc to keep commands out of the store.<br>zhist skips a command when its first word is in the array.

HIST_EXCLUDE=(cd ls clear pwd exit)

Matching is exact and case-sensitive, on the first word only. ls skips<br>ls -la but not lsd.

For multiline commands the first word of the first line decides.

The hook reads the array at record time. Change it in a running shell and<br>the change applies to the next command.

A leading space also skips recording, for one-off exclusions.

Recommended zsh history settings

zhist owns persistence. Keep native history in memory only, for line stepping<br>and ! expansion within a session.

unset HISTFILE # macOS /etc/zshrc sets it; unset stops zsh reading or writing the file<br>HISTSIZE=100000 # In-memory events for up-arrow and ! expansion<br>SAVEHIST=0 # Never write a history file

setopt BANG_HIST # Treat the '!' character specially during expansion<br>setopt HIST_IGNORE_DUPS # Don't record an entry that was just recorded again<br>setopt HIST_IGNORE_ALL_DUPS # Delete old recorded entry if new entry is a duplicate<br>setopt HIST_FIND_NO_DUPS # Do not display a line previously found<br>setopt HIST_IGNORE_SPACE # Don't record an entry starting with a space<br>setopt HIST_REDUCE_BLANKS # Remove superfluous blanks before recording entry<br>setopt HIST_VERIFY # Do not execute immediately upon history expansion

Do not set SHARE_HISTORY, INC_APPEND_HISTORY, or EXTENDED_HISTORY. They<br>only affect the history file, which zhist replaces.

Compatibility notes:

Commands with a leading space are not recorded. This matches HIST_IGNORE_SPACE.

eval "$(zhist init)" must run after plugins that bind ctrl-r or the<br>arrow keys (atuin, zsh-history-substring-search, prompt pickers). The last<br>bind wins.

The record hook prepends itself to precmd_functions and passes $?<br>through. Prompts that read the exit status in their own precmd keep working.

CLI

zhist init Print the zsh integration script<br>zhist add -dir D -exit N Append an entry; command read from stdin<br>zhist list [-dir D] Print entries for fzf, newest first, deduplicated<br>zhist get -id ID Print the full command for an entry<br>zhist delete -id ID [-all] Delete an entry, or all entries with its command<br>zhist import FILE Import a zsh EXTENDED_HISTORY file

About<br>Smarter shell history for zsh<br>Topics<br>clifzfgolanghistoryshellshell-historyterminalzsh<br>Resources<br>Readme<br>MIT license<br>Activity<br>Stars<br>4 stars<br>Watchers<br>0 watching<br>Forks<br>0 forks<br>Report repository

Releases

Used by

Contributors

Languages

You can’t perform that action at this time.

history zhist command entry file setopt

Related Articles