Here is an old one I use:
;;=============================================================
;; OffSet_CMD.lsp by Charles Alan Butler
;; Copyright 2004
;; by Precision Drafting & Design All Rights Reserved.
;; Contact TheSwamp.org
;;
;; Version 1.0 July 29,2004
;; Version 1.1 July 30,2004
;; Version 1.2 April 10,2008
;; Version 1.4 June 28, 2011 added pickfirst code
;;
;; This is a replacement of the Offset command
;; 'ofs' offsets to the objects layer
;; option to place the new object on current layer
;; osmode is forced on for the distance pick and
;; turned off for the side pick
;;
;; Thanks to sinc -richards.64879 for the "Through" coding
;; I blended that idea with my old offset routine
;;=============================================================
(defun c:ofs ( / prv:dist usrcmd prm dist $dist ent pt clayer loop *error*)
(defun *error* (msg)
(if (not
(member msg '("console break" "Function cancelled" "quit / exit abort" "")))
(princ (strcat "\nError: " msg))
) ; if
(and usercmd (setvar "CMDECHO" usercmd))
(and useros (setvar "osmode" useros))
(and clayer (setvar "clayer" clayer))
(princ)
) ; end error function
;; variable L:flg is global:
;; When True, offset to current Layer
;; When nil, offset to objects layer
;; comment out the next line to retain settings else
(setq L:Flg nil) ; default offset to objects layer
(setq usrcmd (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq useros (getvar "osmode"))
(setvar "osmode" 175) ; my favorite setting
(setq clayer (getvar "clayer"))
(setq prv:dist (getvar "offsetdist"))
(if (> prv:dist 0); < 0 is "Through"
(setq dist (rtos prv:dist))
(setq prv:dist "Through"
dist prv:dist)
)
(setq $dist dist)
(while ; stay in loop while user toggles Layer
(or (initget (+ 4 64) "Through Layer") ; 2D positive number only
(= "Layer" (setq dist (getdist
(strcat "\nDistance to offset or [Through] <"
$dist "> or Toggle [Layer] is to "
(if L:flg "current" "original")": ")))))
;; L was pressed, so toggle flag
(setq L:flg (null L:flg))
) ; while
;; Pressing ENTER uses the previous value
(or dist (setq dist prv:dist))
(if (= 'real (type dist))
(setq prm "\nSelect side to offset:")
(setq prm "\nSelect through point:")
)
;; disable osnaps, same as [F3]
(if(<= (getvar "osmode") 15359)
(setvar "osmode" (boole 6 (getvar "osmode") 16384)))
(setvar "ERRNO" 0) ; reset to 0, so that the loop below works.
(while
(progn
;(and
;(null ; always True
(or (setq ss (cadr (ssgetfirst)))
(while ; loop until picked object or ENTER pressed
(and (null (setq ent (entsel "\nSelect object to offset or <exit>:")))
(= (getvar "errno") 7)
)
(prompt "\nMissed, Try again.")
) ; while
)
;) ; null always True
(if (and (or ss
(and ent ; something selected
(null (redraw (car ent) 3)) ; highlite ent
)
)
(setq pt (getpoint "\nSpecify point on side to offset:"))
)
(null ; always True, stay in loop
(and (null
(if ss
(command "_.offset" dist pt "")
(command "_.offset" dist ent pt "")
)) ; always True
L:flg ; if True continue
(command "._CHANGE" "L" "" "P" "LA" Clayer "")
))
;; ENTER pressed, we are done
) ; endif
) ; and
) ; end while
(*error* "")
(princ)
) ; defun
(prompt "\nOffset Loaded. Enter OFS to run.")
(princ)