Subject: Re: bug#19504: 11.88; [siunitx] unit appears without backslash

From: Mosè Giordano <[email-masked]>
Date: Tue, 14 Apr 2015 23:16:56 +0200

Hello,

here is my take to fix the bug: there are three different versions of
`TeX-completing-read-multiple' as suggested by Tassilo.  I'm just not
sure it works with all 24.* versions of Emacs.  A serious problem is
that there are a couple of internal functions (crm--*), and we had
problems  in the past with internal functions,[1] for which we still
get bug reports nowadays.

Actually, the change by Roland Winkler which caused this bug is the
same which forced us to make `TeX-completing-read-multiple' always
return nil,[2] so perhaps we could also revert that change, but in
this way we would break backward compatibility in turn.

Bye,
Mosè

Note:

[1]  http://comments.gmane.org/gmane.emacs.aquamacs.devel/240
[2]  http://comments.gmane.org/gmane.emacs.auctex.devel/3375

2015-03-12 23:05 GMT+01:00 Mosè Giordano <[email-masked]>:
> Hi Tassilo,
>
> 2015-03-12 9:51 GMT+01:00 Tassilo Horn <[email-masked]>:
>> Mosè Giordano <[email-masked]> writes:
>>
>>>> PS: The plan is actually to move the minibuffer completion in that
>>>> direction for normal minibuffer completion, so that TAB is bound to
>>>> completion-at-point in the minibuffer as well.
>>>
>>> Uh, thanks for the suggestion, but according to git blame
>>> `completion-at-point' exists since 2009, so Emacs <23 is left out.
>>
>> Sorry, I didn't follow this issue closely.  But isn't it the case that
>> some quite recent change in Emacs is the culprit?
>
> Yes, with this commit
> http://git.savannah.gnu.org/gitweb/?p=emacs.git;a=commitdiff;h=9c44569ea2a18099307e0571d523d8637000a153
> `completing-read-multiple' ignores empty strings, which was essential
> for completion of `siunitx' units.
>
>> In that case,
>> `TeX-completing-read-multiple' could have 3 versions instead of the
>> current two (one for Emacs, one for XEmacs), i.e., one for Emacs <= 22,
>> one for Emacs 23+, and one for XEmacs.
>
> As I said some messages ago, the best I can think is to copy the last
> Emacs implementation before the mentioned commit (making sure return
> value for empty input is always nil) for all Emacs versions, so we
> should be able to keep the number of versions of
> `TeX-completing-read-multiple' as low as two.  The problem will be of
> course some more work on our side to maintain the function, if needed.
>
> Bye,
> Mosè
diff --git a/tex.el b/tex.el
index 394814e..3b54d79 100644
--- a/tex.el
+++ b/tex.el
@@ -716,18 +716,57 @@ overlays."
 edit-utils >= 2.32 for XEmacs.")))
 
 (if (fboundp 'completing-read-multiple)
-    (defun TeX-completing-read-multiple
-	(prompt table &optional predicate require-match initial-input
-		hist def inherit-input-method)
-      "Like `completing-read-multiple' which see.
-Ensures that empty input results in nil across different emacs versions."
-      (let ((result (completing-read-multiple prompt table predicate
-					      require-match initial-input
-					      hist def inherit-input-method)))
-	(if (equal result '("")) nil result)))
+    (if (< emacs-major-version 24)
+	;; GNU Emacs < 24
+	(defun TeX-completing-read-multiple
+	    (prompt table &optional predicate require-match initial-input
+		    hist def inherit-input-method)
+	  "Like `completing-read-multiple' which see.
+Ensures that empty input results is nil across different emacs versions."
+	  (let ((result (completing-read-multiple prompt table predicate
+						  require-match initial-input
+						  hist def inherit-input-method)))
+	    (if (equal result '("")) nil result)))
+      ;; GNU Emacs >= 24
+      (defun TeX-completing-read-multiple
+	  (prompt table &optional predicate require-match initial-input
+		  hist def inherit-input-method)
+	"Like `completing-read-multiple' which see.
+Ensures that empty input results is nil across different emacs versions."
+	;; Based on implementation in lisp/emacs-lisp/crm.el in Emacs git
+	;; revision 327f1f6f6d934e58921179275547b2d09f219f32 (Sun, 17 Mar 2013
+	;; 00:19:09 +0000)
+	(unwind-protect
+	    (progn
+	      (add-hook 'choose-completion-string-functions
+			'crm--choose-completion-string)
+	      (let* ((minibuffer-completion-table #'crm--collection-fn)
+		     (minibuffer-completion-predicate predicate)
+		     ;; see completing_read in src/minibuf.c
+		     (minibuffer-completion-confirm
+		      (unless (eq require-match t) require-match))
+		     (crm-completion-table table)
+		     (map (if require-match
+			      crm-local-must-match-map
+			    crm-local-completion-map))
+		     ;; If the user enters empty input, `read-from-minibuffer'
+		     ;; returns the empty string, not DEF.
+		     (input (read-from-minibuffer
+			     prompt initial-input map
+			     nil hist def inherit-input-method))
+		     resul)
+		(and def (string-equal input "") (setq input def))
+		;; Make sure to return nil with empty input.
+		(if (equal (setq result (split-string input crm-separator))
+			   '(""))
+		    nil
+		  result)))
+	  (remove-hook 'choose-completion-string-functions
+		       'crm--choose-completion-string))))
+  ;; XEmacs
   (defun TeX-completing-read-multiple
-    (prompt table &optional predicate require-match initial-input
-	    hist def inherit-input-method)
+      (prompt table &optional predicate require-match initial-input
+	      hist def inherit-input-method)
     "Poor mans implementation of Emacs' `completing-read-multiple' for XEmacs.
 The XEmacs package edit-utils-2.32 includes `crm.el'."
     (multi-prompt (if (boundp 'crm-separator) crm-separator ",") nil prompt