New org capture template
[emacs.git] / .emacs.d / elisp / icicle / crosshairs.el
1 ;;; crosshairs.el --- Highlight the current line and column.
2 ;;
3 ;; Filename: crosshairs.el
4 ;; Description: Highlight the current line and column.
5 ;; Author: Drew Adams
6 ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
7 ;; Copyright (C) 2006-2014, Drew Adams, all rights reserved.
8 ;; Created: Fri Sep 08 13:09:19 2006
9 ;; Version: 0
10 ;; Package-Requires: ((hl-line+ "0") (col-highlight "0") (vline "0"))
11 ;; Last-Updated: Thu Dec 26 08:51:16 2013 (-0800)
12 ;; By: dradams
13 ;; Update #: 487
14 ;; URL: http://www.emacswiki.org/crosshairs.el
15 ;; Doc URL: http://www.emacswiki.org/CrosshairHighlighting
16 ;; Keywords: faces, frames, emulation, highlight, cursor, accessibility
17 ;; Compatibility: GNU Emacs: 22.x, 23.x, 24.x
18 ;; Package-Requires: ((col-highlight "22.0") (hl-line+ "20120823") (vline "1.10"))
19 ;;
20 ;; Features that might be required by this library:
21 ;;
22 ;; `col-highlight', `hl-line', `hl-line+', `vline'.
23 ;;
24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;;
26 ;;; Commentary:
27 ;;
28 ;; This library highlights the current line and the current column.
29 ;; It combines the features of libraries `hl-line.el', `hl-line+.el',
30 ;; and `col-highlight.el', which let you highlight the line or column
31 ;; individually. See those libraries for more information, in
32 ;; particular for user options that affect the behavior.
33 ;;
34 ;; If you want the horizontal and vertical highlighting to look the
35 ;; same, then:
36 ;;
37 ;; 1. Set option `col-highlight-vline-face-flag' to non-nil.
38 ;; 2. Customize faces `col-highlight' and `hl-line' to look the same.
39 ;;
40 ;; Command `crosshairs-mode' toggles this highlighting on and off.
41 ;; You can do this twice in succession to flash the crosshairs to
42 ;; show you where the cursor is. An alternative way to
43 ;; flash-highlight is to use command `flash-crosshairs' (once).
44 ;;
45 ;; Command `crosshairs-highlight' shows crosshairs highlighting until
46 ;; your next action (next command, technically). Command
47 ;; `crosshairs-unhighlight' turns off crosshairs highlighting due to
48 ;; `crosshairs-highlight'.
49 ;;
50 ;; With no prefix arg, command `crosshairs' is
51 ;; `crosshairs-highlight'. With a prefix arg, it is
52 ;; `crosshairs-mode'.
53 ;;
54 ;; You can also have crosshairs highlighting come on automatically,
55 ;; when Emacs is idle. Command `toggle-crosshairs-when-idle' toggles
56 ;; this mode.
57 ;;
58 ;; You can use command `flash-crosshairs' to do what its name says
59 ;; when you switch buffers or windows. Here is how one user did it
60 ;; (rejoin the split URL):
61 ;; http://unix.stackexchange.com/questions/83167/emacs-finding-the-
62 ;; cursor-in-multiple-windows
63 ;;
64 ;;
65 ;; See also:
66 ;;
67 ;; * Library `hl-line+.el', which highlights the current line.
68 ;;
69 ;; * Library `col-highlight.el', which highlights the current column.
70 ;;
71 ;; * Library `cursor-chg.el' or library `oneonone.el', to change the
72 ;; cursor type when Emacs is idle.
73 ;;
74 ;;
75 ;; User options defined here:
76 ;;
77 ;; `crosshairs-mode'.
78 ;;
79 ;; Commands defined here:
80 ;;
81 ;; `crosshairs', `crosshairs-flash', `crosshairs-highlight',
82 ;; `crosshairs-mode', `crosshairs-toggle-when-idle',
83 ;; `crosshairs-unhighlight', `flash-crosshairs',
84 ;; `toggle-crosshairs-when-idle'.
85 ;;
86 ;; Internal variables defined here:
87 ;;
88 ;; `crosshairs-flash-col-timer', `crosshairs-flash-line-timer',
89 ;; `crosshairs-highlight-when-idle-p'.
90 ;;
91 ;; Suggested alternative key bindings:
92 ;;
93 ;; (global-set-key [(control ?+)] 'crosshairs)
94 ;; or (global-set-key [(control ?+)] 'crosshairs-mode)
95 ;; or (global-set-key [(control ?+)] 'crosshairs-flash)
96 ;;
97 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
98 ;;
99 ;;; Change Log:
100 ;;
101 ;; 2012/12/25 dadams
102 ;; Added Package-Requires.
103 ;; 2012/05/18 dadams
104 ;; Removed: crosshairs-overlay-priority. Instead, use vline-overlay-priority
105 ;; and col-highlight-overlay-priority.
106 ;; crosshairs-mode, crosshairs-(un)highlight:
107 ;; Do not set the overlay priority - done using defadvice in hl-line+.el and
108 ;; col-highlight.el.
109 ;; 2012/05/17 dadams
110 ;; crosshairs-mode: Made it respect crosshairs-overlay-priority.
111 ;; Removed: crosshairs-vline-same-face-flag.
112 ;; 2011/01/03 dadams
113 ;; Added autoload cookies for defgroup, defcustoms, commands.
114 ;; 2010/06/29 dadams
115 ;; Added: crosshairs-overlay-priority.
116 ;; crosshairs-(un)highlight: Set/remove priority if crosshairs-overlay-priority.
117 ;; 2008/09/03 dadams
118 ;; crosshairs-mode: Don't set previous state if explicit ARG.
119 ;; Added message indicating position.
120 ;; Added: crosshairs, crosshairs-(un)highlight.
121 ;; 2008/08/31 dadams
122 ;; crosshairs-flash: Cancel timers at the outset.
123 ;; Remove hl-line-unhighlight-now from pre-command-hook.
124 ;; 2008/08/08 dadams
125 ;; Added: crosshairs-flash-col-timer, crosshairs-flash-line-timer.
126 ;; crosshairs-flash:
127 ;; Call col-highlight-(un)highlight with arg t.
128 ;; Save unhighlighting timers in crosshairs-flash-(col|line)-timer.
129 ;; First, cancel unhighlighting timers.
130 ;; 2008/01/21 dadams
131 ;; Use vline.el now, instead of column-marker.el.
132 ;; Added group crosshairs, option crosshairs-vline-same-face-flag.
133 ;; crosshairs-mode, crosshairs-toggle-when-idle:
134 ;; If both are already on or off, reflect that as the crosshair state.
135 ;; crosshairs-toggle-when-idle:
136 ;; crosshairs-highlight-when-idle-p, not col-highlight-when-idle-p.
137 ;; crosshairs-flash:
138 ;; Save/restore global-hl-line-mode.
139 ;; Clear and rehighlight column initially. Maybe highlight twice (bug).
140 ;; Don't use highlight modes to unhighlight - just unhighlight.
141 ;; Renamed: line-show-period to hl-line-flash-show-period.
142 ;; Removed semi-support for Emacs 20.
143 ;; 2006/09/08 dadams
144 ;; Created.
145 ;;
146 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
147 ;;
148 ;; This program is free software; you can redistribute it and/or
149 ;; modify it under the terms of the GNU General Public License as
150 ;; published by the Free Software Foundation; either version 3, or
151 ;; (at your option) any later version.
152 ;;
153 ;; This program is distributed in the hope that it will be useful,
154 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
155 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
156 ;; General Public License for more details.
157 ;;
158 ;; You should have received a copy of the GNU General Public License
159 ;; along with this program; see the file COPYING. If not, write to
160 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
161 ;; Floor, Boston, MA 02110-1301, USA.
162 ;;
163 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
164 ;;
165 ;;; Code:
166
167 (require 'hl-line+) ;; Requires `hl-line.el'.
168 (require 'col-highlight) ;; Requires `vline.el'.
169
170 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
171
172 ;;;###autoload
173 (defgroup crosshairs nil
174 "Highlight the current line and column."
175 :prefix "crosshairs-"
176 :group 'editing :group 'cursor :group 'hl-line :group 'frames
177 :link `(url-link :tag "Send Bug Report"
178 ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
179 crosshairs.el bug: \
180 &body=Describe bug here, starting with `emacs -q'. \
181 Don't forget to mention your Emacs and library versions."))
182 :link '(url-link :tag "Other Libraries by Drew"
183 "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
184 :link '(url-link :tag "Download"
185 "http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el"))
186
187 (defvar crosshairs-highlight-when-idle-p nil
188 "Non-nil means highlight current line and column when Emacs is idle.
189 Do NOT change this yourself; instead, use
190 `\\[toggle-crosshairs-when-idle]'.")
191
192 (defvar crosshairs-flash-line-timer (timer-create)
193 "Timer used to unhighlight current line for `crosshairs-flash'.")
194
195 (defvar crosshairs-flash-col-timer (timer-create)
196 "Timer used to unhighlight current column for `crosshairs-flash'.")
197
198 ;;;###autoload
199 (define-minor-mode crosshairs-mode
200 "Toggle highlighting the current line and column.
201 With ARG, turn highlighting on if and only if ARG is positive."
202 :init-value nil :global t :group 'crosshairs
203 :link `(url-link :tag "Send Bug Report"
204 ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\
205 crosshairs.el bug: \
206 &body=Describe bug here, starting with `emacs -q'. \
207 Don't forget to mention your Emacs and library versions."))
208 :link '(url-link :tag "Other Libraries by Drew"
209 "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries")
210 :link '(url-link :tag "Download"
211 "http://www.emacswiki.org/cgi-bin/wiki/crosshairs.el")
212 :link '(url-link :tag "Description"
213 "http://www.emacswiki.org/cgi-bin/wiki/ChangingCursorDynamically")
214 :link '(emacs-commentary-link :tag "Commentary" "crosshairs")
215 ;; If both were already on or off, reflect that as the previous crosshairs state.
216 (unless arg
217 (cond ((and global-hl-line-mode column-highlight-mode)
218 (setq crosshairs-mode nil))
219 ((and (not global-hl-line-mode) (not column-highlight-mode))
220 (setq crosshairs-mode t))))
221 (cond (crosshairs-mode
222 (unless global-hl-line-mode
223 (global-hl-line-mode 1)
224 (global-hl-line-highlight))
225 (column-highlight-mode 1)
226 (message "Point: %d - Crosshairs mode enabled" (point)))
227 (t
228 (global-hl-line-mode -1)
229 (global-hl-line-unhighlight)
230 (column-highlight-mode -1)
231 (message "Point: %d - Crosshairs mode disabled" (point)))))
232
233 ;;;###autoload
234 (defalias 'toggle-crosshairs-when-idle 'crosshairs-toggle-when-idle)
235 ;;;###autoload
236 (defun crosshairs-toggle-when-idle (&optional arg)
237 "Toggle highlighting the current line and column when Emacs is idle.
238 With prefix argument, turn on if ARG > 0; else turn off.
239 You can use commands `col-highlight-set-interval' and
240 `hl-line-when-idle-interval' to change the idle times."
241 (interactive "P")
242 ;; First, if both are already on or off, reflect that as the crosshair state.
243 (when (or (and hl-line-when-idle-p col-highlight-when-idle-p)
244 (and (not hl-line-when-idle-p) (not col-highlight-when-idle-p)))
245 (setq crosshairs-highlight-when-idle-p hl-line-when-idle-p))
246 (setq crosshairs-highlight-when-idle-p (if arg
247 (> (prefix-numeric-value arg) 0)
248 (not crosshairs-highlight-when-idle-p)))
249 (setq hl-line-when-idle-p crosshairs-highlight-when-idle-p
250 col-highlight-when-idle-p crosshairs-highlight-when-idle-p)
251 (cond (crosshairs-highlight-when-idle-p
252 (timer-activate-when-idle col-highlight-idle-timer)
253 (timer-activate-when-idle hl-line-idle-timer)
254 (add-hook 'pre-command-hook #'col-highlight-unhighlight)
255 (add-hook 'pre-command-hook #'hl-line-unhighlight-now)
256 (message "Turned ON highlighting line and column when Emacs is idle."))
257 (t
258 (cancel-timer col-highlight-idle-timer)
259 (cancel-timer hl-line-idle-timer)
260 (remove-hook 'pre-command-hook #'col-highlight-unhighlight)
261 (remove-hook 'pre-command-hook #'hl-line-unhighlight-now)
262 (message "Turned OFF highlighting line and column when Emacs is idle."))))
263
264 ;;;###autoload
265 (defalias 'flash-crosshairs 'crosshairs-flash)
266 ;;;###autoload
267 (defun crosshairs-flash (&optional seconds)
268 "Highlight the current line and column temporarily.
269 Highlight the line for `hl-line-flash-show-period' and the column for
270 `column-show-period' seconds. With prefix argument SECONDS, highlight
271 both for SECONDS seconds."
272 (interactive "P")
273 (cancel-timer crosshairs-flash-line-timer) ; Cancel to prevent duplication.
274 (cancel-timer crosshairs-flash-col-timer)
275 (let ((global-hl-line-mode global-hl-line-mode))
276 (col-highlight-unhighlight t)
277 (col-highlight-highlight t)
278 (when column-highlight-mode (col-highlight-highlight t)) ; Extra - a vline bug.
279 (hl-line-highlight-now)
280 (remove-hook 'pre-command-hook 'hl-line-unhighlight-now)
281 (let ((line-period hl-line-flash-show-period) ; Defined in `hl-line+.el'.
282 (column-period col-highlight-period)) ; Defined in `col-highlight.el'.
283 (when seconds
284 (setq line-period (prefix-numeric-value seconds)
285 column-period line-period))
286 (setq crosshairs-flash-line-timer (run-at-time
287 line-period nil
288 #'global-hl-line-unhighlight)
289 crosshairs-flash-col-timer (run-at-time
290 column-period nil
291 #'col-highlight-unhighlight t)))))
292
293 ;;;###autoload
294 (defun crosshairs (&optional modalp)
295 "Highlight current position with crosshairs.
296 With no prefix arg, highlighting turns off at the next command.
297 With a prefix arg, highlighting stays on until you toggle it off using
298 `crosshairs-mode'."
299 (interactive "P")
300 (if modalp (crosshairs-mode 1) (crosshairs-highlight)))
301
302 ;;;###autoload
303 (defun crosshairs-highlight (&optional mode nomsg)
304 "Echo current position and highlight it with crosshairs.
305 If optional arg MODE is `line-only', then highlight only the line.
306 If optional arg MODE is `col-only', then highlight only the column.
307 Interactively:
308 A non-negative prefix argument uses MODE `line-only'.
309 A negative prefix argument uses MODE `col-only'.
310
311 Optional arg NOMSG non-nil means show no message.
312
313 If the current buffer is not the same as the value of `orig-buff',
314 then indicate the buffer, as well as the position. Variable
315 `orig-buff' is not bound here; if you want to take advantage of this
316 feature in your code, then bind it.
317
318 Return current position as a marker."
319 (interactive (list (and current-prefix-arg
320 (if (wholenump (prefix-numeric-value current-prefix-arg))
321 'line-only
322 'col-only))))
323 (when crosshairs-mode (crosshairs-mode -1))
324 (prog1 (point-marker)
325 (unless (eq mode 'line-only) (require 'col-highlight nil t))
326 (unless (eq mode 'col-only) (require 'hl-line nil t))
327 (setq mark-active nil)
328 (crosshairs-unhighlight 'even-if-frame-switch)
329 (when (and (boundp 'global-hl-line-overlay) (not (eq mode 'col-only)))
330 (unless global-hl-line-overlay
331 (setq global-hl-line-overlay (make-overlay 1 1)) ; to be moved
332 (overlay-put global-hl-line-overlay 'face hl-line-face))
333 (overlay-put global-hl-line-overlay 'window (selected-window))
334 (hl-line-move global-hl-line-overlay))
335 (when (and (fboundp 'col-highlight-highlight) (not (eq mode 'line-only)))
336 (redisplay t) ; Force a redisplay, or else it doesn't always show up.
337 (col-highlight-highlight))
338 (when (or (boundp 'global-hl-line-overlay) (fboundp 'col-highlight-highlight))
339 (add-hook 'pre-command-hook 'crosshairs-unhighlight))
340 (unless nomsg
341 (if (and (boundp 'orig-buff) (eq (current-buffer) orig-buff))
342 (message "Point: %d" (point))
343 (message "Buffer: `%s', Point: %d" (current-buffer) (point))))))
344
345 ;;;###autoload
346 (defun crosshairs-unhighlight (&optional arg)
347 "Turn off crosshairs highlighting of current position.
348 Optional arg nil means do nothing if this event is a frame switch."
349 (interactive)
350 (when (or arg (not (and (consp last-input-event)
351 (eq (car last-input-event) 'switch-frame))))
352 (when (fboundp 'col-highlight-unhighlight) (col-highlight-unhighlight t))
353 (when (and (boundp 'global-hl-line-overlay) global-hl-line-overlay)
354 ;; (when crosshairs-overlay-priority
355 ;; (overlay-put global-hl-line-overlay 'priority nil))
356 (delete-overlay global-hl-line-overlay))
357 (remove-hook 'pre-command-hook 'crosshairs-unhighlight)))
358
359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
360
361 (provide 'crosshairs)
362
363 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
364 ;;; crosshairs.el ends here