diff lisp/auctex/multi-prompt.el @ 24:4103f0995bd7 r19-15b95

Import from CVS: tag r19-15b95
author cvs
date Mon, 13 Aug 2007 08:51:03 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/auctex/multi-prompt.el	Mon Aug 13 08:51:03 2007 +0200
@@ -0,0 +1,138 @@
+;;; multi-prompt.el --- completing read of multiple strings.
+
+;; Copyright (C) 1996, 1997 Per Abrahamsen.
+
+;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
+;; Keywords: extensions
+;; Version: 0.2
+;; Bogus-Bureaucratic-Cruft: How 'bout ESR and the LCD people agreed
+;; 	on a common format?
+
+;; LCD Archive Entry:
+;; multi-prompt|Per Abrahamsen|abraham@dina.kvl.dk|
+;; completing read of multiple strings|
+;; 1996-08-31|0.1|~/functions/multi-prompt.el.Z|
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;; 
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;; 
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, write to the Free Software
+;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;; This package is written for use in emacs lisp programs, where the
+;; user is prompted for a string of the form:
+;;
+;;   FOO,BAR,BAZ
+;;
+;; where FOO, BAR, and BAZ are elements of some table.  The function
+;; `multi-prompt' is a replacement `completing-read' that will allow
+;; the user to enter a string like the above, yet get completion on
+;; both FOO, BAR, and BAZ.
+
+;;; Change Log:
+;;
+;; Sat Feb 15 17:58:31 MET 1997
+;;      * Version 0.2 released.
+;;        Renamed predicate to `mp-predicate'.
+;; Sat Aug 31 18:32:20 MET DST 1996
+;;      * Version 0.1 released.
+;;        Fixed `predicate' bug.  
+;;        Added provide.
+;;        Added `multi-prompt-found' variable.
+;; Sat Aug 31 16:29:14 MET DST 1996
+;;      * Created.
+
+;;; Code:
+
+(provide 'multi-prompt)
+
+(defvar multi-prompt-found nil
+  "List of entries currently added during a `multi-prompt'.")
+
+(defun multi-prompt (separator
+		     unique prompt table
+		     &optional mp-predicate require-match initial history)
+  "Completing prompt for a list of strings.  
+The first argument SEPARATOR should be the string (of length 1) to
+separate the elements in the list.  The second argument UNIQUE should
+be non-nil, if each element must be unique.  The remaining elements
+are the arguments to `completing-read'.  See that."
+  (let ((old-map (if require-match
+		     minibuffer-local-must-match-map
+		   minibuffer-local-completion-map))
+	(new-map (make-sparse-keymap)))
+    (if (fboundp 'set-keymap-parent)
+	;; `set-keymap-parent' was introduced in Emacs 19.32.
+	(set-keymap-parent new-map old-map)
+      (setq new-map (copy-keymap old-map)))
+    (define-key new-map separator (if require-match
+				      'multi-prompt-next-must-match
+				    'multi-prompt-next))
+    (define-key new-map "\C-?" 'multi-prompt-delete)
+    (let* ((minibuffer-local-completion-map new-map)
+	   (minibuffer-local-must-match-map new-map)
+	   (multi-prompt-found nil)
+	   (done nil)
+	   (filter (cond (unique
+			  (lambda (x)
+			    (and (not (member (car x) multi-prompt-found))
+				 (or (null mp-predicate)
+				     (funcall mp-predicate x)))))
+			 (mp-predicate)))
+	   (answer (catch 'multi-prompt-exit
+		     (while t
+		       (let ((extra (catch 'multi-prompt-next
+				      (throw 'multi-prompt-exit
+					     (completing-read prompt 
+							      table
+							      filter
+							      require-match
+							      initial
+							      history)))))
+			 (cond ((eq extra 'back)
+				(when multi-prompt-found
+				  (setq prompt (substring 
+						prompt 0 
+						(- 0 (length separator)
+						   (length
+						    (car multi-prompt-found))))
+					initial (car multi-prompt-found))
+				  (setq multi-prompt-found 
+					(cdr multi-prompt-found))))
+			       (t
+				(setq prompt (concat prompt extra separator)
+				      initial nil)
+				(setq multi-prompt-found
+				      (cons extra multi-prompt-found)))))))))
+      (if answer 
+	  (nreverse (cons answer multi-prompt-found))
+	multi-prompt-found))))
+
+(defun multi-prompt-delete ()
+  (interactive)
+  (if (bobp)
+      (throw 'multi-prompt-next 'back)
+    (call-interactively 'backward-delete-char)))
+
+(defun multi-prompt-next ()
+  (interactive)
+  (throw 'multi-prompt-next
+	 (buffer-substring-no-properties (point-min) (point-max))))
+
+(defun multi-prompt-next-must-match ()
+  (interactive)
+  (if (call-interactively 'minibuffer-complete)
+      (throw 'multi-prompt-next
+	     (buffer-substring-no-properties (point-min) (point-max)))))
+
+;;; multi-prompt.el ends here