this post was submitted on 15 Oct 2025
1 points (60.0% liked)

ShareGPT

88 readers
1 users here now

To share LLM text output that others might find interesting.

founded 2 years ago
MODERATORS
 

You can approximate per-directory history in zsh using plugins or custom hooks. The shell itself doesn’t support this natively (though patches have been proposed). (zsh.org)

Here are viable methods:


Method 1: Use the “per-directory-history” plugin (Oh My Zsh or standalone)

  • Oh My Zsh includes a plugin called per-directory-history. (GitHub)
  • To enable it, add per-directory-history to your plugins=( … ) in ~/.zshrc. (Unix & Linux Stack Exchange)
  • The plugin arranges that commands are saved to both a global history file and to per-directory-history files (mirroring the directory tree under a base history directory). (Jim Hester)
  • There is a toggle (default key binding Ctrl-G) to switch between viewing global history and directory-specific history. (GitHub)
  • You can configure base dir for per-directory history via a variable like HISTORY_BASE. (GitHub)

Method 2: Use another plugin or custom “cwd-history” approach


Method 3: DIY using hooks (zshaddhistory / chpwd)

If you want to roll your own:

  1. In your ~/.zshrc, set a base directory to store local histories, e.g.:

    export DIRHIST_BASE="$HOME/.dirhist"
    
  2. Use chpwd hook (runs on each cd) to switch HISTFILE:

    function chpwd_set_histfile() {
      local dir_rel="${PWD/#$HOME\//}"  # directory relative to home
      local histf="${DIRHIST_BASE}/${dir_rel}/.zsh_history"
      mkdir -p "$(dirname "$histf")"
      HISTFILE="$histf"
    }
    autoload -U add-zsh-hook
    add-zsh-hook chpwd chpwd_set_histfile
    
  3. Optionally, when starting the shell (at prompt or init), you may want to load the relevant directory history:

    if [[ -n $PWD ]]; then
      chpwd_set_histfile
      fc -R  # read history from the new HISTFILE
    fi
    
  4. You may also want to duplicate commands into a global history file (so you don’t lose cross-dir commands). You can use the zshaddhistory function to append each new command to a global log as well. Example:

    function zshaddhistory() {
      local cmd=${1%%$'\n'}  # strip newline
      print -sr -- "$cmd"   # to current HISTFILE
      print -s -- "$cmd" >> "$HOME/.zsh_global_history"
      return 1  # prevent double logging by default handler
    }
    

Caveats:

  • You must manage HISTSIZE, SAVEHIST, trimming, etc.
  • If you have concurrent shells in the same directory, they write to the same file.
  • Performance may degrade if you have many directories with deep trees.
  • Some plugins limit history size per directory.

If you like, I can generate a ready-to-use .zshrc snippet (or plugin setup) for your environment (Linux/macOS). Do you prefer plugin-based or DIY?

top 4 comments
sorted by: hot top controversial new old
[–] PumpkinDrama@reddthat.com 2 points 2 months ago (1 children)

Is fuzzy search a better alternative to exact reverse-search in Zsh?

[–] PumpkinDrama@reddthat.com 2 points 2 months ago

Absolutely! Instead of implementing per-directory command history, you can enhance your Zsh experience by integrating fuzzy search for command history. This approach offers several advantages:

  • Fuzzy Matching: Allows you to recall commands even if you don't remember the exact syntax.

  • Efficiency: Enables quick searching through your command history, saving time.

  • Simplicity: Doesn't require complex configurations or additional plugins.

To implement this, you can use the fzf (fuzzy finder) tool in combination with Zsh's reverse search functionality. Here's how you can set it up:

  1. Install fzf: If you haven't already, install fzf by running:

    git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
    ~/.fzf/install
    
  2. Configure Reverse Search: Add the following to your ~/.zshrc to bind Ctrl+R to an fzf-powered reverse search:

    source ~/.fzf.zsh
    

    This configuration replaces the default reverse search with a more powerful fuzzy search.

  3. Optional - Customize Key Bindings: If you prefer a different key binding, you can modify the bindkey settings in your ~/.zshrc. For example, to bind Ctrl+S to the reverse search:

    bindkey '^S' fzf-history-widget
    

By following these steps, you'll have a fuzzy search integrated into your Zsh history, allowing for more efficient command recall without the need for per-directory history setups.

Let me know if you need further assistance with this setup!

[–] PumpkinDrama@reddthat.com 1 points 2 months ago (1 children)

Would you recommend using a per-directory history setup, or is it more trouble than it’s worth?

[–] PumpkinDrama@reddthat.com 1 points 2 months ago

It depends on how you work and how much benefit you'd get vs overhead. Here’s a breakdown to help you decide.


Pros

  1. Easier recall in project contexts When you're working in a particular directory (project), your relevant commands are grouped. You don’t sift through unrelated commands.

  2. Cleaner history per context Less “noise” when using reverse-search (Ctrl-R) or browsing history while in a directory.

  3. Better separation If you work on many unrelated things, per-directory history isolates each context.

  4. Toggle flexibility Some plugins allow toggling between global and per-directory history. (e.g. the per-directory-history plugin in Oh My Zsh) (Unix & Linux Stack Exchange)


Cons / Costs

  1. Implementation complexity / maintenance burden You’ll need to manage hooks (chpwd, zshaddhistory), directory tree creation, collisions, trimming histories, etc.

  2. Cross-shell or concurrent sessions issues Two shells in the same directory may write to the same history file -> race conditions or interleaving.

  3. Disk & file overhead Many small history files over deep directory trees will clutter your ~/.dirhist (or whatever base).

  4. Fragmentation of history Sometimes you do want to search across all your commands globally. If you forget some context, per-dir history might hide useful commands you used elsewhere.

  5. Plugin shortcomings / bugs Some users report that existing plugins don’t handle all edge cases (editing history, switching modes reliably). (Unix & Linux Stack Exchange)


Recommendation

  • If you frequently jump between multiple projects and find that global history is cluttered for you, it may be worth trying as an experiment.
  • If you’re more of a generalist user (single domain, occasional commands), the overhead probably isn’t justified.
  • Start simple: enable a mature plugin (e.g. per-directory-history) and use it for a few weeks. If you like the improvement and don’t hit issues, keep it.
  • Always keep a global history fallback (so you don’t “lose” commands irrecoverably).

If you like, I can simulate (or produce) a benchmark or user feedback comparing both setups for your workflow to see whether it's worth it for you. Do you want me to do that?