about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-06-11 20:08:01 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-06-11 20:08:01 +0000
commit64d431d98b022d186aa088a295d723b2ec727b84 (patch)
treeafbefc353e804ea6728d2b0b3eb823f005e80fcd
parent48fe7377795684992cb569328e730a5954aecd74 (diff)
downloadzsh-64d431d98b022d186aa088a295d723b2ec727b84.tar.gz
zsh-64d431d98b022d186aa088a295d723b2ec727b84.tar.xz
zsh-64d431d98b022d186aa088a295d723b2ec727b84.zip
28025: (D) parameter flag
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/expn.yo28
-rw-r--r--Src/subst.c34
-rw-r--r--Src/utils.c17
4 files changed, 65 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 080d5ca6d..03a69a846 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-11  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 28025: Doc/Zsh/expn.yo, Src/subst.c, Src/utils.c: (D)
+	parameter flag to abbreviate directories.
+
 2010-06-09  Peter Stephenson  <pws@csr.com>
 
 	* Haakon Riiser: 28009: Completion/Unix/Command/_ffmpeg: new.
@@ -13267,5 +13272,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.4997 $
+* $Revision: 1.4998 $
 *****************************************************
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 2641fd61f..83a195def 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -771,6 +771,13 @@ Capitalize the resulting words.  `Words' in this case refers to sequences
 of alphanumeric characters separated by non-alphanumerics, em(not) to words
 that result from field splitting.
 )
+item(tt(D))(
+Assume the string or array elements contain directories and attempt
+to substitute the leading part of these by names.  This is the reverse
+of `tt(~)' substitution:  see
+ifnzman(noderef(Filename Expansion))\
+ifzman(the section FILENAME EXPANSION below).
+)
 item(tt(e))(
 Perform em(parameter expansion), em(command substitution) and
 em(arithmetic expansion) on the result. Such expansions can be
@@ -1199,40 +1206,43 @@ item(tt(13.) em(Quote application))(
 Any quoting or unquoting using tt((q)) and tt((Q)) and related flags
 is applied.
 )
-item(tt(14.) em(Visibility enhancment))(
+item(tt(14.) em(Directory naming))(
+Any directory name substitution using tt((D)) flag is applied.
+)
+item(tt(15.) em(Visibility enhancment))(
 Any modifications to make characters visible using the tt((V)) flag
 are applied.
 )
-item(tt(15.) em(Forced Splitting))(
+item(tt(16.) em(Forced Splitting))(
 If one of the `tt((s))', `tt((f))' or `tt((z))' flags are present, or the `tt(=)'
 specifier was present (e.g. tt(${=)var(var)tt(})), the word is split on
 occurrences of the specified string, or (for tt(=) with neither of the two
 flags present) any of the characters in tt($IFS).
 )
-item(tt(16.) em(Shell Word Splitting))(
+item(tt(17.) em(Shell Word Splitting))(
 If no `tt((s))', `tt((f))' or `tt(=)' was given, but the word is not
 quoted and the option tt(SH_WORD_SPLIT) is set, the word is split on
 occurrences of any of the characters in tt($IFS).  Note this step, too,
 takes place at all levels of a nested substitution.
 )
-item(tt(17.) em(Uniqueness))(
+item(tt(18.) em(Uniqueness))(
 If the result is an array and the `tt((u))' flag was present, duplicate
 elements are removed from the array.
 )
-item(tt(18.) em(Ordering))(
+item(tt(19.) em(Ordering))(
 If the result is still an array and one of the `tt((o))' or `tt((O))' flags
 was present, the array is reordered.
 )
-item(tt(19.) em(Re-Evaluation))(
+item(tt(20.) em(Re-Evaluation))(
 Any `tt((e))' flag is applied to the value, forcing it to be re-examined
 for new parameter substitutions, but also for command and arithmetic
 substitutions.
 )
-item(tt(20.) em(Padding))(
+item(tt(21.) em(Padding))(
 Any padding of the value by the `tt(LPAR()l.)var(fill)tt(.RPAR())' or
 `tt(LPAR()r.)var(fill)tt(.RPAR())' flags is applied.
 )
-item(tt(21.) em(Semantic Joining))(
+item(tt(22.) em(Semantic Joining))(
 In contexts where expansion semantics requires a single word to
 result, all words are rejoined with the first character of tt(IFS)
 between.  So in `tt(${LPAR()P)tt(RPAR()${LPAR()f)tt(RPAR()lines}})'
@@ -1241,7 +1251,7 @@ joined again before the tt(P) flag can be applied.
 
 If a single word is not required, this rule is skipped.
 )
-item(tt(22.) em(Empty argument removal))(
+item(tt(23.) em(Empty argument removal))(
 If the substitution does not appear in double quotes, any resulting
 zero-length argument, whether from a scalar or an element of an array,
 is elided from the list of arguments inserted into the command line.
diff --git a/Src/subst.c b/Src/subst.c
index 304add6f9..2543c7cce 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1459,14 +1459,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
      */
     int quotemod = 0, quotetype = QT_NONE, quoteerr = 0;
     /*
-     * (V) flag: fairly straightforward, except that as with so
-     * many flags it's not easy to decide where to put it in the order.
+     * Various fairly straightforward modifications, except that as with so
+     * many flags it's not easy to decide where to put them in the order.
+     * bit 0: (D) flag.
+     * bit 1: (V) flag.
      */
-    int visiblemod = 0;
+    int mods = 0;
     /*
      * The (z) flag, nothing to do with SH_WORD_SPLIT which is tied
      * spbreak, see above; fairly straighforward in use but c.f.
-     * the comment for visiblemod.
+     * the comment for mods.
      */
     int shsplit = 0;
     /*
@@ -1514,7 +1516,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
      */
     int aspar = 0;
     /*
-     * The (%) flag, c.f. visiblemod again.
+     * The (%) flag, c.f. mods again.
      */	
     int presc = 0;
     /*
@@ -1678,8 +1680,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
 		    indord = 1;
 		    break;
 
+		case 'D':
+		    mods |= 1;
+		    break;
 		case 'V':
-		    visiblemod++;
+		    mods |= 2;
 		    break;
 
 		case 'q':
@@ -2954,19 +2959,26 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
     }
     /*
      * Transform special characters in the string to make them
-     * printable.
+     * printable, or to show directories, or possibly even both.
      */
-    if (visiblemod) {
+    if (mods) {
 	if (isarr) {
 	    char **ap;
 	    if (!copied)
 		aval = arrdup(aval), copied = 1;
-	    for (ap = aval; *ap; ap++)
-		*ap = nicedupstring(*ap);
+	    for (ap = aval; *ap; ap++) {
+		if (mods & 1)
+		    *ap = substnamedir(*ap);
+		if (mods & 2)
+		    *ap = nicedupstring(*ap);
+	    }
 	} else {
 	    if (!copied)
 		val = dupstring(val), copied = 1;
-	    val = nicedupstring(val);
+	    if (mods & 1)
+		val = substnamedir(val);
+	    if (mods & 2)
+		val = nicedupstring(val);
 	}
     }
     /*
diff --git a/Src/utils.c b/Src/utils.c
index 184b2f354..379f9f738 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -766,6 +766,23 @@ fprintdir(char *s, FILE *f)
     }
 }
 
+/*
+ * Substitute a directory using a name.
+ * If there is none, return the original argument.
+ */
+
+/**/
+char *
+substnamedir(char *s)
+{
+    Nameddir d = finddir(s);
+
+    if (!d)
+	return s;
+    return zhtricat("~", d->node.nam, s + strlen(d->dir));
+}
+
+
 /* Returns the current username.  It caches the username *
  * and uid to try to avoid requerying the password files *
  * or NIS/NIS+ database.                                 */