Merge from emacs-24; up to 2012-12-11T09:51:12Z!dmantipov@yandex.ru
[bpt/emacs.git] / lisp / emacs-lisp / crm.el
index 8a15bb2..f88cb0e 100644 (file)
@@ -1,7 +1,6 @@
 ;;; crm.el --- read multiple strings with completion
 
-;; Copyright (C) 1985, 1986, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1986, 1993-2013 Free Software Foundation, Inc.
 
 ;; Author: Sen Nagata <sen@eccosys.com>
 ;; Keywords: completion, minibuffer, multiple elements
 ;; a single prompt, optionally using completion.
 
 ;; Multiple strings are specified by separating each of the strings
-;; with a prespecified separator character.  For example, if the
-;; separator character is a comma, the strings 'alice', 'bob', and
+;; with a prespecified separator regexp.  For example, if the
+;; separator regexp is ",", the strings 'alice', 'bob', and
 ;; 'eve' would be specified as 'alice,bob,eve'.
 
-;; The default value for the separator character is the value of
-;; `crm-default-separator' (comma).  The separator character may be
+;; The default value for the separator regexp is the value of
+;; `crm-default-separator' (comma).  The separator regexp may be
 ;; changed by modifying the value of `crm-separator'.
 
 ;; Contiguous strings of non-separator-characters are referred to as
 ;;   first revamped version
 
 ;;; Code:
-(defconst crm-default-separator ","
-  "Default separator for `completing-read-multiple'.")
+(defconst crm-default-separator "[ \t]*,[ \t]*"
+  "Default separator regexp for `completing-read-multiple'.")
 
 (defvar crm-separator crm-default-separator
-  "Separator used for separating strings in `completing-read-multiple'.
-It should be a single character string that doesn't appear in the list of
-completion candidates.  Modify this value to make `completing-read-multiple'
-use a separator other than `crm-default-separator'.")
+  "Separator regexp used for separating strings in `completing-read-multiple'.
+It should be a regexp that does not match the list of completion candidates.
+Modify this value to make `completing-read-multiple' use a separator other
+than `crm-default-separator'.")
 
 (defvar crm-local-completion-map
   (let ((map (make-sparse-keymap)))
@@ -144,7 +143,7 @@ nil if none.
 
 The value of FLAG is used to specify the type of completion operation.
 A value of nil specifies `try-completion'.  A value of t specifies
-`all-completions'.  A value of lambda specifes a test for an exact match.
+`all-completions'.  A value of lambda specifies a test for an exact match.
 
 For more information on STRING, PREDICATE, and FLAG, see the Elisp
 Reference sections on 'Programmed Completion' and 'Basic Completion
@@ -174,13 +173,17 @@ Place an overlay on the element, with a `field' property, and return it."
     (overlay-put ol 'field (make-symbol "crm"))
     ol))
 
+(defmacro crm--completion-command (command)
+  "Make COMMAND a completion command for `completing-read-multiple'."
+  `(let ((ol (crm--select-current-element)))
+     (unwind-protect
+         ,command
+       (delete-overlay ol))))
+
 (defun crm-completion-help ()
   "Display a list of possible completions of the current minibuffer element."
   (interactive)
-  (let ((ol (crm--select-current-element)))
-    (unwind-protect
-        (minibuffer-completion-help)
-      (delete-overlay ol)))
+  (crm--completion-command (minibuffer-completion-help))
   nil)
 
 (defun crm-complete ()
@@ -189,19 +192,13 @@ If no characters can be completed, display a list of possible completions.
 
 Return t if the current element is now a valid match; otherwise return nil."
   (interactive)
-  (let ((ol (crm--select-current-element)))
-    (unwind-protect
-        (minibuffer-complete)
-      (delete-overlay ol))))
+  (crm--completion-command (minibuffer-complete)))
 
 (defun crm-complete-word ()
   "Complete the current element at most a single word.
 Like `minibuffer-complete-word' but for `completing-read-multiple'."
   (interactive)
-  (let ((ol (crm--select-current-element)))
-    (unwind-protect
-        (minibuffer-complete-word)
-      (delete-overlay ol))))
+  (crm--completion-command (minibuffer-complete-word)))
 
 (defun crm-complete-and-exit ()
   "If all of the minibuffer elements are valid completions then exit.
@@ -223,11 +220,23 @@ This function is modeled after `minibuffer-complete-and-exit'."
                      (setq doexit nil))
                  (goto-char (overlay-end ol))
                  (delete-overlay ol))
-               (not (eobp))))
+               (not (eobp)))
+             (looking-at crm-separator))
       ;; Skip to the next element.
-      (forward-char 1))
+      (goto-char (match-end 0)))
     (if doexit (exit-minibuffer))))
 
+(defun crm--choose-completion-string (choice buffer base-position
+                                             &rest ignored)
+  "Completion string chooser for `completing-read-multiple'.
+This is called from `choose-completion-string-functions'.
+It replaces the string that is currently being completed, without
+exiting the minibuffer."
+  (let ((completion-no-auto-exit t)
+        (choose-completion-string-functions nil))
+    (choose-completion-string choice buffer base-position)
+    t))
+
 ;; superemulates behavior of completing_read in src/minibuf.c
 ;;;###autoload
 (defun completing-read-multiple
@@ -238,12 +247,12 @@ By using this functionality, a user may specify multiple strings at a
 single prompt, optionally using completion.
 
 Multiple strings are specified by separating each of the strings with
-a prespecified separator character.  For example, if the separator
-character is a comma, the strings 'alice', 'bob', and 'eve' would be
+a prespecified separator regexp.  For example, if the separator
+regexp is \",\", the strings 'alice', 'bob', and 'eve' would be
 specified as 'alice,bob,eve'.
 
-The default value for the separator character is the value of
-`crm-default-separator' (comma).  The separator character may be
+The default value for the separator regexp is the value of
+`crm-default-separator' (comma).  The separator regexp may be
 changed by modifying the value of `crm-separator'.
 
 Contiguous strings of non-separator-characters are referred to as
@@ -259,22 +268,28 @@ The return value of this function is a list of the read strings.
 See the documentation for `completing-read' for details on the arguments:
 PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT, HIST, DEF, and
 INHERIT-INPUT-METHOD."
-  (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)))
-    (and def (string-equal input "") (setq input def))
-    (split-string input crm-separator)))
+  (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)))
+         (and def (string-equal input "") (setq input def))
+         (split-string input crm-separator)))
+    (remove-hook 'choose-completion-string-functions
+                'crm--choose-completion-string)))
 
 (define-obsolete-function-alias 'crm-minibuffer-complete 'crm-complete "23.1")
 (define-obsolete-function-alias
@@ -304,5 +319,4 @@ INHERIT-INPUT-METHOD."
 
 (provide 'crm)
 
-;; arch-tag: db1911d9-86c6-4a42-b32a-4910701b15a6
 ;;; crm.el ends here