romkatv/zsh4humans

Dedupe paths, ignore path patterns in alt-r dir history search

codyhan94 opened this issue · 7 comments

Would it be possible to dedupe paths stored in the stickycache and set patterns to ignore to prevent certain paths from getting added to the history?

  1. for example, bazel-bin and bazel-out directories are transient and I never want to save them.
  2. I have ~/projects symlinked to a directory at /path/to/local/disk where my home directory is mounted on NFS. Sometimes I navigate to files from ~/projects, and sometimes I navigate to them from /path/to/local/disk/.... Would it be possible to dedupe files in the list?

I added a hook in there. Try it out by adding the following line to .zshrc:

zstyle -e :z4h:dir-history: cwd 'reply=("${${PWD:A}:#*/(bazel-bin|bazel-out)}")'

Let me know whether that works for you. If it does, I'll add it to the docs.

This works great! Exactly what I expect (modulo one tiny tweak, described in next section). Paths rooted at ~ that are not symlinks still show up as ~/... while paths that contain symlinks get resolved.

I added a * after the (bazel-bin|bazel-out) pattern to ensure that the pattern matching any part of the current directory will be excluded (rather than just at the end?). I was finding that some /var/tmp/bazel-output-user-root/... directories were still getting added to the cache, as well as my bazel-bin/path/to/src directories if I navigated directly to them via a shell function that inserts bazel-bin into the correct part of my path.

So applying your commit and using

zstyle -e :z4h:dir-history: cwd 'reply=("${${PWD:A}:#*/(bazel-bin|bazel-out)*}")'

gave me exactly the behavior I expected.

Thanks for verifying.

Paths rooted at ~ that are not symlinks still show up as ~/...

That's just presentation. It's shorter.

I believe you want (|/*) instead of the plain *. The former won't match /bazel-binder while the latter will.

understood. in my case I do want to actually match those substrings in any part of the path (not just when they constitute the entirety of directory names), so I will be using the plain * formulation, but I understand why it would be appealing to specify exact path segments to exclude. I had to look up the docs to understand why (|/*) is required (so | doesn't get interpreted as a shell pipeline), but then was left wondering if this would be equivalent:

zstyle -e :z4h:dir-history: cwd 'reply=("${${PWD:A}:#*/(bazel-bin|bazel-out)/*}")'

Immediately after pasting this, I realized that this would not exclude a bazel-bin directory if it is the last part of your current path, since the / at the end is required to match now. I'll leave this comment here in case anyone else uses this feature and gets this idea.