Emacs-PDE

 view release on metacpan or  search on metacpan

lisp/imenu-tree.el  view on Meta::CPAN

       (cancel-timer imenu-tree-update-timer))
  (when imenu-tree-auto-update
    (setq imenu-tree-update-timer
          (run-with-timer nil imenu-tree-update-interval
                          'imenu-tree-update-timer))
    (mapc (lambda (buf)
            (when (local-variable-if-set-p 'imenu-tree)
              (set (make-local-variable 'imenu-tree-need-update) t)
              (add-hook 'after-change-functions 'imenu-tree-after-change nil t)))
          (buffer-list))))

(defun imenu-tree-update-timer ()
  "Update and show the tree if needed."
  (imenu-tree-show)
  (when (and imenu-tree
             ;; the tree is visible
             (get-buffer-window imenu-tree-buffer) 
             imenu-tree-need-update
             ;; the buffer is not too large
             (not (> (buffer-size) imenu-auto-rescan-maxout)))
    (setq imenu--index-alist nil)
    (imenu--make-index-alist t)
    (let ((tree imenu-tree))
      (with-current-buffer imenu-tree-buffer
        (goto-char (widget-get tree :from))
        (tree-mode-reflesh)))
    (setq imenu-tree-need-update nil)))

(defun imenu-tree-after-change (&rest ignore)
  "Mark `imenu-tree-need-update' if make change in buffer"
  (setq imenu-tree-need-update t))

(defun imenu-tree-widget (buf)
  `(tree-widget
    :node (push-button
           :tag ,(with-current-buffer buf
                   (eval imenu-tree-name))
           :format "%[%t%]\n"
           :notify tree-mode-reflesh-parent)
    :dynargs imenu-tree-expand
    :has-children t
    :buffer ,buf
    :open t))

(defun imenu-tree-item (item buf icon)
  (if (listp (cdr item))
      `(tree-widget
        :node (push-button
               :tag ,(car item)
               :button-icon "bucket"
               :notify tree-mode-reflesh-parent
               :format "%[%t%]\n")
        :dynargs imenu-tree-expand-bucket
        :has-children t)
    `(push-button
      :tag ,(car item)
      :imenu-marker ,(let ((pos (cdr item)))
                       (cond ((markerp pos) pos)
                             ((numberp pos)
                              (set-marker (make-marker) pos buf))
                             ((overlayp pos)
                              (set-marker (make-marker) (overlay-start pos) buf))
                             (t (error "Unknown position type: %S" pos))))
      :button-icon ,icon
      :format "%[%t%]\n"
      :notify imenu-tree-select)))

(defun imenu-tree-select (node &rest ignore)
  (let ((marker (widget-get node :imenu-marker)))
    (select-window (display-buffer (marker-buffer marker)))
    (goto-char marker)))

(defun imenu-tree-expand-bucket (bucket)
  (let ((tree bucket) path buf index name)
    (while (and (tree-widget-p tree)
                (widget-get tree :parent))
      (push (widget-get (widget-get tree :node) :tag) path)
      (setq tree (widget-get tree :parent)))
    (setq buf (widget-get tree :buffer)
          name (car (last path)))
    (setq index (buffer-local-value 'imenu--index-alist buf))
    (while path
      (setq index (cdr (assoc (car path) index)))
      (if (null index)
          (error "Type g to update imenu index"))
      (setq path (cdr path)))
    (mapcar (lambda (item)
              (imenu-tree-item item buf
                               (or (assoc-default name imenu-tree-icons
                                                  'string-match)
                                   "function")))
            index)))

(defun imenu-tree-expand (tree)
  (or (widget-get tree :args)
      (let ((buf (widget-get tree :buffer))
            index)
        (setq index (with-current-buffer buf
                      (setq imenu--index-alist nil)
                      (imenu--make-index-alist t)
                      (delq nil imenu--index-alist)))
        (mapcar (lambda (item)
                  (imenu-tree-item item buf "function"))
                index))))

(defun imenu-tree-display ()
  (interactive)
  (let ((widget (widget-at (1- (line-end-position))))
        marker)
    (if (setq marker (widget-get widget :imenu-marker))
        (with-selected-window (display-buffer (marker-buffer marker))
          (goto-char marker)))))

(define-key imenu-tree-mode-map "\C-o" 'imenu-tree-display)

;;; imenu-tree.el ends here



( run in 1.572 second using v1.01-cache-2.11-cpan-5a3173703d6 )