13

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 Answers 4

10

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)
2
  • 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. Commented Jun 2, 2015 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. Commented Jun 16, 2015 at 5:26
6

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.

1
  • 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. Commented Jun 2, 2015 at 15:14
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.

1
  • Link only answers are discouraged here, please add some explanation of what is/how it works. Commented Feb 16, 2016 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.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.