diff options
| author | Stephen Berman | 2016-05-26 11:30:29 +0200 |
|---|---|---|
| committer | Stephen Berman | 2016-05-26 11:30:29 +0200 |
| commit | 16be3e90545972dec16014253a843229d5bdf388 (patch) | |
| tree | 862abd927225b9f9d1a1f68af8d9dfe0f41e2b72 | |
| parent | e971ce6de27f982720ef312637e1d40da80e8d1f (diff) | |
| download | emacs-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.el | 71 |
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 | ||
| 127 | This variable is expected to be made buffer-local by modes.") | 127 | This 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 | ||
| 143 | When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the | 146 | When `hl-line-sticky-flag' is nil, Hl-Line mode highlights the |
| 144 | line about point in the selected window only. In this case, it | 147 | line about point in the selected window only. In this case, it |
| 145 | uses the function `hl-line-unhighlight' on `pre-command-hook' in | 148 | uses the function `hl-line-maybe-unhighlight' in |
| 146 | addition to `hl-line-highlight' on `post-command-hook'." | 149 | addition 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. | ||
| 188 | Specifically, when `hl-line-sticky-flag' is nil deactivate all | ||
| 189 | such 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 | |||
| 189 | the mode if ARG is omitted or nil. | 207 | the mode if ARG is omitted or nil. |
| 190 | 208 | ||
| 191 | If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode | 209 | If `global-hl-line-sticky-flag' is non-nil, Global Hl-Line mode |
| 192 | highlights the line about the current buffer's point in all | 210 | highlights the line about the current buffer's point in all live |
| 193 | windows. | 211 | windows. |
| 194 | 212 | ||
| 195 | Global-Hl-Line mode uses the functions `global-hl-line-unhighlight' and | 213 | Global-Hl-Line mode uses the functions `global-hl-line-highlight' |
| 196 | `global-hl-line-highlight' on `pre-command-hook' and `post-command-hook'." | 214 | and `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. | ||
| 256 | Specifically, when `global-hl-line-sticky-flag' is nil deactivate | ||
| 257 | all 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) |