aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Berman2016-05-26 11:30:29 +0200
committerStephen Berman2016-05-26 11:30:29 +0200
commit16be3e90545972dec16014253a843229d5bdf388 (patch)
tree862abd927225b9f9d1a1f68af8d9dfe0f41e2b72
parente971ce6de27f982720ef312637e1d40da80e8d1f (diff)
downloademacs-16be3e90545972dec16014253a843229d5bdf388.tar.gz
emacs-16be3e90545972dec16014253a843229d5bdf388.zip
hl-line.el: Fix flickering of highlighted line (bug#23510)
* lisp/hl-line.el (hl-line-maybe-unhighlight) (global-hl-line-highlight-all) (global-hl-line-maybe-unhighlight): New functions. (hl-line-overlay-buffer): New variable. (hl-line-mode): Use it. Replace hl-line-unhighlight on pre-command-hook by hl-line-maybe-unhighlight on post-command-hook, to prevent hl-line from flickering. Adjust document string. (global-hl-line-mode): Use global-hl-line-highlight-all to simultaneously highlight the current line in all live windows. Replace global-hl-line-unhighlight on pre-command-hook by global-hl-line-maybe-unhighlight on post-command-hook, to prevent global-hl-line from flickering. Remove global-hl-line-unhighlight from change-major-mode-hook on disabling the mode. Adjust document string.
-rw-r--r--lisp/hl-line.el71
1 files changed, 55 insertions, 16 deletions
diff --git a/lisp/hl-line.el b/lisp/hl-line.el
index 25c8a087f42..d75e52f2973 100644
--- a/lisp/hl-line.el
+++ b/lisp/hl-line.el
@@ -126,6 +126,9 @@ It should return nil if there's no region to be highlighted.
126 126
127This variable is expected to be made buffer-local by modes.") 127This variable is expected to be made buffer-local by modes.")
128 128
129(defvar hl-line-overlay-buffer nil
130 "Most recently visited buffer in which Hl-Line mode is enabled.")
131
129;;;###autoload 132;;;###autoload
130(define-minor-mode hl-line-mode 133(define-minor-mode hl-line-mode
131 "Toggle highlighting of the current line (Hl-Line mode). 134 "Toggle highlighting of the current line (Hl-Line mode).
@@ -142,22 +145,21 @@ non-selected window. Hl-Line mode uses the function
142 145
143When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the 146When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the
144line about point in the selected window only. In this case, it 147line about point in the selected window only. In this case, it
145uses the function `hl-line-unhighlight' on `pre-command-hook' in 148uses the function `hl-line-maybe-unhighlight' in
146addition to `hl-line-highlight' on `post-command-hook'." 149addition to `hl-line-highlight' on `post-command-hook'."
147 :group 'hl-line 150 :group 'hl-line
148 (if hl-line-mode 151 (if hl-line-mode
149 (progn 152 (progn
150 ;; In case `kill-all-local-variables' is called. 153 ;; In case `kill-all-local-variables' is called.
151 (add-hook 'change-major-mode-hook #'hl-line-unhighlight nil t) 154 (add-hook 'change-major-mode-hook #'hl-line-unhighlight nil t)
152 (if hl-line-sticky-flag
153 (remove-hook 'pre-command-hook #'hl-line-unhighlight t)
154 (add-hook 'pre-command-hook #'hl-line-unhighlight nil t))
155 (hl-line-highlight) 155 (hl-line-highlight)
156 (add-hook 'post-command-hook #'hl-line-highlight nil t)) 156 (setq hl-line-overlay-buffer (current-buffer))
157 (add-hook 'post-command-hook #'hl-line-highlight nil t)
158 (add-hook 'post-command-hook #'hl-line-maybe-unhighlight nil t))
157 (remove-hook 'post-command-hook #'hl-line-highlight t) 159 (remove-hook 'post-command-hook #'hl-line-highlight t)
158 (hl-line-unhighlight) 160 (hl-line-unhighlight)
159 (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t) 161 (remove-hook 'change-major-mode-hook #'hl-line-unhighlight t)
160 (remove-hook 'pre-command-hook #'hl-line-unhighlight t))) 162 (remove-hook 'post-command-hook #'hl-line-maybe-unhighlight t)))
161 163
162(defun hl-line-make-overlay () 164(defun hl-line-make-overlay ()
163 (let ((ol (make-overlay (point) (point)))) 165 (let ((ol (make-overlay (point) (point))))
@@ -181,6 +183,22 @@ addition to `hl-line-highlight' on `post-command-hook'."
181 (when hl-line-overlay 183 (when hl-line-overlay
182 (delete-overlay hl-line-overlay))) 184 (delete-overlay hl-line-overlay)))
183 185
186(defun hl-line-maybe-unhighlight ()
187 "Maybe deactivate the Hl-Line overlay on the current line.
188Specifically, when `hl-line-sticky-flag' is nil deactivate all
189such overlays in all buffers except the current one."
190 (let ((hlob hl-line-overlay-buffer)
191 (curbuf (current-buffer)))
192 (when (and (not hl-line-sticky-flag)
193 (not (eq curbuf hlob))
194 (not (minibufferp)))
195 (with-current-buffer hlob
196 (when (overlayp hl-line-overlay)
197 (delete-overlay hl-line-overlay))))
198 (when (and (overlayp hl-line-overlay)
199 (eq (overlay-buffer hl-line-overlay) curbuf))
200 (setq hl-line-overlay-buffer curbuf))))
201
184;;;###autoload 202;;;###autoload
185(define-minor-mode global-hl-line-mode 203(define-minor-mode global-hl-line-mode
186 "Toggle line highlighting in all buffers (Global Hl-Line mode). 204 "Toggle line highlighting in all buffers (Global Hl-Line mode).
@@ -189,25 +207,24 @@ positive, and disable it otherwise. If called from Lisp, enable
189the mode if ARG is omitted or nil. 207the mode if ARG is omitted or nil.
190 208
191If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode 209If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode
192highlights the line about the current buffer's point in all 210highlights the line about the current buffer's point in all live
193windows. 211windows.
194 212
195Global-Hl-Line mode uses the functions `global-hl-line-unhighlight' and 213Global-Hl-Line mode uses the functions `global-hl-line-highlight'
196`global-hl-line-highlight' on `pre-command-hook' and `post-command-hook'." 214and `global-hl-line-maybe-unhighlight' on `post-command-hook'."
197 :global t 215 :global t
198 :group 'hl-line 216 :group 'hl-line
199 (if global-hl-line-mode 217 (if global-hl-line-mode
200 (progn 218 (progn
201 ;; In case `kill-all-local-variables' is called. 219 ;; In case `kill-all-local-variables' is called.
202 (add-hook 'change-major-mode-hook #'global-hl-line-unhighlight) 220 (add-hook 'change-major-mode-hook #'global-hl-line-unhighlight)
203 (if global-hl-line-sticky-flag 221 (global-hl-line-highlight-all)
204 (remove-hook 'pre-command-hook #'global-hl-line-unhighlight) 222 (add-hook 'post-command-hook #'global-hl-line-highlight)
205 (add-hook 'pre-command-hook #'global-hl-line-unhighlight)) 223 (add-hook 'post-command-hook #'global-hl-line-maybe-unhighlight))
206 (global-hl-line-highlight)
207 (add-hook 'post-command-hook #'global-hl-line-highlight))
208 (global-hl-line-unhighlight-all) 224 (global-hl-line-unhighlight-all)
209 (remove-hook 'pre-command-hook #'global-hl-line-unhighlight) 225 (remove-hook 'post-command-hook #'global-hl-line-highlight)
210 (remove-hook 'post-command-hook #'global-hl-line-highlight))) 226 (remove-hook 'change-major-mode-hook #'global-hl-line-unhighlight)
227 (remove-hook 'post-command-hook #'global-hl-line-maybe-unhighlight)))
211 228
212(defun global-hl-line-highlight () 229(defun global-hl-line-highlight ()
213 "Highlight the current line in the current window." 230 "Highlight the current line in the current window."
@@ -222,11 +239,33 @@ Global-Hl-Line mode uses the functions `global-hl-line-unhighlight' and
222 (selected-window))) 239 (selected-window)))
223 (hl-line-move global-hl-line-overlay)))) 240 (hl-line-move global-hl-line-overlay))))
224 241
242(defun global-hl-line-highlight-all ()
243 "Highlight the current line in all live windows."
244 (walk-windows (lambda (w)
245 (with-current-buffer (window-buffer w)
246 (global-hl-line-highlight)))
247 nil t))
248
225(defun global-hl-line-unhighlight () 249(defun global-hl-line-unhighlight ()
226 "Deactivate the Global-Hl-Line overlay on the current line." 250 "Deactivate the Global-Hl-Line overlay on the current line."
227 (when global-hl-line-overlay 251 (when global-hl-line-overlay
228 (delete-overlay global-hl-line-overlay))) 252 (delete-overlay global-hl-line-overlay)))
229 253
254(defun global-hl-line-maybe-unhighlight ()
255 "Maybe deactivate the Global-Hl-Line overlay on the current line.
256Specifically, when `global-hl-line-sticky-flag' is nil deactivate
257all such overlays in all buffers except the current one."
258 (mapc (lambda (ov)
259 (let ((ovb (overlay-buffer ov)))
260 (when (and (not global-hl-line-sticky-flag)
261 (bufferp ovb)
262 (not (eq ovb (current-buffer)))
263 (not (minibufferp)))
264 (with-current-buffer ovb
265 (when (overlayp global-hl-line-overlay)
266 (delete-overlay global-hl-line-overlay))))))
267 global-hl-line-overlays))
268
230(defun global-hl-line-unhighlight-all () 269(defun global-hl-line-unhighlight-all ()
231 "Deactivate all Global-Hl-Line overlays." 270 "Deactivate all Global-Hl-Line overlays."
232 (mapc (lambda (ov) 271 (mapc (lambda (ov)