10

Is there a way to make a modern shell's history feature be scoped to a path?

My working contexts are split up as paths on the file system, and the pattern of shell activity, such as repeatedly issued commands, tends to be distinct to each 'project'. It would be nice if I could scope the history feature to commands issued from the current path (or sub-path).

4

With zsh, you could do:

mkdir -p ~/.zsh/dirhist

And add to your ~/.zshrc:

HISTSIZE=1000
SAVEHIST=10000
setopt HIST_SAVE_NO_DUPS INC_APPEND_HISTORY
HISTFILE=~/.zsh/dirhist/${PWD//\//@}
chpwd() {
  [[ $PWD = $OLDPWD ]] || fc -Pp ~/.zsh/dirhist/${PWD//\//@}
}

chpwd() is called whenever the current directory changes. There, we reset the history file to something like ~/.zsh/dirhist/@foo@bar when you cd to /foo/bar.

  • I like this approach, as it doesn't require changing my shell usage habits, and in the few days of testing it seems fare well. – sohocoke Jun 2 '15 at 15:14
9

Not a neat answer but an alternative if you're using bash as your shell: you could createt some alias in your .bashrc.

For instance:

alias a='cd /tmp/A ; history -w ; history -c ; export HISTFILE=/home/user/.a_history ; history -r $HISTFILE'
alias b='cd /tmp/B ; history -w ; history -c ; export HISTFILE=/home/user/.b_history ; history -r $HISTFILE'

Then, if you type a:

  1. you will be moved in your project directory
  2. the current history will be saved (history -w)
  3. then the history kept in memory will be reset (history -c)
  4. the project history file will be set to /home/user/.a_history and read (history -r)
  • I realise my question had omitted a wish / requirement, sorry for the missing detail. Namely: I'd prefer not to have to remember to use aliases / functions; i.e. the scoping should work as an add-on to the way I normally interact with the shell. – sohocoke Jun 2 '15 at 15:15
  • Don't export HISTFILE. There's no reason to export it to other programs, and ~/.bashrc is executed for every interactive bash process, so your code for setting it is going to be run in every bash anyway. In general, if a shell-defined variable isn't exported by default, you rarely should export it. – Chris Page Jun 16 '15 at 5:26
1

If you are using ZSH, take a look at this small plugin I recently wrote to handle this:

https://github.com/ericfreese/zsh-cwd-history

It stores a separate HISTFILE for every directory you've executed commands in, and adds a chpwd hook to switch between HISTFILEs when you change directories.

It also provides a zle widget you can bind to a keypress that will toggle the HISTFILE between your original "global" HISTFILE and the HISTFILE for your current working directory.

It was originally based on Jim Hester's per-directory-history plugin, but has since been rewritten from the ground up to fix many of the issues with that plugin.

  • Link only answers are discouraged here, please add some explanation of what is/how it works. – user79743 Feb 16 '16 at 6:38
0

I wrote a ZSH plugin which does what you want: https://github.com/tymm/zsh-directory-history

In contrast to other solutions my plugin falls back to the global history automatically. That means that you don't have to switch between directory history and global history.

However the other solutions are a little more lightweight I guess.

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.