From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.bugs Subject: bug#6871: Please make linum-mode per buffer, not per major mode Date: Thu, 19 Aug 2010 16:45:16 +0200 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1282230970 1270 80.91.229.12 (19 Aug 2010 15:16:10 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 19 Aug 2010 15:16:10 +0000 (UTC) Cc: Juanma Barranquero , 6871@debbugs.gnu.org To: Lennart Borgman Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Aug 19 17:16:08 2010 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Om6qe-00030p-4q for geb-bug-gnu-emacs@m.gmane.org; Thu, 19 Aug 2010 17:16:08 +0200 Original-Received: from localhost ([127.0.0.1]:41196 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Om6qc-0003DS-Os for geb-bug-gnu-emacs@m.gmane.org; Thu, 19 Aug 2010 11:16:06 -0400 Original-Received: from [140.186.70.92] (port=36280 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Om6nr-0001UK-WA for bug-gnu-emacs@gnu.org; Thu, 19 Aug 2010 11:13:17 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Om6jl-0003sO-8d for bug-gnu-emacs@gnu.org; Thu, 19 Aug 2010 11:09:03 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:47558) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Om6jl-0003sH-5o for bug-gnu-emacs@gnu.org; Thu, 19 Aug 2010 11:09:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1Om6MZ-00078a-0u; Thu, 19 Aug 2010 10:45:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stefan Monnier Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 19 Aug 2010 14:45:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 6871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 6871-submit@debbugs.gnu.org id=B6871.128222905527410 (code B ref 6871); Thu, 19 Aug 2010 14:45:02 +0000 Original-Received: (at 6871) by debbugs.gnu.org; 19 Aug 2010 14:44:15 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Om6Ln-000783-6r for submit@debbugs.gnu.org; Thu, 19 Aug 2010 10:44:15 -0400 Original-Received: from impaqm1.telefonica.net ([213.4.138.1]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Om6Lj-00077x-Ag for 6871@debbugs.gnu.org; Thu, 19 Aug 2010 10:44:12 -0400 Original-Received: from IMPmailhost5.adm.correo ([10.20.102.126]) by IMPaqm1.telefonica.net with bizsmtp id wBh71e00C2jdgqJ01ElHux; Thu, 19 Aug 2010 16:45:17 +0200 Original-Received: from ceviche.home ([83.61.35.93]) by IMPmailhost5.adm.correo with BIZ IMP id wElG1e00820aCvn1lElG8Q; Thu, 19 Aug 2010 16:45:17 +0200 X-Brightmail-Tracker: AAAAAA== X-TE-authinfo: authemail="monnier$movistar.es" |auth_email="monnier@movistar.es" X-TE-AcuTerraCos: auth_cuTerraCos="cosuitnetc01" Original-Received: by ceviche.home (Postfix, from userid 20848) id 216AA660E9; Thu, 19 Aug 2010 16:45:16 +0200 (CEST) In-Reply-To: (Lennart Borgman's message of "Thu, 19 Aug 2010 15:25:44 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Thu, 19 Aug 2010 10:45:03 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:39628 Archived-At: > I think I have attached the diff now ;-) Yes, this time it looks right, thanks. >>> There are some other changes to linum.el too. >> Why? If they are not related, that should be sent as another patch. > Maybe. Linum is rather small and it is quicker to do it this way. I don't mind a few cosmetic changes as long as they don't drown the main change, but in this case, the changes aren't cosmetic at all. They don't sound bad, tho. So please post them separately, with an explanation for why they're right. And please resend a new patch that only fixes the permanent-local part of linum-mode, because I'm having a hard time figuring out which part belongs to what. Stefan > === modified file 'lisp/linum.el' > --- trunk/lisp/linum.el 2010-01-13 08:35:10 +0000 > +++ patched/lisp/linum.el 2010-08-19 04:22:04 +0000 > @@ -38,6 +38,8 @@ > "Functions run in each buffer before line numbering starts.") > (mapc #'make-variable-buffer-local '(linum-overlays linum-available)) > +(put 'linum-overlays 'permanent-local t) > +(put 'linum-available 'permanent-local t) > (defgroup linum nil > "Show line numbers in the left margin." > @@ -58,13 +60,6 @@ > "Face for displaying line numbers in the display margin." > :group 'linum) > -(defcustom linum-eager t > - "Whether line numbers should be updated after each command. > -The conservative setting `nil' might miss some buffer changes, > -and you have to scroll or press \\[recenter-top-bottom] to update the numbers." > - :group 'linum > - :type 'boolean) > - > (defcustom linum-delay nil > "Delay updates to give Emacs a chance for other changes." > :group 'linum > @@ -76,30 +71,29 @@ > :lighter "" ; for desktop.el > (if linum-mode > (progn > - (if linum-eager > (add-hook 'post-command-hook (if linum-delay > 'linum-schedule > - 'linum-update-current) nil t) > - (add-hook 'after-change-functions 'linum-after-change nil t)) > + 'linum-update-current-buffer) nil t) > + (add-hook 'before-change-functions 'linum-before-change nil t) > + (add-hook 'after-change-functions 'linum-after-change nil t) > (add-hook 'window-scroll-functions 'linum-after-scroll nil t) > ;; Using both window-size-change-functions and > ;; window-configuration-change-hook seems redundant. --Stef > ;; (add-hook 'window-size-change-functions 'linum-after-size nil t) > - (add-hook 'change-major-mode-hook 'linum-delete-overlays nil t) > (add-hook 'window-configuration-change-hook > - ;; FIXME: If the buffer is shown in N windows, this > - ;; will be called N times rather than once. We should use > - ;; something like linum-update-window instead. > - 'linum-update-current nil t) > - (linum-update-current)) > - (remove-hook 'post-command-hook 'linum-update-current t) > + ;; Update just the selected window > + 'linum-update-selected-window nil t) > + (setq linum-change-beg 1) > + (linum-update-current-buffer)) > + (remove-hook 'post-command-hook 'linum-update-current-buffer t) > (remove-hook 'post-command-hook 'linum-schedule t) > ;; (remove-hook 'window-size-change-functions 'linum-after-size t) > (remove-hook 'window-scroll-functions 'linum-after-scroll t) > + (remove-hook 'before-change-functions 'linum-before-change t) > (remove-hook 'after-change-functions 'linum-after-change t) > - (remove-hook 'window-configuration-change-hook 'linum-update-current t) > - (remove-hook 'change-major-mode-hook 'linum-delete-overlays t) > + (remove-hook 'window-configuration-change-hook 'linum-update-selected-window t) > (linum-delete-overlays))) > +(put 'linum-mode 'permanent-local t) > ;;;###autoload > (define-globalized-minor-mode global-linum-mode linum-mode linum-on) > @@ -115,22 +109,34 @@ > (dolist (w (get-buffer-window-list (current-buffer) nil t)) > (set-window-margins w 0 (cdr (window-margins w))))) > -(defun linum-update-current () > +(defun linum-update-current-buffer () > "Update line numbers for the current buffer." > (linum-update (current-buffer))) > +(put 'linum-update-current-buffer 'permanent-local-hook t) > (defun linum-update (buffer) > "Update line numbers for all windows displaying BUFFER." > (with-current-buffer buffer > - (when linum-mode > + (when (and linum-mode > + linum-change-beg) > (setq linum-available linum-overlays) > (setq linum-overlays nil) > (save-excursion > (mapc #'linum-update-window > (get-buffer-window-list buffer nil 'visible))) > (mapc #'delete-overlay linum-available) > + (setq linum-change-beg nil) > (setq linum-available nil)))) > +(defun linum-update-selected-window () > + "Update line numbers for the selected window." > + (let ((here (window-point)) > + ;; We might have scrolled or changed win config > + (linum-change-beg 1)) > + (linum-update-window (selected-window)) > + (goto-char here))) > +(put 'linum-update-selected-window 'permanent-local-hook t) > + > (defun linum-update-window (win) > "Update line numbers for the portion visible in window WIN." > (goto-char (window-start win)) > @@ -142,6 +148,7 @@ > (count-lines (point-min) (point-max)))))) > (concat "%" (number-to-string w) "d"))))) > (width 0)) > + (when (<= linum-change-beg limit) > (run-hooks 'linum-before-numbering-hook) > ;; Create an overlay (or reuse an existing one) for each > ;; line visible in this window, if necessary. > @@ -171,24 +178,40 @@ > (let ((inhibit-point-motion-hooks t)) > (forward-line)) > (setq line (1+ line))) > - (set-window-margins win width (cdr (window-margins win))))) > + (set-window-margins win width (cdr (window-margins win)))))) > + > +(defvar linum-change-beg nil > + "Position of change beginning, recorded after change.") > +(make-variable-buffer-local 'linum-change-beg) > +(put linum-change-beg 'permanent-local t) > + > +(defvar linum-changed-region-has-newline nil) > +(defun linum-before-change (beg end) > + ;; Record new lines in changed region for check in after change function. > + (when (string-match-p "\n" (buffer-substring-no-properties beg end)) > + (setq linum-changed-region-has-newline t))) > +(put 'linum-before-change 'permanent-local-hook t) > (defun linum-after-change (beg end len) > - ;; update overlays on deletions, and after newlines are inserted > - (when (or (= beg end) > - (= end (point-max)) > + ;; update overlays after newlines are delete or inserted > + (when (or linum-changed-region-has-newline > (string-match-p "\n" (buffer-substring-no-properties beg end))) > - (linum-update-current))) > + (setq linum-changed-region-has-newline nil) > + (setq linum-change-beg beg))) > +(put 'linum-after-change 'permanent-local-hook t) > (defun linum-after-scroll (win start) > - (linum-update (window-buffer win))) > + (with-selected-window win > + (linum-update-selected-window))) > +(put 'linum-after-scroll 'permanent-local-hook t) > ;; (defun linum-after-size (frame) > ;; (linum-after-config)) > (defun linum-schedule () > ;; schedule an update; the delay gives Emacs a chance for display changes > - (run-with-idle-timer 0 nil #'linum-update-current)) > + (run-with-idle-timer 0 nil #'linum-update-current-buffer)) > +(put 'linum-schedule 'permanent-local-hook t) > ;; (defun linum-after-config () > ;; (walk-windows (lambda (w) (linum-update (window-buffer w))) nil 'visible))