From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stephen Berman Newsgroups: gmane.emacs.bugs Subject: bug#23554: Followup to bug#23510: Strange redisplay in global highlighted mode moving the scroll bar Date: Fri, 13 May 2016 20:44:58 +0200 Message-ID: <877fexu79x.fsf@rub.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1463422707 32469 80.91.229.3 (16 May 2016 18:18:27 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 16 May 2016 18:18:27 +0000 (UTC) To: 23554@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon May 16 20:18:14 2016 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1b2N5q-0002UZ-6G for geb-bug-gnu-emacs@m.gmane.org; Mon, 16 May 2016 20:18:14 +0200 Original-Received: from localhost ([::1]:46112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5p-0000A7-I8 for geb-bug-gnu-emacs@m.gmane.org; Mon, 16 May 2016 14:18:13 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37163) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5j-0008Uh-Pd for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:18:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2N5f-0006Fq-2Y for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:18:07 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:41885) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5e-0006Fg-Nv for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:18:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1b2N5e-0003Ld-KS for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:18:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Stephen Berman Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 16 May 2016 18:18:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 23554 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.146342267412848 (code B ref -1); Mon, 16 May 2016 18:18:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 16 May 2016 18:17:54 +0000 Original-Received: from localhost ([127.0.0.1]:54222 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1b2N5W-0003LA-7Z for submit@debbugs.gnu.org; Mon, 16 May 2016 14:17:54 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:45740) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1b2N5T-0003Kw-Ic for submit@debbugs.gnu.org; Mon, 16 May 2016 14:17:52 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2N5M-00066J-PT for submit@debbugs.gnu.org; Mon, 16 May 2016 14:17:46 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:60502) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5M-00065o-Mx for submit@debbugs.gnu.org; Mon, 16 May 2016 14:17:44 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36639) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5J-0007ex-U5 for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:17:43 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2N5C-00061T-No for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:17:41 -0400 Original-Received: from mout.gmx.net ([212.227.15.18]:61935) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2N5C-00061F-DC for bug-gnu-emacs@gnu.org; Mon, 16 May 2016 14:17:34 -0400 Original-Received: from rosalinde ([89.245.95.252]) by mail.gmx.com (mrgmx001) with ESMTPSA (Nemesis) id 0MOw4N-1avXae1Lqp-006NQ8 for ; Fri, 13 May 2016 20:44:59 +0200 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) X-Provags-ID: V03:K0:NaisutwRHwHSiktJ5cE9Ty7M6PbNy+6fWYFLgMFKpxdWEdrRJu5 diQn+VZQNHpEAS/UGJaVJyH3ebPZdojoHm5ROx6S3u8AVW3SwfCfQYQRZvWMhBrN62cYDNo dRiHa2R8krIF81vezRk7jeVJWDg6KW8/fM0A7jFWqJVdD8hysBB2ymULMWPffVO3JKG0a8P AIcbwVnQoySbyYIj69eDg== X-UI-Out-Filterresults: notjunk:1;V01:K0:sMH1lHq9ESM=:yKBxyUBMo5mlsAbXLONNDy kzrqqQ3XwAAMvslmZCuuMYXsoo+2rGJXrXZLf0Vro1u9nxHer+Hyih37uQnDjy8CypFriW0MS +jSp0KE/0EgLB79IRt5TTSCN3Fenk9HcPWs50rWn8kj6SvtPFqe0H5unQj+USA3RLDmT2AsRq AIFEeGimuChe7LuUu9lC0vKjRRd3M4en92S/OwHsSQDFCZNypfIJdbDYknN1a/g9tQwxaxwP9 I3uSh/o/sLJ0jxPvyKZNguMZmoTy91ve58+LfgHSgaCmyUlY/mhJkYhpSzf6rQj86LUDIid5F NJbDVuXCbvs8phz2cNcGxR7qFnqS7ncBppI/PP9DfJSSvHEONJOD+8U1AFSv5QAHgu+F4VFEV 6zuvOsqJl8A0iiX2bbzKSEqljPEWypQBrCqfyzn1rNtzWXtBjhOYYpc1rpX8uGIyGJDuWqFav IvC5dWMipgVD41hSxdwoCSlQBHO7trnLlg6ZPdSK0gfzDUgGuK3xXpdFF5XwAsPzG/cha+dyQ QKbPKWmembTw2X3++zeX8D9tu/dddpMGMomHEBMtVAkAijR+ERhAyNr2dl6cyEWjBEo98ibqg elHYUhxNJ2q+IdzmMzKpJKZRjyk6l86wl4IjLwLS8zN0a0bN6NnxfX2NwGJ8uwM+zTEd1F176 m4MhZWg3QDizYs0dimEqiRAW2kNqkoX4e6ZJbMjy4P4f2T9c61Ao8ACtwlF9s9wIgipdD4FrB cPdZVkrPcPZD0Q1vyAjOE4WCN/EU1FJEl3yV/vqrZvMECKemijEws+v9NIoTE/qa+PYvG4T4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 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: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:118306 Archived-At: [I sent this last night to the bug#23510 thread, but it never arrived, and I resent it twice today from two different email addresses, and I also sent a test message to the bug thread, but none of these have arrived, although other posts have appeared in the list since my attempts were sent. I don't know what the problem is, but now I'm trying to open a new bug; if this succeeds, it should be merged with bug#23510.] On Wed, 11 May 2016 12:44:43 +0300 Eli Zaretskii wrote: >> From: Stephen Berman >> Cc: "angelo.graziosi\@libero.it" , >> 23510@debbugs.gnu.org >> Date: Wed, 11 May 2016 11:25:24 +0200 >> >> What you say about the use of pre- and post-command-hook and moving >> overlays may well be (perhaps the main) part of the problem here, but I >> found out that there's an specific condition inducing it: I noticed that >> the flickering only happens when global-hl-line-mode is enabled, but not >> when hl-line-mode is enabled, and it turns out that the crucial >> difference between them is that in the former, >> global-hl-line-sticky-flag is nil by default, while in the latter, >> hl-line-sticky-flag is t by default: when I set >> global-hl-line-sticky-flag to t and then enable global-hl-line-mode, the >> flickering no longer happens, and when I set hl-line-sticky-flag to nil >> and then enable hl-line-mode, the flickering does happen. > > If you can suggest a patch that fixes that and doesn't have any > adverse effects, please do. Ok, I've given it a try; patch below. Debugging showed that the flickering is caused by calling delete-overlay on pre-command-hook, so I eliminated the uses of this hook and replaced them with the new functions hl-line-maybe-unhighlight and global-hl-line-maybe-unhighlight added to post-command-hook that call delete-overlay under more specific conditions. According to my tests this does not lead to flickering and highlights and unhighlights as before (but others should test the code, in case I missed or messed up anything). I also noticed that the definition of global-hl-line-mode fails to remove global-hl-line-highlight from change-major-mode-hook when the mode is disabled; I assume this was an oversite, so I rectified it. If my fix is found acceptable, I assume it should go to master, since the flickering problem was probably always there, so is not a regression in emacs-25. With that in mind, I took the opportunity to make global-hl-line-mode automatically taken effect in all live windows when global-hl-line-sticky-flag is non-nil (the new function global-hl-line-highlight-all); in the current (and I assume original) implementation, enabling global-hl-line-mode only highlights the current line of the selected window, even when global-hl-line-sticky-flag is non-nil (the highlighting appears in other windows when they become selected). This change seems consistent with the idea of Global-Hl-Line mode, expressed in its doc string ("Toggle line highlighting in all buffers"). I tested it with three windows in each of two frames (the most that comfortably fit on my display), and the highlighting was as fast as with two windows on one frame, but I suppose it's possible that more windows on more frames might be slower. Steve Berman diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 25c8a08..642a8ba 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -126,6 +126,9 @@ hl-line-range-function This variable is expected to be made buffer-local by modes.") +(defvar hl-line-overlay-buffer nil + "Most recently visited buffer in which Hl-Line mode is enabled.") + ;;;###autoload (define-minor-mode hl-line-mode "Toggle highlighting of the current line (Hl-Line mode). @@ -142,22 +145,21 @@ hl-line-mode When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the line about point in the selected window only. In this case, it -uses the function `hl-line-unhighlight' on `pre-command-hook' in +uses the function `hl-line-maybe-unhighlight' in addition to `hl-line-highlight' on `post-command-hook'." :group 'hl-line (if hl-line-mode (progn ;; In case `kill-all-local-variables' is called. (add-hook 'change-major-mode-hook #'hl-line-unhighlight nil t) - (if hl-line-sticky-flag - (remove-hook 'pre-command-hook #'hl-line-unhighlight t) - (add-hook 'pre-command-hook #'hl-line-unhighlight nil t)) (hl-line-highlight) - (add-hook 'post-command-hook #'hl-line-highlight nil t)) + (setq hl-line-overlay-buffer (current-buffer)) + (add-hook 'post-command-hook #'hl-line-highlight nil t) + (add-hook 'post-command-hook #'hl-line-maybe-unhighlight)) (remove-hook 'post-command-hook #'hl-line-highlight t) (hl-line-unhighlight) (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t) - (remove-hook 'pre-command-hook #'hl-line-unhighlight t))) + (remove-hook 'post-command-hook #'hl-line-maybe-unhighlight t))) (defun hl-line-make-overlay () (let ((ol (make-overlay (point) (point)))) @@ -181,6 +183,22 @@ hl-line-unhighlight (when hl-line-overlay (delete-overlay hl-line-overlay))) +(defun hl-line-maybe-unhighlight () + "Maybe deactivate the Hl-Line overlay on the current line. +Specifically, when `hl-line-sticky-flag' is nil deactivate all +such overlays in all buffers except the current one." + (let ((hlob hl-line-overlay-buffer) + (curbuf (current-buffer))) + (when (and (not hl-line-sticky-flag) + (not (eq curbuf hlob)) + (not (minibufferp))) + (with-current-buffer hlob + (when (overlayp hl-line-overlay) + (delete-overlay hl-line-overlay)))) + (when (and (overlayp hl-line-overlay) + (eq (overlay-buffer hl-line-overlay) curbuf)) + (setq hl-line-overlay-buffer curbuf)))) + ;;;###autoload (define-minor-mode global-hl-line-mode "Toggle line highlighting in all buffers (Global Hl-Line mode). @@ -189,25 +207,24 @@ global-hl-line-mode the mode if ARG is omitted or nil. If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode -highlights the line about the current buffer's point in all +highlights the line about the current buffer's point in all live windows. -Global-Hl-Line mode uses the functions `global-hl-line-unhighlight' and -`global-hl-line-highlight' on `pre-command-hook' and `post-command-hook'." +Global-Hl-Line mode uses the functions `global-hl-line-highlight' +and `global-hl-line-maybe-unhighlight' on `post-command-hook'." :global t :group 'hl-line (if global-hl-line-mode (progn ;; In case `kill-all-local-variables' is called. (add-hook 'change-major-mode-hook #'global-hl-line-unhighlight) - (if global-hl-line-sticky-flag - (remove-hook 'pre-command-hook #'global-hl-line-unhighlight) - (add-hook 'pre-command-hook #'global-hl-line-unhighlight)) - (global-hl-line-highlight) - (add-hook 'post-command-hook #'global-hl-line-highlight)) + (global-hl-line-highlight-all) + (add-hook 'post-command-hook #'global-hl-line-highlight) + (add-hook 'post-command-hook #'global-hl-line-maybe-unhighlight)) (global-hl-line-unhighlight-all) - (remove-hook 'pre-command-hook #'global-hl-line-unhighlight) - (remove-hook 'post-command-hook #'global-hl-line-highlight))) + (remove-hook 'post-command-hook #'global-hl-line-highlight) + (remove-hook 'change-major-mode-hook #'global-hl-line-unhighlight) + (remove-hook 'post-command-hook #'global-hl-line-maybe-unhighlight))) (defun global-hl-line-highlight () "Highlight the current line in the current window." @@ -222,11 +239,33 @@ global-hl-line-highlight (selected-window))) (hl-line-move global-hl-line-overlay)))) +(defun global-hl-line-highlight-all () + "Highlight the current line in all live windows." + (walk-windows (lambda (w) + (with-current-buffer (window-buffer w) + (global-hl-line-highlight))) + nil t)) + (defun global-hl-line-unhighlight () "Deactivate the Global-Hl-Line overlay on the current line." (when global-hl-line-overlay (delete-overlay global-hl-line-overlay))) +(defun global-hl-line-maybe-unhighlight () + "Maybe deactivate the Global-Hl-Line overlay on the current line. +Specifically, when `global-hl-line-sticky-flag' is nil deactivate +all such overlays in all buffers except the current one." + (mapc (lambda (ov) + (let ((ovb (overlay-buffer ov))) + (when (and (not global-hl-line-sticky-flag) + (bufferp ovb) + (not (eq ovb (current-buffer))) + (not (minibufferp))) + (with-current-buffer ovb + (when (overlayp global-hl-line-overlay) + (delete-overlay global-hl-line-overlay)))))) + global-hl-line-overlays)) + (defun global-hl-line-unhighlight-all () "Deactivate all Global-Hl-Line overlays." (mapc (lambda (ov)