anchor.diff:             (funcall fn))
            (setf *last-command* fn)))))
   
  -(defun ed (&optional thing)
  +(defclass editor-window (sys.graphics::window-with-chrome)
  +  ((input-buffer :initarg :input-buffer)
  +   (process :reader window-process))
  +  (:default-initargs :input-buffer (sys.graphics::make-fifo 500 'character)))
  +
  +(defmethod initialize-instance :after ((instance editor-window))
     (unless *buffer*
       (set-buffer (get-buffer-create "*scratch*"))
       (setf *main-screen-buffer* (get-buffer-create "*scratch*"))
       (setf *minibuffer* (get-buffer-create " *minibuffer*")
             (buffer-key *minibuffer* #\Newline) 'exit-minibuffer))
  -  ;; Avoid the echo behaviour of framebuffer streams.
  -  (let ((*input-stream* (make-instance 'sys.int::ps/2-keyboard-stream)))
  -    (sys.int::with-saved-screen (fb) ; binding special variables using lambda seems to be astonishingly broken.
  -      (let ((*main-screen* fb))
  -        (handler-case
  -            (editor-loop)
  -          (exit-editor ()))))))
  +  (let ((process (make-instance 'sys.int::process :name "Edit")))
  +    (setf (slot-value instance 'process) process)
  +    (sys.int::process-preset process 'editor-top-level instance)
  +    (sys.int::process-enable process)))
  +
  +(defmethod sys.graphics::window-close-event :before ((window editor-window))
  +  (sys.int::process-arrest-reason (window-process window) :window-closed))
  +
  +(defmethod sys.graphics::key-press-event ((window editor-window) character)
  +  (sys.graphics::fifo-push character (slot-value window 'input-buffer)))
  +
  +(defmethod sys.graphics::window-redraw ((window editor-window))
  +  (let* ((fb (sys.graphics::window-backbuffer window))
  +         (dims (array-dimensions fb))
  +         (width (second dims))
  +         (height (first dims))
  +         (text-colour (sys.graphics::make-colour sys.graphics::*default-foreground-colour*)))
  +    (multiple-value-bind (left right top bottom)
  +        (sys.graphics::compute-window-margins window)
  +      (display-buffer *main-screen-buffer* fb
  +                      left top
  +                      (- width left right) (- height 16 16 2 top bottom))
  +      (display-buffer *minibuffer* fb
  +                      left (- height 16 bottom)
  +                      (- width left right) 16)
  +      (sys.graphics::bitset 16 (- width left right)
  +                            (sys.graphics::make-colour sys.graphics::*default-background-darker-colour*)
  +                            fb
  +                            (- height 16 16 1 bottom) left)
  +      (let ((name (buffer-name *main-screen-buffer*))
  +            (ofs left))
  +        (dotimes (i (length name))
  +          (let* ((ch (char name i))
  +                 (char-width (if (eql ch #\Space) 8 (sys.int::unifont-glyph-width ch)))
  +                 (glyph (sys.int::map-unifont-2d ch)))
  +            (when (and (< (+ ofs char-width) width)
  +                       (not (eql ch #\Space))
  +                       glyph)
  +              (sys.graphics::bitset-argb-xrgb-mask-1 16 char-width text-colour
  +                                                     glyph 0 0
  +                                                     fb (- height 16 16 1 bottom) ofs))
  +            (incf ofs char-width))))
  +      (sys.graphics::bitset 1 (- width left right) #xFFD0D0D0 fb (- height 16 1 bottom) left)
  +      (sys.graphics::bitset 1 (- width left right) #xFFD0D0D0 fb (- height 16 16 2 bottom) left))))
  +
  +(defun read-editor-character ()
  +  (loop
  +     (let ((char (sys.graphics::fifo-pop (slot-value *frame* 'input-buffer))))
  +       (when char (return char)))
  +     (sys.int::process-wait "User input"
  +                            (lambda (frame)
  +                              (not (sys.graphics::fifo-emptyp (slot-value frame 'input-buffer))))
  +                            *frame*)))
  +
  +(defun editor-top-level (window)
  +  (let ((*buffer* (get-buffer-create "*scratch*"))
  +        (*last-key-pressed* nil)
  +        (*frame* window))
  +    (unwind-protect
  +         (handler-case (editor-loop)
  +           (exit-editor ()))
  +      (sys.graphics::close-window window))))
  +
  +(defun ed (&optional thing)
  +  (unless *editor-window*
  +    (setf *editor-window* (sys.graphics::make-window "Edit.com" 600 600 'editor-window)))
  +  (sys.graphics::window-set-visibility *editor-window* t))
  +(defun create-or-show-editor-window ()
  +  (unless *editor-window*
  +    (setf *editor-window* (sys.graphics::make-window "Edit.com" 600 600 'editor-window)))
  +  (sys.graphics::window-set-visibility *editor-window* t))
  +(defun create-or-show-editor-window ()
  +  (let ((win (sys.graphics::make-window "Edit" 600 600 'editor-window)))
  +    (sys.graphics::window-set-visibility win t)))
  +
  +(setf (gethash (name-char "F6") sys.graphics::*global-keybindings*) 'create-or-show-editor-window)
  +(setf (gethash (name-char "M-F6") sys.graphics::*global-keybindings*) 'create-editor-window)
  
positive.code: (define-condition simple-editor-error (simple-error) ())
  (define-condition minibuffer-complete () ())
  
  (defvar *minibuffer* nil)
  (defvar *delayed-minibuffer-clear* nil)
  (defvar *dispatch-table* (make-hash-table))
  (defvar *last-key-pressed* nil)
  (defvar *last-command* nil)
  (defvar *input-stream* nil)
  (defvar *main-screen* nil)
  (defvar *main-screen-buffer* nil)
  
  (defun global-key (character)
  
negative.code:       (setf line next))))
  
  (defun redraw-screen ()
    (sys.graphics::window-redraw *frame*))
  
  (defun read-from-minibuffer (prompt-string &key read)
    (let ((*buffer* *minibuffer*)
  