Subject: bug#2957: 23.0.92; ucs-insert: Completion does not work correctly with Unicode Character Name Input

From: Stefan Monnier <[email-masked]>
Date: Sat, 11 Apr 2009 09:57:36 -0400

>> BUG DESCRIPTION:
>> When I type the following:
>> C-x 8 RET greek letter alpha
>> and press TAB, I get several choices for the greek letter alpha
>> variants.  But I'm unable to type anything into the minibuffer (neither
>> SPC nor any character) -- Emacs just doesn't accept the input.

I understand that SPC would signal an error, but any normal character
should be inserted in the minibuffer just fine.  Do you really mean that
you can't type anything in the minibuffer, or just that anything you
type will later lead to a completion failure or to the error you mention:

>> If I press RET at this point, I get the error message "ucs-insert:
>> Not a Unicode character code: nil".

That looks like a (minor) bug indeed.

> This is a problem with partial-completion.
> (completing-read "Type a SPC b TAB: "
>                  '("a 1 b" "a 1 b c" "a 1 b d" "a 2 b" "a 2 b c" "a 2 b d"))
> The minibuffer contents become "a SPC SPC b", indicating that a word is
> missing between "a" and "b".  Either partial-completion should move
> point back to where the word is missing or accept SPC as input.

Actually, it's a problem with minibuffer-complete-word which sometimes
wants partial completion and sometimes doesn't.
The patch below provides an alternative way to choose between using
partial-completion and not, which is finer-grained and should fix the
above problem without reintroducing the problems it tried to fix,

        Stefan

=== modified file 'lisp/minibuffer.el'
--- lisp/minibuffer.el	2009-03-19 04:24:15 +0000
+++ lisp/minibuffer.el	2009-04-11 13:51:07 +0000
@@ -780,13 +780,13 @@
       ;; If completion finds next char not unique,
       ;; consider adding a space or a hyphen.
       (when (= (length string) (length (car comp)))
-        (let ((exts '(" " "-"))
+        ;; Mark the added char with the `completion-word' property, so it
+        ;; can be handled specially by completion styles such as
+        ;; partial-completion.
+        (let ((exts (mapcar (lambda (str) (propertize str 'completion-word t))
+                            '(" " "-")))
               (before (substring string 0 point))
               (after (substring string point))
-	      ;; Disable partial-completion for this.
-	      (completion-styles
-	       (or (remove 'partial-completion completion-styles)
-		   completion-styles))
 	      tem)
 	  (while (and exts (not (consp tem)))
             (setq tem (completion-try-completion
@@ -1598,7 +1598,13 @@
            (p 0)
            (p0 p))
 
-      (while (setq p (string-match completion-pcm--delim-wild-regex string p))
+      (while (and (setq p (string-match completion-pcm--delim-wild-regex
+                                        string p))
+                  ;; If the char was added by minibuffer-complete-word, then
+                  ;; don't treat it as a delimiter, otherwise "M-x SPC"
+                  ;; ends up inserting a "-" rather than listing
+                  ;; all completions.
+                  (not (get-text-property p 'completion-word string)))
         ;; Usually, completion-pcm--delim-wild-regex matches a delimiter,
         ;; meaning that something can be added *before* it, but it can also
         ;; match a prefix and postfix, in which case something can be added