Subject: 28.0.92; [PATCH] Fix negated argument predicates in Eshell

From: Jim Porter <[email-masked]>
Date: Sat, 12 Mar 2022 22:34:16 -0800

From "emacs -Q --eval '(eshell)'":

   ~ $ echo *(^.)
   Lisp nesting exceeds ‘max-lisp-eval-depth’

On Emacs 27, this correctly prints a list of everything in the current 
directory *except* for regular files. ("*" matches all files, "()" 
specifies an argument predicate, "." says "match regular files", and "^" 
says "invert that logic".)

I think this is due to the lexical binding change in 28. Attached is a 
patch to fix this. No unit tests right now, but I'm working on a patch 
for 29 with full unit tests for Eshell globs and argument 
predicates/modifiers. (I pulled this bit out of my branch for that, 
since it's a regression that should probably get fixed in 28.)

Regarding the patch itself, I'm not sure if there's a cleaner way to do 
this; it feels like there should be, but this is the only way I could 
think of off-hand to fix it.
From 08c1fd35490e205a7706c94eacf12968b8253c02 Mon Sep 17 00:00:00 2001
From: Jim Porter <[email-masked]>
Date: Sat, 12 Mar 2022 22:14:19 -0800
Subject: [PATCH] Fix evaluation of negated argument predicates in Eshell

* lisp/eshell/em-pred.el (eshell-add-pred-func): Let-bind 'pred' so
the lambdas see the original value.
---
 lisp/eshell/em-pred.el | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el
index 216c71f59e..970329e12a 100644
--- a/lisp/eshell/em-pred.el
+++ b/lisp/eshell/em-pred.el
@@ -360,12 +360,12 @@ eshell-parse-modifiers
 
 (defun eshell-add-pred-func (pred funcs negate follow)
   "Add the predicate function PRED to FUNCS."
-  (if negate
-      (setq pred (lambda (file)
-		   (not (funcall pred file)))))
-  (if follow
-      (setq pred (lambda (file)
-		   (funcall pred (file-truename file)))))
+  (when negate
+    (setq pred (let ((pred pred))
+                 (lambda (file) (not (funcall pred file))))))
+  (when follow
+    (setq pred (let ((pred pred))
+                 (lambda (file) (funcall pred (file-truename file))))))
   (cons pred funcs))
 
 (defun eshell-pred-user-or-group (mod-char mod-type attr-index get-id-func)
-- 
2.25.1