Subject: bug#60464: 29.0.60; Regression - pcomplete-arg fails with argument 'last

From: Gregory Heytings <[email-masked]>
Date: Sun, 01 Jan 2023 16:59:37 +0000

After working a bit more on this bug, I concluded that what Stefan 
initially suggested, to use the string representation of the value, is 
safer than trying to extract the string corresponding to the argument that 
the user typed in from the command line.

But that's not the end of the story.  The problem is that, IIUC, in 
Eshell, in a directory with .el files and without .EL files:

(1) ls *.el TAB should display all these files in *Completions*

(2) ls *.EL TAB should say "No match"

(3) ls *.el SPC TAB should display all files (not just the .el ones) in *Completions*

(4) ls *.EL SPC TAB should display all files (not just the .el ones) in *Completions*

IOW, sometimes pcomplete-arg should in fact return a list and not a single 
string value, because that's what Eshell expects (case (1) above), and 
sometimes it shouldn't.  According to my tests, a non-string value can be 
returned if and only if index is 'last'.  Hopefully, this is also what 
other users of pcomplete expect.

Can you please test the attached patch as extensively as possible, and 
report if you see regressions?

Jim, can you also try the patch and report if you see regressions?

Stefan and Eli, does that patch look right to you?

Thanks.
From ee2877018b1cdb93f11fffc89b9dd4ed461fcc96 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <[email-masked]>
Date: Sun, 1 Jan 2023 16:47:36 +0000
Subject: [PATCH] Further improvement for non-string values in pcomplete

* lisp/pcomplete.el (pcomplete-arg): Use the string representation
of the argument value instead of the text representation of the
argument.  Return the value, even when it is not a string, when
index is 'last'.  Fixes bug#60464.
---
 lisp/pcomplete.el | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 5bee515246..bce9aa5b4d 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -648,10 +648,10 @@ pcomplete-arg
 accessing absolute argument positions.
 
 When the argument has been transformed into something that is not
-a string by `pcomplete-parse-arguments-function', the text
-representation of the argument, namely what the user actually
-typed in, is returned, and the value of the argument is stored in
-the pcomplete-arg-value text property of that string."
+a string by `pcomplete-parse-arguments-function' and INDEX is not
+`last', the string representation of that value is returned, and
+the value is stored in the pcomplete-arg-value text property of
+that string."
   (let ((arg
          (nth (+ (pcase index
 	           ('first 0)
@@ -659,12 +659,10 @@ pcomplete-arg
 	           (_      (- pcomplete-index (or index 0))))
 	         (or offset 0))
               pcomplete-args)))
-    (if (stringp arg)
+    (if (or (stringp arg)
+            (eq index 'last))
         arg
-      (propertize
-       (buffer-substring (pcomplete-begin index offset)
-                         (pcomplete-begin (1- (or index 0)) offset))
-       'pcomplete-arg-value arg))))
+      (propertize (format "%S" arg) 'pcomplete-arg-value arg))))
 
 (defun pcomplete-begin (&optional index offset)
   "Return the beginning position of the INDEXth argument.
-- 
2.39.0