It is because ALIGN command is little specific - it uses (align) ALISP function which already has built-in undo mark statements... ALIGN can't be performed directly by using transformation - modification of source objects once - it uses instead multiple commands and therefore they had to be wrapped in UNDO group... So after you call ALIGN command, one UNDO takes you back right before you call ALIGN - built-in undo mark activates, so at that point your OSMODE = 0, just like you coded - so you need UNDO again to take you back to your undo mark were OSMODE = osmorig... As a workaround I suggest that you use either 2nd or 3rd mod. of your routine since first just do what you did and prompt user to type "UNDO" "B" for back which is IMHO somewhat cumbersome...
(defun c:ALIGN2D (/ *error* osmorig sel o1 m1 o2 m2)
(defun *error* (msg)
(princ "error: ")
(princ msg)
(setvar 'OSMODE osmorig))
(if (= 8 (logand 8 (getvar 'UNDOCTL)))
(command "_.UNDO" "_END")
)
(command "_.UNDO" "_GROUP")
(setq osmorig (getvar 'OSMODE))
(setq sel (ssget "_:L"))
(setq o1 (getpoint "\nSpecify first source point: "))
(setq m1 (getpoint o1 "\nSpecify first destination point: "))
(setq o2 (getpoint "\nSpecify second source point: "))
(setq m2 (getpoint o2 "\nSpecify second destination point: "))
(setvar 'OSMODE 0)
(command "_.ALIGN" sel ""
(strcat (rtos (car o1) 2 16) "," (rtos (cadr o1) 2 16))
(strcat (rtos (car m1) 2 16) "," (rtos (cadr m1) 2 16))
(strcat (rtos (car o2) 2 16) "," (rtos (cadr o2) 2 16))
(strcat (rtos (car m2) 2 16) "," (rtos (cadr m2) 2 16))
"" "")
(setvar 'OSMODE osmorig)
(command "_.UNDO" "_END")
(prompt "\nType \"UNDO\" \"B\" (back) for back...")
(princ)
)
(defun c:ALIGN2D (/ *error* osmorig sel o1 m1 o2 m2)
(defun *error* (msg)
(princ "error: ")
(princ msg)
(setvar 'OSMODE osmorig))
(if (= 8 (logand 8 (getvar 'UNDOCTL)))
(command "_.UNDO" "_END")
)
(command "_.UNDO" "_GROUP")
;(setq osmorig (getvar 'OSMODE))
(setq sel (ssget "_:L"))
(setq o1 (getpoint "\nSpecify first source point: "))
(setq m1 (getpoint o1 "\nSpecify first destination point: "))
(setq o2 (getpoint "\nSpecify second source point: "))
(setq m2 (getpoint o2 "\nSpecify second destination point: "))
;(setvar 'OSMODE 0)
(align sel o1 m1 o2 m2 "" "")
;|
(command "_.ALIGN" sel ""
(strcat (rtos (car o1) 2 16) "," (rtos (cadr o1) 2 16))
(strcat (rtos (car m1) 2 16) "," (rtos (cadr m1) 2 16))
(strcat (rtos (car o2) 2 16) "," (rtos (cadr o2) 2 16))
(strcat (rtos (car m2) 2 16) "," (rtos (cadr m2) 2 16))
"" "")
|;
;(setvar 'OSMODE osmorig)
(command "_.UNDO" "_END")
(princ)
)
(defun c:ALIGN2D (/ *error* osmorig sel o1 m1 o2 m2)
(defun *error* (msg)
(princ "error: ")
(princ msg)
(setvar 'OSMODE osmorig))
(if (= 8 (logand 8 (getvar 'UNDOCTL)))
(command "_.UNDO" "_END")
)
(command "_.UNDO" "_GROUP")
;(setq osmorig (getvar 'OSMODE))
(setq sel (ssget "_:L"))
(setq o1 (getpoint "\nSpecify first source point: "))
(setq m1 (getpoint o1 "\nSpecify first destination point: "))
(setq o2 (getpoint "\nSpecify second source point: "))
(setq m2 (getpoint o2 "\nSpecify second destination point: "))
;(setvar 'OSMODE 0)
(command "_.ALIGN" sel ""
"_non" (strcat (rtos (car o1) 2 16) "," (rtos (cadr o1) 2 16))
"_non" (strcat (rtos (car m1) 2 16) "," (rtos (cadr m1) 2 16))
"_non" (strcat (rtos (car o2) 2 16) "," (rtos (cadr o2) 2 16))
"_non" (strcat (rtos (car m2) 2 16) "," (rtos (cadr m2) 2 16))
"" "")
;(setvar 'OSMODE osmorig)
(command "_.UNDO" "_END")
(princ)
)
HTH.
BTW. I modified your original code to include localizing error handler, to check if previous UNDO mark was ENDED and added "_:L" mode for selection set acquiring since you can't apply ALIGN or any other mod. with selected entities that belong to locked layer(s)...
[EDIT]
P.S. This problem is not relevant for users of BricsCAD, since (I suppose) (align) function was better implemented. After single UNDO, ESNAPs work... ESNAP(BricsCAD)=OSNAP(AutoCAD)
[/EDIT]