X-Git-Url: https://code.delx.au/gnu-emacs-elpa/blobdiff_plain/30cbf7485c48453b5a4df02c58c1728b9529266a..424572b6db84c984458666041dbdff2dcb06b645:/packages/minimap/minimap.el diff --git a/packages/minimap/minimap.el b/packages/minimap/minimap.el index 7c519c0d5..86ed0a154 100644 --- a/packages/minimap/minimap.el +++ b/packages/minimap/minimap.el @@ -1,10 +1,10 @@ ;;; minimap.el --- Sidebar showing a "mini-map" of a buffer -;; Copyright (C) 2009-2011 Free Software Foundation, Inc. +;; Copyright (C) 2009-2014 Free Software Foundation, Inc. -;; Author: David Engster +;; Author: David Engster ;; Keywords: -;; Version: 1.0 +;; Version: 1.1 ;; This file is part of GNU Emacs. @@ -28,15 +28,12 @@ ;; highlights the currently shown region and updates its position ;; automatically. You can navigate in the minibar by dragging the ;; active region with the mouse, which will scroll the corresponding -;; edit buffer. +;; edit buffer. Additionally, you can overlay information from the +;; tags gathered by CEDET's semantic analyzer. -;; To create the minimap sidebar, type M-x minimap-create. -;; To dismiss it, type M-x minimap-kill. - -;; Usage: -;; * Use 'M-x minimap-create' in a buffer you're currently editing. -;; * Use 'M-x minimap-kill' to kill the minimap. -;; * Use 'M-x customize-group RET minimap RET' to adapt minimap to your needs. +;; Simply use M-x minimap-mode to toggle activation of the minimap. +;; Use 'M-x customize-group RET minimap RET' to adapt minimap to your +;; needs. ;;; KNOWN BUGS: @@ -51,6 +48,24 @@ ;; * Moving the active region with the keyboard / mouse-wheel ? +;;; News: + +;;;; Changes since v1.0: +;; +;; - Largely rewritten as a minor mode; use M-x minimap-mode to +;; enable/disable. +;; - Minimap will now remain active for all buffers which derive from +;; `prog-mode' (can be changed through `minimap-major-modes'). The +;; minimap window will be automatically created or deleted (see new +;; variables `minimap-recreate-window' and +;; `minimap-automatically-delete-window'). +;; - Possibility to set a minimum width of the minimap window +;; (`minimap-minimum-width'). +;; - Minimap window will be marked so that you should not be able to +;; enter it. +;; - Semantic overlays will be automatically updated during editing. +;; - Lots of bug fixes. + ;;; Customizable variables: (defgroup minimap nil @@ -76,37 +91,43 @@ By default, this is only a different background color." '((((background dark)) (:box (:line-width 1 :color "white") :inherit (font-lock-function-name-face minimap-font-face) - :height 2.5 :background "gray10")) + :height 2.75 :background "gray10")) (t (:box (:line-width 1 :color "black") :inherit (font-lock-function-name-face minimap-font-face) - :height 2.5 :background "gray90"))) + :height 2.75 :background "gray90"))) "Face used for functions in the semantic overlay.") (defface minimap-semantic-variable-face '((((background dark)) (:box (:line-width 1 :color "white") :inherit (font-lock-variable-name-face minimap-font-face) - :height 2.5 :background "gray10")) + :height 2.75 :background "gray10")) (t (:box (:line-width 1 :color "black") :inherit (font-lock-function-name-face minimap-font-face) - :height 2.5 :background "gray90"))) + :height 2.75 :background "gray90"))) "Face used for variables in the semantic overlay.") (defface minimap-semantic-type-face '((((background dark)) (:box (:line-width 1 :color "white") :inherit (font-lock-type-face minimap-font-face) - :height 2.5 :background "gray10")) + :height 2.75 :background "gray10")) (t (:box (:line-width 1 :color "black") :inherit (font-lock-function-name-face minimap-font-face) - :height 2.5 :background "gray90"))) + :height 2.75 :background "gray90"))) "Face used for types in the semantic overlay.") -(defcustom minimap-width-fraction 0.2 +(defcustom minimap-width-fraction 0.15 "Fraction of width which should be used for minimap sidebar." :type 'number :group 'minimap) +(defcustom minimap-minimum-width 30 + "Minimum width of minimap in characters (default size). +Use nil to disable." + :type 'number + :group 'minimap) + (defcustom minimap-window-location 'left "Location of the minimap window. Can be either the symbol `left' or `right'." @@ -114,8 +135,8 @@ Can be either the symbol `left' or `right'." (const :tag "Right" right)) :group 'minimap) -(defcustom minimap-buffer-name-prefix "*MINIMAP* " - "Prefix for buffer names of minimap sidebar." +(defcustom minimap-buffer-name " *MINIMAP*" + "Buffer name of minimap sidebar." :type 'string :group 'minimap) @@ -167,12 +188,12 @@ bottom or top." :type 'boolean :group 'minimap) -(defcustom minimap-hide-fringes t +(defcustom minimap-hide-fringes nil "Whether the minimap should hide the fringes." :type 'boolean :group 'minimap) -(defcustom minimap-dedicated-window nil +(defcustom minimap-dedicated-window t "Whether the minimap should create a dedicated window." :type 'boolean :group 'minimap) @@ -229,119 +250,198 @@ minimap buffer." :type '(repeat symbol) :group 'minimap) +(defcustom minimap-major-modes '(prog-mode) + "Major modes for which a minimap should be created. +This can also be a parent mode like 'prog-mode. +If nil, a minimap must be explicitly created for each buffer." + :type '(repeat symbol) + :group 'minimap) + +(defcustom minimap-recreate-window t + "Whether the minimap window should be automatically re-created. +If this is non-nil, the side window for the minimap will be +automatically re-created as soon as you kill it." + :type 'boolean + :group 'minimap) + +(defcustom minimap-automatically-delete-window t + "Whether the minimap window should be automatically deleted. +Setting this to non-nil will delete the minibuffer side window +when you enter a buffer which is not derived from +`minimap-major-modes' (excluding the minibuffer)." + :type 'boolean + :group 'minimap) + ;;; Internal variables +;; The buffer currently displayed in the minimap +(defvar minimap-active-buffer nil) +;; Window start/end from the base buffer (defvar minimap-start nil) (defvar minimap-end nil) +;; General overlay for the minimap +(defvar minimap-base-overlay nil) +;; Overlay for the active region (defvar minimap-active-overlay nil) -(defvar minimap-bufname nil) +;; Timer (defvar minimap-timer-object nil) -(defvar minimap-active-minimaps 0) -(defvar minimap-base-overlay nil) +;; Lines the minimap can display (defvar minimap-numlines nil) (defvar minimap-pointmin-overlay nil) -(make-variable-buffer-local 'minimap-start) -(make-variable-buffer-local 'minimap-end) -(make-variable-buffer-local 'minimap-active-overlay) -(make-variable-buffer-local 'minimap-bufname) -(make-variable-buffer-local 'minimap-base-overlay) -(make-variable-buffer-local 'minimap-numlines) -(make-variable-buffer-local 'minimap-pointmin-overlay) +;;; Helpers + +(defun minimap-active-current-buffer-p () + "Whether the current buffer is displayed in the minimap." + (and (eq (current-buffer) minimap-active-buffer) + (get-buffer minimap-buffer-name) + (with-current-buffer minimap-buffer-name + (eq minimap-active-buffer (buffer-base-buffer))))) + +(defsubst minimap-get-window () + "Get current minimap window." + (when (get-buffer minimap-buffer-name) + (get-buffer-window minimap-buffer-name))) + +(defsubst minimap-kill-buffer () + "Kill the minimap buffer." + (when (get-buffer minimap-buffer-name) + (kill-buffer minimap-buffer-name))) + +(defun minimap-create-window () + (let ((width (round (* (window-width) + minimap-width-fraction)))) + (when (< width minimap-minimum-width) + (setq width minimap-minimum-width)) + (if (eq minimap-window-location 'left) + (split-window-horizontally width) + (split-window-horizontally + (* -1 width)) + (other-window 1)) + ;; Set up the minimap window: + ;; You should not be able to enter the minimap window. + (set-window-parameter nil 'no-other-window t) + ;; Hide things. + (when minimap-hide-scroll-bar + (setq vertical-scroll-bar nil)) + (when minimap-hide-fringes + (set-window-fringes nil 0 0)) + ;; Switch to buffer. + (switch-to-buffer + (get-buffer-create minimap-buffer-name) t t) + ;; Do not fold lines in the minimap. + (toggle-truncate-lines 1) + ;; Make it dedicated. + (when minimap-dedicated-window + (set-window-dedicated-p nil t)) + (prog1 + (selected-window) + (other-window 1)))) + +(defun minimap-setup-hooks (&optional remove) + "Hook minimap into other modes. +If REMOVE is non-nil, remove minimap from other modes." + (if remove + (progn + (remove-hook 'outline-view-change-hook 'minimap-sync-overlays) + (remove-hook 'hs-hide-hook 'minimap-sync-overlays) + (remove-hook 'hs-show-hook 'minimap-sync-overlays)) + ;; outline-(minor-)mode + (add-hook 'outline-view-change-hook 'minimap-sync-overlays) + ;; hideshow + (add-hook 'hs-hide-hook 'minimap-sync-overlays) + (add-hook 'hs-show-hook 'minimap-sync-overlays))) ;;; Minimap creation / killing +(define-minor-mode minimap-mode + "Toggle minimap mode." + :global t + :group 'minimap + :lighter " MMap" + (if minimap-mode + (progn + (when (and minimap-major-modes + (apply 'derived-mode-p minimap-major-modes)) + (unless (minimap-get-window) + (minimap-create-window)) + ;; Create minimap. + (minimap-new-minimap)) + ;; Create timer. + (setq minimap-timer-object + (run-with-idle-timer minimap-update-delay t 'minimap-update)) + ;; Hook into other modes. + (minimap-setup-hooks)) + ;; Turn it off + (minimap-kill) + (minimap-setup-hooks t))) + ;;;###autoload (defun minimap-create () - "Create a minimap sidebar for the current window." + "Create a minimap sidebar." (interactive) - ;; If minimap is visible, do nothing. - (unless (and minimap-bufname - (get-buffer minimap-bufname) - (get-buffer-window (get-buffer minimap-bufname))) - (let ((bufname (concat minimap-buffer-name-prefix - (buffer-name (current-buffer)))) - (new-win (if (eq minimap-window-location 'left) - (split-window-horizontally - (round (* (window-width) - minimap-width-fraction))) - (split-window-horizontally - (round (* (window-width) - (- 1 minimap-width-fraction)))) - (other-window 1)))) - ;; If minimap exists but isn't visible, reuse it. - (if (and minimap-bufname - (get-buffer minimap-bufname)) - (switch-to-buffer minimap-bufname t) - ;; Otherwise create new minimap - (minimap-new-minimap bufname) - ;; If this is the first minimap, create the idle timer. - (when (zerop minimap-active-minimaps) - (setq minimap-timer-object - (run-with-idle-timer minimap-update-delay t 'minimap-update))) - (setq minimap-active-minimaps - (1+ minimap-active-minimaps)))) - (other-window 1) - (minimap-sync-overlays))) + (minimap-mode 1)) -(defun minimap-new-minimap (bufname) - "Create new minimap BUFNAME for current buffer and window." - (let ((indbuf (make-indirect-buffer (current-buffer) bufname t)) +(defun minimap-new-minimap () + "Create new minimap BUFNAME for current buffer and window. +Re-use already existing minimap window if possible." + (interactive) + (let ((currentbuffer (current-buffer)) + (win (minimap-get-window)) + (indbuf (make-indirect-buffer (current-buffer) + (concat minimap-buffer-name "_temp"))) (edges (window-pixel-edges))) - (setq minimap-bufname bufname) - (set-buffer indbuf) - (when minimap-hide-scroll-bar - (setq vertical-scroll-bar nil)) - (switch-to-buffer indbuf) - (setq minimap-base-overlay (make-overlay (point-min) (point-max) nil t t)) - (overlay-put minimap-base-overlay 'face 'minimap-font-face) - (overlay-put minimap-base-overlay 'priority 1) - (setq minimap-pointmin-overlay (make-overlay (point-min) (1+ (point-min)))) - (setq minimap-start (window-start) - minimap-end (window-end) - minimap-active-overlay (make-overlay minimap-start minimap-end) - line-spacing 0) - (overlay-put minimap-active-overlay 'face - 'minimap-active-region-background) - (overlay-put minimap-active-overlay 'priority 5) - (minimap-mode 1) - (when (and (boundp 'linum-mode) - linum-mode) - (linum-mode 0)) - (when minimap-hide-fringes - (set-window-fringes nil 0 0)) - (when minimap-dedicated-window - (set-window-dedicated-p nil t)) - (setq buffer-read-only t) - ;; Calculate the actual number of lines displayable with the minimap face. - (setq minimap-numlines - (floor - (/ - (- (nth 3 edges) (nth 1 edges)) - (car (progn (redisplay) (window-line-height)))))))) + ;; Remember the active buffer currently displayed in the minimap. + (setq minimap-active-buffer (current-buffer)) + ;; Hook into CEDET if necessary. + (when (and minimap-display-semantic-overlays + (boundp 'semantic-after-toplevel-cache-change-hook)) + (add-hook 'semantic-after-partial-cache-change-hook + 'minimap-apply-semantic-overlays nil t) + (add-hook 'semantic-after-toplevel-cache-change-hook + 'minimap-apply-semantic-overlays nil t)) + (with-selected-window win + ;; Now set up the minimap: + (when (window-dedicated-p) + (set-window-dedicated-p nil nil)) + (switch-to-buffer indbuf t t) + (minimap-kill-buffer) + (rename-buffer minimap-buffer-name) + ;; Do not fold lines in the minimap. + (toggle-truncate-lines 1) + (when minimap-dedicated-window + (set-window-dedicated-p nil t)) + (setq minimap-base-overlay (make-overlay (point-min) (point-max) nil t t)) + (overlay-put minimap-base-overlay 'face 'minimap-font-face) + (overlay-put minimap-base-overlay 'priority 1) + (setq minimap-pointmin-overlay (make-overlay (point-min) (1+ (point-min)))) + (setq minimap-start (window-start) + minimap-end (window-end) + minimap-active-overlay (make-overlay minimap-start minimap-end) + line-spacing 0) + (overlay-put minimap-active-overlay 'face + 'minimap-active-region-background) + (overlay-put minimap-active-overlay 'priority 5) + (minimap-sb-mode 1) + (when (and (boundp 'linum-mode) + linum-mode) + (linum-mode 0)) + (setq buffer-read-only t) + ;; Calculate the actual number of lines displayable with the minimap face. + (setq minimap-numlines + (floor + (/ + (- (nth 3 edges) (nth 1 edges)) + (car (progn (redisplay t) (window-line-height))))))) + (minimap-sync-overlays))) ;;;###autoload (defun minimap-kill () - "Kill minimap for current buffer. -Cancel the idle timer if no more minimaps are active." + "Kill minimap." (interactive) - (if (null minimap-bufname) - (message "No minimap associated with %s." (buffer-name (current-buffer))) - (let ((curname (buffer-name (current-buffer))) - (buf (get-buffer minimap-bufname)) - (win (get-buffer-window minimap-bufname))) - (setq minimap-bufname nil) - (if (null buf) - (message "No minimap associated with %s." curname) - (when win - (delete-window win)) - (kill-buffer buf) - (when (zerop - (setq minimap-active-minimaps - (1- minimap-active-minimaps))) - (cancel-timer minimap-timer-object) - (setq minimap-timer-object nil)) - (message "Minimap for %s killed." curname))))) + (when (minimap-get-window) + (delete-window (minimap-get-window))) + (cancel-timer minimap-timer-object)) ;;; Minimap update @@ -349,28 +449,70 @@ Cancel the idle timer if no more minimaps are active." "Update minimap sidebar if necessary. This is meant to be called from the idle-timer or the post command hook. When FORCE, enforce update of the active region." - (when minimap-bufname - (let ((win (get-buffer-window minimap-bufname)) - start end pt ov) - (when win - (setq start (window-start) - end (window-end) - pt (point) - ov) - (with-selected-window win - (unless (and (not force) - (= minimap-start start) - (= minimap-end end)) - (move-overlay minimap-active-overlay start end) - (setq minimap-start start - minimap-end end) - (minimap-recenter (line-number-at-pos (/ (+ end start) 2)) - (/ (- (line-number-at-pos end) - (line-number-at-pos start)) - 2))) - (goto-char pt) - (when minimap-always-recenter - (recenter (round (/ (window-height) 2))))))))) + (interactive) + ;; If we are in the minibuffer, do nothing. + (unless (active-minibuffer-window) + (if (minimap-active-current-buffer-p) + ;; We are still in the same buffer, so just update the minimap. + (let ((win (minimap-get-window)) + (start (window-start)) + (end (window-end)) + (pt (point))) + (when (and (null win) + minimap-recreate-window) + ;; The minimap window is no longer visible, so create it again... + (setq win (minimap-create-window)) + ;; ...and switch to existing minimap buffer. + (with-selected-window win + (when (window-dedicated-p) + (set-window-dedicated-p nil nil)) + (switch-to-buffer minimap-buffer-name t t) + (when minimap-dedicated-window + (set-window-dedicated-p nil t)))) + (with-selected-window win + ;; Make sure the base overlay spans the whole buffer. + (unless (and (= (overlay-start minimap-base-overlay) (point-min)) + (= (overlay-end minimap-base-overlay) (point-max))) + (move-overlay minimap-base-overlay (point-min) (point-max))) + (unless (and (not force) + (= minimap-start start) + (= minimap-end end)) + ;; Update the overlay. + (move-overlay minimap-active-overlay start end) + (setq minimap-start start + minimap-end end) + (minimap-recenter (line-number-at-pos (/ (+ end start) 2)) + (/ (- (line-number-at-pos end) + (line-number-at-pos start)) + 2))) + (goto-char pt) + (when minimap-always-recenter + (recenter (round (/ (window-height) 2))))) + ;; Redisplay + (sit-for 0)) + ;; The buffer was switched, check if the minimap should switch, too. + (if (and minimap-major-modes + (apply 'derived-mode-p minimap-major-modes)) + (progn + ;; Create window if necessary... + (unless (minimap-get-window) + (minimap-create-window)) + ;; ...and re-create minimap with new buffer... + (minimap-new-minimap) + ;; Redisplay + (sit-for 0) + ;; ...and call update again. + (minimap-update t)) + ;; Otherwise, delete window if the user so wishes. + (when (and (minimap-get-window) + minimap-automatically-delete-window) + ;; We wait a tiny bit before deleting the window, since we + ;; might only be temporarily in another buffer. + (run-with-timer 0.3 nil + (lambda () + (when (and (null (minimap-active-current-buffer-p)) + (minimap-get-window)) + (delete-window (minimap-get-window)))))))))) ;;; Overlay movement @@ -384,6 +526,7 @@ When FORCE, enforce update of the active region." (start-point (posn-point end-posn)) (make-cursor-line-fully-visible nil) (cursor-type nil) + (minimap-automatically-delete-window nil) (pcselmode (when (boundp 'pc-selection-mode) pc-selection-mode)) pt ev) @@ -501,16 +644,16 @@ active region." ;;; Minimap minor mode -(defvar minimap-mode-map (make-sparse-keymap) - "Keymap used by `minimap-mode'.") + (defvar minimap-sb-mode-map (make-sparse-keymap) + "Keymap used by `minimap-sb-mode'.") -(define-key minimap-mode-map [down-mouse-1] 'minimap-move-overlay-mouse) -(define-key minimap-mode-map [down-mouse-2] 'minimap-move-overlay-mouse) -(define-key minimap-mode-map [down-mouse-3] 'minimap-move-overlay-mouse) +(define-key minimap-sb-mode-map [down-mouse-1] 'minimap-move-overlay-mouse) +(define-key minimap-sb-mode-map [down-mouse-2] 'minimap-move-overlay-mouse) +(define-key minimap-sb-mode-map [down-mouse-3] 'minimap-move-overlay-mouse) -(define-minor-mode minimap-mode +(define-minor-mode minimap-sb-mode "Minor mode for minimap sidebar." - nil "minimap" minimap-mode-map) + nil "minimap" minimap-sb-mode-map) ;;; Sync minimap with modes which create/delete overlays. @@ -518,39 +661,48 @@ active region." "Synchronize overlays between base and minimap buffer. Apply semantic overlays or face enlargement if necessary." (interactive) - (when minimap-bufname - (let ((baseov (overlays-in (point-min) (point-max))) - (semantic (and (boundp 'semantic-version) - (semantic-active-p))) - ov props p) - (with-current-buffer minimap-bufname - (remove-overlays) - (while baseov - (when (setq props (minimap-get-sync-properties (car baseov))) - (setq ov (make-overlay (overlay-start (car baseov)) - (overlay-end (car baseov)))) - (while (setq p (car props)) - (overlay-put ov (car p) (cadr p)) - (setq props (cdr props)))) - (setq baseov (cdr baseov))) - (move-overlay minimap-pointmin-overlay (point-min) (1+ (point-min))) - ;; Re-apply font overlay - (move-overlay minimap-base-overlay (point-min) (point-max))) - ;; Face enlargement - (when (and font-lock-mode - (or (eq minimap-enlarge-certain-faces 'always) - (and (eq minimap-enlarge-certain-faces 'as-fallback) - (or (not minimap-display-semantic-overlays) - (not semantic))))) - (when (eq font-lock-support-mode 'jit-lock-mode) - (jit-lock-fontify-now)) - (with-current-buffer minimap-bufname - (minimap-enlarge-faces))) - ;; Semantic overlays - (when (and semantic - minimap-display-semantic-overlays) - (minimap-apply-semantic-overlays))) - (minimap-update t))) + ;; Get overlays and Semantic status from base buffer. + (when (and minimap-mode + (minimap-active-current-buffer-p)) + (with-current-buffer minimap-active-buffer + (let ((baseov (overlays-in (point-min) (point-max))) + (semantic (and (boundp 'semantic-version) + (semantic-active-p))) + ov props p) + ;; Apply overlays to minimap. + (with-current-buffer minimap-buffer-name + ;; Delete overlays (but keep our own). + (let ((ovs (overlays-in (point-min) (point-max)))) + (dolist (ov ovs) + (unless (member ov (list minimap-pointmin-overlay + minimap-base-overlay + minimap-active-overlay)) + (delete-overlay ov)))) + (while baseov + (when (and (eq (overlay-buffer (car baseov)) minimap-active-buffer) + (setq props (minimap-get-sync-properties (car baseov)))) + (setq ov (make-overlay (overlay-start (car baseov)) + (overlay-end (car baseov)))) + (while (setq p (car props)) + (overlay-put ov (car p) (cadr p)) + (setq props (cdr props)))) + (setq baseov (cdr baseov))) + (move-overlay minimap-pointmin-overlay (point-min) (1+ (point-min))) + ;; Re-apply font overlay + (move-overlay minimap-base-overlay (point-min) (point-max))) + ;; Face enlargement + (when (and font-lock-mode + (or (eq minimap-enlarge-certain-faces 'always) + (and (eq minimap-enlarge-certain-faces 'as-fallback) + (or (not minimap-display-semantic-overlays) + (not semantic))))) + (when (eq font-lock-support-mode 'jit-lock-mode) + (jit-lock-fontify-now)) + (minimap-enlarge-faces)) + ;; Semantic overlays + (when (and semantic + minimap-display-semantic-overlays) + (minimap-apply-semantic-overlays t)))))) (defun minimap-get-sync-properties (ov) "Get properties from overlay OV which should be synced. @@ -566,61 +718,67 @@ You can specify those properties with minimap-sync-overlay-properties))) (defun minimap-enlarge-faces () - "Apply default font to all faces in `minimap-normal-height-faces'. -This has to be called in the minimap buffer." + "Apply default font to all faces in `minimap-normal-height-faces'." (let ((pos (next-single-property-change (point-min) 'face)) next ov face) (while pos (setq face (get-text-property pos 'face)) - (when (delq nil (mapcar (lambda (x) (equal x face)) - minimap-normal-height-faces)) - (setq ov - (make-overlay pos - (setq pos (next-single-property-change pos 'face)))) - (overlay-put ov 'face `(:family ,(face-font 'default))) - (overlay-put ov 'priority 5)) + (when (and face + (member face minimap-normal-height-faces)) + (with-current-buffer minimap-buffer-name + (setq ov + (make-overlay pos + (setq pos (next-single-property-change pos 'face)))) + (overlay-put ov 'face `(:family ,(face-font 'default))) + (overlay-put ov 'priority 5))) (setq pos (next-single-property-change pos 'face))))) -(defun minimap-apply-semantic-overlays () +(defun minimap-apply-semantic-overlays (tags) "Apply semantic overlays to the minimap. -This has to be called from the base buffer." - (let ((tags (semantic-fetch-tags)) - tag class ov ovnew) - (while tags - (setq tag (car tags)) - (setq class (semantic-tag-class tag)) - (setq ov (semantic-tag-overlay tag)) - (when (and (overlayp ov) - (or (eq class 'function) - (eq class 'type) - (eq class 'variable))) - (with-current-buffer minimap-bufname - (let ((start (overlay-start ov)) - (end (overlay-end ov)) - (name (semantic-tag-name tag))) - (overlay-put - (setq ovnew (make-overlay start end)) - 'face `(:background ,(face-background - (intern (format "minimap-semantic-%s-face" - (symbol-name class)))))) - (overlay-put ovnew 'priority 1) - (setq start - (minimap-line-to-pos (/ (+ (line-number-at-pos start) - (line-number-at-pos end)) 2))) - (setq end (progn (goto-char start) (point-at-eol))) - (setq ovnew (make-overlay start end)) - (overlay-put ovnew 'face (format "minimap-semantic-%s-face" - (symbol-name class))) - (overlay-put ovnew 'display (concat " " name " ")) - (overlay-put ovnew 'priority 6)))) - (setq tags (cdr tags))))) - -;; outline-(minor-)mode -(add-hook 'outline-view-change-hook 'minimap-sync-overlays) - -;; hideshow -(add-hook 'hs-hide-hook 'minimap-sync-overlays) -(add-hook 'hs-show-hook 'minimap-sync-overlays) +TAGS is the list of tags. If it is t, fetch tags from buffer." + (when (and tags + minimap-mode) + (with-current-buffer minimap-active-buffer + (let (tag class ov ovnew) + (when (eq tags t) + (setq tags (semantic-fetch-tags))) + (while tags + (setq tag (car tags)) + (setq class (semantic-tag-class tag)) + (setq ov (semantic-tag-overlay tag)) + (when (and (overlayp ov) + (or (eq class 'function) + (eq class 'type) + (eq class 'variable))) + (with-current-buffer minimap-buffer-name + (let ((start (overlay-start ov)) + (end (overlay-end ov)) + (name (semantic-tag-name tag))) + ;; First, remove old Semantic overlays. + (remove-overlays start end 'minimap-semantic t) + ;; Now put the new ones. + (overlay-put + (setq ovnew (make-overlay start end)) + 'face `(:background ,(face-background + (intern (format "minimap-semantic-%s-face" + (symbol-name class)))))) + (overlay-put ovnew 'priority 1) + (overlay-put ovnew 'minimap-semantic t) + (setq start + (minimap-line-to-pos (/ (+ (line-number-at-pos start) + (line-number-at-pos end)) 2))) + (goto-char start) + (while (looking-at "^$") + (forward-line -1)) + (setq start (point)) + (setq end (progn (goto-char start) (point-at-eol))) + (setq ovnew (make-overlay start end)) + (overlay-put ovnew 'face (format "minimap-semantic-%s-face" + (symbol-name class))) + (overlay-put ovnew 'display (concat " " name " ")) + (overlay-put ovnew 'priority 6) + (overlay-put ovnew 'minimap-semantic t)))) + (setq tags (cdr tags))))))) (provide 'minimap)