I set my $HISTFILE env var to something custom, and my zsh is indeed writing to the new histfile.

But when using up-arrow or other history-searching capabilities, it still reads from ~/.zsh_history.

Ie if I open a new shell, and press up-arrow directly, I will get the last line written to ~/.zsh_history :(

I use oh-my-zsh (with osx brew celery gem git-flow npm pip screen vi-mode last-working-dir docker), and here are the setopts that I use:

# zsh options
setopt appendhistory autocd beep extendedglob nomatch notify
setopt extended_history
setopt hist_expire_dups_first
setopt hist_ignore_dups # ignore duplication command history list
setopt hist_ignore_space
setopt hist_verify
setopt inc_append_history
setopt share_history # share command history data
setopt autopushd pushdminus pushdsilent pushdtohome pushdignoredups
setopt auto_name_dirs
setopt multios
setopt cdablevarS
setopt prompt_subst
setopt long_list_jobs
setopt correct_all
setopt auto_menu         # show completion menu on succesive tab press
setopt complete_in_word
setopt completealiases
setopt always_to_end
setopt chaselinks
#stop pissing me off when using ! in line
unsetopt banghist    

# The following lines were added by compinstall
zstyle :compinstall filename '/Users/alex/.zshrc'

# Already in ohmyzsh
#autoload -Uz compinit
# End of lines added by compinstall

# Key bindings, vi, etc.
autoload -U edit-command-line
zle -N edit-command-line
bindkey -M vicmd 'v' edit-command-line

# create a zkbd compatible hash;
# to add other keys to this hash, see: man 5 terminfo
typeset -A key


# setup key accordingly
[[ -n "${key[Home]}"    ]]  && bindkey  "${key[Home]}"    beginning-of-line
[[ -n "${key[BackSpace]}" ]]  &&  bindkey "${key[BackSpace]}" backward-delete-char
[[ -n "${key[BackSpace]}" ]] &&  bindkey -M vicmd "${key[BackSpace]}" backward-delete-char
bindkey '^H' backward-delete-char
bindkey -M vicmd '^H' backward-delete-char
bindkey "^?" backward-delete-char
bindkey -M vicmd "^?" backward-delete-char
[[ -n "${key[End]}"     ]]  && bindkey  "${key[End]}"     end-of-line
[[ -n "${key[Insert]}"  ]]  && bindkey  "${key[Insert]}"  overwrite-mode
[[ -n "${key[Delete]}"  ]]  && bindkey  "${key[Delete]}"  delete-char
[[ -n "${key[Delete]}"  ]]  && bindkey -M vicmd "${key[Delete]}"  delete-char

[[ -n "${key[Left]}"    ]]  && bindkey  "${key[Left]}"    backward-char
[[ -n "${key[Right]}"   ]]  && bindkey  "${key[Right]}"   forward-char

[[ -n "${key[Up]}"   ]]  && bindkey  "${key[Up]}"    history-beginning-search-backward && bindkey -M vicmd "${key[Up]}"    history-beginning-search-backward
[[ -n "${key[Down]}" ]]  && bindkey  "${key[Down]}"  history-beginning-search-forward && bindkey -M vicmd "${key[Down]}"  history-beginning-search-forward

bindkey -M vicmd 'h'  backward-char
bindkey -M vicmd 'l'  forward-char
bindkey -M vicmd '^R' redo
bindkey -M vicmd 'u'  undo
bindkey -M vicmd 'ga' what-cursor-position
bindkey -M vicmd 'v'  edit-command-line

# Finally, make sure the terminal is in application mode, when zle is
# active. Only then are the values from $terminfo valid.
if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
    function zle-line-init () {
        printf '%s' "${terminfo[smkx]}"
    function zle-line-finish () {
        printf '%s' "${terminfo[rmkx]}"
    zle -N zle-line-init
    zle -N zle-line-finish
  • What happens when you do Ctrl+R backward search? – Augustin Riedinger Mar 2 '16 at 9:47

Setting HISTFILE in your zsh configuration really should change to where the history is written and from where it is read. It is likely that oh-my-zsh sets HISTFILE=~/.zsh_history before you set it, in which case the history has already been read from ~/.zsh_history.

Looking at the oh-my-zsh code, there are two ways to solve this:

  • set HISTFILE before loading oh-my-zsh. That is, it has to be set in your ~/.zshrc before the line containing

    source $ZSH/oh-my-zsh.sh

    This would be a simple solution, if you only want to change HISTFILE.

  • overload the history.zsh module with your own custom version. Oh-my-zsh loads all files matching $ZSH/lib/*.zsh (where $ZSH usually is ~/.oh-my-zsh) at startup, unless in ${ZSH_CUSTOM}/lib/ is a file with the same name (ZSH_CUSTOM usually is $ZSH/custom). The history settings can be found in $ZSH/lib/history.zsh and can therefore replaced by ${ZSH_CUSTOM}/lib/history.zsh.

    If you want to change more of the settings found in $ZSH/lib/history.zsh this is probably the way to go. Otherwise you would have to set HISTFILE before loading oh-my-zsh and everything else after.

A way to change HISTFILE (temporarily) later in a shell session is

fc -p /path/to/new_history

This puts the current history on a stack, sets HISTFILE=/path/to/new_history and reads the history from that file (if it exists). Any new commands will then also be written to the new HISTFILE. You can go back to the original history with fc -P.

  • Excellent. The fc -p solution is the one I use now. I will later dig deeper in the zsh builtins. – lajarre Mar 6 '16 at 17:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.