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
 
 ;;; 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
 
 ;; 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
 ;; 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'.
 
 ;; '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
 ;; changed by modifying the value of `crm-separator'.
 
 ;; Contiguous strings of non-separator-characters are referred to as
 ;;   first revamped version
 
 ;;; Code:
 ;;   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
 
 (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)))
 
 (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
 
 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
 
 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))
 
     (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)
 (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 ()
   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)
 
 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)
 
 (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.
 
 (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))
                      (setq doexit nil))
                  (goto-char (overlay-end ol))
                  (delete-overlay ol))
-               (not (eobp))))
+               (not (eobp)))
+             (looking-at crm-separator))
       ;; Skip to the next element.
       ;; Skip to the next element.
-      (forward-char 1))
+      (goto-char (match-end 0)))
     (if doexit (exit-minibuffer))))
 
     (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
 ;; 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
 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'.
 
 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
 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."
 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
 
 (define-obsolete-function-alias 'crm-minibuffer-complete 'crm-complete "23.1")
 (define-obsolete-function-alias
@@ -304,5 +319,4 @@ INHERIT-INPUT-METHOD."
 
 (provide 'crm)
 
 
 (provide 'crm)
 
-;; arch-tag: db1911d9-86c6-4a42-b32a-4910701b15a6
 ;;; crm.el ends here
 ;;; crm.el ends here