Skip to content

Instantly share code, notes, and snippets.

@torinkwok
Last active July 20, 2016 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torinkwok/88fa3edc13bc05e66c539f2f19f15f76 to your computer and use it in GitHub Desktop.
Save torinkwok/88fa3edc13bc05e66c539f2f19f15f76 to your computer and use it in GitHub Desktop.
Unofficial mirror of hl-spotlight.el. https://www.emacswiki.org/emacs/hl-spotlight.el
;;; hl-spotlight.el --- Extension of hl-line.el to spotlight current few lines.
;;
;; Filename: hl-spotlight.el
;; Description: Extension of hl-line.el to spotlight current few lines.
;; Author: Drew Adams
;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
;; Copyright (C) 2009-2016, Drew Adams, all rights reserved.
;; Created: Sat Aug 26 18:17:18 2006
;; Version: 0
;; Package-Requires: ()
;; Last-Updated: Thu Dec 31 13:46:01 2015 (-0800)
;; By: dradams
;; Update #: 475
;; URL: http://www.emacswiki.org/hl-spotlight.el
;; Doc URL: http://www.emacswiki.org/HighlightCurrentLine
;; Keywords: highlight, cursor, accessibility
;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x, 25.x
;;
;; Features that might be required by this library:
;;
;; `hl-line'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; This library extends standard library `hl-line.el'. It provides
;; local and global modes to highlight several lines surrounding
;; point using a different face, `hl-spotlight'. You can enlarge or
;; shrink this spotlight highlighting, using command
;; `hl-spotlight-enlarge'. You can repeat, to enlarge or shrink the
;; spotlight incrementally, by using `C-x z z z z...'.
;;
;; Spotlight highlighting can be used together with library
;; `centered-cursor-mode.el', which keeps point (hence also the
;; spotlight) centered in the window. This can be helpful when
;; reading text (as opposed to code). This is controlled by user
;; option `hl-spotlight-keep-centered-flag'. You can obtain library
;; `centered-cursor-mode.el' here:
;; http://www.emacswiki.org/emacs/centered-cursor-mode.el.
;;
;; If you want the spotlight to automatically move down the page
;; progressively, use command `hl-spotlight-scan'. You might find
;; this useful for some kinds of reading. Or not. ;-)
;;
;; To use this library, put this in your Emacs init file (~/.emacs):
;;
;; (require 'hl-spotlight) ; Load this file (it will load `hl-line.el')
;;
;;
;; See also library `hl-line+.el', which extends `hl-line.el' in
;; other ways.
;;
;;
;; Faces defined here:
;;
;; `hl-spotlight'.
;;
;; User options defined here:
;;
;; `hl-spotlight-height', `hl-spotlight-keep-centered-flag',
;; `hl-spotlight-scan-period'.
;;
;; Commands defined here:
;;
;; `global-hl-spotlight-mode', `hl-spotlight-enlarge',
;; `hl-spotlight-mode', `hl-spotlight-scan'.
;;
;; Non-interactive functions defined here:
;;
;; `hl-spotlight-down', `hl-spotlight-limits'.
;;
;; Internal variables defined here:
;;
;; `hl-spotlight-old-state', `hl-spotlight-scan-timer'.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;;
;; 2011/01/04 dadams
;; Added autoload cookies for defcustom, defface, and commands.
;; 2009/02/16 dadams
;; Added: hl-spotlight-scan*, hl-spotlight-down.
;; Created: Moved code from hl-line+.el.
;;
;; Log from hl-line+.el:
;;
;; 2009/02/15 dadams
;; Added: hl-spotlight(-height|-old-state|widen|limits|mode),
;; global-hl-spotlight-mode.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
;; Floor, Boston, MA 02110-1301, USA.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'hl-line) ;; global-hl-line-highlight, global-hl-line-mode,
;; global-hl-line-overlay, global-hl-line-unhighlight,
;; hl-line-face, hl-line-highlight, hl-line-mode,
;; hl-line-overlay, hl-line-range-function, hl-line-sticky-flag,
;; hl-line-unhighlight.
(eval-when-compile
(require 'centered-cursor-mode nil t)) ;; (no error if not found):
;; centered-cursor-mode,
;; global-centered-cursor-mode.
(defvar hl-line-face) ; Quiet the byte-compiler.
(defvar global-hl-line-mode) ; Quiet the byte-compiler.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;###autoload
(defface hl-spotlight
'((t :inherit highlight))
"*Face for the spotlight in Hl-Line-Window mode."
:group 'hl-line)
;;;###autoload
(defcustom hl-spotlight-height 2
"*Number of lines to highlight, before and after the current line."
:type 'integer :group 'hl-line)
;;;###autoload
(defcustom hl-spotlight-keep-centered-flag t
"*Non-nil means keep the cursor and spotlight centered in the window.
This has no effect unless library `centered-cursor-mode' is available."
:type 'boolean :group 'hl-line)
;;;###autoload
(defcustom hl-spotlight-scan-period 1.5
"*Number of seconds to wait before moving cursor to next line.
Set this to nil if you do not want the cursor to automatically scan."
:type '(choice
(const :tag "No cursor scanning" nil)
(number :tag "Seconds before cursor moves to next line"))
:group 'hl-line)
(defvar hl-spotlight-old-state nil
"Saved Hl-Line mode values, before `hl-spotlight-mode'.")
(defvar hl-spotlight-scan-timer (timer-create)
"Timer used to move point downward.")
;;;###autoload
(defun hl-spotlight-enlarge (n)
"Enlarge the hl-line spotlight by N lines.
N is the numeric prefix arg (one, by default).
A negative prefix arg shrinks the spotlight.
The spotlight is used by `hl-spotlight-mode' and
`global-hl-spotlight-mode'."
(interactive "p")
(set-variable 'hl-spotlight-height (+ n hl-spotlight-height))
(when global-hl-spotlight-mode (global-hl-line-highlight))
(when hl-spotlight-mode (hl-line-highlight)))
(defun hl-spotlight-limits ()
"Return a cons of the limits to use for `hl-line-range-function'."
(let ((start (save-excursion (forward-line (- hl-spotlight-height)) (point)))
(end (save-excursion (forward-line (1+ hl-spotlight-height)) (point))))
(cons start end)))
;;;###autoload
(define-minor-mode hl-spotlight-mode
"Buffer-local minor mode to highlight lines surrounding point.
With ARG, turn Hl-Spotlight mode on if ARG is positive, off otherwise.
Hl-Spotlight mode uses Hl-Line mode. Whenever Hl-Spotlight mode is on
in the current buffer, its overlay is used by Hl-Line mode, which
means that face `hl-spotlight' and option `hl-spotlight-height' are
used; face `hl-line' is not used.
Turn the spotlight on and off by using toggle command
`hl-spotlight-mode'. After turning Hl-Spotlight mode on, command
`hl-line-mode' also toggles the spotlight on and off, but without
turning off Hl-Spotlight mode. To return to the normal behavior of
`hl-line-mode', you must turn off Hl-Spotlight mode. Turning off
Hl-Spotlight mode also turns off Hl-Line mode."
:group 'hl-line
(cond (hl-spotlight-mode
(unless hl-spotlight-old-state
(setq hl-spotlight-old-state (list hl-line-face
hl-line-overlay
global-hl-line-overlay
hl-line-range-function
hl-line-sticky-flag)))
(hl-line-unhighlight)
(setq hl-line-overlay nil
hl-line-face 'hl-spotlight
hl-line-range-function 'hl-spotlight-limits
hl-line-sticky-flag nil)
(when (and (require 'centered-cursor-mode nil t)
hl-spotlight-keep-centered-flag)
(centered-cursor-mode 1))
;; 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))
(add-hook 'post-command-hook #'hl-line-highlight nil t))
(t
(cancel-timer hl-spotlight-scan-timer)
(setq hl-line-face (nth 0 hl-spotlight-old-state)
hl-line-overlay (nth 1 hl-spotlight-old-state)
global-hl-line-overlay (nth 2 hl-spotlight-old-state)
hl-line-range-function (nth 3 hl-spotlight-old-state)
hl-line-sticky-flag (nth 4 hl-spotlight-old-state))
(when hl-spotlight-old-state (setq hl-spotlight-old-state nil))
(when (require 'centered-cursor-mode nil t) (centered-cursor-mode -1))
(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)))
(hl-line-mode (if hl-spotlight-mode 1 -1)))
;;;###autoload
(define-minor-mode global-hl-spotlight-mode
"Global minor mode to highlight lines around point in current window.
With ARG, turn Global-Hl-Spotlight mode on if ARG is positive, off
otherwise.
See `hl-spotlight-mode'. The interaction between
`global-hl-spotlight-mode' and `global-hl-line-mode' is similar to
that between `hl-spotlight-mode' and `hl-line-mode'."
:global t :group 'hl-line
(cond (global-hl-spotlight-mode
(unless hl-spotlight-old-state
(setq hl-spotlight-old-state (list hl-line-face
hl-line-overlay
global-hl-line-overlay
hl-line-range-function
hl-line-sticky-flag)))
(global-hl-line-unhighlight)
(setq global-hl-line-overlay nil
hl-line-face 'hl-spotlight
hl-line-range-function 'hl-spotlight-limits
hl-line-sticky-flag nil)
(when (and (require 'centered-cursor-mode nil t)
hl-spotlight-keep-centered-flag)
(global-centered-cursor-mode 1))
(add-hook 'pre-command-hook #'global-hl-line-unhighlight)
(add-hook 'post-command-hook #'global-hl-line-highlight))
(t
(setq hl-line-face (nth 0 hl-spotlight-old-state)
hl-line-overlay (nth 1 hl-spotlight-old-state)
global-hl-line-overlay (nth 2 hl-spotlight-old-state)
hl-line-range-function (nth 3 hl-spotlight-old-state)
hl-line-sticky-flag (nth 4 hl-spotlight-old-state))
(when hl-spotlight-old-state (setq hl-spotlight-old-state nil))
(when (require 'centered-cursor-mode nil t)
(global-centered-cursor-mode -1))
(global-hl-line-unhighlight)
(remove-hook 'pre-command-hook #'global-hl-line-unhighlight)
(remove-hook 'post-command-hook #'global-hl-line-highlight)))
(global-hl-line-mode (if global-hl-spotlight-mode 1 -1)))
;;;###autoload
(defun hl-spotlight-scan (arg)
"Scan the buffer, moving the cursor down automatically.
Every `hl-spotlight-scan-period' seconds, move the cursor down one
line or the number of lines specified by a prefix arg. Scanning
starts at point.
With a plain prefix arg (`C-u'), stop a scan already in progess.
With a numeric prefix arg, scan down that many lines.
A negative prefix arg means scan up, not down.
With `C-u C-u', scan down the height of a full spotlight."
(interactive "P")
(if (and (consp arg) (= (car arg) 4))
(cancel-timer hl-spotlight-scan-timer)
(when (consp arg) (setq arg (1+ (* 2 hl-spotlight-height))))
(setq arg (prefix-numeric-value arg))
(setq hl-spotlight-scan-timer (run-at-time 0 hl-spotlight-scan-period
#'hl-spotlight-down arg))))
(defun hl-spotlight-down (&optional n)
"Move the spotlight down N lines (default 1)."
(unless n (setq n 1))
(if (eobp)
(cancel-timer hl-spotlight-scan-timer)
(forward-line n)
(ccm-position-cursor)
(hl-line-highlight)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'hl-spotlight)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; hl-spotlight.el ends here
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment