EmacsWiki: crosshairs.el (original) (raw)

Download Git Homepage

;;; crosshairs.el --- Highlight the current line and column. ;; ;; Filename: crosshairs.el ;; Description: Highlight the current line and column. ;; Author: Drew Adams ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") ;; Copyright (C) 2006-2022, Drew Adams, all rights reserved. ;; Created: Fri Sep 08 13:09:19 2006 ;; Version: 0 ;; Package-Requires: ((hl-line+ "0") (col-highlight "0") (vline "0")) ;; Last-Updated: Wed Jan 12 12:47:40 2022 (-0800) ;; By: dradams ;; Update #: 519 ;; URL: https://www.emacswiki.org/emacs/download/crosshairs.el ;; Doc URL: https://www.emacswiki.org/emacs/CrosshairHighlighting ;; Keywords: faces, frames, emulation, highlight, cursor, accessibility ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x, 25.x, 26.x ;; ;; Features that might be required by this library: ;; ;; backquote', bytecomp', cconv', cl-lib', col-highlight', ;; hl-line', hl-line+', macroexp', vline'. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Commentary: ;; ;; This library highlights the current line and the current column. ;; It combines the features of libraries hl-line.el', hl-line+.el', ;; and col-highlight.el', which let you highlight the line or column ;; individually. See those libraries for more information, in ;; particular for user options that affect the behavior. ;; ;; If you want the horizontal and vertical highlighting to look the ;; same, then: ;; ;; 1. Set option col-highlight-vline-face-flag' to non-nil. ;; 2. Customize faces col-highlight' and hl-line' to look the same. ;; ;; Command crosshairs-mode' toggles this highlighting on and off. ;; You can do this twice in succession to flash the crosshairs to ;; show you where the cursor is. An alternative way to ;; flash-highlight is to use command flash-crosshairs' (once). ;; ;; Command crosshairs-highlight' shows crosshairs highlighting until ;; your next action (next command, technically). Command ;; crosshairs-unhighlight' turns off crosshairs highlighting due to ;; crosshairs-highlight'. ;; ;; With no prefix arg, command crosshairs' is ;; crosshairs-highlight'. With a prefix arg, it is ;; crosshairs-mode'. ;; ;; You can also have crosshairs highlighting come on automatically, ;; when Emacs is idle. Command toggle-crosshairs-when-idle' toggles ;; this mode. ;; ;; You can use command flash-crosshairs' to do what its name says ;; when you switch buffers or windows. Here is how one user did it ;; (rejoin the split URL): ;; https://unix.stackexchange.com/questions/83167/emacs-finding-the- ;; cursor-in-multiple-windows ;; ;; ;; See also: ;; ;; * Library hl-line+.el', which highlights the current line. ;; ;; * Library col-highlight.el', which highlights the current column. ;; ;; * Library cursor-chg.el' or library oneonone.el', to change the ;; cursor type when Emacs is idle. ;; ;; ;; User options defined here: ;; ;; crosshairs-mode'. ;; ;; Commands defined here: ;; ;; crosshairs', crosshairs-flash', crosshairs-highlight', ;; crosshairs-mode', crosshairs-toggle-when-idle', ;; crosshairs-unhighlight', flash-crosshairs', ;; toggle-crosshairs-when-idle'. ;; ;; Internal variables defined here: ;; ;; crosshairs-flash-col-timer', crosshairs-flash-line-timer', ;; `crosshairs-highlight-when-idle-p'. ;; ;; Suggested alternative key bindings: ;; ;; (global-set-key [(control ?+)] 'crosshairs) ;; or (global-set-key [(control ?+)] 'crosshairs-mode) ;; or (global-set-key [(control ?+)] 'crosshairs-flash) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Change Log: ;; ;; 2022/01/12 dadams ;; Explicitly require hl-line.el and vline.el. ;; 2017/06/26 dadams ;; crosshairs-flash: ;; Use hl-line-unhighlight-now, not global-hl-line-unhighlight, for ;; crosshairs-flash-line-timer. Thx to Dan Harms. ;; 2014/11/28 dadams ;; crosshairs-mode: Call global-hl-line-unhighlight-all (Emacs 24.4+). ;; crosshairs-highlight: ;; Push global-hl-line-overlay to global-hl-line-overlays (Emacs 24.4+). ;; crosshairs-unhighlight: Call global-hl-line-unhighlight-all (Emacs 24.4+). ;; 2014/07/22 dadams ;; Removed extra, vestigial package-requires. ;; 2012/12/25 dadams ;; Added Package-Requires. ;; 2012/05/18 dadams ;; Removed: crosshairs-overlay-priority. Instead, use vline-overlay-priority ;; and col-highlight-overlay-priority. ;; crosshairs-mode, crosshairs-(un)highlight: ;; Do not set the overlay priority - done using defadvice in hl-line+.el and ;; col-highlight.el. ;; 2012/05/17 dadams ;; crosshairs-mode: Made it respect crosshairs-overlay-priority. ;; Removed: crosshairs-vline-same-face-flag. ;; 2011/01/03 dadams ;; Added autoload cookies for defgroup, defcustoms, commands. ;; 2010/06/29 dadams ;; Added: crosshairs-overlay-priority. ;; crosshairs-(un)highlight: Set/remove priority if crosshairs-overlay-priority. ;; 2008/09/03 dadams ;; crosshairs-mode: Don't set previous state if explicit ARG. ;; Added message indicating position. ;; Added: crosshairs, crosshairs-(un)highlight. ;; 2008/08/31 dadams ;; crosshairs-flash: Cancel timers at the outset. ;; Remove hl-line-unhighlight-now from pre-command-hook. ;; 2008/08/08 dadams ;; Added: crosshairs-flash-col-timer, crosshairs-flash-line-timer. ;; crosshairs-flash: ;; Call col-highlight-(un)highlight with arg t. ;; Save unhighlighting timers in crosshairs-flash-(col|line)-timer. ;; First, cancel unhighlighting timers. ;; 2008/01/21 dadams ;; Use vline.el now, instead of column-marker.el. ;; Added group crosshairs, option crosshairs-vline-same-face-flag. ;; crosshairs-mode, crosshairs-toggle-when-idle: ;; If both are already on or off, reflect that as the crosshair state. ;; crosshairs-toggle-when-idle: ;; crosshairs-highlight-when-idle-p, not col-highlight-when-idle-p. ;; crosshairs-flash: ;; Save/restore global-hl-line-mode. ;; Clear and rehighlight column initially. Maybe highlight twice (bug). ;; Don't use highlight modes to unhighlight - just unhighlight. ;; Renamed: line-show-period to hl-line-flash-show-period. ;; Removed semi-support for Emacs 20. ;; 2006/09/08 dadams ;; Created. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; 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) ;; Needed by hl-line+.el'. (require 'hl-line+) ;; Requires hl-line.el'. (require 'vline) ;; Needed by col-highlight.el'. (require 'col-highlight) ;; Requires vline.el'.

(defvar global-hl-line-overlays) ; In `hl-line.el' (Emacs 24.4+)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;###autoload (defgroup crosshairs nil "Highlight the current line and column." :prefix "crosshairs-" :group 'editing :group 'cursor :group 'hl-line :group 'frames :link (url-link :tag "Send Bug Report" ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ crosshairs.el bug: \ &body=Describe bug here, starting with emacs -q'.
Don't forget to mention your Emacs and library versions.")) :link '(url-link :tag "Other Libraries by Drew" "https://www.emacswiki.org/emacs/DrewsElispLibraries") :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/crosshairs.el"))

(defvar crosshairs-highlight-when-idle-p nil "Non-nil means highlight current line and column when Emacs is idle. Do NOT change this yourself; instead, use `\[toggle-crosshairs-when-idle]'.")

(defvar crosshairs-flash-line-timer (timer-create) "Timer used to unhighlight current line for `crosshairs-flash'.")

(defvar crosshairs-flash-col-timer (timer-create) "Timer used to unhighlight current column for `crosshairs-flash'.")

;;;###autoload (define-minor-mode crosshairs-mode "Toggle highlighting the current line and column. With ARG, turn highlighting on if and only if ARG is positive." :init-value nil :global t :group 'crosshairs :link (url-link :tag "Send Bug Report" ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ crosshairs.el bug: \ &body=Describe bug here, starting with emacs -q'.
Don't forget to mention your Emacs and library versions.")) :link '(url-link :tag "Other Libraries by Drew" "https://www.emacswiki.org/emacs/DrewsElispLibraries") :link '(url-link :tag "Download" "https://www.emacswiki.org/emacs/download/crosshairs.el") :link '(url-link :tag "Description" "https://www.emacswiki.org/emacs/ChangingCursorDynamically") :link '(emacs-commentary-link :tag "Commentary" "crosshairs") ;; If both were already on or off, reflect that as the previous crosshairs state. (unless arg (cond ((and global-hl-line-mode column-highlight-mode) (setq crosshairs-mode nil)) ((and (not global-hl-line-mode) (not column-highlight-mode)) (setq crosshairs-mode t)))) (cond (crosshairs-mode (unless global-hl-line-mode (global-hl-line-mode 1) (global-hl-line-highlight)) (column-highlight-mode 1) (message "Point: %d - Crosshairs mode enabled" (point))) (t (global-hl-line-mode -1) (global-hl-line-unhighlight) (when (fboundp 'global-hl-line-unhighlight-all) ; Emacs 24.4+ (global-hl-line-unhighlight-all)) (column-highlight-mode -1) (message "Point: %d - Crosshairs mode disabled" (point)))))

;;;###autoload (defalias 'toggle-crosshairs-when-idle 'crosshairs-toggle-when-idle) ;;;###autoload (defun crosshairs-toggle-when-idle (&optional arg) "Toggle highlighting the current line and column when Emacs is idle. With prefix argument, turn on if ARG > 0; else turn off. You can use commands col-highlight-set-interval' and hl-line-when-idle-interval' to change the idle times." (interactive "P") ;; First, if both are already on or off, reflect that as the crosshair state. (when (or (and hl-line-when-idle-p col-highlight-when-idle-p) (and (not hl-line-when-idle-p) (not col-highlight-when-idle-p))) (setq crosshairs-highlight-when-idle-p hl-line-when-idle-p)) (setq crosshairs-highlight-when-idle-p (if arg (> (prefix-numeric-value arg) 0) (not crosshairs-highlight-when-idle-p))) (setq hl-line-when-idle-p crosshairs-highlight-when-idle-p col-highlight-when-idle-p crosshairs-highlight-when-idle-p) (cond (crosshairs-highlight-when-idle-p (timer-activate-when-idle col-highlight-idle-timer) (timer-activate-when-idle hl-line-idle-timer) (add-hook 'pre-command-hook #'col-highlight-unhighlight) (add-hook 'pre-command-hook #'hl-line-unhighlight-now) (message "Turned ON highlighting line and column when Emacs is idle.")) (t (cancel-timer col-highlight-idle-timer) (cancel-timer hl-line-idle-timer) (remove-hook 'pre-command-hook #'col-highlight-unhighlight) (remove-hook 'pre-command-hook #'hl-line-unhighlight-now) (message "Turned OFF highlighting line and column when Emacs is idle."))))

;;;###autoload (defalias 'flash-crosshairs 'crosshairs-flash) ;;;###autoload (defun crosshairs-flash (&optional seconds) "Highlight the current line and column temporarily. Highlight the line for hl-line-flash-show-period' and the column for column-show-period' seconds. With prefix argument SECONDS, highlight both for SECONDS seconds." (interactive "P") (cancel-timer crosshairs-flash-line-timer) ; Cancel to prevent duplication. (cancel-timer crosshairs-flash-col-timer) (let ((global-hl-line-mode global-hl-line-mode)) (col-highlight-unhighlight t) (col-highlight-highlight t) (when column-highlight-mode (col-highlight-highlight t)) ; Extra - a vline bug. (hl-line-highlight-now) (remove-hook 'pre-command-hook 'hl-line-unhighlight-now) (let ((line-period hl-line-flash-show-period) ; Defined in hl-line+.el'. (column-period col-highlight-period)) ; Defined in col-highlight.el'. (when seconds (setq line-period (prefix-numeric-value seconds) column-period line-period)) ;; $$$$ Do we need to worry about `global-hl-line-unhighlight-all' here? (setq crosshairs-flash-line-timer (run-at-time line-period nil #'hl-line-unhighlight-now) crosshairs-flash-col-timer (run-at-time column-period nil #'col-highlight-unhighlight t)))))

;;;###autoload (defun crosshairs (&optional modalp) "Highlight current position with crosshairs. With no prefix arg, highlighting turns off at the next command. With a prefix arg, highlighting stays on until you toggle it off using `crosshairs-mode'." (interactive "P") (if modalp (crosshairs-mode 1) (crosshairs-highlight)))

;;;###autoload (defun crosshairs-highlight (&optional mode nomsg) "Echo current position and highlight it with crosshairs. If optional arg MODE is line-only', then highlight only the line. If optional arg MODE is col-only', then highlight only the column. Interactively: A non-negative prefix argument uses MODE line-only'. A negative prefix argument uses MODE col-only'.

Optional arg NOMSG non-nil means show no message.

If the current buffer is not the same as the value of orig-buff', then indicate the buffer, as well as the position. Variable orig-buff' is not bound here; if you want to take advantage of this feature in your code, then bind it.

Return current position as a marker." (interactive (list (and current-prefix-arg (if (wholenump (prefix-numeric-value current-prefix-arg)) 'line-only 'col-only)))) (when crosshairs-mode (crosshairs-mode -1)) (prog1 (point-marker) (unless (eq mode 'line-only) (require 'col-highlight nil t)) (unless (eq mode 'col-only) (require 'hl-line nil t)) (setq mark-active nil) (crosshairs-unhighlight 'even-if-frame-switch) (when (and (boundp 'global-hl-line-overlay) (not (eq mode 'col-only))) (unless global-hl-line-overlay (setq global-hl-line-overlay (make-overlay 1 1)) ; to be moved (overlay-put global-hl-line-overlay 'face hl-line-face)) (when (and (boundp 'global-hl-line-overlays) (not (member global-hl-line-overlay global-hl-line-overlays))) (push global-hl-line-overlay global-hl-line-overlays)) (overlay-put global-hl-line-overlay 'window (selected-window)) (hl-line-move global-hl-line-overlay)) (when (and (fboundp 'col-highlight-highlight) (not (eq mode 'line-only))) (redisplay t) ; Force a redisplay, or else it doesn't always show up. (col-highlight-highlight)) (when (or (boundp 'global-hl-line-overlay) (fboundp 'col-highlight-highlight)) (add-hook 'pre-command-hook 'crosshairs-unhighlight)) (unless nomsg (if (and (boundp 'orig-buff) (eq (current-buffer) orig-buff)) (message "Point: %d" (point)) (message "Buffer: `%s', Point: %d" (current-buffer) (point))))))

;;;###autoload (defun crosshairs-unhighlight (&optional arg) "Turn off crosshairs highlighting of current position. Optional arg nil means do nothing if this event is a frame switch." (interactive) (when (or arg (not (and (consp last-input-event) (eq (car last-input-event) 'switch-frame)))) (when (fboundp 'col-highlight-unhighlight) (col-highlight-unhighlight t)) (when (and (boundp 'global-hl-line-overlay) global-hl-line-overlay) ;; (when crosshairs-overlay-priority ;; (overlay-put global-hl-line-overlay 'priority nil)) (delete-overlay global-hl-line-overlay)) (when (fboundp 'global-hl-line-unhighlight-all) ; Emacs 24.4+ (global-hl-line-unhighlight-all)) (remove-hook 'pre-command-hook 'crosshairs-unhighlight)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(provide 'crosshairs)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; crosshairs.el ends here