anchor.diff:        (cons element (cdr list))
         (cons (car list) (replace-nth (1- n) element (cdr list)))))
   
  -;; TODO: rename to clear, make clear a method specialized on fields
  +;; TODO: rename to clear, make clear a method specialized on fields, forms and windows.
  +;; TODO: (defmethod clear (win (field field)))
   (defun clear-field (win field)
     "Do what (clear win) does, but for a single field.
   
   clear = write space combined with the background char."
     (with-accessors ((pos .position) (width .width)) field
       (setf (.cursor-position win) pos)
  +    ;; TODO: overwrite the field with the background char, not just with a space.
       (add-char win #\space :n width)
       (setf (.cursor-position win) pos)
       ;; this is the only place we set the attribute for the whole field
       (change-attributes win width '(:underline))))
   
  -;; TODO: do we need to refresh here?
  -(defun update-cursor-position (win object)
  -  "Update the cursor position of object, which can be a form or a single field."
  -  (typecase object
  -    (field
  -     (with-accessors ((pos .position) (inptr .fill-pointer)) object
  -       (move win
  -             (car pos)
  -             (+ (cadr pos) inptr))))
  -    (form
  -     (with-accessors ((current-field .current-field)) object
  -       (update-cursor-position win current-field)))))
  +(defgeneric update-cursor-position (window object)
  +  (:documentation "Update the cursor position of a form or a field."))
  +
  +(defmethod update-cursor-position (win (field field))
  +  "Update the cursor position of a field."
  +  (with-accessors ((pos .position) (inptr .fill-pointer)) field
  +    (move win
  +          (car pos)
  +          (+ (cadr pos) inptr))))
  +
  +(defmethod update-cursor-position (win (form form))
  +  "Update the cursor position of the current field of the form."
  +  (update-cursor-position win (.current-field form)))
   
   (defgeneric draw (window object)
     (:documentation "Draw forms and their elements like fields and buttons."))
  
positive.code:   (update-cursor-position win form)
    (refresh win))
  
  (defun move-prev-char (win event form)
    "Move the cursor to the previous char in the current field."
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((inptr .fill-pointer)) current-field
        (when (> inptr 0)
          (decf inptr))))
    (update-cursor-position win form)
    (refresh win))
  
  (defun move-next-char (win event form)
    "Move the cursor to the previous char in the current field."
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((inbuf .buffer) (inptr .fill-pointer)) current-field
        (when (< inptr (length inbuf))
          (incf inptr))))
    (update-cursor-position win form)
    (refresh win))
  
  ;; :backspace, delete one char to the left
  (defun delete-prev-char (win event form)
    "Delete the previous char in the current field, moving the cursor to the left."
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((inbuf .buffer) (inptr .fill-pointer)) current-field
        (when (> inptr 0)
          (decf inptr)
          (setf inbuf (remove-nth (- (length inbuf) 1 inptr) inbuf))))
      ;; we dont have to redraw the complete form, just the changed field.
      (draw win current-field))
    (refresh win))
  
  ;; :dc, delete one char to the right
  (defun delete-next-char (win event form)
    "Delete the next char in the current field, not moving the cursor."
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((inbuf .buffer) (inptr .fill-pointer)) current-field
        ;; we can only delete to the right if the inptr is not at the end of the inbuf.
        (when (> (length inbuf) inptr)
          (setf inbuf (remove-nth (- (length inbuf) (1+ inptr)) inbuf))))
      (draw win current-field))
    (refresh win))
  
  ;; TODO: test that char is graphic
  (defun form-add-char (win char form)
    "Add char to the current field of the form."
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((width .width) (inbuf .buffer) (inptr .fill-pointer)) current-field
        (let ((len (length inbuf)))
          ;; only add chars when we haven reached the max width of the field
          ;; longer buffers and scrolling are not supported yet.
          (unless (= len width)
            ;; if we're at the end of the inbuf
            (if (= inptr len)
                ;; just add another char to the inbuf
                (setf inbuf (cons char inbuf))
                ;; if we're in the middle of the field, either insert or replace
                (if (.insert-enabled win)
                    (setf inbuf (insert-nth  (- len inptr)      char inbuf))
                    (setf inbuf (replace-nth (- len (1+ inptr)) char inbuf))))
            ;; both replacing and inserting advance the cursor
            (incf inptr))))
      ;; after were done with editing, redraw the field.
      ;; TODO: redraw the entire field or echo one single char?
      (draw win current-field))
    (refresh win))
  
  (defun field-buffer-to-string (field)
    "Return the value of the field buffer (list of chars) as a string."
    (coerce (reverse (.buffer field)) 'string))
  
  (defun debug-print-field-buffer (win event form)
    (declare (ignore event))
    (with-accessors ((current-field .current-field)) form
      (with-accessors ((inbuf .buffer) (inptr .fill-pointer)) current-field
        (when (> (length inbuf) 0)
          (clear win)
          (format win "~A ~%" (coerce (reverse inbuf) 'string))
          (setf inbuf nil inptr 0)
          (draw win form) ))))
  
  (add-keymap :form-default-keymap
    (make-keymap
  
  
negative.code:     (loop for field in fields do
        (draw win field))
      ;; after drawing the fields, reposition the cursor to the current field
      (update-cursor-position win form)
      (refresh win)))
  
  ;; prev-field and next-field are the only two elements where the current-field-number is changed.
  ;; here also current-field has to be set.
  