Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: BUG: locals remove setopt autonamedirs



I think that changing AND to only work for global parameters makes perfect sense. I don't see when/how turning local parameters into named directories is useful.

AND only works in interactive mode because of this check (should that be documented in the AND description?). The effect of AND is to automatically create a named directory NAME for any parameter NAME whose value starts with a "/". Named directories are mainly useful for ~NA<TAB> completions, for ~NAME expansions, and for the shortening of absolute paths by replacing a prefix with a ~NAME.

The user can only ever perform ~NA<TAB> completions in the global context. So turning local parameters into named directories is never useful for ~NA<TAB> completions. The point of shortened paths is to eventually display them to the user who will read them in the global context. So again, local parameters are not useful. Finally, the user types commands that may contain ~NAME expansions in the global context and again local parameters are not useful. It's true that a user could write a function that contains a ~NAME expansion that depends on a local NAME parameter. However, that function would only work in interactive mode. Furthermore the user could, arguably should, in that case use $NAME. I don't think that we need to maintain AND for local parameters if that's the only argument in its favor.

Here is a patch that restricts AND to global parameters:

Only ever turn global parameters into named directories

Note that the patch is built on top of workers/54299.

Philippe

diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo
index a7e862c70..85bf0b28a 100644
--- a/Doc/Zsh/options.yo
+++ b/Doc/Zsh/options.yo
@@ -240,7 +240,7 @@ pindex(AUTONAMEDIRS)
 pindex(NOAUTONAMEDIRS)
 cindex(directories, named)
 item(tt(AUTO_NAME_DIRS))(
-Any parameter that is set to the absolute name of a directory
+Any global parameter that is set to the absolute name of a directory
 immediately becomes a name for that directory, that will be used
 by the `tt(%~)'
 and related prompt sequences, and will be available when completion
diff --git a/Src/params.c b/Src/params.c
index 461e02acf..b32beabd2 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -2778,17 +2778,10 @@ assignstrvalue(Value v, char *val, int flags)
                 strcat(x + v->start, z + v->end);
                 v->pm->gsu.s->setfn(v->pm, x);
             } else {
-		Param pm = v->pm;
                 /* Size doesn't change, can limit actions to only
                  * overwriting bytes in already allocated string */
 		memcpy(z + v->start, val, vlen);
-		/* Implement remainder of strsetfn */
-		if (!(pm->node.flags & PM_HASHELEM) &&
-		    ((pm->node.flags & PM_NAMEDDIR) ||
-		     isset(AUTONAMEDIRS))) {
-		    pm->node.flags |= PM_NAMEDDIR;
-		    adduserdir(pm->node.nam, z, 0, 0);
-		}
+                v->pm->gsu.s->setfn(v->pm, z);
             }
             zsfree(val);
 	}
@@ -2982,10 +2975,7 @@ setarrvalue(Value v, char **val)
 	}
 
 	if (pre_assignment_length == post_assignment_length
-	    && v->pm->gsu.a->setfn == arrsetfn
-	    /* ... and isn't something that arrsetfn() treats specially */
-	    && 0 == (v->pm->node.flags & (PM_SPECIAL|PM_UNIQUE))
-	    && NULL == v->pm->ename)
+	    && v->pm->gsu.a->setfn == arrsetfn)
 	{
 	    /* v->start is 0-based */
 	    p = old + v->start;
@@ -2995,6 +2985,7 @@ setarrvalue(Value v, char **val)
 		/* Give away ownership of the string */
 		*p++ = *r++;
 	    }
+	    v->pm->gsu.a->setfn(v->pm, old);
 	} else {
             /* arr+=( ... )
              * arr[${#arr}+x,...]=( ... ) */
@@ -3940,11 +3931,6 @@ unsetparam_pm(Param pm, int altflag, int exp)
     if (pm->old) {
 	oldpm = pm->old;
 	paramtab->addnode(paramtab, oldpm->node.nam, oldpm);
-	if ((PM_TYPE(oldpm->node.flags) == PM_SCALAR) &&
-	    !(pm->node.flags & PM_HASHELEM) &&
-	    (oldpm->node.flags & PM_NAMEDDIR) &&
-	    oldpm->gsu.s == &stdscalar_gsu)
-	    adduserdir(oldpm->node.nam, oldpm->u.str, 0, 0);
 	if (oldpm->node.flags & PM_EXPORTED) {
 	    /*
 	     * Re-export the old value which we removed in typeset_single().
@@ -4059,15 +4045,15 @@ strgetfn(Param pm)
 mod_export void
 strsetfn(Param pm, char *x)
 {
-    zsfree(pm->u.str);
-    pm->u.str = x;
-    if (!(pm->node.flags & PM_HASHELEM) &&
+    if (pm->u.str != x) {
+	if (pm->u.str) zsfree(pm->u.str);
+	pm->u.str = x;
+    }
+    if (!(pm->node.flags & PM_HASHELEM) && !pm->level &&
 	((pm->node.flags & PM_NAMEDDIR) || isset(AUTONAMEDIRS))) {
 	pm->node.flags |= PM_NAMEDDIR;
 	adduserdir(pm->node.nam, x, 0, 0);
     }
-    /* If you update this function, you may need to update the
-     * `Implement remainder of strsetfn' block in assignstrvalue(). */
 }
 
 /* Function to get value of an array parameter */
@@ -4087,16 +4073,15 @@ arrgetfn(Param pm)
 mod_export void
 arrsetfn(Param pm, char **x)
 {
-    if (pm->u.arr && pm->u.arr != x)
-	freearray(pm->u.arr);
+    if (pm->u.arr != x) {
+	if (pm->u.arr) freearray(pm->u.arr);
+	pm->u.arr = x;
+    }
     if (pm->node.flags & PM_UNIQUE)
 	uniqarray(x);
-    pm->u.arr = x;
     /* Arrays tied to colon-arrays may need to fix the environment */
     if (pm->ename && x)
 	arrfixenv(pm->ename, x);
-    /* If you extend this function, update the list of conditions in
-     * setarrvalue(). */
 }
 
 /* Function to get value of an association parameter */
diff --git a/Src/utils.c b/Src/utils.c
index a1d7c8cc2..eb48e2b0f 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1257,7 +1257,7 @@ getnameddir(char *name)
     /* Check if there is a scalar parameter with this name whose value *
      * begins with a `/'.  If there is, add it to the hash table and   *
      * return the new value.                                           */
-    if ((pm = (Param) paramtab->getnode(paramtab, name)) &&
+    if ((pm = (Param) paramtab->getnode(paramtab, name)) && !pm->level &&
 	    (PM_TYPE(pm->node.flags) == PM_SCALAR) &&
 	    (str = getsparam(name)) && *str == '/') {
 	pm->node.flags |= PM_NAMEDDIR;


Messages sorted by: Reverse Date, Date, Thread, Author