aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2008-08-31 08:47:03 +0000
committerMartin Rudalics2008-08-31 08:47:03 +0000
commit787cb9bac9f95a1ee19a7f32fe1dbb9803606cde (patch)
tree8d7bef645c28574ec8f87be970bd87a9c21d44e4
parent23dc7615cdba5a0a4a8ac141b973e407966821c6 (diff)
downloademacs-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/ChangeLog6
-rw-r--r--lisp/linum.el395
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 @@
12008-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
12008-08-30 Glenn Morris <rgm@gnu.org> 72008-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.
49Either a format string like \"%7d\", `dynamic' to adapt the width 49Either a format string like \"%7d\", `dynamic' to adapt the width
50as needed, or a function that is called with a line number as its 50as needed, or a function that is called with a line number as its
51argument and should evaluate to a string to be shown on that line. 51argument and should evaluate to a string to be shown on that line.
52See also `linum-before-numbering-hook'." 52See 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.
63The conservative setting `nil' might miss some buffer changes, 63The conservative setting `nil' might miss some buffer changes,
64and you have to scroll or press \\[recenter-top-bottom] to update the numbers." 64and 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