about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/contrib.yo12
-rw-r--r--Functions/Chpwd/cdr37
3 files changed, 48 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index ae61df68d..2e31d243b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-14  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 36856: Doc/Zsh/contrib.yo, Functions/Chpwd/cdr: add -p and -P
+	options to cdr for pruning the directory list.
+
 2015-10-11  Barton E. Schaefer  <schaefer@zsh.org>
 
 	* 36841: Completion/Base/Widget/_complete_help: factor out and
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 635f9b010..d367d8b0f 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -415,6 +415,18 @@ newlines, where I have in any case no sympathy); directories are in
 unabbreviated from and contain an absolute path, i.e. they start with tt(/).
 Usually the first entry should be left as the current directory.
 )
+item(tt(-p ')var(pattern)tt('))(
+Prunes any items in the directory list that match the given extended glob
+pattern; the pattern needs to be quoted from immediate expansion on the
+command line.  The pattern is matched against each completely expanded
+file name in the list; the full string must match, so wildcards at the
+end (e.g. tt('*removeme*')) are needed to remove entries with a given
+substring.
+
+If output is to a terminal, then the function will print the new list
+after pruning and prompt for confirmation by the user.  This output and
+confirmation step can be skipped by using tt(-P) instead of tt(-p).
+)
 enditem()
 
 subsect(Configuration)
diff --git a/Functions/Chpwd/cdr b/Functions/Chpwd/cdr
index 4f399106b..4bed88b13 100644
--- a/Functions/Chpwd/cdr
+++ b/Functions/Chpwd/cdr
@@ -51,6 +51,13 @@
 # (and only /).  Usually the first entry should be left as the current
 # directory.
 #
+# "cdr -p 'pattern'" prunes anything matching the given extended glob
+# pattern from the directory list.  The match is against the fully
+# expanded directory path and the full string must match (use wildcards
+# at the ends if needed).  If output is going to a terminal, the
+# function will print the new list for the user to confrim; this can be
+# skipped by giving -P instead of -p.
+#
 # Details of directory handling
 # =============================
 #
@@ -217,11 +224,11 @@ setopt extendedglob
 
 autoload -Uz chpwd_recent_filehandler chpwd_recent_add
 
-integer list set_reply i bad edit
-local opt dir
+integer list set_reply i bad edit force_prune
+local opt dir prune
 local -aU dirs
 
-while getopts "elr" opt; do
+while getopts "elp:P:r" opt; do
   case $opt in
     (e)
     edit=1
@@ -231,6 +238,12 @@ while getopts "elr" opt; do
     list=1
     ;;
 
+    ([pP])
+    prune=$OPTARG
+    edit=1
+    [[ $opt = P ]] && force_prune=1
+    ;;
+
     (r)
     set_reply=1
     ;;
@@ -278,10 +291,22 @@ if [[ $PWD != $reply[1] ]]; then
 fi
 
 if (( edit )); then
-  local compcontext='directories:directory:_path_files -/'
-IFS='
+  if [[ -n $prune ]]; then
+    reply=(${reply:#$~prune})
+    if [[ force_prune -eq 0 && -t 1 ]]; then
+      print -nrl "New list:" $reply 'Accept? '
+      if ! read -q; then
+	print
+	return 1
+      fi
+      print
+    fi
+  else
+    local compcontext='directories:directory:_path_files -/'
+    IFS='
 ' vared reply || return 1
-chpwd_recent_filehandler $reply
+  fi
+  chpwd_recent_filehandler $reply
 fi
 
 # Skip current directory if present (may have been pruned).