agkozak/zsh-z

Add option to disable removal of non-existent paths

phiresky opened this issue · 5 comments

I have most of my data on a secondary drive. Since this drive is encrypted, it is not auto-mounted. Every time I run z while the drive is not mounted, all of my entries are removed, which makes it basically useless for the long term.

It would be great if an option to prevent removal would exist. This implementation might be enough:

diff --git a/zsh-z.plugin.zsh b/zsh-z.plugin.zsh
index 98e029a..8cad69f 100644
--- a/zsh-z.plugin.zsh
+++ b/zsh-z.plugin.zsh
@@ -56,6 +56,7 @@
 #     ZSHZ_NO_RESOLVE_SYMLINKS -> '1' prevents symlink resolution
 #     ZSHZ_EXCLUDE_DIRS -> array of directories to exclude from your database
 #     ZSHZ_OWNER -> your username (if you want use ZSH-z while using sudo -s) }}}
+#     ZSHZ_NO_REMOVE_NONEXIST -> '1' prevents removal of nonexistent paths from the data file
 #
 # vim: fdm=indent:ts=2:et:sts=2:sw=2:
 
@@ -198,11 +199,13 @@ _zshz_update_datafile() {
   # Load the datafile into an array
   lines=( ${(f)"$(< $datafile)"} ) 2> /dev/null
 
-  # Remove paths from database if they no longer exist
-  for line in $lines; do
-    [[ -d ${line%%\|*} ]] && existing_paths+=( $line )
-  done
-  lines=( $existing_paths )
+  if (( ! ZSHZ_NO_REMOVE_NONEXIST )); then
+    # Remove paths from database if they no longer exist
+    for line in $lines; do
+      [[ -d ${line%%\|*} ]] && existing_paths+=( $line )
+    done
+    lines=( $existing_paths )
+  fi
 
   for line in $lines; do
     path_field=${line%%\|*}

I like your idea very much, and while I have not tried your patch yet, I am sure that it will work.

I think, however, I may try to write something a little more nuanced. Perhaps there could be an array of directories to be ignored, and ZSH-z could work normally everywhere else? You could put ZSHZ_DO_NOT_REMOVE=( '/mnt/d' '/mnt/portable' ) or whatever in your .zshrc, and ZSH-z would remove directories unless they were in those specified directories.

Give me a few days and I will write something for you to try out.

And thanks for contributing!

Try the keep-dirs branch.

All you have to do is to put an array in your .zshrc that contains directories you never want removed from your database, e.g.

ZSHZ_KEEP_DIRS=( /mnt/removable_drive /mnt/usb_stick )

If you never want any directories to be removed from the database (unless you're using z -x), you can set

ZSHZ_KEEP_DIRS=( / )

Let me know what you think.

I just refined ZSHZ_KEEP_DIRS a bit. Be sure to pull the latest commit.

thanks! i'm running that branch now, and it solves my problem :)

Perhaps there could be an array of directories to be ignored, and ZSH-z could work normally everywhere else?

Actually, in my case I have the permissions of the mount point set to 000, so if the drive is not mounted accessing drive/foo/bar fails with "permission denied" - I did this so some other programs that use "file not found" don't do whatever they usually do when a directory was removed, but it's not really fool proof and many applications handle it the same as file not found (like [[ -d ). So that would be might be another way this could be implemented, but probably having an explicit whitelist ist better.

ZSHZ_KEEP_DIRS is now part of the master branch, so I'm going to close this issue. Thank you for helping to improve this plugin.