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

From: Gregory Heytings <[email-masked]>
Date: Wed, 04 Jan 2023 13:48:25 +0000

>> Jim, can you also try the patch and report if you see regressions?
>
> Thanks. I tried this out for a bit, and I haven't been able to break it 
> yet (although I didn't notice the issue that spawned this bug# the last 
> time either, so it's possible I'm missing some problem this time around, 
> too).
>

Thanks for your confirmation.

Stefan, do you agree with the attached patch?  Or would you like something 
else?

Eli, are you okay with that patch?

The difference between the code before dafa6d6bad and the code with this 
patch applied can be summarized as follows:

  (defun pcomplete-arg (&optional index offset)
    (let ((arg
           (nth (+ (pcase index
  	           ('first 0)
  	           ('last  pcomplete-last)
  	           (_      (- pcomplete-index (or index 0))))
  	         (or offset 0))
                pcomplete-args)))
-    arg
+    (if (or (stringp arg)
+            (eq index 'last))
+        arg
+      (propertize
+       (car (split-string (pcomplete-actual-arg index offset)))
+       'pcomplete-arg-value arg))))

IOW, instead of unconditionally returning arg, we now sometimes (when arg 
is not already a string and when index is not last) return the textual 
representation of that argument (what the user typed in) with the value of 
arg attached to it.
From e5e197a68a25315e93586db299757911862e74a8 Mon Sep 17 00:00:00 2001
From: Gregory Heytings <[email-masked]>
Date: Wed, 4 Jan 2023 13:36:04 +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.
(pcomplete-actual-arg): Move it before 'pcomplete-arg'.
---
 lisp/pcomplete.el | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 5bee515246..73e14c562b 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -632,6 +632,13 @@ pcomplete-list
 ;;; Internal Functions:
 
 ;; argument handling
+(defsubst pcomplete-actual-arg (&optional index offset)
+  "Return the actual text representation of the last argument.
+This is different from `pcomplete-arg', which returns the textual value
+that the last argument evaluated to.  This function returns what the
+user actually typed in."
+  (buffer-substring (pcomplete-begin index offset) (point)))
+
 (defun pcomplete-arg (&optional index offset)
   "Return the textual content of the INDEXth argument.
 INDEX is based from the current processing position.  If INDEX is
@@ -648,10 +655,11 @@ 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 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."
   (let ((arg
          (nth (+ (pcase index
 	           ('first 0)
@@ -659,11 +667,11 @@ 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))
+       (car (split-string (pcomplete-actual-arg index offset)))
        'pcomplete-arg-value arg))))
 
 (defun pcomplete-begin (&optional index offset)
@@ -679,13 +687,6 @@ pcomplete-begin
       (setq index (+ index offset)))
   (nth index pcomplete-begins))
 
-(defsubst pcomplete-actual-arg (&optional index offset)
-  "Return the actual text representation of the last argument.
-This is different from `pcomplete-arg', which returns the textual value
-that the last argument evaluated to.  This function returns what the
-user actually typed in."
-  (buffer-substring (pcomplete-begin index offset) (point)))
-
 (defsubst pcomplete-next-arg ()
   "Move the various pointers to the next argument."
   (setq pcomplete-index (1+ pcomplete-index)
-- 
2.39.0