[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

:CHOOSE-MULTIPLE functionality of TV:CHOOSE-VARIABLE-VALUES



    Date: Fri, 15 Sep 89 09:42:00 cdt
    From: bcsaic!HUNTSAI!rodney@beaver.cs.washington.edu (Rodney Daughtrey)

    Anyone know how or have a way to implement the functionality of the
    :CHOOSE-MULTIPLE option to TV:CHOOSE-VARIABLE-VALUES in an analogous
    DW facility (such as DW:ACCEPT-VALUES, DW:ACCEPT-VARIABLE-VALUES, etc)?
    What's the cleanest/most elegant solution?

The closest thing seems to be the SUBSET presentation type.  It doesn't
provide a way to specify a displayed form of each item distinct from the
item itself, but this is easy enough to do in your own code after ACCEPT
returns the strings.  Here's a simple function that does it:

(defun choose-multiple (alist &rest accept-options)
  (let ((result (apply #'accept `((subset .,(mapcar #'car alist))) accept-options)))
    (mapcar #'(lambda (item) (cdr (assoc item alist))) result)))

(dw:accepting-values (*query-io*)
  (choose-multiple '(("Foo" . :foo) ("Bar" . :bar) ("Baz" . :baz))
		   :prompt "Enter"))
Enter: 1Foo0  Bar  1Baz
0<ABORT> aborts, <END> uses these values
(:BAZ :FOO)

The only problem with this is specifying the default, since the SUBSET
presentation type is comparing the elements of the :DEFAULT list to the
elements of the set using EQL, and you don't get EQL string when you
type a similar string.  You can work around it by using #n= and #n#, but
here's a version that handles :DEFAULT specially, allowing you to
specify the items rather than the strings:

(defun choose-multiple (alist &rest accept-options
			&key (default nil default-p) &allow-other-keys)
  (flet ((inverse-map-keywords (keywords)
	   (mapcar #'(lambda (item) (car (rassoc item alist))) keywords)))
    (when default-p
      (setq default (inverse-map-keywords default)))
    (let ((result (apply #'accept `((subset .,(mapcar #'car alist)))
			 (append (and default-p `(:default ,default))
				 accept-options))))
      (mapcar #'(lambda (item) (cdr (assoc item alist))) result))))

(dw:accepting-values (*query-io*)
  (choose-multiple '(("Foo" . :foo) ("Bar" . :bar) ("Baz" . :baz))
		   :prompt "Enter" :default '(:foo :baz)))

It probably wouldn't be too hard to implement this as a new presentation
type.

                                                barmar