Daron, I would use the ARC command as you do it, also. About the undo option, I would build a list of points as the command progresses and use those points to backtrace during undo sessions.
Below is my suggestion for implementing the undo mechanism. I'll let the comments take over further explanation:
(defun c:aet (/ ptpnt endpnt lpnt stpnt pmpt undolst cmde init omod pmp)
(setq cmde (getvar "cmdecho")
omod (getvar "orthomode")
)
(setvar "cmdecho" 0)
(setvar "orthomode" 0)
;; instead of LASTPOINT (which can be set by numerous actions), I'd
;; suggest that you use a dedicated global point to continue from.
;; first, check if the global holds a point list
(cond ((vl-consp *aet_pt*)
;; ok, global point exists (highly probable at least)
;; go set up the prompt and initget option .. also set
;; lpnt to the global point
(setq pmp "\nSelect start point of arc or [<C>ontinue]: "
init "Continue"
lpnt *aet_pt*
)
)
;; no global exists .. just ask for initial point with no
;; initget options
((setq pmp "\nSelect start point of arc: "
init 0
)
)
)
;; go ask for point or option
(initget init)
(setq stpnt (getpoint pmp))
;; check result
;; if "Continue" or nothing then simply jump right into the loop
(cond ((or (not stpnt) (= stpnt "Continue")))
;; if not the above, get endpoint and start to build the
;; undo data list. Because CMDECHO is off, help the user
;; by issuing the standard prompt at the user input
((setq endpnt (getpoint stpnt "\nSelect end point of arc: "))
(princ
"\nSpecify tangent direction for the start point of arc: "
)
(command ".arc" stpnt "e" endpnt "d" pause)
(setq lpnt endpnt
undolst (list stpnt)
)
)
)
;; initialize the loop prompt
(setq pmp "\nSelect end point or [Undo]: ")
(while
(progn (initget "Undo")
(setq pmpt (getpoint lpnt pmp))
)
;; if Undo, then first check the undo data and see if it's
;; even possible to undo (otherwise do nothing but tell there
;; is nothing to undo)
(cond ((= pmpt "Undo")
(cond ((not undolst) (princ "Nothing to undo"))
;; if undo data exists: go erase the last arc,
;; reset lpnt to first occurence in the undo list
;; and chop off the "undid" point from the undo list
(T
(command ".ERASE" "Last" "")
(setq lpnt (car undolst)
undolst (cdr undolst)
)
)
)
)
;; if point is received: go draw the arc, append point
;; to the undo list and set lpnt to the new point.
;; again, help the user by issuing the standard prompt
(pmpt
(princ
"\nSpecify tangent direction for the start point of arc: "
)
(command ".ARC" lpnt "E" pmpt "D" pause)
(setq undolst (cons lpnt undolst)
lpnt pmpt
)
)
)
;; adjust prompt to reflect the status of the undo data
(setq pmp (if undolst
"\nSelect end point or [Undo]: "
"\nSelect end point: "
)
)
)
;; put last point up for later continuance
(setq *aet_pt* lpnt)
(setvar "cmdecho" cmde)
(setvar "orthomode" omod)
(princ)
)