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