LISP: getkword differentiate between cancel and enter
Example code:
(defun c:TKW ( / )
(initget "Yes No")
(setq result (getkword "\nAre you sure? [Yes/No]: "))
(if (not result) (princ "\nYou pressed enter or cancelled "))
(princ)
)
I could of course do this: (initget 1 "Yes No"). But I also want to allow the user to press enter to accept a default option.
Note: I use BC7.
TIA.
Comments
-
Hi Roy,
Not sure if this will help you but here is one way to handle Enter as a default action.
(defun C:SAMP1 ( / kw )
(initget "YES,Y NO,N")
(setq kw (getkword "Yes/No/<Yes>: "))
(cond
((not kw)
(princ "I take your silence on the issue to mean YES!")
)
((= (strcase kw) "YES")
(princ "Ahhh... YES is a good choice...")
)
((= (strcase kw) "NO")
(princ "Hurumph! You take the NO option!")
)
(1
(princ "Unknown command...")
(princ "\nWe should never get here...")
NIL
)
)
(princ)
)
(princ "Run the sample with command: SAMP1")
(princ)But the user hitting Esc will just jump to the error handler. I am unaware of a way to capture Esc with v7 other than with a custom error handler, but I don't think you can prevent the Esc from terminating the Lisp.
I am no expert but I have not read a way to handle Esc and continue with plain Autolisp.
0 -
If that was any help you could use it like so:
(defun nss:yes_no ( default_yes / msg def_ans kw )
;; Initialise the default
(cond
(default_yes
(setq msg "Yes/No/<Yes>: ")
(setq def_ans 1)
)
(1
(setq msg "Yes/No/<No>: ")
(setq def_ans NIL)
)
)
;; Get the choice
(initget "YES,Y NO,N")
(setq kw (getkword msg))
(cond
((not kw)
def_ans
)
((= (strcase kw) "YES")
1
)
((= (strcase kw) "NO")
NIL
)
(1
(princ "ERR: nss:yes_no: Unknown command...")
(exit)
)
)
)
(defun C:SAMP2 ( / )
(princ "\nrunning nss:yes_no with default_yes = T...")
(if (nss:yes_no T)
(princ "It's a YES... Here we go...")
(princ "Let's all go home... It's a big NO!")
)
(print)
(princ "\nrunning nss:yes_no with default_yes = NIL...")
(if (nss:yes_no NIL)
(princ "It's a YES... Here we go...")
(princ "Let's all go home... It's a big NO!")
)
(princ)
)
(princ "Run the sample with command: SAMP2")
(princ)0 -
Greg thank you for responding. But my problem is that getkword returns nil either if the user hits Enter or Escape (cancel).
I need to differentiate between the two:
- Enter: The user accepts the default option.
- Escape: The user wants to quit the routine.
0 -
> But the user hitting Esc will just jump to the error handler
Greg: this doesn't happen in BC7. Using my example code:
: C:TKW
: tkw
Are you sure? [Yes/No]:
Cancel
You pressed enter or cancelled0 -
Ah, sorry then. I posted without being able to check it until Monday... I had not noticed the difference with v7. I usually only run it together with a particular add-on.
Something new for me so it was not a waste
0 -
Hi Roy,
Did you find a way to do this? It looks like you can use getstring, handle null input and still have the Esc key trigger the error handler...
0 -
That's a good idea Greg.
;;; AltGetKword uses getstring instead of getkword.
;;; Using getkword there is no way to differentiate between the user hitting Enter or Escape (Cancel).
;;; With AltGetKword, Enter equals choosing the default option and hitting Escape triggers an error
;;; that can be handled by an error-function.
;;;
;;; kWordLst can look like this:
;;; '("Y" "YES" "YE" "YES" "N" "NO")
;;; This will return "YES" or "NO"
;;; Or this:
;;; '("YES" "Y" "YE" "Y" "NO" "N")
;;; This will return "Y" or "N"
;;; Or this:
;;; '("Y" T "YE" T "YES" T "N" nil "NO" nil)
;;; This will return T or nil
;;; The first and second element in kWordLst belong together. If the user enters the first element
;;; (in the first example the string "Y") the second element (in the first example the string "YES")
;;; will be returned. The same goes for the third and fourth element etc. If the user enters the
;;; second or fourth element that element will simply be returned.
;;; Note that the strings inside kWordLst must be all caps. If default is a string it also should be all caps.
;;;
;;; Made by Roy Klein Gebbinck. Based on an idea by Greg Skelhorn.
;;; http://forum.bricsys.com/discussion/10864
(defun AltGetKword (message kWordLst default / breakLoop result kWordLstSegment)
(while (not breakLoop)
(setq result (strcase (getstring message)))
(cond
((= result "")
(setq
result default
breakLoop T
)
)
((setq kWordLstSegment (member result kWordLst))
(if (= (rem (length kWordLstSegment) 2) 0) (setq kWordLstSegment (cdr kWordLstSegment)))
(setq
result (car kWordLstSegment)
breakLoop T
)
)
(T
(princ "\nUnable to recognize entry. Please try again. ")
)
)
)
result
)
(defun MyError (message / )
(if (/= message "Function cancelled") (princ (strcat "\nError: " message)))
(if oldError (setq *error* oldError))
(princ "\nError handler has kicked in! ")
(princ)
)
(defun c:test ( / )
(setq
oldError *error*
*error* MyError
)
(setq answer (AltGetKword "\nAre you sure? [Yes/No] <Yes>: " '("Y" "YES" "YE" "YES" "N" "NO") "YES"))
; Just an alternative:
; (setq answer (AltGetKword "\nAre you sure? [Yes/No] <Yes>: " '("Y" T "YE" T "YES" T "N" nil "NO" nil) T))
(princ answer)
(princ)
)Of course there is no dialog. And with getkword the user can enter any (significant) portion of a keyword.
0