anchor.diff:      (if value
           (frame-multiplexer-on)
           (frame-multiplexer-off))))
  +
  +(defstruct tab
  +  focus-p
  +  number
  +  buffer-name)
  +
  +(defun make-tabs (virtual-frame frames)
  +  (loop :for frame :in frames
  +        :collect (make-tab
  +                  :focus-p (eq frame
  +                               (virtual-frame-current virtual-frame))
  +                  :number (find-frame-id virtual-frame frame)
  +                  :buffer-name (let* ((buffer (window-buffer (frame-current-window frame)))
  +                                      (name (buffer-name buffer)))
  +                                 (if (>= (length name) +max-width-of-each-frame-name+)
  +                                     (format nil "~a..."
  +                                             (subseq name 0 +max-width-of-each-frame-name+))
  +                                     name)))))
  +
  +(defun tab-content (tab)
  +  (format nil "~A~A:~A "
  +          (if (tab-focus-p tab) #\# #\space)
  +          (tab-number tab)
  +          (tab-buffer-name tab)))
  +
  +(defun tab= (tab1 tab2)
  +  (and (equal (tab-focus-p tab1) (tab-focus-p tab2))
  +       (equal (tab-number tab1) (tab-number tab2))
  +       (equal (tab-buffer-name tab1) (tab-buffer-name tab2))))
  +
  +(defun equal-tabs (tabs1 tabs2)
  +  (and (= (length tabs1) (length tabs2))
  +       (every #'tab= tabs1 tabs2)))
   
   (defclass virtual-frame (header-window)
     ((implementation
  
positive.code:   (coerce (remove-if #'null (virtual-frame-id/frame-table virtual-frame))
            'list))
  
  (defun changed-current-buffer-p (current-frame)
    (not (eq (current-buffer)
             (window-buffer (frame-current-window current-frame)))))
  
  (defun require-update-p (virtual-frame)
    (or (virtual-frame-changed virtual-frame)
        (not (= (display-width)
                (virtual-frame-width virtual-frame)))
        (not (= (display-height)
                (virtual-frame-height virtual-frame)))
        (virtual-frame-current virtual-frame)
        (changed-current-buffer-p (virtual-frame-current virtual-frame))))
  
  (defmethod window-redraw ((window virtual-frame) force)
    (when (or force (require-update-p window))
      ;; draw button for frames
      (let* ((buffer (virtual-frame-header-buffer window))
             (p (buffer-point buffer))
             (charpos (point-charpos p)))
        (erase-buffer buffer)
        (dolist (frame (virtual-frame-frames window))
          (let ((focusp (eq frame (virtual-frame-current window)))
                (start-pos (point-charpos p)))
            (insert-button p
                           ;; virtual frame name on header
                           (let* ((buffer (window-buffer (frame-current-window frame)))
                                  (name (buffer-name buffer)))
                             (format nil "~a~a:~a "
                                     (if focusp #\# #\space)
                                     (find-frame-id window frame)
                                     (if (>= (length name) +max-width-of-each-frame-name+)
                                         (format nil "~a..."
                                                 (subseq name 0 +max-width-of-each-frame-name+))
                                         name)))
                           ;; set action when click
                           (let ((frame frame))
                             (lambda ()
                               (switch-current-frame window frame)))
                           :attribute (if focusp
                                          'frame-multiplexer-active-frame-name-attribute
                                          'frame-multiplexer-frame-name-attribute))
            ;; increment charpos
            (when focusp
              (let ((end-pos (point-charpos p)))
                (unless (<= start-pos charpos (1- end-pos))
                  (setf charpos start-pos))))))
        ;; fill right margin
        (let ((margin-right (- (display-width) (point-column p))))
          (when (> margin-right 0)
            (insert-string p (make-string margin-right :initial-element #\space)
                           :attribute 'frame-multiplexer-background-attribute)))
        (line-offset p 0 charpos)))
    ;; clear virtual-frame-changed to nil because of applying redraw
    (setf (virtual-frame-changed window) nil)
    (call-next-method))
  
  (defun frame-multiplexer-init ()
    (clrhash *virtual-frame-map*)
  
negative.code:               (lem::window-buffer-point (current-window)))
  
    (setf (virtual-frame-current virtual-frame) frame)
    (notify-frame-redisplay-required frame)
    (map-frame (implementation) frame)
  
  