18

I am happily using zsh since a while now, and I am quite satisfied with my history settings, which are:

# Write to history immediately
setopt inc_append_history
# History shared among terminals
setopt share_history
# Save extended info in history
setopt extended_history
# Ignore duplicates
setopt hist_ignoredups

But it happens often that I need to use specific commands inside some specific directories. For example, when I am in ~/my_project I usually invoke make target1 && ./run1, but when I am in ~/second_project I usually need make target2 && cat foobar | ./run2.

That is: different directories, but similar commands.

So, I usually cd ~/my_project and type make and then search backward in the history until I find what I need. But if it happen that I worked in second_project, when searching the history I will find some commands that I do not need.

So, my question: does a plugin/setting/something exist for zsh such that, when searching in history, commands invoked in the current directory are displayed first?

Ideally, every other matching history command will appear after those, optionally specifying a max number of priority elements.

I would try to write something like this by myself, but I still do not know how to write custom zsh plugins, how to handle history and so on.

1

4 Answers 4

13

There is a plugin that claims to do exactly what you are looking for, appropriately named per directory history plugin:

https://github.com/jimhester/oh-my-zsh/commit/baa187e4b903f39422a84b580e6e617ec3738e09

"Per-directory-history - tracks previous command history both per current directory and globally, with the ability to switch between them on the fly, bound to ctrl-g." says their wiki.

I did not test it myself (yet), but according to the comments it should work.

3
  • 1
    Nice, thanks! I will try it before accepting, if you don't mind :)
    – AkiRoss
    Apr 5, 2013 at 17:07
  • 1
    Until I missed something, the plugin does not exactly what I need, in the sense that per directory and global histories are mutually switched using ctrl-g (and not by priority as I asked). Nevertheless, I still find it extremely useful and a good answer to my question, so, thanks :)
    – AkiRoss
    Apr 5, 2013 at 17:20
  • Perhaps its due to changes in ZSH, but this plugin in its current version does not seem to handle editing ZSH's history correctly.
    – Owen
    Sep 23, 2019 at 4:28
4

The current version of oh-my-zsh comes with the plug-in included. Simply add per-directory-history to the plugins list in your .zshrc:

plugins=(... per-directory-history)
3

I had the exact same issue and wrote a ZSH plugin which solves it: https://github.com/tymm/zsh-directory-history

You don't have to manually switch between global and directory history when using my plugin.

Ideally, every other matching history command will appear after those, optionally specifying a max number of priority elements.

This also works out of the box with my plugin.

0

I just wrote a small plugin that does much of what Jim Hester's plugin does, but uses a different approach that fixes many of the issues listed in that plugin's GitHub repo:

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.

So, my question: does a plugin/setting/something exist for zsh such that, when searching in history, commands invoked in the current directory are displayed first?

The zsh-cwd-history plugin doesn't currently support this, but I'm hoping to add support for it soon.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .