(defvar *cmds* nil) (defun %edit (fun) (cond ((null *cmds*) fun) ((eq (car *cmds*) #\b) (pop *cmds*) fun) ((eq (car *cmds*) #\e) (pop *cmds*) (%edit (list fun))) ((eq (car *cmds*) #\h) (pop *cmds*) (%edit (cons 'highlight (list fun)))) ((consp (car *cmds*)) (let ((val (cdar *cmds*))) (case (caar *cmds*) (#\r (pop *cmds*) (%edit val)) ((#\c #\i) (pop *cmds*) (%edit (cons val fun))) (#\f (cond ((null fun) nil) ((equal val fun) (pop *cmds*) (%edit fun)) ((atom fun) fun) (t (cons (%edit (car fun)) (%edit (cdr fun))))))))) ((atom fun) (pop *cmds*) (%edit fun)) ((eq (car *cmds*) #\d) (pop *cmds*) (%edit (cons (car fun) (%edit (cdr fun))))) ((eq (car *cmds*) #\a) (pop *cmds*) (%edit (cons (%edit (car fun)) (cdr fun)))) ((eq (car *cmds*) #\x) (pop *cmds*) (%edit (cdr fun))) (t fun))) (defun edit (name) (let ((fun (eval name)) cc) (setq *cmds* nil) (loop (write-byte 12) (setq cc (append cc (list #\h))) (setq *cmds* cc) (pprint (%edit fun)) (setq cc (butlast cc)) (let ((c (get-key))) (case c (#\q (set name fun) (return name)) (#\s (setq *cmds* cc) (set name (%edit fun)) (return name)) (#\z (when cc (setq cc (butlast cc)))) ((#\r #\c #\i #\f #\e) (write-byte 11) (princ c) (princ #\:) (setq cc (append cc (list (cons c (read)))))) ((#\d #\a #\x #\b) (setq cc (append cc (list c)))) (t (write-byte 7)))))))