reingold@m.cs.uiuc.edu (02/08/90)
I need a function read-number that would behave like (interactive "n"); that is, it would keep trying until a numeric value was typed. Any suggestions?
eliot@phoenix.Princeton.EDU (Eliot Handelman) (02/08/90)
In article <4300068@m.cs.uiuc.edu> reingold@m.cs.uiuc.edu writes:
;
;I need a function read-number that would behave like (interactive "n");
;that is, it would keep trying until a numeric value was typed.
;
;Any suggestions?
How's about this:
(defun read-number (number)
(interactive "nNumber: ")
number)
kjones@talos.uu.net (Kyle Jones) (02/08/90)
reingold@m.cs.uiuc.edu writes: > I need a function read-number that would behave like (interactive "n"); > that is, it would keep trying until a numeric value was typed. [ Assuming GNU emacs here... ] Yah, I had to code this one myself. I don't know if a function like this should be standard in the distribution or not. Common Lisp's elephantiasis is largely due to adopting functions from everyone's toolbox. Anyway, here's the function. (defun read-number (prompt &optional initial-input) "Read a number from the minibuffer prompting with PROMPT. If non-nil, the optional second argument INITIAL-INPUT should be a string to insert into the minibuffer before reading." (let (result) (while (null result) (setq result (read-string prompt initial-input)) (if (string-match "^ *-?[0-9]+" result) (setq result (string-to-int result)) (setq result nil))) result ))
jr@bbn.com (John Robinson) (02/08/90)
In article <4300068@m.cs.uiuc.edu>, reingold@m.cs writes: > >I need a function read-number that would behave like (interactive "n"); >that is, it would keep trying until a numeric value was typed. In article <1990Feb8.132524.1694@talos.uu.net>, kjones@talos (Kyle Jones) writes: >Yah, I had to code this one myself. I don't know if a function like >this should be standard in the distribution or not. Common Lisp's >elephantiasis is largely due to adopting functions from everyone's >toolbox. [defun omited]. It occurred to me that you could generalize Kyle's function into somthing like: (read-thing prompt checker-function &optional initial-contents) which asks for a lisp object until it gets one with the right type, as passed by the checker-function. Maybe ought to be a macro, or should accept symbols like 'integer, 'string instead of a function name and dispatch on them. In article <13690@phoenix.Princeton.EDU>, eliot@phoenix (Eliot Handelman) writes: >How's about this: > >(defun read-number (number) > (interactive "nNumber: ") > number) Yeah, my initial reaction too. This requires the additional observation that, to call it from inside lisp code, you need to say: (call-interactively 'read-number) ... and there is no easy way to pass it a prompt at run time. For that, you would probably want to replace the defined function in the call-interactively with a lambda-expression, but I'm not sure it is possible to get the (interactive) part right if you do. Or (ugh) evaluate the defun inside the caller... -- /jr, nee John Robinson Life did not take over the globe by combat, jr@bbn.com or bbn!jr but by networking -- Lynn Margulis
ange@hplb.hpl.hp.com (Andy Norman) (02/09/90)
>>>>> On 8 Feb 90 01:40:30 GMT, reingold@m.cs.uiuc.edu said:
ed> I need a function read-number that would behave like (interactive "n");
ed> that is, it would keep trying until a numeric value was typed.
Well, this is absolutely disgusting, but it might do what you want:
(defun read-number (&optional prompt)
(call-interactively (list 'lambda
'(num)
(list 'interactive
(concat "n" prompt))
'num)))
If you don't want a prompt, it becomes much easier:
(defun read-number ()
(call-interactively '(lambda (num) (interactive "n") num)))
Hope this helps...
--
-- ange --
ange@hplb.hpl.hp.com
reingold@m.cs.uiuc.edu (02/09/90)
Here is the best suggestion I received (from Dale Worley): (defun read-integer (prompt) "Read an integer from the minibuffer, prompting with PROMPT." (let ((value)) (while (not (integerp value)) (setq value (read-minibuffer prompt))) value))
merlyn@iwarp.intel.com (Randal Schwartz) (02/09/90)
In article <1990Feb8.132524.1694@talos.uu.net>, kjones@talos (Kyle Jones) writes: | > I need a function read-number that would behave like (interactive "n"); | > that is, it would keep trying until a numeric value was typed. | [ Assuming GNU emacs here... ] | Yah, I had to code this one myself. I don't know if a function like | this should be standard in the distribution or not. Common Lisp's | elephantiasis is largely due to adopting functions from everyone's | toolbox. [code deleted] why not just: (defun rls-read-number () "read a number from the keyboard" (call-interactively (function (lambda (arg) (interactive "n") arg)))) Okay, so, it's cheating. :-) Just another GNU emacs hacker, -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
merlyn@iwarp.intel.com (Randal Schwartz) (02/09/90)
In article <51906@bbn.COM>, jr@bbn (John Robinson) writes: | ... and there is no easy way to pass it a prompt at run time. For | that, you would probably want to replace the defined function in the | call-interactively with a lambda-expression, but I'm not sure it is | possible to get the (interactive) part right if you do. Or (ugh) | evaluate the defun inside the caller... Ooops. I should read *all* my news before posting. Anyway, to get a prompt into the thing, try: (defun rls-read-number (prompt) "read a number from the keyboard, with PROMPT for a prompt" (call-interactively (list 'lambda '(arg) (list 'interactive (concat "n" prompt)) 'arg))) It seems to work for me. But, I only tested it once! :-) Just another GNU Emacs hacker, -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
reingold@m.cs.uiuc.edu (02/10/90)
Here's the way I've written the general form. Now that I've got it, I can't figure out how I managed without it! (defun read-object (prompt acceptable &optional initial-contents) "Return an object read from the minibuffer. Prompt with the string PROMPT and use the function ACCEPTABLE to decide if entered item is acceptable. If non-nil, optional third arg INITIAL-CONTENTS is a string to insert in the minibuffer before reading." (let ((value (read-minibuffer prompt initial-contents))) (while (not (funcall acceptable value)) (setq value (read-minibuffer prompt initial-contents))) value)) For example, to read a month, defaulting to current-month, use (read-object "Enter month (1-12): " '(lambda (x) (and (integerp x) (<= 1 x) (<= x 12))) (int-to-string current-month))