diff options
| author | Martin Rudalics | 2008-08-31 08:47:03 +0000 |
|---|---|---|
| committer | Martin Rudalics | 2008-08-31 08:47:03 +0000 |
| commit | 787cb9bac9f95a1ee19a7f32fe1dbb9803606cde (patch) | |
| tree | 8d7bef645c28574ec8f87be970bd87a9c21d44e4 | |
| parent | 23dc7615cdba5a0a4a8ac141b973e407966821c6 (diff) | |
| download | emacs-787cb9bac9f95a1ee19a7f32fe1dbb9803606cde.tar.gz emacs-787cb9bac9f95a1ee19a7f32fe1dbb9803606cde.zip | |
(linum-mode): `window-size-change-functions' can now be buffer-local.
(linum-update-window): Use result of `move-overlay'.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/linum.el | 395 |
2 files changed, 202 insertions, 199 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 226e198eacf..28ea7ef3b72 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2008-08-30 Markus Triska <markus.triska@gmx.at> | ||
| 2 | |||
| 3 | * linum.el (linum-mode): `window-size-change-functions' can now be | ||
| 4 | buffer-local. | ||
| 5 | (linum-update-window): Use result of `move-overlay'. | ||
| 6 | |||
| 1 | 2008-08-30 Glenn Morris <rgm@gnu.org> | 7 | 2008-08-30 Glenn Morris <rgm@gnu.org> |
| 2 | 8 | ||
| 3 | * subr.el (make-variable-frame-local): Tweak obsolescence message. | 9 | * subr.el (make-variable-frame-local): Tweak obsolescence message. |
diff --git a/lisp/linum.el b/lisp/linum.el index a88bb610d8c..043c9d3420b 100644 --- a/lisp/linum.el +++ b/lisp/linum.el | |||
| @@ -1,199 +1,196 @@ | |||
| 1 | ;;; linum.el --- display line numbers in the left margin | 1 | ;;; linum.el --- display line numbers in the left margin |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2008 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2008 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Markus Triska <markus.triska@gmx.at> | 5 | ;; Author: Markus Triska <markus.triska@gmx.at> |
| 6 | ;; Maintainer: FSF | 6 | ;; Maintainer: FSF |
| 7 | ;; Keywords: convenience | 7 | ;; Keywords: convenience |
| 8 | 8 | ||
| 9 | ;; This file is part of GNU Emacs. | 9 | ;; This file is part of GNU Emacs. |
| 10 | 10 | ||
| 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | 11 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
| 12 | ;; it under the terms of the GNU General Public License as published by | 12 | ;; it under the terms of the GNU General Public License as published by |
| 13 | ;; the Free Software Foundation, either version 3 of the License, or | 13 | ;; the Free Software Foundation, either version 3 of the License, or |
| 14 | ;; (at your option) any later version. | 14 | ;; (at your option) any later version. |
| 15 | 15 | ||
| 16 | ;; GNU Emacs is distributed in the hope that it will be useful, | 16 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | ;; GNU General Public License for more details. | 19 | ;; GNU General Public License for more details. |
| 20 | 20 | ||
| 21 | ;; You should have received a copy of the GNU General Public License | 21 | ;; You should have received a copy of the GNU General Public License |
| 22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | 22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 23 | 23 | ||
| 24 | ;;; Commentary: | 24 | ;;; Commentary: |
| 25 | 25 | ||
| 26 | ;; Display line numbers for the current buffer. | 26 | ;; Display line numbers for the current buffer. |
| 27 | ;; | 27 | ;; |
| 28 | ;; Toggle display of line numbers with M-x linum-mode. To enable | 28 | ;; Toggle display of line numbers with M-x linum-mode. To enable |
| 29 | ;; line numbering in all buffers, use M-x global-linum-mode. | 29 | ;; line numbering in all buffers, use M-x global-linum-mode. |
| 30 | 30 | ||
| 31 | ;;; Code: | 31 | ;;; Code: |
| 32 | 32 | ||
| 33 | (defconst linum-version "0.9wz") | 33 | (defconst linum-version "0.9x") |
| 34 | 34 | ||
| 35 | (defvar linum-overlays nil "Overlays used in this buffer.") | 35 | (defvar linum-overlays nil "Overlays used in this buffer.") |
| 36 | (defvar linum-available nil "Overlays available for reuse.") | 36 | (defvar linum-available nil "Overlays available for reuse.") |
| 37 | (defvar linum-before-numbering-hook nil | 37 | (defvar linum-before-numbering-hook nil |
| 38 | "Functions run in each buffer before line numbering starts.") | 38 | "Functions run in each buffer before line numbering starts.") |
| 39 | 39 | ||
| 40 | (mapc #'make-variable-buffer-local '(linum-overlays linum-available)) | 40 | (mapc #'make-variable-buffer-local '(linum-overlays linum-available)) |
| 41 | 41 | ||
| 42 | (defgroup linum nil | 42 | (defgroup linum nil |
| 43 | "Show line numbers in the left margin." | 43 | "Show line numbers in the left margin." |
| 44 | :group 'convenience) | 44 | :group 'convenience) |
| 45 | 45 | ||
| 46 | ;;;###autoload | 46 | ;;;###autoload |
| 47 | (defcustom linum-format 'dynamic | 47 | (defcustom linum-format 'dynamic |
| 48 | "Format used to display line numbers. | 48 | "Format used to display line numbers. |
| 49 | Either a format string like \"%7d\", `dynamic' to adapt the width | 49 | Either a format string like \"%7d\", `dynamic' to adapt the width |
| 50 | as needed, or a function that is called with a line number as its | 50 | as needed, or a function that is called with a line number as its |
| 51 | argument and should evaluate to a string to be shown on that line. | 51 | argument and should evaluate to a string to be shown on that line. |
| 52 | See also `linum-before-numbering-hook'." | 52 | See also `linum-before-numbering-hook'." |
| 53 | :group 'linum | 53 | :group 'linum |
| 54 | :type 'sexp) | 54 | :type 'sexp) |
| 55 | 55 | ||
| 56 | (defface linum | 56 | (defface linum |
| 57 | '((t :inherit (shadow default))) | 57 | '((t :inherit (shadow default))) |
| 58 | "Face for displaying line numbers in the display margin." | 58 | "Face for displaying line numbers in the display margin." |
| 59 | :group 'linum) | 59 | :group 'linum) |
| 60 | 60 | ||
| 61 | (defcustom linum-eager t | 61 | (defcustom linum-eager t |
| 62 | "Whether line numbers should be updated after each command. | 62 | "Whether line numbers should be updated after each command. |
| 63 | The conservative setting `nil' might miss some buffer changes, | 63 | The conservative setting `nil' might miss some buffer changes, |
| 64 | and you have to scroll or press \\[recenter-top-bottom] to update the numbers." | 64 | and you have to scroll or press \\[recenter-top-bottom] to update the numbers." |
| 65 | :group 'linum | 65 | :group 'linum |
| 66 | :type 'boolean) | 66 | :type 'boolean) |
| 67 | 67 | ||
| 68 | (defcustom linum-delay nil | 68 | (defcustom linum-delay nil |
| 69 | "Delay updates to give Emacs a chance for other changes." | 69 | "Delay updates to give Emacs a chance for other changes." |
| 70 | :group 'linum | 70 | :group 'linum |
| 71 | :type 'boolean) | 71 | :type 'boolean) |
| 72 | 72 | ||
| 73 | ;;;###autoload | 73 | ;;;###autoload |
| 74 | (define-minor-mode linum-mode | 74 | (define-minor-mode linum-mode |
| 75 | "Toggle display of line numbers in the left margin." | 75 | "Toggle display of line numbers in the left margin." |
| 76 | :lighter "" ; for desktop.el | 76 | :lighter "" ; for desktop.el |
| 77 | (if linum-mode | 77 | (if linum-mode |
| 78 | (progn | 78 | (progn |
| 79 | (if linum-eager | 79 | (if linum-eager |
| 80 | (add-hook 'post-command-hook (if linum-delay | 80 | (add-hook 'post-command-hook (if linum-delay |
| 81 | 'linum-schedule | 81 | 'linum-schedule |
| 82 | 'linum-update-current) nil t) | 82 | 'linum-update-current) nil t) |
| 83 | (add-hook 'after-change-functions 'linum-after-change nil t)) | 83 | (add-hook 'after-change-functions 'linum-after-change nil t)) |
| 84 | (add-hook 'window-scroll-functions 'linum-after-scroll nil t) | 84 | (add-hook 'window-scroll-functions 'linum-after-scroll nil t) |
| 85 | ;; mistake in Emacs: window-size-change-functions cannot be local | 85 | (add-hook 'window-size-change-functions 'linum-after-size nil t) |
| 86 | (add-hook 'window-size-change-functions 'linum-after-size) | 86 | (add-hook 'change-major-mode-hook 'linum-delete-overlays nil t) |
| 87 | (add-hook 'change-major-mode-hook 'linum-delete-overlays nil t) | 87 | (add-hook 'window-configuration-change-hook |
| 88 | (add-hook 'window-configuration-change-hook | 88 | 'linum-after-config nil t) |
| 89 | 'linum-after-config nil t) | 89 | (linum-update-current)) |
| 90 | (linum-update-current)) | 90 | (remove-hook 'post-command-hook 'linum-update-current t) |
| 91 | (remove-hook 'post-command-hook 'linum-update-current t) | 91 | (remove-hook 'post-command-hook 'linum-schedule t) |
| 92 | (remove-hook 'post-command-hook 'linum-schedule t) | 92 | (remove-hook 'window-size-change-functions 'linum-after-size t) |
| 93 | (remove-hook 'window-size-change-functions 'linum-after-size) | 93 | (remove-hook 'window-scroll-functions 'linum-after-scroll t) |
| 94 | (remove-hook 'window-scroll-functions 'linum-after-scroll t) | 94 | (remove-hook 'after-change-functions 'linum-after-change t) |
| 95 | (remove-hook 'after-change-functions 'linum-after-change t) | 95 | (remove-hook 'window-configuration-change-hook 'linum-after-config t) |
| 96 | (remove-hook 'window-configuration-change-hook 'linum-after-config t) | 96 | (remove-hook 'change-major-mode-hook 'linum-delete-overlays t) |
| 97 | (remove-hook 'change-major-mode-hook 'linum-delete-overlays t) | 97 | (linum-delete-overlays))) |
| 98 | (linum-delete-overlays))) | 98 | |
| 99 | 99 | ;;;###autoload | |
| 100 | ;;;###autoload | 100 | (define-globalized-minor-mode global-linum-mode linum-mode linum-on) |
| 101 | (define-globalized-minor-mode global-linum-mode linum-mode linum-on) | 101 | |
| 102 | 102 | (defun linum-on () | |
| 103 | (defun linum-on () | 103 | (unless (minibufferp) |
| 104 | (unless (minibufferp) | 104 | (linum-mode 1))) |
| 105 | (linum-mode 1))) | 105 | |
| 106 | 106 | (defun linum-delete-overlays () | |
| 107 | (defun linum-delete-overlays () | 107 | "Delete all overlays displaying line numbers for this buffer." |
| 108 | "Delete all overlays displaying line numbers for this buffer." | 108 | (mapc #'delete-overlay linum-overlays) |
| 109 | (mapc #'delete-overlay linum-overlays) | 109 | (setq linum-overlays nil) |
| 110 | (setq linum-overlays nil) | 110 | (dolist (w (get-buffer-window-list (current-buffer) nil t)) |
| 111 | (dolist (w (get-buffer-window-list (current-buffer) nil t)) | 111 | (set-window-margins w 0))) |
| 112 | (set-window-margins w 0))) | 112 | |
| 113 | 113 | (defun linum-update-current () | |
| 114 | (defun linum-update-current () | 114 | "Update line numbers for the current buffer." |
| 115 | "Update line numbers for the current buffer." | 115 | (linum-update (current-buffer))) |
| 116 | (linum-update (current-buffer))) | 116 | |
| 117 | 117 | (defun linum-update (buffer) | |
| 118 | (defun linum-update (buffer) | 118 | "Update line numbers for all windows displaying BUFFER." |
| 119 | "Update line numbers for all windows displaying BUFFER." | 119 | (with-current-buffer buffer |
| 120 | (with-current-buffer buffer | 120 | (when linum-mode |
| 121 | (when linum-mode | 121 | (setq linum-available linum-overlays) |
| 122 | (setq linum-available linum-overlays) | 122 | (setq linum-overlays nil) |
| 123 | (setq linum-overlays nil) | 123 | (save-excursion |
| 124 | (save-excursion | 124 | (mapc #'linum-update-window |
| 125 | (mapc #'linum-update-window | 125 | (get-buffer-window-list buffer nil 'visible))) |
| 126 | (get-buffer-window-list buffer nil 'visible))) | 126 | (mapc #'delete-overlay linum-available) |
| 127 | (mapc #'delete-overlay linum-available) | 127 | (setq linum-available nil)))) |
| 128 | (setq linum-available nil)))) | 128 | |
| 129 | 129 | (defun linum-update-window (win) | |
| 130 | (defun linum-update-window (win) | 130 | "Update line numbers for the portion visible in window WIN." |
| 131 | "Update line numbers for the portion visible in window WIN." | 131 | (goto-char (window-start win)) |
| 132 | (goto-char (window-start win)) | 132 | (let ((line (line-number-at-pos)) |
| 133 | (let ((line (line-number-at-pos)) | 133 | (limit (window-end win t)) |
| 134 | (limit (window-end win t)) | 134 | (fmt (cond ((stringp linum-format) linum-format) |
| 135 | (fmt (cond ((stringp linum-format) linum-format) | 135 | ((eq linum-format 'dynamic) |
| 136 | ((eq linum-format 'dynamic) | 136 | (let ((w (length (number-to-string |
| 137 | (let ((w (length (number-to-string | 137 | (count-lines (point-min) (point-max)))))) |
| 138 | (count-lines (point-min) (point-max)))))) | 138 | (concat "%" (number-to-string w) "d"))))) |
| 139 | (concat "%" (number-to-string w) "d"))))) | 139 | (width 0)) |
| 140 | (width 0)) | 140 | (run-hooks 'linum-before-numbering-hook) |
| 141 | (run-hooks 'linum-before-numbering-hook) | 141 | ;; Create an overlay (or reuse an existing one) for each |
| 142 | ;; Create an overlay (or reuse an existing one) for each | 142 | ;; line visible in this window, if necessary. |
| 143 | ;; line visible in this window, if necessary. | 143 | (while (and (not (eobp)) (<= (point) limit)) |
| 144 | (while (and (not (eobp)) (<= (point) limit)) | 144 | (let* ((str (if fmt |
| 145 | (let* ((str (if fmt | 145 | (propertize (format fmt line) 'face 'linum) |
| 146 | (propertize (format fmt line) 'face 'linum) | 146 | (funcall linum-format line))) |
| 147 | (funcall linum-format line))) | 147 | (visited (catch 'visited |
| 148 | (visited (catch 'visited | 148 | (dolist (o (overlays-in (point) (point))) |
| 149 | (dolist (o (overlays-in (point) (point))) | 149 | (when (string= (overlay-get o 'linum-str) str) |
| 150 | (when (string= (overlay-get o 'linum-str) str) | 150 | (unless (memq o linum-overlays) |
| 151 | (unless (memq o linum-overlays) | 151 | (push o linum-overlays)) |
| 152 | (push o linum-overlays)) | 152 | (setq linum-available (delete o linum-available)) |
| 153 | (setq linum-available (delete o linum-available)) | 153 | (throw 'visited t)))))) |
| 154 | (throw 'visited t)))))) | 154 | (setq width (max width (length str))) |
| 155 | (setq width (max width (length str))) | 155 | (unless visited |
| 156 | (unless visited | 156 | (let ((ov (if (null linum-available) |
| 157 | (let (ov) | 157 | (make-overlay (point) (point)) |
| 158 | (if (null linum-available) | 158 | (move-overlay (pop linum-available) (point) (point))))) |
| 159 | (setq ov (make-overlay (point) (point))) | 159 | (push ov linum-overlays) |
| 160 | (setq ov (pop linum-available)) | 160 | (overlay-put ov 'before-string |
| 161 | (move-overlay ov (point) (point))) | 161 | (propertize " " 'display `((margin left-margin) ,str))) |
| 162 | (push ov linum-overlays) | 162 | (overlay-put ov 'linum-str str)))) |
| 163 | (overlay-put ov 'before-string | 163 | (forward-line) |
| 164 | (propertize " " 'display `((margin left-margin) ,str))) | 164 | (setq line (1+ line))) |
| 165 | (overlay-put ov 'linum-str str)))) | 165 | (set-window-margins win width))) |
| 166 | (forward-line) | 166 | |
| 167 | (setq line (1+ line))) | 167 | (defun linum-after-change (beg end len) |
| 168 | (set-window-margins win width))) | 168 | ;; update overlays on deletions, and after newlines are inserted |
| 169 | 169 | (when (or (= beg end) | |
| 170 | (defun linum-after-change (beg end len) | 170 | (= end (point-max)) |
| 171 | ;; update overlays on deletions, and after newlines are inserted | 171 | (string-match-p "\n" (buffer-substring-no-properties beg end))) |
| 172 | (when (or (= beg end) | 172 | (linum-update-current))) |
| 173 | (= end (point-max)) | 173 | |
| 174 | (string-match-p "\n" (buffer-substring-no-properties beg end))) | 174 | (defun linum-after-scroll (win start) |
| 175 | (linum-update-current))) | 175 | (linum-update (window-buffer win))) |
| 176 | 176 | ||
| 177 | (defun linum-after-scroll (win start) | 177 | (defun linum-after-size (frame) |
| 178 | (linum-update (window-buffer win))) | 178 | (linum-after-config)) |
| 179 | 179 | ||
| 180 | (defun linum-after-size (frame) | 180 | (defun linum-schedule () |
| 181 | (linum-after-config)) | 181 | ;; schedule an update; the delay gives Emacs a chance for display changes |
| 182 | 182 | (run-with-idle-timer 0 nil #'linum-update-current)) | |
| 183 | (defun linum-schedule () | 183 | |
| 184 | ;; schedule an update; the delay gives Emacs a chance for display changes | 184 | (defun linum-after-config () |
| 185 | (run-with-idle-timer 0 nil #'linum-update-current)) | 185 | (walk-windows (lambda (w) (linum-update (window-buffer w))) nil 'visible)) |
| 186 | 186 | ||
| 187 | (defun linum-after-config () | 187 | (defun linum-unload-function () |
| 188 | (walk-windows (lambda (w) (linum-update (window-buffer w))) nil 'visible)) | 188 | "Unload the Linum library." |
| 189 | 189 | (global-linum-mode -1) | |
| 190 | (defun linum-unload-function () | 190 | ;; continue standard unloading |
| 191 | "Unload the Linum library." | 191 | nil) |
| 192 | (global-linum-mode -1) | 192 | |
| 193 | ;; continue standard unloading | 193 | (provide 'linum) |
| 194 | nil) | 194 | |
| 195 | 195 | ;; arch-tag: dea45631-ed3c-4867-8b49-1c41c80aec6a | |
| 196 | (provide 'linum) | 196 | ;;; linum.el ends here |
| 197 | |||
| 198 | ;; arch-tag: dea45631-ed3c-4867-8b49-1c41c80aec6a | ||
| 199 | ;;; linum.el ends here | ||