*olt-action-immediately*

(defvar-local *olt-action-immediately* nil
  "即時ノード実行")

*olt-chase-cursor*

(defvar-local *olt-chase-cursor* nil
  "カーソルに追従")

*olt-range-type-narrow*

(defvar-local *olt-range-type-narrow* nil
  "範囲タイプ:狭")

*olt-view-restriction*

(defvar-local *olt-view-restriction* nil
  "表示範囲制限")

*olt-view-emphasis*

(defvar-local *olt-view-emphasis* nil
  "強調表示")

*olt-make-function*

(defvar-local *olt-make-function* 'olt-make-regexp
  "アウトライン作成関数")

*olt-buffer-latest*

(defvar-local *olt-buffer-latest* nil)

*olt-name*

(defvar *olt-name* "Outline-Tree"
  "outline-tree の表示名")

*olt-short-name*

(defvar *olt-short-name* "OLT"
  "outline-tree の省略表示名")

*olt-long-name*

(defvar *olt-long-name* *olt-name*
  "outline-tree の非省略表示名")

*olt-config-file*

(defvar *olt-config-file* "~/.olt"
  "outline-tree 設定ファイルパス")

*olt-width*

(defvar *olt-width* 200
  "treeview の幅")

*olt-height*

(defvar *olt-height* 100
  "treeview の高さ")

*olt-position*

(defvar *olt-position* XPIS_LEFT
  "treeview の表示位置")

*olt-add-treeview-window*

(defvar *olt-add-treeview-window* :enlarge
  "nil, :fix, :enlarge (t)")

*olt-close-unnecessary-treeview*

(defvar *olt-close-unnecessary-treeview* t
  "表示ノードがなければ treeview を閉じる")

*olt-save-size*

(defvar *olt-save-size* t
  "treeview を閉じる際、幅、高さを記録")

*olt-treeview-style-hasbuttons*

(defvar *olt-treeview-style-hasbuttons* t
  "treeview にボタンを表示")

*olt-treeview-style-haslines*

(defvar *olt-treeview-style-haslines* t
  "treeview にラインを表示")

*olt-treeview-style-linesatroot*

(defvar *olt-treeview-style-linesatroot* t
  "treeview にライン・ボタンをルートから表示")

*olt-treeview-style-checkboxes*

(defvar *olt-treeview-style-checkboxes* nil
  "treeview にチェックボックスを表示")

*olt-treeview-style-trackselect*

(defvar *olt-treeview-style-trackselect* t
  "treeview でトラックセレクト")

*olt-treeview-style-fullrowselect*

(defvar *olt-treeview-style-fullrowselect* nil
  "treeview で一行選択表示")

*olt-treeview-style-notooltips*

(defvar *olt-treeview-style-notooltips* nil
  "treeview でツールチップを表示しない")

*olt-text-color-manual-p*

(defvar *olt-text-color-manual-p* nil)

*olt-text-color*

(defvar *olt-text-color* nil)

*olt-bk-color-manual-p*

(defvar *olt-bk-color-manual-p* nil)

*olt-bk-color*

(defvar *olt-bk-color* nil)

*olt-modify-text-color-manual-p*

(defvar *olt-modify-text-color-manual-p* nil)

*olt-modify-text-color*

(defvar *olt-modify-text-color* nil)

*olt-modify-bk-color-manual-p*

(defvar *olt-modify-bk-color-manual-p* nil)

*olt-modify-bk-color*

(defvar *olt-modify-bk-color* nil)

*olt-treeview-indent-manual-p*

(defvar *olt-treeview-indent-manual-p* nil)

*olt-treeview-indent*

(defvar *olt-treeview-indent* nil)

*olt-treeview-item-height-manual-p*

(defvar *olt-treeview-item-height-manual-p* nil)

*olt-treeview-item-height*

(defvar *olt-treeview-item-height* nil)

*olt-font-facename-manual-p*

(defvar *olt-font-facename-manual-p* nil)

*olt-font-facename-default*

(defvar *olt-font-facename-default* nil)

*olt-font-facename*

(defvar *olt-font-facename* nil)

*olt-font-height-manual-p*

(defvar *olt-font-height-manual-p* nil)

*olt-font-height-default*

(defvar *olt-font-height-default* 12)

*olt-font-height*

(defvar *olt-font-height* nil)

*olt-font-weight-manual-p*

(defvar *olt-font-weight-manual-p* nil)

*olt-font-weight-default*

(defvar *olt-font-weight-default* 0)

*olt-font-weight*

(defvar *olt-font-weight* nil)

*olt-font-italic*

(defvar *olt-font-italic* nil)

*olt-font-underline*

(defvar *olt-font-underline* nil)

*olt-tool-bar-local*

(defvar *olt-tool-bar-local* nil
  "ツールバーではローカル設定")

*olt-emphasis-attribute*

(defvar *olt-emphasis-attribute* '(:background 3 :prefix #\T :extend t)
  "強調表示属性")

*olt-make-expand*

(defvar *olt-make-expand* :depth "t, nil, :depth")

*olt-make-expand-depth*

(defvar *olt-make-expand-depth* 2)

*olt-chase-expand*

(defvar *olt-chase-expand* :depth "t, nil, :depth")

*olt-chase-expand-depth*

(defvar *olt-chase-expand-depth* 3)

*olt-recenter*

(defvar *olt-recenter* :line "t, nil, :line")

*olt-recenter-line*

(defvar *olt-recenter-line* 3)

*olt-treeview-recenter*

(defvar *olt-treeview-recenter* nil "t, nil, :line")

*olt-treeview-recenter-line*

(defvar *olt-treeview-recenter-line* 3)

*olt-treeview-scroll-margin*

(defvar *olt-treeview-scroll-margin* 0)

*olt-select-node-delay-sec*

(defvar *olt-select-node-delay-sec* 0.01 "olt-select-node-delay 用変数")

*olt-fix-map*

(defvar *olt-fix-map* nil "outline-tree: treeview keymap (デフォルト動作対策)")

*olt-map*

(defvar *olt-map* nil "outline-tree: treeview keymap")

*olt-header-node-title*

(defvar *olt-header-node-title* "<先頭>")

*olt-dummy-node-title*

(defvar *olt-dummy-node-title* "<dummy>")

*olt-treeview-style-icon*

(defvar *olt-treeview-style-icon* t)

*olt-icon-directory*

(defvar *olt-icon-directory* (merge-pathnames "site-lisp/olt/icon" (si:system-root))
  "olt: icon ディレクトリ")

*olt-item-icon*

(defvar *olt-item-icon* nil)

*olt-selected-item-icon*

(defvar *olt-selected-item-icon* nil)

*olt-buffer-icon*

(defvar *olt-buffer-icon* nil)

*olt-file-icon*

(defvar *olt-file-icon* nil)

*olt-section-icon*

(defvar *olt-section-icon* nil)

*olt-dependent-icon*

(defvar *olt-dependent-icon* nil)

*olt-info-icon*

(defvar *olt-info-icon* nil)

*olt-update-item-icon*

(defvar *olt-update-item-icon* nil)

*olt-open-hook*

(defvar *olt-open-hook* nil)

*olt-close-hook*

(defvar *olt-close-hook* nil)

*olt-make-hook*

(defvar *olt-make-hook* nil)

*olt-delete-hook*

(defvar *olt-delete-hook* nil)

*olt-focus-editor-hook*

(defvar *olt-focus-editor-hook* nil)

*olt-focus-outline-hook*

(defvar *olt-focus-outline-hook* nil)

*olt-uninstall-hook*

(defvar *olt-uninstall-hook* nil)

*olt-tag*

(defvar *olt-tag* 'olt
  "強調表示の際の識別タグ")

*olt-hash*

(defvar *olt-hash* (make-hash-table))

*olt-buffer-hash*

(defvar *olt-buffer-hash* (make-hash-table))

*olt-make-function-alist*

(defvar *olt-make-function-alist* nil)

*olt-shutting-hook*

(defvar *olt-shutting-hook* nil)

*olt-opening-hook*

(defvar *olt-opening-hook* nil)

*olt-window-size-min*

(defvar *olt-window-size-min* 5)

*olt-window-size-threshold*

(defvar *olt-window-size-threshold* 20)

*olt-window-size-default*

(defvar *olt-window-size-default* 200)

*before-olt-make-only-buffer-node-hook*

(defvar *before-olt-make-only-buffer-node-hook* nil)

*olt-except-buffer-name-regexp-list*

(defvar *olt-except-buffer-name-regexp-list* nil)

*olt-except-commands-for-select-cursor-related-node*

(defvar *olt-except-commands-for-select-cursor-related-node* nil)

*olt-node-begin*

(defvar *olt-node-begin* "node: *")

*olt-node-end*

(defvar *olt-node-end* " *:end")

*olt-sync-local-variables-list*

(defvar *olt-sync-local-variables-list*
  '((*olt-action-immediately*
     *olt-chase-cursor*
     *olt-range-type-narrow*
     *olt-view-restriction*
     *olt-view-emphasis*)))

*olt-escape-char-alist*

(defvar *olt-escape-char-alist*
  '(("\n" . "\\\\n")
    ("\r" . "\\\\r")
    ("\t" . "\\\\t")
    ("\f" . "\\\\f")))

*olt-option-prop-page*

(defvar *olt-option-prop-page* nil)

*olt-option-prop-page-no*

(defvar *olt-option-prop-page-no* nil)

*olt-make-function-auto-mode-parameter*

(defvar *olt-make-function-auto-mode-parameter* nil)

olt-message

(defun olt-message (fmt &rest args)
  "メッセージをステータスバーに表示"
  (apply #'message (concat *olt-short-name* ": " fmt) args))

olt-minibuffer-prompt

(defun olt-minibuffer-prompt (fmt &rest args)
  "書式に従ってミニバッファにメッセージを表示"
  (apply #'minibuffer-prompt (concat *olt-short-name* ": " fmt) args))

olt-config-load

  (defun olt-config-load ()
    "設定ファイルを読み込む"
    (when (and *olt-config-file*
               (file-exist-p *olt-config-file*))
      (load *olt-config-file*)
      (setq loaded-p t)))

olt-config-loaded-p

  (defun olt-config-loaded-p ()
    "設定ファイルを読み込み済み"
    loaded-p)

olt-shutting-p

  (defun olt-shutting-p ()
    (and (treeview-open-p)
         (or (and (find (treeview-get-position) (list XPIS_LEFT XPIS_RIGHT))
                  (<= (olt-get-window-width (treeview-get-hwnd)) *olt-window-size-threshold*))
             (and (find (treeview-get-position) (list XPIS_TOP XPIS_BOTTOM))
                  (<= (olt-get-window-height (treeview-get-hwnd)) *olt-window-size-threshold*)))))

olt-insert-item

(defun olt-insert-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter))

olt-insert-buffer-item

(defun olt-insert-buffer-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-buffer-icon* :sicon *olt-buffer-icon*))

olt-insert-normal-item

(defun olt-insert-normal-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-item-icon* :sicon *olt-selected-item-icon*))

olt-insert-dependent-item

(defun olt-insert-dependent-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-dependent-icon* :sicon *olt-selected-item-icon*))

olt-insert-info-item

(defun olt-insert-info-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-info-icon* :sicon *olt-info-icon*))

olt-insert-section-item

(defun olt-insert-section-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-section-icon* :sicon *olt-section-icon*))

olt-insert-update-item

(defun olt-insert-update-item (text parent &key (insertafter TVI_LAST))
  (treeview-insert-item text parent :insertafter insertafter
                        :icon *olt-update-item-icon* :sicon *olt-selected-item-icon*))

olt-treeview-modify-style

(defun olt-treeview-modify-style ()
  "treeview の style を変更"
  (unless (treeview-open-p)
    (return-from olt-treeview-modify-style nil))

  ;; style
  (treeview-modify-style
   (logior
    (if (not *olt-treeview-style-hasbuttons*) TVS_HASBUTTONS 0)
    (if (not *olt-treeview-style-haslines*) TVS_HASLINES 0)
    (if (not *olt-treeview-style-linesatroot*) TVS_LINESATROOT 0)
    ;
    (if (not *olt-treeview-style-notooltips*) TVS_NOTOOLTIPS 0)
    (if (not *olt-treeview-style-checkboxes*) TVS_CHECKBOXES 0)
    (if (not *olt-treeview-style-trackselect*) TVS_TRACKSELECT 0)
    ;
    (if (not *olt-treeview-style-fullrowselect*) TVS_FULLROWSELECT 0)
    )
   (logior
    (if *olt-treeview-style-hasbuttons* TVS_HASBUTTONS 0)
    (if *olt-treeview-style-haslines* TVS_HASLINES 0)
    (if *olt-treeview-style-linesatroot* TVS_LINESATROOT 0)
;   TVS_EDITLABELS
;   TVS_DISABLEDRAGDROP
    TVS_SHOWSELALWAYS
;   TVS_RTLREADING
    (if *olt-treeview-style-notooltips* TVS_NOTOOLTIPS 0)
    (if *olt-treeview-style-checkboxes* TVS_CHECKBOXES 0)
    (if *olt-treeview-style-trackselect* TVS_TRACKSELECT 0)
;   TVS_SINGLEEXPAND
;   TVS_INFOTIP
    (if *olt-treeview-style-fullrowselect* TVS_FULLROWSELECT 0)
;   TVS_NOSCROLL
;   TVS_NONEVENHEIGHT
;   TVS_NOHSCROLL
    )
   0)
  ;; icon
  (olt-treeview-modify-icon)

  ;; color
  (olt-treeview-modify-color)

  ;; font
  (olt-treeview-modify-font)

  ;; item-height
  (cond
   ((not *olt-treeview-item-height-manual-p*)
    (treeview-set-item-height -1))
   ((not (eql (treeview-get-item-height) *olt-treeview-item-height*))
    (treeview-set-item-height *olt-treeview-item-height*)))
  
  ;; indent
  (cond
   ((not *olt-treeview-indent-manual-p*)
    (treeview-set-indent 0))
   ((not (eql (treeview-get-indent) *olt-treeview-indent*))
    (treeview-set-indent *olt-treeview-indent*)))
  )

olt-treeview-modify-icon

(defun olt-treeview-modify-icon ()
  "treeview の icon を変更"
  (unless (treeview-open-p)
    (return-from olt-treeview-modify-icon nil))
  (if (and *olt-treeview-style-icon*
           (file-exist-p *olt-icon-directory*)
           (file-directory-p *olt-icon-directory*))
      (progn
        (setq *olt-item-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "item.ico" *olt-icon-directory*))))
        (setq *olt-selected-item-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "selected-item.ico" *olt-icon-directory*))))
        (setq *olt-dependent-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "dependent.ico" *olt-icon-directory*))))
        (setq *olt-info-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "info.ico" *olt-icon-directory*))))
        (setq *olt-buffer-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "buffer.ico" *olt-icon-directory*))))
        (setq *olt-file-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "file.ico" *olt-icon-directory*))))
        (setq *olt-section-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "section.ico" *olt-icon-directory*))))
        (setq *olt-update-item-icon*
              (treeview-add-file-icon
               (map-slash-to-backslash (merge-pathnames "update.ico" *olt-icon-directory*))))
          )
    (progn
      (treeview-remove-all-icons)
      (setq *olt-item-icon* nil)
      (setq *olt-selected-item-icon* nil)
      (setq *olt-dependent-icon* nil)
      (setq *olt-info-icon* nil)
      (setq *olt-buffer-icon* nil)
      (setq *olt-file-icon* nil)
      (setq *olt-section-icon* nil)
      (setq *olt-update-item-icon* nil))))

olt-treeview-modify-color

(defun olt-treeview-modify-color (&optional (modified-p nil sv))
  "treeview の色を変更"
  (unless (treeview-open-p)
    (return-from olt-treeview-modify-color nil))
  (unless sv
    (setq modified-p (olt-get-modified-buffer-list)))
  (treeview-set-bk-color
   (cond
    ((and modified-p *olt-modify-bk-color-manual-p*)
     *olt-modify-bk-color*)
    (*olt-bk-color-manual-p*
     *olt-bk-color*)
    (t
     nil)))
  (treeview-set-text-color
   (cond
    ((and modified-p *olt-modify-text-color-manual-p*)
     *olt-modify-text-color*)
    (*olt-text-color-manual-p*
     *olt-text-color*)
    (t
     nil))))

olt-treeview-modify-font

(defun olt-treeview-modify-font ()
  "treeview のフォントを変更"
  (unless (treeview-open-p)
    (return-from olt-treeview-modify-font nil))
  (olt-set-font :font-facename (if *olt-font-facename-manual-p*
                                   *olt-font-facename* *olt-font-facename-default*)
                :font-height (if *olt-font-height-manual-p*
                                 *olt-font-height* *olt-font-height-default*)
                :font-weight (if *olt-font-weight-manual-p*
                                 *olt-font-weight* *olt-font-weight-default*)
                :font-italic *olt-font-italic*
                :font-underline *olt-font-underline*))

olt-except-buffer-name-match-p

(defun olt-except-buffer-name-match-p (buffer)
  (unless (or (bufferp buffer)
              (and (stringp buffer) (find-buffer buffer)))
    (return-from olt-except-buffer-name-match-p nil))
  (let ((name (buffer-name buffer)))
    (dolist (regexp *olt-except-buffer-name-regexp-list*)
      (when (string-match regexp name)
        (return-from olt-except-buffer-name-match-p t)))))

olt-get-buffer-list

(defun olt-get-buffer-list ()
  (let (buffers)
    (when (treeview-open-p)
      (maphash #'(lambda (buffer hitem)
                   (push buffer buffers))
               *olt-buffer-hash*))
    buffers))

olt-get-modified-buffer-list

(defun olt-get-modified-buffer-list ()
  (let (buffers)
    (when (treeview-open-p)
      (maphash #'(lambda (buffer hitem)
                   (if (and (not (deleted-buffer-p buffer))
                            (not (buffer-local-value buffer '*olt-buffer-latest*)))
                       (push buffer buffers)))
               *olt-buffer-hash*))
    buffers))

olt-select-node-1

(defun olt-select-node-1 (base-hitem hitem-mover)
  (let* ((selected-hitem (treeview-get-selected-item))
         (window-line (treeview-get-window-line selected-hitem))
         hitem scroll-margin recenter-arg need-not-recenter-p)
    (when (or (and (eq base-hitem nil)
                   (treeview-hitem-valid-p
                    (setq hitem (funcall hitem-mover))))
              (and (treeview-hitem-valid-p base-hitem)
                   (functionp hitem-mover)
                   (treeview-hitem-valid-p
                    (setq hitem (funcall hitem-mover base-hitem)))))

      (cond
       ;; recenter 指定時
       (*olt-treeview-recenter*
        (setq recenter-arg (if (and (eq *olt-treeview-recenter* :line)
                                   (integerp *olt-treeview-recenter-line*))
                               *olt-treeview-recenter-line* nil)))
       ;; scroll-margin 考慮
       (t
        (setq scroll-margin (if (and (numberp *olt-treeview-scroll-margin*)
                                     (integerp *olt-treeview-scroll-margin*)
                                     (plusp *olt-treeview-scroll-margin*))
                                *olt-treeview-scroll-margin* nil))
        (if scroll-margin
            (progn
              (setq scroll-margin
                    (min scroll-margin (truncate (treeview-window-height) 2)))
              (cond
               ((treeview-hitem-equal selected-hitem hitem)
                (setq need-not-recenter-p t))
               ;; 上に移動している場合
               ((treeview-hitem-greaterp selected-hitem hitem)
                (setq recenter-arg scroll-margin)
                (cond
                 ((<= window-line recenter-arg)
                  (setq recenter-arg window-line))
                 ((>= (treeview-get-window-line hitem) recenter-arg)
                  (setq need-not-recenter-p t))))
               ;; 下に移動している場合
               (t
                (setq recenter-arg (- (1- (treeview-window-height)) scroll-margin))
                (cond
                 ((>= window-line recenter-arg)
                  (setq recenter-arg window-line))
                 ((< (treeview-get-window-line hitem) recenter-arg)
                  (setq need-not-recenter-p t))))))
          (setq need-not-recenter-p t))))

      (if (or need-not-recenter-p
              (and (treeview-item-window-visible-p hitem)
                   (let ((scroll (treeview-recenter-scroll-height
                                  hitem recenter-arg)))
                     (cond
                      ((not (numberp scroll)) nil)
                      ((zerop scroll) t)
                      ((plusp scroll) (treeview-window-bottom-p))
                      (t              (treeview-window-top-p))))))
          (treeview-select-item hitem)
        (olt-suppress-redraw
         (treeview-select-item hitem)
         (treeview-recenter recenter-arg))))

    (if (olt-get-action-immediately hitem)
        (olt-node-action hitem))))

olt-get-buffer-related-buffer-node

(defun olt-get-buffer-related-buffer-node (&optional buffer)
  "buffer に対応した buffer-node を取得。
対応するノードがなければ nil を返す。"
  (when (treeview-open-p)
    (unless (bufferp buffer)
      (setq buffer (selected-buffer)))
    (gethash buffer *olt-buffer-hash*)))

olt-get-cursor-related-node

(defun olt-get-cursor-related-node (&optional (expand t))
  "olt: ポイントの位置に対応したノードを取得。
EXPAND: t   可能な限り展開
        <integer> 展開する階層レベル
        上記以外 展開しない"
  (labels ((olt-get-cursor-related-node-1 (parent-hitem position)
             (unless (and (treeview-hitem-valid-p parent-hitem)
                          (integerp position))
               (return-from olt-get-cursor-related-node-1 nil))
             (let (hitem child-hitem value wide-range)
               (when (not (zerop (treeview-item-has-children parent-hitem)))
                 (setq hitem (treeview-get-child-item parent-hitem))
                 (while (treeview-hitem-valid-p hitem)
                   (setq value (gethash hitem *olt-hash*))
                   (case (car value)
                     ((:node :header-node :dependent-node)
                      (setq wide-range (nth 2 value))
                      (when (and wide-range
                                 (<= (car wide-range) position)
                                 (< position (cdr wide-range)))
                        (return-from olt-get-cursor-related-node-1
                          (or (olt-get-cursor-related-node-1 hitem position) hitem))))
                     (t
                      (setq child-hitem (olt-get-cursor-related-node-1 hitem position))
                      (if child-hitem
                          (return-from olt-get-cursor-related-node-1 child-hitem))))
                   (setq hitem (treeview-get-next-sibling-item hitem)))))
             nil))
    (when (treeview-open-p)
      (let ((hitem (olt-get-buffer-related-buffer-node (selected-buffer))) child-hitem)
        (when hitem
          (setq child-hitem (olt-get-cursor-related-node-1 hitem (point)))
          (when child-hitem
            (setq hitem child-hitem))
          (cond
           ((eq expand t))
           ((and (integerp expand)
                 (plusp expand))
            (let ((i (- (treeview-get-depth hitem) expand))
                  (parent-hitem (treeview-get-parent-item hitem)))
              (while (and (plusp i)
                          (treeview-hitem-valid-p parent-hitem)
                          (not (treeview-expand-p parent-hitem)))
                (setq hitem parent-hitem
                      parent-hitem (treeview-get-parent-item hitem))
                (decf i))))
           (t
            (let ((parent-hitem (treeview-get-parent-item hitem)))
              (while (and (treeview-hitem-valid-p parent-hitem)
                          (not (treeview-expand-p parent-hitem)))
                (setq hitem parent-hitem
                      parent-hitem (treeview-get-parent-item hitem)))))))
        hitem))))

olt-get-node-related-buffer

(defun olt-get-node-related-buffer (&optional (hitem (treeview-get-selected-item)))
  (let (buffer)
    (multiple-value-bind (hitem value)
        (olt-get-parent-buffer-node hitem)
      (when value
        (setq buffer (nth 2 value))
        buffer))))

olt-get-jump-node-info

(defun olt-get-jump-node-info ()
  (save-excursion
    (let ((opoint (point))
          (bol-point (progn (goto-bol) (point)))
          (eol-point (progn (goto-eol) (point)))
          wide-begin wide-end narrow-begin narrow-end)
      (if (scan-buffer *olt-node-begin* :regexp t
                       :reverse t :left-bound bol-point)
          (progn
            (setq wide-begin (match-beginning 0))
            (setq narrow-begin (match-end 0)))
        (return-from olt-get-jump-node-info (values nil nil nil)))
      (goto-char wide-begin)
      (if (scan-buffer *olt-node-end* :regexp t
                       :reverse nil :right-bound eol-point)
          (progn
            (setq wide-end (match-end 0))
            (setq narrow-end (match-beginning 0)))
        (return-from olt-get-jump-node-info (values nil nil nil)))
      (if (and (<= wide-begin opoint) (< opoint wide-end))
          (values (buffer-substring narrow-begin narrow-end)
                  wide-begin wide-end)
        (values nil nil nil)))))

olt-select-nodes-dialog

(defun olt-select-nodes-dialog (hitems)
  (multiple-value-bind (result data)
      (dialog-box
       '(dialog 0 0 254 207
         (:caption "outline-tree: ノードジャンプ")
         (:font 9 "MS Pゴシック")
         (:control
          (:listbox list nil #x50b10001 2 3 188 203)
          (:button IDOK "移動(&G)" #x50030001 198 7 52 14)
          (:button IDCANCEL "キャンセル" #x50030000 198 27 52 14)))
       (list (cons 'list (mapcar #'treeview-get-item-text hitems))
             '(list . 0))
       '((list :index t :must-match t :enable (IDOK))))
    (when result
      (nth (cdr (assoc 'list data)) hitems))))

olt-set-action-immediately

(defun olt-set-action-immediately (arg &key local)
  (olt-toggle-action-immediately :arg arg :local local))

olt-set-chase

(defun olt-set-chase (arg &key local)
  (olt-toggle-chase :arg arg :local local))

olt-set-range-type-narrow

(defun olt-set-range-type-narrow (arg &key local)
  (olt-toggle-range-type-narrow :arg arg :local local))

olt-set-view-restriction

(defun olt-set-view-restriction (arg &key local)
  (olt-toggle-view-restriction :arg arg :local local))

olt-set-view-emphasis

(defun olt-set-view-emphasis (arg &key local)
  (olt-toggle-view-emphasis :arg arg :local local))

olt-set-hide-restricted-region

(defun olt-set-hide-restricted-region (arg &key local)
  (olt-toggle-hide-restricted-region :arg arg :local local))

olt-set-outline-old

(defun olt-set-outline-old (&optional buffer operation from to undo-p)
  "olt: アウトラインが最新状態でないことを表現する。"
  (unless buffer
    (setq buffer (selected-buffer)))
  (when (and (buffer-local-value buffer '*olt-buffer-latest*) (treeview-open-p))
    (save-excursion
      (unless (eq (selected-buffer) buffer)
        (set-buffer buffer))
      (setq *olt-buffer-latest* nil))
    (let ((root-hitem (gethash buffer *olt-buffer-hash*))
          (hitem (treeview-get-selected-item)))
      (when (treeview-hitem-valid-p root-hitem)
        (treeview-set-item-text root-hitem (concat "* " (buffer-name buffer)))
        ;; update.ico 処理 start
        (while (and (treeview-hitem-valid-p hitem)
                    (not (eq (nth 0 (gethash hitem *olt-hash*)) :buffer-node)))
          (setq hitem (treeview-get-parent-item hitem)))
        (when (eql root-hitem hitem)
          (setq hitem (treeview-get-selected-item))
          (while (and (treeview-hitem-valid-p hitem)
                      (not (eq (nth 0 (gethash hitem *olt-hash*)) :buffer-node)))
            (when (member (nth 0 (gethash hitem *olt-hash*))
                          '(:node :header-node :dependent-node))
              (treeview-set-item-icon hitem *olt-update-item-icon* *olt-selected-item-icon*))
            (setq hitem (treeview-get-parent-item hitem))))
        ;; update.ico 処理 end
        ))
    (olt-treeview-modify-color t)))

olt-get-ranges

(defun olt-get-ranges (&optional (hitem (treeview-get-selected-item)))
  (when (and (treeview-open-p)
             (treeview-hitem-valid-p hitem))
    (let (value wide-range narrow-range view-range restriction-range emphasis-range)
      (setq value (gethash hitem *olt-hash*))
      (when (find (car value) '(:node :header-node :dependent-node :dummy-node :info-node))
        (setq wide-range (nth 2 value))
        (setq narrow-range (nth 3 value))
        (setq title-range (nth 4 value))
        (if (and *olt-range-type-narrow* narrow-range)
            (setq view-range narrow-range)
          (setq view-range wide-range))
        (when *olt-view-restriction*
          (if (and (numberp (cdr view-range))
                   (< (car view-range) (cdr view-range))
                   (save-excursion
                     (goto-char (cdr view-range))
                     (and (bolp) (not (eobp)))))
              (setq restriction-range (cons (car view-range) (1- (cdr view-range))))
            (setq restriction-range view-range)))
        (when *olt-view-emphasis*
          (if restriction-range
              (setq emphasis-range title-range)
            (setq emphasis-range view-range)))
        (values view-range restriction-range emphasis-range wide-range narrow-range title-range)))))

olt-get-parent-buffer-node

(defun olt-get-parent-buffer-node (&optional (hitem (treeview-get-selected-item)))
  (let (value)
    (setq value (gethash hitem *olt-hash*))
    (while (and value (not (eq (car value) :buffer-node)))
      (setq hitem (treeview-get-parent-item hitem))
      (setq value (gethash hitem *olt-hash*)))
    (if (eq (car value) :buffer-node)
        (values hitem value)
      nil)))

olt-get-action-immediately

(defun olt-get-action-immediately (&optional (hitem (treeview-get-selected-item)))
  "バッファの設定が即ノード実行であるか"
  (let ((buffer (olt-get-node-related-buffer hitem)))
    (cond ((eq buffer (selected-buffer))
           *olt-action-immediately*)
          ((bufferp buffer)
           (save-excursion
             (set-buffer buffer)
             *olt-action-immediately*))
          (t nil))))

olt-unset-text-emphasis

(defun olt-unset-text-emphasis ()
  (when *olt-view-emphasis*
    (delete-text-attributes *olt-tag*)))

olt-set-text-emphasis

(defun olt-set-text-emphasis (range)
  (olt-unset-text-emphasis)
  (apply #'set-text-attribute
         (append (list (car range) (cdr range) *olt-tag*)
                 *olt-emphasis-attribute*)))

olt-sync-local-variables

(defun olt-sync-local-variables (sym &optional (local t))
  (dolist (variables *olt-sync-local-variables-list*)
    (when (find sym variables)
      (if local
          (dolist (variable variables)
            (set variable (symbol-value variable)))
        (dolist (variable variables)
          (set-default variable (symbol-value variable))
          (kill-local-variable variable))))))

olt-local-variables-local-p

(defun olt-local-variables-local-p (sym)
  "グループ内のいずれかが local なら t"
  (let (result)
    (dolist (variables *olt-sync-local-variables-list*)
      (when (find sym variables)
        (dolist (variable variables)
          (when (local-variable-p variable)
            (setq result t)
            (return)))
        (return)))
    result))

olt-encode-escape-sequence

(defun olt-encode-escape-sequence (string)
  (cond
   ((stringp string)
    (dolist (ec *olt-escape-char-alist*)
      (setq string (substitute-string string (car ec) (cdr ec))))
    string)
   (t nil)))

olt-add-option-prop-page

(defun olt-add-option-prop-page (ident tmpl init handlers result)
  (setq *olt-option-prop-page* (delete ident *olt-option-prop-page* :test #'eq
                                           :key #'(lambda (x) (if (consp x) (car x) nil))))
  (setf (get ident 'olt-prop-result) result)
  (push (list ident tmpl init handlers) *olt-option-prop-page*))

olt-tool-bar-update-close

(defun olt-tool-bar-update-close ()
  (or (treeview-open-p) :disable))

olt-tool-bar-update-action-immediately

(defun olt-tool-bar-update-action-immediately ()
  (cond ((not (treeview-open-p)) :disable)
        (*olt-action-immediately* :check)))

olt-tool-bar-update-range-type-narrow

(defun olt-tool-bar-update-range-type-narrow ()
  (cond ((not (treeview-open-p)) :disable)
        (*olt-range-type-narrow* :check)))

olt-tool-bar-update-view-restriction

(defun olt-tool-bar-update-view-restriction ()
  (cond ((not (treeview-open-p)) :disable)
        (*olt-view-restriction* :check)))

olt-tool-bar-update-view-emphasis

(defun olt-tool-bar-update-view-emphasis ()
  (cond ((not (treeview-open-p)) :disable)
        (*olt-view-emphasis* :check)))

olt-tool-bar-update-chase

(defun olt-tool-bar-update-chase ()
  (cond ((not (treeview-open-p)) :disable)
        (*olt-chase-cursor* :check)))

olt-tool-bar-update-restricted-region

(defun olt-tool-bar-update-restricted-region ()
  (and hide-restricted-region :check))

olt-tool-bar-update-opening-and-shutting

(defun olt-tool-bar-update-opening-and-shutting ()
  (cond ((not (treeview-open-p)) :disable)
        ((olt-shutting-p) :check)))

olt-tool-bar

(defun olt-tool-bar ()
  (create-tool-bar
   'olt-tool-bar
   (merge-pathnames "site-lisp/olt/olt-toolbar.bmp" (si:system-root))
   '(("アウトライン作成(更新)" 0 olt-make)
     ("最大化" 8 olt-toggle-opening-and-shutting olt-tool-bar-update-opening-and-shutting)
     ("閉じる" 1 olt-close olt-tool-bar-update-close)
     :sep
     ("即時ノード実行" 2 olt-toggle-action-immediately-tool-bar olt-tool-bar-update-action-immediately)
     ("カーソルに追従" 3 olt-toggle-chase-tool-bar olt-tool-bar-update-chase)
     ("範囲タイプ:狭" 4 olt-toggle-range-type-narrow-tool-bar olt-tool-bar-update-range-type-narrow)
     ("表示範囲制限" 5 olt-toggle-view-restriction-tool-bar olt-tool-bar-update-view-restriction)
     ("強調表示" 6 olt-toggle-view-emphasis-tool-bar olt-tool-bar-update-view-emphasis)
     :sep
     ("制限範囲の隠蔽" 7 olt-toggle-hide-restricted-region olt-tool-bar-update-restricted-region)
     )))

olt-tool-bar

    (defun olt-tool-bar ()
      (create-tool-bar
       'olt-tool-bar
       (merge-pathnames "site-lisp/olt/olt-toolbar.bmp" (si:system-root))
       '(("アウトライン作成(更新)" 0 olt-make)
         ("閉じる" 1 olt-close olt-tool-bar-update-close))))

find-file-auto-olt-mode

(defun find-file-auto-olt-mode (string)
  (let ((package (find-package "outline-tree"))
        olt-mode)
    (when (or (and (setq olt-mode (find-symbol (concat "olt-make-" string) package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-" (string-downcase string)) package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-" string "-mode") package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-" (string-downcase string) "-mode") package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-regexp-" string) package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-regexp-" (string-downcase string)) package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-regexp-" string "-mode") package))
                   (fboundp olt-mode))
              (and (setq olt-mode (find-symbol (concat "olt-make-regexp-" (string-downcase string) "-mode") package))
                   (fboundp olt-mode)))
      (setq *olt-make-function-auto-mode-parameter* olt-mode)
      (setq *olt-make-function* olt-mode)
      t)))

olt-open

(defun olt-open ()
  "outline-tree を開く"
  (interactive)
  (unless (treeview-open-p)
    (unless (olt-config-loaded-p)
      (olt-config-load)
      (olt-update-olt-make-function-menu)
      (olt-init-setting))
    (cond
     ((find *olt-position* (list XPIS_LEFT XPIS_RIGHT))
      (treeview-create-ex *olt-width* *olt-position*))
     ((find *olt-position* (list XPIS_TOP XPIS_BOTTOM))
      (treeview-create-ex *olt-height* *olt-position*)))
    (when *olt-add-treeview-window*
      (case *olt-add-treeview-window*
        (:fix      (olt-enlarge-window nil))
        (:enlarge  (olt-enlarge-window t))
        (t         (olt-enlarge-window t))))
    (clrhash *olt-hash*)
    (clrhash *olt-buffer-hash*)
    (add-hook '*delete-buffer-hook* 'olt-delete)
    (add-hook '*pre-command-hook* 'olt-unset-text-emphasis)
    (add-hook '*post-command-hook* 'olt-select-cursor-related-node-for-hook)
    (add-hook 'ed::*after-save-buffer-hook* 'olt-update-buffer-node-title)
    (add-hook 'post-buffer-modified-hook 'olt-set-outline-old)
    (add-hook '*kill-xyzzy-hook* 'olt-close)
    ;;
    (treeview-disable-char-jump t)
    ;;
    (treeview-click-callback
     #'(lambda (hitem)
         (when (olt-get-action-immediately hitem)
           (stop-timer 'olt-node-action)
           (start-timer 0.01 'olt-node-action t))))
    (treeview-dblclk-callback
     #'(lambda (hitem)
         (unless (olt-get-action-immediately hitem)
           (stop-timer 'olt-node-action)
           (start-timer 0.01 'olt-node-action t))))
    ;;
    (let (keymap key x key-str)
      (treeview-keydown-callback
       #'(lambda (hitem vkey flag)
           (unless (keymapp keymap)
             (setq keymap *olt-map*)
             (setq key-str ""))
           (setq key (win-user:vkey-to-key vkey))
           (setq x (lookup-keymap *olt-fix-map* key))
           (if x
               (progn
                 (setq keymap nil)
                 (setq key-str "")
                 (olt-message "[fix] ~A" (key-to-string key))
                 (when (and (fboundp x) (commandp x))
                   (setq ed::*last-command* ed::*this-command*)
                   (setq ed::*this-command* x)
                   (call-interactively x)
                   (run-hooks 'ed::*post-command-hook*)))
             (progn
               (setq x (lookup-keymap keymap key))
               (if (keymapp x)
                   (progn
                     (if (string= key-str "")
                         (setq key-str (key-to-string key))
                       (setq key-str (concat key-str " " (key-to-string key))))
                     (olt-message "~A-" key-str)
                     (setq keymap x))
                 (progn
                   (if (string/= key-str "")
                       (progn
                         (setq key-str (concat key-str " " (key-to-string key)))
                         (olt-message "~A" key-str))
                     (message " "))
                   (setq keymap nil)
                   (when (and (fboundp x) (commandp x))
                     (setq ed::*last-command* ed::*this-command*)
                     (setq ed::*this-command* x)
                     (call-interactively x)
                     (run-hooks 'ed::*post-command-hook*)))))))))
    (olt-focus-editor)
    (olt-treeview-modify-style)
    (run-hooks '*olt-open-hook*)))

olt-close

(defun olt-close ()
  "outline-tree を閉じる"
  (interactive)
  (widen)
  (maphash #'(lambda (buffer hitem)
               (if (and (not (deleted-buffer-p buffer))
                        (gethash buffer *olt-buffer-hash*))
                   (olt-delete buffer)))
           *olt-buffer-hash*)
  (when *olt-add-treeview-window*
    (case *olt-add-treeview-window*
      (:fix      (olt-shrink-window nil))
      (:enlarge  (olt-shrink-window t))
      (t         (olt-shrink-window t))))
  (when (and *olt-save-size*
             (not (olt-shutting-p)))
    (cond
     ((find (treeview-get-position) (list XPIS_LEFT XPIS_RIGHT))
      (setq *olt-width* (olt-get-window-width (treeview-get-hwnd))))
     ((find (treeview-get-position) (list XPIS_TOP XPIS_BOTTOM))
      (setq *olt-height* (olt-get-window-height (treeview-get-hwnd))))))
  (treeview-close)
  (delete-hook '*delete-buffer-hook* 'olt-delete)
  (delete-hook '*pre-command-hook* 'olt-unset-text-emphasis)
  (delete-hook '*post-command-hook* 'olt-select-cursor-related-node-for-hook)
  (delete-hook 'ed::*after-save-buffer-hook* 'olt-update-buffer-node-title)
  (delete-hook 'post-buffer-modified-hook 'olt-set-outline-old)
  (delete-hook '*kill-xyzzy-hook* 'olt-close)
  (olt-focus-editor)
  (refresh-screen)
  (run-hooks '*olt-close-hook*))

olt-delete

(defun olt-delete (&optional (buffer (selected-buffer)))
  "エディタ部のバッファに対応するノードを削除"
  (interactive)
  (let ((hitem (gethash buffer *olt-buffer-hash*)))
    (when (and (treeview-open-p)
               (treeview-hitem-valid-p hitem))
      (treeview-delete-item hitem)
      (remhash buffer *olt-buffer-hash*)))
  (save-excursion
    (set-buffer buffer)
    (run-hooks '*olt-delete-hook*))
  (when (and *olt-close-unnecessary-treeview*
             (zerop (treeview-get-count)))
    (olt-set-outline-old)
    (olt-close))
  t)

olt-shutting

  (defun olt-shutting ()
    (interactive)
    (when (treeview-open-p)
      (cond
       ((find (treeview-get-position) (list XPIS_LEFT XPIS_RIGHT))
        (setq window-size (olt-get-window-width (treeview-get-hwnd))))
       ((find (treeview-get-position) (list XPIS_TOP XPIS_BOTTOM))
        (setq window-size (olt-get-window-height (treeview-get-hwnd)))))
      (treeview-setsize *olt-window-size-min* *olt-window-size-min* 10000 1)
      (run-hooks '*olt-shutting-hook*)))

olt-opening

  (defun olt-opening ()
    (interactive)
    (when (treeview-open-p)
      (treeview-setsize
       (if (<= *olt-window-size-threshold* window-size)
           window-size *olt-window-size-default*)
       *olt-window-size-min* 10000 1)
      (run-hooks '*olt-opening-hook*)))

olt-toggle-opening-and-shutting

  (defun olt-toggle-opening-and-shutting ()
    (interactive)
    (when (treeview-open-p)
      (if (olt-shutting-p)
          (olt-opening) (olt-shutting))))

olt-make

(defun olt-make (&optional buffer following); following が形骸化している
  (interactive)
  (unless buffer
    (setq buffer (selected-buffer)))
  (if (listp buffer)
      (dolist (x buffer)
        (olt-make x following))
    (save-excursion
      (unless (eq buffer (selected-buffer))
        (set-buffer buffer))
      (olt-open)
      (save-excursion
        (save-restriction
          (widen)
          (if following
              (narrow-to-region (progn (goto-bol) (point)) (point-max)))
          (let ((root-hitem (gethash (selected-buffer) *olt-buffer-hash*)))
            ;; 既にバッファに対応する node が存在するかどうか
            (if root-hitem
                (progn
                  (while (not (eql 0 (treeview-item-has-children root-hitem)))
                    (treeview-delete-item (treeview-get-child-item root-hitem)))
                  ;; バッファ名が変更されていた場合への対処
                  (treeview-set-item-text root-hitem (buffer-name (selected-buffer)))
                  (if (get-buffer-file-name (selected-buffer))
                      (treeview-set-item-icon root-hitem *olt-file-icon* *olt-file-icon*)))
              (progn
                (setq root-hitem
                      (olt-insert-buffer-item (buffer-name (selected-buffer)) TVI_ROOT))
                (if (get-buffer-file-name (selected-buffer))
                    (treeview-set-item-icon root-hitem *olt-file-icon* *olt-file-icon*))
                (setf (gethash root-hitem *olt-hash*)
                      `(:buffer-node () ,(selected-buffer) ()))
                (setf (gethash (selected-buffer) *olt-buffer-hash*) root-hitem)))
            ;; 作成
            (when *olt-make-function-auto-mode-parameter*
              (setq *olt-make-function* *olt-make-function-auto-mode-parameter*)
              (setq *olt-make-function-auto-mode-parameter* nil))
            (when (or (functionp *olt-make-function*)
                      (and (symbolp *olt-make-function*)
                           (fboundp *olt-make-function*)))
              (long-operation
                (funcall *olt-make-function* root-hitem)))
            (treeview-expand-expand root-hitem :child t :visible nil
                                    :depth (if (eq *olt-make-expand* :depth)
                                               *olt-make-expand-depth*
                                             *olt-make-expand*))
            (olt-select-cursor-related-node nil)
            (olt-focus-editor)
            (refresh-screen))
          (setq *olt-buffer-latest* t)
          (enable-post-buffer-modified-hook t)))
      (olt-treeview-modify-color)
      (run-hooks '*olt-make-hook*))))

olt-make-only-buffer-node

(defun olt-make-only-buffer-node (&optional buffer open-p)
  "olt: buffer-node のみ作成
BUFFER には buffer または buffer の list を指定。
nil の場合は (selected-buffer) が対象となる。
olt-make とは異なり、treeview が開いていない場合は指定がない限り
olt-open を行わない。"
  (interactive)
  (unless (or open-p (treeview-open-p))
    (return-from olt-make-only-buffer-node))
  (let (r (*olt-make-function* nil))
    (declare (special *olt-make-function*))
    (unless buffer
      (setq buffer (selected-buffer)))
    (cond
     ((listp buffer)
      (dolist (x buffer)
        (olt-make-only-buffer-node x)))
     ((bufferp buffer)
      (setq r (run-hook-with-args-until-success
               '*before-olt-make-only-buffer-node-hook* buffer))
      (when r (return-from olt-make-only-buffer-node r))
      (olt-make buffer)
      (olt-set-outline-old buffer)))))

olt-make-only-buffer-node-all-buffer

(defun olt-make-only-buffer-node-all-buffer ()
  (interactive)
  (olt-make-only-buffer-node (buffer-list)))

olt-goto-node-related-point

(defun olt-goto-node-related-point (&optional (hitem (treeview-get-selected-item))
                                    &key (top nil))
  (interactive)
  (when (and (treeview-open-p)
             (treeview-hitem-valid-p hitem))
    (olt-set-buffer hitem)
    (let ((po (point)))
      (multiple-value-bind (view-range restriction-range emphasis-range)
          (olt-get-ranges hitem)
        (when (and view-range
                   (or top
                       (< po (car view-range))
                       (< (cdr view-range) po)))
          (widen)
          (goto-char (car view-range))
          (cond
           ((and (eq *olt-recenter* :line)
                 (numberp *olt-recenter-line*)
                 (integerp *olt-recenter-line*))
            (recenter *olt-recenter-line*))
           (*olt-recenter*
            (recenter))))))))

olt-select-node

(defun olt-select-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (if (treeview-hitem-valid-p hitem)
      (olt-select-node-1 hitem #'identity)))

olt-select-child-node

(defun olt-select-child-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-child-item))

olt-select-next-sibling-node

(defun olt-select-next-sibling-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-next-sibling-item))

olt-select-prev-sibling-node

(defun olt-select-prev-sibling-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-prev-sibling-item))

olt-select-parent-node

(defun olt-select-parent-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-parent-item))

olt-select-first-visible-node

(defun olt-select-first-visible-node ()
  (interactive)
  (olt-select-node-1 nil #'treeview-get-first-visible-item))

olt-select-last-visible-node

(defun olt-select-last-visible-node ()
  (interactive)
  (olt-select-node-1 nil #'treeview-get-last-visible-item))

olt-select-last-window-visible-node

(defun olt-select-last-window-visible-node ()
  (interactive)
  (olt-select-node-1 nil #'treeview-get-last-window-visible-item))

olt-select-next-visible-node

(defun olt-select-next-visible-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-next-visible-item))

olt-select-prev-visible-node

(defun olt-select-prev-visible-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-prev-visible-item))

olt-select-ancestor-node

(defun olt-select-ancestor-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-ancestor-item))

olt-select-descendants-node

(defun olt-select-descendants-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-descendants-item))

olt-select-up-node

(defun olt-select-up-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-up-item))

olt-select-down-node

(defun olt-select-down-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-down-item))

olt-select-youngest-child-node

(defun olt-select-youngest-child-node (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-youngest-child-item))

olt-select-root-node

(defun olt-select-root-node ()
  (interactive)
  (olt-select-node-1 nil #'treeview-get-root-item))

olt-select-bottom-node

(defun olt-select-bottom-node ()
  (interactive)
  (olt-select-node-1 nil #'treeview-get-bottom-item))

olt-select-node-delay

(defun olt-select-node-delay ()
  (interactive)
  (let* ((ohitem (treeview-get-selected-item))
         (fn #'(lambda ()
                 (let ((hitem (treeview-get-selected-item)))
                   (when (treeview-hitem-valid-p hitem)
                     (treeview-select-item ohitem)
                     (olt-select-node-1 hitem #'identity))))))
    (start-timer *olt-select-node-delay-sec* fn t)))

olt-select-up-key-node-and-default-action

(defun olt-select-up-key-node-and-default-action (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-up-key-item))

olt-select-down-key-node-and-default-action

(defun olt-select-down-key-node-and-default-action (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-down-key-item))

olt-select-left-key-node-and-default-action

(defun olt-select-left-key-node-and-default-action (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-left-key-item)
  (when (treeview-expand-p hitem)
    (treeview-expand-collapse hitem)))

olt-select-right-key-node-and-default-action

(defun olt-select-right-key-node-and-default-action (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-select-node-1 hitem #'treeview-get-right-key-item)
  (when (and (not (zerop (treeview-item-has-children hitem)))
             (not (treeview-expand-p hitem)))
    (treeview-expand-expand hitem)))

olt-select-buffer-related-buffer-node

(defun olt-select-buffer-related-buffer-node (&optional buffer)
  "buffer に対応した buffer-node を選択。"
  (interactive)
  (olt-select-node (olt-get-buffer-related-buffer-node buffer)))

olt-select-cursor-related-node

(defun olt-select-cursor-related-node (&optional (expand t))
  "olt: ポイントの位置に対応したノードを選択。
EXPAND: t   可能な限り展開
        <integer> 展開する階層レベル
        上記以外 展開しない"
  (interactive)
  (let ((*olt-action-immediately* nil))
    (declare (special *olt-action-immediately*))
    (olt-select-node (olt-get-cursor-related-node expand))))

olt-select-cursor-related-node-for-hook

(defun olt-select-cursor-related-node-for-hook ()
  (interactive)
  (when (and *olt-chase-cursor*
             (treeview-open-p)
             (and (symbolp *this-command*)
                  (string/= (package-name (symbol-package *this-command*))
                            "outline-tree"))
             (not (find *this-command* *olt-except-commands-for-select-cursor-related-node*)))
    (olt-select-cursor-related-node (if (eq *olt-chase-expand* :depth)
                                        *olt-chase-expand-depth*
                                      *olt-chase-expand*))))

olt-select-cursor-related-node-or-make

(defun olt-select-cursor-related-node-or-make (&optional buffer)
  (interactive)
  (unless buffer
    (setq buffer (selected-buffer)))
  (if (listp buffer)
      (dolist (x buffer)
        (olt-select-cursor-related-node-or-make x))
    (when (and (bufferp buffer)
               (not (deleted-buffer-p buffer)))
      (save-excursion
        (unless (eq buffer (selected-buffer))
          (set-buffer buffer))
        (if (and (treeview-open-p) *olt-buffer-latest*)
            (olt-select-cursor-related-node)
          (olt-make))))))

olt-update-all-modified-buffer-node

(defun olt-update-all-modified-buffer-node ()
  (interactive)
  (when (treeview-open-p)
    (let ((buffer-list (olt-get-modified-buffer-list)))
      (if buffer-list
          (olt-make buffer-list)))))

olt-update-buffer-node-title

(defun olt-update-buffer-node-title (&optional buffer)
  (interactive)
  (unless buffer
    (setq buffer (selected-buffer)))
  (cond
   ((listp buffer)
    (dolist (x buffer)
      (olt-update-buffer-node-title x)))
   ((bufferp buffer)
    (let ((hitem (gethash buffer *olt-buffer-hash*)))
      (when hitem
        (treeview-set-item-text
         hitem
         (concat (if (buffer-local-value buffer '*olt-buffer-latest*) "" "* ")
                 (buffer-name buffer))))))))

olt-node-action

(defun olt-node-action (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (let (value func)
    (setq value (gethash hitem *olt-hash*))
    (if (null value)
        (return-from olt-node-action nil))
    (setq func (nth 1 value))
    (if func
        (funcall func)
      (case (car value)
        (:buffer-node
         (olt-set-buffer)
         (widen)
         (refresh-screen))
        ((:node :header-node :dependent-node)
         (olt-goto-node-related-point hitem :top t)
         (multiple-value-bind (view-range restriction-range emphasis-range)
             (olt-get-ranges hitem)
           (widen)
           (when restriction-range
             (narrow-to-region (car restriction-range) (cdr restriction-range)))
           (when emphasis-range
             (olt-set-text-emphasis emphasis-range)))
         (refresh-screen))
        ((:info-node :dummy-node)
         (olt-node-action (treeview-get-parent-item hitem)))))))

olt-set-buffer

(defun olt-set-buffer (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (let ((buffer (olt-get-node-related-buffer hitem)) window)
    (when (and (bufferp buffer)
               (not (deleted-buffer-p buffer)))
      (setq window (get-buffer-window buffer))
      (if window
          (set-window window)
        (set-buffer buffer)))))

olt-set-insert-mark

(defun olt-set-insert-mark (&optional (hitem (treeview-get-selected-item)) (after 1))
  (interactive)
  (treeview-set-insert-mark hitem))

olt-edit-label

(defun olt-edit-label (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (when (treeview-hitem-valid-p hitem)
    (treeview-edit-label hitem)))

olt-nop

(defun olt-nop (&optional hitem)
  (interactive)
  nil)

olt-expand-expand

(defun olt-expand-expand (&optional (hitem (treeview-get-selected-item))
                          &key sibling child)
  (interactive)
  (treeview-expand-expand hitem :sibling sibling :child child)
  (treeview-ensure-visible (treeview-get-selected-item)))

olt-expand-expand-child

(defun olt-expand-expand-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-expand hitem :child t))

olt-expand-expand-sibling

(defun olt-expand-expand-sibling (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-expand hitem :sibling t))

olt-expand-expand-sibling-child

(defun olt-expand-expand-sibling-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-expand hitem :sibling t :child t))

olt-expand-expand-all

(defun olt-expand-expand-all ()
  (interactive)
  (olt-expand-expand TVGN_ROOT :sibling t :child t))

olt-expand-collapse

(defun olt-expand-collapse (&optional (hitem (treeview-get-selected-item))
                                      &key sibling child)
  (interactive)
  (treeview-expand-collapse hitem :sibling sibling :child child)
  (treeview-ensure-visible (treeview-get-selected-item)))

olt-expand-collapse-child

(defun olt-expand-collapse-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-collapse hitem :child t))

olt-expand-collapse-sibling

(defun olt-expand-collapse-sibling (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-collapse hitem :sibling t))

olt-expand-collapse-sibling-child

(defun olt-expand-collapse-sibling-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-collapse hitem :sibling t :child t))

olt-expand-collapse-all

(defun olt-expand-collapse-all ()
  (interactive)
  (olt-expand-collapse TVGN_ROOT :sibling t :child t))

olt-expand-toggle

(defun olt-expand-toggle (&optional (hitem (treeview-get-selected-item))
                          &key sibling child)
  (interactive)
  (treeview-expand-toggle hitem :sibling sibling :child child)
  (treeview-ensure-visible (treeview-get-selected-item)))

olt-expand-toggle-child

(defun olt-expand-toggle-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-toggle hitem :child t))

olt-expand-toggle-sibling

(defun olt-expand-toggle-sibling (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-toggle hitem :sibling t))

olt-expand-toggle-sibling-child

(defun olt-expand-toggle-sibling-child (&optional (hitem (treeview-get-selected-item)))
  (interactive)
  (olt-expand-toggle hitem :sibling t :child t))

olt-expand-toggle-all

(defun olt-expand-toggle-all (&optional dummy-hitem)
  (interactive)
  (olt-expand-toggle TVGN_ROOT :sibling t :child t))

olt-jump-node

(defun olt-jump-node (pattern)
  (interactive "sOLT: Node Jump: "
    :default0 *treeview-last-search-string* :history0 'ed::search)
  (long-operation
    (when (interactive-p)
      (setq *treeview-last-search-string* pattern))
    (let (hitem hitems)
      (unless pattern
        (setq pattern (olt-get-jump-node-info)))
      (when pattern
        (setq hitems (treeview-find-nodes pattern))
        (when (null hitems)
          (olt-message "~Aが見つかりません" pattern)
          (return-from olt-jump-node nil))
        (if (= 1 (length hitems))
            (setq hitem (car hitems))
          (setq hitem (olt-select-nodes-dialog hitems)))
        (if (treeview-hitem-valid-p hitem)
            (olt-select-node hitem))))))

olt-describe-key-briefly

(defun olt-describe-key-briefly (key &optional arg)
  (interactive
      (list
       (let (key one-key (keymap *olt-map*) x (key-str ""))
         (loop
           (olt-focus-editor)
           (minibuffer-prompt "OLT: Describe key briefly: ~A" key-str)
           (setq one-key (read-char *keyboard*))
           (push one-key key)
           (when (lookup-keymap *olt-fix-map* one-key)
             (setq key (list one-key))
             (return))
           (setq x (lookup-keymap keymap one-key))
           (if (keymapp x)
               (progn
                 (setq key-str (concat key-str (key-to-string one-key) " "))
                 (setq keymap x))
             (return)))
         (minibuffer-message "")
         (nreverse key))
       nil))
  (let (command)
    (if (setq command (lookup-keymap *olt-fix-map* key))
        (progn
          (setq key (key-to-string key))
          (cond
           (arg
            (save-excursion
              (insert (format nil "OLT: [fix] ~a (~a)" key command))))
           (t
            (olt-message "[fix] ~a runs the command ~A" key command))))
      (progn
        (setq command (lookup-keymap *olt-map* key))
        (setq key (key-to-string key))
        (cond ((null command)
               (olt-message "~a is not bound" key))
              (arg
               (save-excursion
                 (insert (format nil "OLT: ~a (~a)" key command))))
              (t
               (olt-message "~a runs the command ~A" key command)))))))

olt-describe-bindings

(defun olt-describe-bindings ()
  (interactive)
  (let ((shadow nil))
    (long-operation
      (olt-message "Building binding list...")
      (with-output-to-temp-buffer ("*Help*")
        (format t "Outline-Tree Fix Bindings:~%key~20Tbinding~%---~20T-------~%")
        (ed::describe-bindings-1 "" *olt-fix-map* nil)
        (push *olt-fix-map* shadow)
        (format t "~%Outline-Tree Bindings:~%key~20Tbinding~%---~20T-------")
        (ed::describe-bindings-1 "" *olt-map* shadow)
        (format t "~%Outline-Tree I-search Bindings:~%key~20Tbinding~%---~20T-------")
        (ed::describe-bindings-1 "" *treeview-isearch-map* nil)
        
        (goto-char 0))
      (olt-message "Building binding list...done"))))

olt-other-window-on-treeview

(defun olt-other-window-on-treeview (&optional (arg 1 f) no-error)
  (interactive "p")
  (olt-other-window-on-editor arg no-error t))

olt-move-previous-window-on-treeview

(defun olt-move-previous-window-on-treeview (&optional (arg 1 f))
  (interactive "p")
  (olt-other-window-on-treeview (- arg) (null f)))

olt-other-window-on-editor

(defun olt-other-window-on-editor (&optional (arg 1 f) no-error outline-focus-p)
  (interactive "p")
  (let* ((first (car (caaddr (current-window-configuration))))
         (last (caar (last (caddr (current-window-configuration)))))
         (current (if outline-focus-p
                      (if (> arg 0) last first)
                    (selected-window)))
         (target current)
         (treeview-open-p (treeview-open-p))
         (outline-focus-p outline-focus-p))
    (if (> arg 0)
        (dotimes (x arg)
          (if (and treeview-open-p
                   (not outline-focus-p)
                   (eq target last))
              (setq outline-focus-p t)
            (progn
              (setq outline-focus-p nil)
              (setq target (next-window target))
              (when (eq target current)
                (olt-focus-editor)
                (refresh-screen)
                (and f (not no-error)
                     (error 'range-error :datum arg))
                (return)))))
      (dotimes (x (- arg))
        (if (and treeview-open-p
                 (not outline-focus-p)
                 (eq target first))
            (setq outline-focus-p t)
          (progn
            (setq outline-focus-p nil)
            (setq target (previous-window target))
            (when (eq target current)
              (olt-focus-editor)
              (refresh-screen)
              (and f (not no-error)
                   (error 'range-error :datum arg))
              (return))))))
    (if outline-focus-p
        (olt-focus-outline)
      (progn
        (olt-focus-editor)
        (set-window target)
        (refresh-screen)))))

olt-move-previous-window-on-editor

(defun olt-move-previous-window-on-editor (&optional (arg 1 f))
  (interactive "p")
  (olt-other-window-on-editor (- arg) (null f)))

olt-focus-editor

(defun olt-focus-editor ()
  (interactive)
  (winapi:SetFocus (get-window-handle))
  (run-hooks '*olt-focus-editor-hook*))

olt-focus-outline

(defun olt-focus-outline ()
  (interactive)
  (let (hitem)
    (when (treeview-open-p)
      (winapi:SetFocus (treeview-get-hwnd))
;      (if (treeview-hitem-valid-p
;           (setq hitem (treeview-get-selected-item)))
;          (treeview-ensure-visible hitem))
      ))
  (run-hooks '*olt-focus-outline-hook*))

olt-toggle-action-immediately

(defun olt-toggle-action-immediately (&key (arg nil sv) local)
  (interactive)
  (cond ((or local (local-variable-p '*olt-action-immediately*))
         (setq *olt-action-immediately*
               (if (null sv) (not *olt-action-immediately*) arg)))
        (t
         (setq-default *olt-action-immediately*
                       (if (null sv) (not *olt-action-immediately*) arg)))))

olt-toggle-chase

(defun olt-toggle-chase (&key (arg nil sv) local)
  (interactive)
  (cond ((or local (local-variable-p '*olt-chase-cursor*))
         (setq *olt-chase-cursor*
               (if (null sv) (not *olt-chase-cursor*) arg)))
        (t
         (setq-default *olt-chase-cursor*
                       (if (null sv) (not *olt-chase-cursor*) arg)))))

olt-toggle-range-type-narrow

(defun olt-toggle-range-type-narrow (&key (arg nil sv) local)
  (interactive)
  (cond ((or local (local-variable-p '*olt-range-type-narrow*))
         (setq *olt-range-type-narrow*
               (if (null sv) (not *olt-range-type-narrow*) arg)))
        (t
         (setq-default *olt-range-type-narrow*
                       (if (null sv) (not *olt-range-type-narrow*) arg)))))

olt-toggle-view-restriction

(defun olt-toggle-view-restriction (&key (arg nil sv) local)
  (interactive)
  (if *olt-view-restriction*
      (widen))
  (cond ((or local (local-variable-p '*olt-view-restriction*))
         (setq *olt-view-restriction*
               (if (null sv) (not *olt-view-restriction*) arg)))
        (t
         (setq-default *olt-view-restriction*
                       (if (null sv) (not *olt-view-restriction*) arg)))))

olt-toggle-view-emphasis

(defun olt-toggle-view-emphasis (&key (arg nil sv) local)
  (interactive)
  (if *olt-view-emphasis*
    (olt-unset-text-emphasis))
  (cond ((or local (local-variable-p '*olt-view-emphasis*))
         (setq *olt-view-emphasis*
               (if (null sv) (not *olt-view-emphasis*) arg)))
        (t
         (setq-default *olt-view-emphasis*
                       (if (null sv) (not *olt-view-emphasis*) arg)))))

olt-toggle-hide-restricted-region

(defun olt-toggle-hide-restricted-region (&key (arg nil sv) local)
  (interactive)
  (cond ((or local (local-variable-p 'hide-restricted-region))
         (setq hide-restricted-region
               (if (null sv) (not hide-restricted-region) arg)))
        (t
         (setq-default hide-restricted-region
                       (if (null sv) (not hide-restricted-region) arg)))))

olt-option-property-sheet

(defun olt-option-property-sheet ()
  (interactive)
  (let (sheet result)
    (dolist (page *olt-option-prop-page*)
      (cond ((symbolp page)
             (push page sheet))
            (t
             (push (list (car page)
                         (cadr page)
                         (let ((init (caddr page)))
                           (when init
                             (funcall init)))
                         (cadddr page))
                   sheet))))
    (multiple-value-setq (result *olt-option-prop-page-no*)
      (property-sheet sheet "アウトラインツリー設定" *olt-option-prop-page-no*))
    (dolist (r result)
      (let ((f (get (car r) 'olt-prop-result)))
        (when f
          (funcall f (cdr r))))))
  (olt-set-outline-old))

olt-toggle-action-immediately-tool-bar

(defun olt-toggle-action-immediately-tool-bar ()
  (interactive)
  (olt-toggle-action-immediately :local *olt-tool-bar-local*))

olt-toggle-chase-tool-bar

(defun olt-toggle-chase-tool-bar ()
  (interactive)
  (olt-toggle-chase :local *olt-tool-bar-local*))

olt-toggle-range-type-narrow-tool-bar

(defun olt-toggle-range-type-narrow-tool-bar ()
  (interactive)
  (olt-toggle-range-type-narrow :local *olt-tool-bar-local*))

olt-toggle-view-restriction-tool-bar

(defun olt-toggle-view-restriction-tool-bar ()
  (interactive)
  (olt-toggle-view-restriction :local *olt-tool-bar-local*))

olt-toggle-view-emphasis-tool-bar

(defun olt-toggle-view-emphasis-tool-bar ()
  (interactive)
  (olt-toggle-view-emphasis :local *olt-tool-bar-local*))

olt-tool-bar-change

(defun olt-tool-bar-change ()
  (interactive)
  (let ((visible-p (ed::command-bar-visible-p (ed::find-command-bar 'olt-tool-bar))))
;    (msgbox "visible-p: done")
    (when visible-p
      (hide-command-bar 'olt-tool-bar))
;    (msgbox "hide-command-bar: done")
    (delete-command-bar 'olt-tool-bar)
    (gc)
    (olt-message "outline-tree ツールバー更新中")
    (sleep-for 0.2)
;    (msgbox "delete-command-bar: done")
    (defun olt-tool-bar ()
      (create-tool-bar
       'olt-tool-bar
       (merge-pathnames "site-lisp/olt/olt-toolbar.bmp" (si:system-root))
       '(("アウトライン作成(更新)" 0 olt-make)
         ("閉じる" 1 olt-close olt-tool-bar-update-close))))
;    (msgbox "defun: done")
    (define-command-bar 'olt-tool-bar "Outline(&O)")
;    (msgbox "define-command-bar: done")
    (when visible-p
      (show-command-bar 'olt-tool-bar))
;    (msgbox "show-command-bar: done")
    ))

olt-uninstall

(defun olt-uninstall ()
  (interactive)
  (olt-close)
  (run-hooks 'outline-tree::*olt-uninstall-hook*)
  (delete-command-bar 'outline-tree::olt-tool-bar)
  (let ((package (find-package "outline-tree")))
    (dolist (x (copy-list ed::*history-variable-list*))
      (if (eq (symbol-package x) package)
          (unregister-history-variable x)))))