Search code examples
autocadautocad-pluginautolisp

Execute Code On Lisp Exit


I have a lisp written that involves setting a variable, then selecting points inside of a loop. Once I decide that I am done selecting points, I would like to be able to revert that variable back to what it was originally when I press the escape key. eg.

(defun c:df ()
(setq oom (getvar "osmode")) ;store current state


(setq type(getint "\nEnter Type: 1 For Horizontal, 2 For Vertical : "))

(setq startpt (getpoint "\nChoose Start Point : ")) 
(setq ptx (+ (nth 0 startpt)10))
(setq pty (+ (nth 1 startpt)10))

(setvar "osmode" 2); change state state

(while 

     (setq nextpt (getpoint "'Pick Mid: ")) ;make selection



     (if (null nextpt) ((princ "\nNull Value Error.") return))

     (if (= type 1) (command "dimlinear" startpt nextpt "H" (list 0 pty) )) 
     (if (= type 2) (command "dimlinear" startpt nextpt "V" ptx ))

     (setq ptx (+ 5 ptx))   
     (setq pty (+ 5 pty))
)

;do after escape key is pressed.

(setvar "osmode" oom) ;revert state back to original.
)

I have found possible leads to do with "User Input Errors" but couldn't really get anything to work. To my understating, when escape is pressed lisp just exits and doesn't finish executing.

Thanks in advance.


Solution

  • AutoLISP considers a cancellation an error. You can therefore manage the cancellations with an error handling. AutoLISP provides the *error* function that can be locally redefined.

    In addition, I would like to make a few recommendations:

    • do not use the type symbol for a variable, it is the name of a built-in AutoLISP function

    • declare the variables locally (imperatively the *error* function)

    • use getkword and initget to let the user choose an option.

      (defun c:df (/ *error* oom option startpt ptx pty nextpt) ; local variables
      
        ;; *error* local redefinition
        (defun *error* (msg)
          (if (/= msg "Function cancelled")
            (princ (strcat "\nError: " msg))
          )
          (if oom
            (setvar "osmode" oom)
          )
          (princ)
        )
      
        (setq oom (getvar "osmode"))          ;store current state
      
        (initget 1 "Horizontal Vertical")
        (setq option (getkword "\nChoose an option [Horizontal/Vertical]: "))
      
        (if (setq startpt (getpoint "\nChoose Start Point : "))
          (progn
            (setq ptx (+ (car startpt) 10))
            (setq pty (+ (cadr startpt) 10))
      
            (setvar "osmode" 2)               ; change state state
      
            (while (setq nextpt (getpoint "'Pick Mid: ")) ;make selection
               (if (= option "Horizontal")
                 (command "_dimlinear" startpt nextpt "H" (list 0 pty))
                 (command "_dimlinear" startpt nextpt "V" (list ptx 0))
               )
      
               (setq ptx (+ 5 ptx))
               (setq pty (+ 5 pty))
            )
      
            (setvar "osmode" oom)             ;revert state back to original.
          )
        )
        (princ)
      )