Download
(require 'hl-line+)
(require 'col-highlight)
(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"
"http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
:link '(url-link :tag "Download"
"http://www.emacswiki.org/cgi-bin/wiki/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'.")
(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"
"http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
:link '(url-link :tag "Download"
"http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el")
:link '(url-link :tag "Description"
"http://www.emacswiki.org/cgi-bin/wiki/ChangingCursorDynamically")
:link '(emacs-commentary-link :tag "Commentary" "crosshairs")
(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)
(column-highlight-mode -1)
(message "Point: %d - Crosshairs mode disabled" (point)))))
(defalias 'toggle-crosshairs-when-idle 'crosshairs-toggle-when-idle)
(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")
(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."))))
(defalias 'flash-crosshairs 'crosshairs-flash)
(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-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))
(hl-line-highlight-now)
(remove-hook 'pre-command-hook 'hl-line-unhighlight-now)
(let ((line-period hl-line-flash-show-period)
(column-period col-highlight-period))
(when seconds
(setq line-period (prefix-numeric-value seconds)
column-period line-period))
(setq crosshairs-flash-line-timer (run-at-time
line-period nil
#'global-hl-line-unhighlight)
crosshairs-flash-col-timer (run-at-time
column-period nil
#'col-highlight-unhighlight t)))))
(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)))
(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))
(overlay-put global-hl-line-overlay 'face hl-line-face))
(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)
(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))))))
(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)
(delete-overlay global-hl-line-overlay))
(remove-hook 'pre-command-hook 'crosshairs-unhighlight)))
(provide 'crosshairs)