0
|
1 ;; -*- Syntax: Emacs-Lisp; Mode: emacs-lisp -*-
|
|
2 ;;
|
|
3 ;; Per mode and per buffer mouse tracking with highlighting
|
|
4 ;;
|
|
5 ;; Copyright (C) 1992, 1993 by Guido Bosch <Guido.Bosch@loria.fr>
|
|
6
|
|
7 ;; This file is written in GNU Emacs Lisp, It is a part of XEmacs.
|
|
8
|
|
9 ;; The software contained in this file is free software; you can
|
|
10 ;; redistribute it and/or modify it under the terms of the GNU General
|
|
11 ;; Public License as published by the Free Software Foundation; either
|
|
12 ;; version 2, or (at your option) any later version.
|
|
13
|
|
14 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 ;; GNU General Public License for more details.
|
|
18
|
|
19 ;; You should have received a copy of the GNU General Public License
|
|
20 ;; along with GNU Emacs; see the file COPYING. If not, write to
|
|
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
22 ;;
|
|
23 ;;; Synched up with: Not in FSF.
|
|
24
|
|
25 ;; Please send bugs and comments to Russell.Ritchie@gssec.bt.co.uk or
|
|
26 ;; tlp00@spg.amdahl.com.
|
|
27 ;;
|
|
28 ;; <DISCLAIMER>
|
|
29 ;; This program is still under development. Neither the author nor any
|
|
30 ;; of the maintainers accepts responsibility to anyone for the consequences of
|
|
31 ;; using it or for whether it serves any particular purpose or works
|
|
32 ;; at all.
|
|
33
|
|
34 ; Change History
|
|
35 ; Revision 3.15 Thu Feb 15 14:26:34 GMT 1996 Russell.Ritchie@gssec.bt.co.uk
|
|
36 ; lisp-interaction-popup-menu => lisp-interaction-mode-popup-menu,
|
|
37 ; emacs-lisp-popup-menu => emacs-lisp-mode-popup-menu.
|
|
38
|
|
39 ; Revision 3.14 Tue Nov 14 11:14:38 GMT 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
40 ; Made nil the default value for mode-motion-focus-on-window. Too many people
|
|
41 ; hate it when the cursor warps into Dired and GNUS buffers because some
|
|
42 ; window managers auto-raise the window with keyboard focus with predictably
|
|
43 ; nauseous results.
|
|
44
|
|
45 ; Revision 3.13 Thu Sep 14 10:30:04 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
46 ; Fix the `spontaneous scrolling' problem (at last). It's funny how
|
|
47 ; easy things are once you actually understand the issues involved.
|
|
48 ; As ever, what we sought was the right question...
|
|
49
|
|
50 ; Revision 3.12 Wed Jul 12 11:30:43 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
51 ; Track `don't highlight non-file lines in dired buffers' functionality (in a
|
|
52 ; pretty tasteless manner if I say so myself :-)).
|
|
53
|
|
54 ; Revision 3.11 Fri Jul 7 16:26:56 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
55 ; Minor extent detaching bug fix.
|
|
56
|
|
57 ; Revision 3.10 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
58 ; Quiet, faster, non-interactive initialistion, mild list-motion-handlers
|
|
59 ; chrome and minor formatting clean-ups.
|
|
60
|
|
61 ; Revision 3.9 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
62 ; Fixed the `mouse-motion whilst reading filename in minibuffer auto-ftp' bug.
|
|
63
|
|
64 ; Revision 3.8 Thus Mar 23 1995 tlp00@spg.amdahl.com
|
|
65 ; added in menu controls from paquette@atomas.crim.ca
|
|
66 ; re-added minibuffer support (from 3.5)
|
|
67 ;
|
|
68 ; Revision 3.7 Tue Feb 21 11:06:38 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
69 ; Extended mode-motion+-religion and made the defaulting frame-buffer aware.
|
|
70 ; Reworked and added new mode-motion-handlers.
|
|
71 ; Doc string clean up.
|
|
72 ; Fixed unintentional frame/screen reversion.
|
|
73
|
|
74 ; Revision 3.6 Mon Feb 20 11:46:32 1995 Russell.Ritchie@gssec.bt.co.uk
|
|
75 ; Made mouse tracking use mode-motion-hook for better integration with
|
|
76 ; the default mouse-motion system (help-echo and friends now work).
|
|
77
|
|
78 ; Revision 3.5 1995/02/16 13:40:00 tlp00@spg.amdahl.com
|
|
79 ; fixed sporatic scroll bug
|
|
80 ; added M-button2 binding for mode-motion-copy
|
|
81 ;
|
|
82 ; Revision 3.4 1995/02/14 14:30:15 Russell.Ritchie@gssec.bt.co.uk
|
|
83 ; Small code cleanups: let* -> let, duplicate defvars.
|
|
84 ; Chromed list-motion-handlers a little.
|
|
85 ; Added variable mode-motion+-religion for easy choice twixt underline & bold.
|
|
86
|
|
87 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tlp00 changes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
88
|
|
89 ; tlp00@spg.amdahl.com 2/11/93
|
|
90 ; modified mode-motion-track-pointer to move cursor cross windows
|
|
91 ; renamed mode-motion-delete to mode-motion-kill to follow kill
|
|
92 ; convention
|
|
93 ; mode-motion-highlight-with-handler to put cursor at beginning of line
|
|
94 ; follow operations.
|
|
95 ; mode-motion-copy/delete and mode-motion-kill to position cursor at
|
|
96 ; delete point start. Also set this-command to avoid appends
|
|
97 ; set mode-motion-extent priority to 1, so it will override font-lock
|
|
98 ; changed default handlers for buffer-mode, c-mode, dired-mode, added occur
|
|
99 ; and compilation mode.
|
|
100 ; fixed bug in minibuffer-selection-boundaries where C-g was leaving the wrong
|
|
101 ; syntax table.
|
|
102 ; added support for pending-delete.
|
|
103 ; adds the copy/delete motion-extent to the clipboard even if kill-hooks is nil.
|
|
104 ;
|
|
105 ; Revision 3.3 1995/02/13 tlp00@spg.amdahl.com
|
|
106 ; merged Russell.Ritchie@gssec.bt.co.uk versions with molli/bosch versions
|
|
107 ; renamed versioning 3.0+ for molli/bosch versions.
|
|
108 ;
|
|
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Russell Ritchie changes;;;;;;;;;;;;;;;;;;;;;;;;
|
|
110 ; !Log: mode-motion+.el,v !
|
|
111 ; Revision 2.14.R 1994/09/09 10:19:18 rieke@darmstadt.gmd.de
|
|
112 ; Merged in my changes to support motion-gray. This needs a file
|
|
113 ; named "gray1.xbm" in your data-directory (etc) like the following.
|
|
114 ; -------------------------------snip--------------------------
|
|
115 ; #define bg2_width 16
|
|
116 ; #define bg2_height 16
|
|
117 ; static char bg2_bits[] = {
|
|
118 ; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
|
|
119 ; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,
|
|
120 ; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};
|
|
121 ; -------------------------------snip--------------------------
|
|
122 ; This one looks good on SUN 19'' screens with 10x20 font,
|
|
123 ; black foreground and khaki background.
|
|
124 ; To use the gray-handlers instead of the underline-handlers
|
|
125 ; include the following into your .emacs:
|
|
126 ; (set-mode-motion-handler 'emacs-lisp-mode 'gray-thing)
|
|
127 ; (set-mode-motion-handler 'lisp-interaction-mode 'gray-thing)
|
|
128 ; (set-mode-motion-handler 'c++-mode 'gray-c)
|
|
129 ; (set-mode-motion-handler 'c-mode 'gray-c)
|
|
130 ; (set-mode-motion-handler 'tcl-mode 'gray-tcl)
|
|
131 ; (set-mode-motion-handler 'dired-mode 'gray-line@)
|
|
132 ; (set-mode-motion-handler 'gnus-group-mode 'gray-vline@)
|
|
133 ; (set-mode-motion-handler 'gnus-summary-mode 'gray-vline@)
|
|
134 ; (set-mode-motion-handler 'texinfo-mode 'gray-Texinfo)
|
|
135 ; (setq default-motion-handler (find-motion-handler 'gray-thing))
|
|
136 ;
|
|
137 ;
|
|
138 ; Revision 2.13.R 1994/08/08 19:47:34 Russell.Ritchie@gssec.bt.co.uk
|
|
139 ; Made default handler be underline-thing, as most bold fonts seem to
|
|
140 ; be greater in height than their corresponding normal versions,
|
|
141 ; causing irritating screen flicker.
|
|
142 ;
|
|
143 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Molli/bosch changes;;;;;;;;;;;;;;;;;;;;;;;;
|
|
144 ;
|
|
145 ; Revision 3.2 1994/09/28 15:14:29 molli
|
|
146 ; add "(set-mode-motion-handler 'latex-mode 'raise-LaTeX)". Barry
|
|
147 ; Waraw's C/C++ mode is now changed to cc-mode ...
|
|
148 ;
|
|
149 ; Revision 3.1 1994/09/28 15:10:36 molli
|
|
150 ; Initial revision
|
|
151 ;
|
|
152 ; Revision 2.15 1993/11/18 08:13:28 bosch
|
|
153 ; Constant `mode-motion+-version' added.
|
|
154 ; Minor bug fix in `tcl-forward-sexp1'.
|
|
155 ;
|
|
156 ; Revision 2.14 1993/10/29 20:04:59 bosch
|
|
157 ; Minibuffer name matching improved. Made `tcl-boundaries' smarter by
|
|
158 ; use of new function `tcl-forward-sexp1'. `tcl-commands' list updated
|
|
159 ; -- should be complete now. A message is printed if the syntax scanner
|
|
160 ; matched or failed for known tcl/tk commands. Seperated `tcl-commands'
|
|
161 ; from `tk-commands' -- `tk-commands' not yet complete. New motion
|
|
162 ; handler `raise-LaTeX' added, for tex-mode.
|
|
163 ;
|
|
164 ; Revision 2.13 1993/10/08 09:43:00 bosch
|
|
165 ; New user option `mode-motion-setup-cut-and-paste-bindings'. Function
|
|
166 ; `mode-motion-copy/delete' now takes into account the primary and the
|
|
167 ; motion selection.
|
|
168 ;
|
|
169 ; Revision 2.12 1993/10/08 09:08:46 bosch
|
|
170 ; Avoid highlighting empty lines, even if
|
|
171 ; `mode-motion-highlight-lines-when-behind' is non-nil.
|
|
172
|
|
173 ; Revision 2.12 1994/07/07 18:33:38 Russell.Ritchie@gssec.bt.co.uk
|
|
174 ; Made list-motion-handlers and mode-motion-set-handler work in lemacs-19.10.
|
|
175 ;
|
|
176 ; Revision 2.11 1993/09/20 08:29:15 bosch
|
|
177 ; Code reorganized: variables declared before used.
|
|
178 ; Compatibility hack patched again.
|
|
179 ;
|
|
180 ; Revision 2.10 1993/09/17 18:50:33 bosch
|
|
181 ; Bug in the compatibility hack fixed. Call to `make-cursor' replaced by
|
|
182 ; `x-pointer-cache'. Compatibility hack for Lemacs 19.8 removed. Tcl
|
|
183 ; motion handler improved (needs still some work).
|
|
184 ;
|
|
185 ; Revision 2.9 1993/09/15 17:52:53 bosch
|
|
186 ; Compatibility patch for Lucid Emacs 19.8. tcl motion handler added.
|
|
187 ;
|
|
188 ; Revision 2.8 1993/08/27 15:17:07 bosch
|
|
189 ; Select window conflict between motion handlers and process filters
|
|
190 ; resolved by using `enqueue-eval-event' for selecting a different
|
|
191 ; window (functions `mode-motion-track-pointer' and
|
|
192 ; `mode-motion-highlight-with-handler' modified). This fixes the nasty
|
|
193 ; bug that made GNUS hanging during NNTP activity while the mouse was
|
|
194 ; moved.
|
|
195 ;
|
|
196 ; Revision 2.7 1993/08/27 12:50:10 bosch
|
|
197 ; TeX and LaTeX motion handler generalized. Motion handler
|
|
198 ; `highlight-Texinfo' added.
|
|
199 ;
|
|
200 ; Revision 2.6 1993/06/24 11:58:52 bosch
|
|
201 ; Mode motion+ support for pcl-cvs added. #undef syntax for C added.
|
|
202 ;
|
|
203 ; Revision 2.5 1993/06/09 12:04:31 bosch
|
|
204 ; Delivery motion handlers for `c++-c-mode', `gnus-group-mode', and
|
|
205 ; `gnus-summary-mode' added. Mode motion commands bound to copy/cut/past
|
|
206 ; keys for Sun keyboards (f16, f18, f20). Comment added.
|
|
207 ;
|
|
208 ; Revision 2.4 1993/02/15 12:59:47 bosch
|
|
209 ; Modifications sent by Tibor Polgar integrated:
|
|
210 ; Optional parameter added to `mode-motion-copy/delete'. User option
|
|
211 ; `mode-motion-focus-on-window' added. It controls window selection for
|
|
212 ; the motion handlers. Minor changes of the delivery motion handlers.
|
|
213 ;
|
|
214 ; Revision 2.3 1993/02/04 18:10:09 bosch
|
|
215 ; User option `mode-motion-minibuffer-completion' added. It controls
|
|
216 ; the minibuffer completion highlighting.
|
|
217 ;
|
|
218 ; Revision 2.2 1993/01/27 13:08:12 bosch
|
|
219 ; Improved clearing of `sticky' mode-motion-extents when leaving screen
|
|
220 ; or buffer. Function `mode-motion-clear-extent' added.
|
|
221 ; Highlight line mouse cursor is behind.
|
|
222 ; `mode-motion-highlight-with-handler' now takes an event as argument.
|
|
223 ; Cut and paste functions renamed and rewritten. Now they are called:
|
|
224 ; `mode-motion-move', `mode-motion-delete', `mode-motion-copy',
|
|
225 ; `mode-motion-copy-as-kill'. Bug fixes in the C scanner stuff.
|
|
226 ; Motion handler `underline-c' added.
|
|
227 ;
|
|
228 ; Revision 2.1 1993/01/19 18:29:58 bosch
|
|
229 ; Scanner and motion handler for C syntax added.
|
|
230 ; Function `set-default-motion-handler' added.
|
|
231 ; Minor improvements on the `list-motion-handlers' interface done.
|
|
232 ; Minor bug fixes.
|
|
233 ;
|
|
234 ; Revision 2.0 1993/01/14 19:17:29 bosch
|
|
235 ; Lot of things rewritten and reorganized. This version fits in only
|
|
236 ; one file (beside the required package thing.el).
|
|
237 ;
|
|
238 ; New basic features are:
|
|
239 ; - buffer, mode and default motion handlers
|
|
240 ; - easy composition of own motion handlers
|
|
241 ; - listing of motion handlers in tabular form
|
|
242 ; - menu interface for changing motion handlers
|
|
243 ; - only two elisp files: mode-motion+.el, thing.el
|
|
244 ;
|
|
245
|
|
246 (require 'thing)
|
|
247 (require 'mode-motion)
|
|
248 (defconst mode-motion+-version "3.15")
|
|
249
|
|
250 ;;; This file defines a set of mouse motion handlers that do some
|
|
251 ;;; highlighting of the text when the mouse moves over.
|
|
252 ;;; An exhaustive list of the motion handlers defined in this file may be
|
|
253 ;;; obtained with M-x list-motion-handlers.
|
|
254 ;;; User Options and their Custommisation
|
|
255 ;;;
|
|
256 ;;; Mode-motion+ provides four user options, defined beyond. See their
|
|
257 ;;; documentation string to know what they are good for. If you want
|
|
258 ;;; to modify their default values, just setq them in your ~/.emacs.
|
|
259
|
|
260 (defvar mode-motion+-religion nil ; Initialised in mode-motion-init.
|
|
261 "*Default highlight religion: one of bold, gray, highlight, invert or underline.
|
|
262
|
|
263 Unless you setq this otherwise, it defaults to underline when
|
|
264 (x-display-color-p) is non-nil and invert otherwise.
|
|
265 Setting it to 'highlight should cause mode-motion+ extents to be
|
|
266 indistinguishable from any other type of highlighted extent which may or may
|
|
267 not be advisable, depending on your point of view.")
|
|
268
|
|
269 (defvar mode-motion-highlight-lines-when-behind t
|
|
270 "*If non-nil highlight the whole line if the mouse is past the end.")
|
|
271
|
|
272 (defvar mode-motion-focus-on-window nil
|
|
273 "*Controls whether moving the mouse into another window selects this window.
|
|
274 The following values are possible:
|
|
275
|
|
276 nil - Window selection isn't influenced at all by mode motion.
|
|
277
|
|
278 t - Window selection always follows the mouse cursor. Copying motion
|
|
279 active regions doesn't work any longer between different buffers.
|
|
280
|
|
281 any other - window selection follows the mouse cursor if the motion handler
|
|
282 of the buffer under the mouse has the follow-point property set.
|
|
283 Useful for selecting line mode buffers just by moving the mouse
|
|
284 inside in order to execute commands there (VM summary,
|
|
285 GNUS Group and Subject, DIRED, Buffer menu etc.)")
|
|
286
|
|
287 (defvar mode-motion-setup-cut-and-paste-bindings t
|
|
288 "*If non-nil, bind commands to the Copy, Paste and Cut keys.")
|
|
289
|
|
290 ;; Options sub-menu for mode-motion+
|
|
291 (defvar mode-motion+-options-menu
|
|
292 '("Motion Highlighting"
|
|
293 "For Current Buffer"
|
|
294 "---"
|
|
295 ["None"
|
|
296 (progn
|
|
297 (set-buffer-motion-handler (current-buffer) 'no-thing)
|
|
298 (mode-motion-clear-extent))
|
|
299 :style radio
|
|
300 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
301 'no)
|
|
302 :active (mode-motion+-active-p)]
|
|
303 ["Bold"
|
|
304 (progn
|
|
305 (modify-buffer-motion-handler (current-buffer) 'bold))
|
|
306 :style radio
|
|
307 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
308 'bold)
|
|
309 :active (mode-motion+-active-p)]
|
|
310 ["Underline"
|
|
311 (progn
|
|
312 (modify-buffer-motion-handler (current-buffer) 'underline))
|
|
313 :style radio
|
|
314 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
315 'underline)
|
|
316 :active (mode-motion+-active-p)]
|
|
317 ["Gray"
|
|
318 (progn
|
|
319 (modify-buffer-motion-handler (current-buffer) 'gray))
|
|
320 :style radio
|
|
321 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
322 'gray)
|
|
323 :active (mode-motion+-active-p)]
|
|
324 ["Highlight"
|
|
325 (progn
|
|
326 (modify-buffer-motion-handler (current-buffer) 'highlight))
|
|
327 :style radio
|
|
328 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
329 'highlight)
|
|
330 :active (mode-motion+-active-p)]
|
|
331 ["Invert"
|
|
332 (progn
|
|
333 (modify-buffer-motion-handler (current-buffer) 'invert))
|
|
334 :style radio
|
|
335 :selected (eq (mode-motion+-buffer-handler-religion (current-buffer))
|
|
336 'invert)
|
|
337 :active (mode-motion+-active-p)]
|
|
338 "---"
|
|
339 "For Current Mode"
|
|
340 "---"
|
|
341 ["None"
|
|
342 (progn
|
|
343 (set-mode-motion-handler major-mode 'no-thing)
|
|
344 (mode-motion-clear-extent))
|
|
345 :style radio
|
|
346 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'no)
|
|
347 :active (mode-motion+-active-p)]
|
|
348 ["Bold"
|
|
349 (progn
|
|
350 (modify-mode-motion-handler major-mode 'bold))
|
|
351 :style radio
|
|
352 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'bold)
|
|
353 :active (mode-motion+-active-p)]
|
|
354 ["Underline"
|
|
355 (progn
|
|
356 (modify-mode-motion-handler major-mode 'underline))
|
|
357 :style radio
|
|
358 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'underline)
|
|
359 :active (mode-motion+-active-p)]
|
|
360 ["Gray"
|
|
361 (progn
|
|
362 (modify-mode-motion-handler major-mode 'gray))
|
|
363 :style radio
|
|
364 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'gray)
|
|
365 :active (mode-motion+-active-p)]
|
|
366 ["Highlight"
|
|
367 (progn
|
|
368 (modify-mode-motion-handler major-mode 'highlight))
|
|
369 :style radio
|
|
370 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'highlight)
|
|
371 :active (mode-motion+-active-p)]
|
|
372 ["Invert"
|
|
373 (progn
|
|
374 (modify-mode-motion-handler major-mode 'invert))
|
|
375 :style radio
|
|
376 :selected (eq (mode-motion+-mode-handler-religion major-mode) 'invert)
|
|
377 :active (mode-motion+-active-p)]
|
|
378 "---"
|
|
379 "For All"
|
|
380 "---"
|
|
381 ["None"
|
|
382 (progn
|
|
383 (setq mode-motion+-religion 'no)
|
|
384 (mode-motion-init-handlers-according-to-religion 'force)
|
|
385 (mode-motion-clear-extent))
|
|
386 :style radio
|
|
387 :selected (eq mode-motion+-religion 'no)
|
|
388 :active (mode-motion+-active-p)]
|
|
389 ["Bold"
|
|
390 (progn
|
|
391 (setq mode-motion+-religion 'bold)
|
|
392 (mode-motion-init-handlers-according-to-religion 'force))
|
|
393 :style radio
|
|
394 :selected (eq mode-motion+-religion 'bold)
|
|
395 :active (mode-motion+-active-p)]
|
|
396 ["Underline"
|
|
397 (progn
|
|
398 (setq mode-motion+-religion 'underline)
|
|
399 (mode-motion-init-handlers-according-to-religion 'force))
|
|
400 :style radio
|
|
401 :selected (eq mode-motion+-religion 'underline)
|
|
402 :active (mode-motion+-active-p)]
|
|
403 ["Gray"
|
|
404 (progn
|
|
405 (setq mode-motion+-religion 'gray)
|
|
406 (mode-motion-init-handlers-according-to-religion 'force))
|
|
407 :style radio
|
|
408 :selected (eq mode-motion+-religion 'gray)
|
|
409 :active (mode-motion+-active-p)]
|
|
410 ["Highlight"
|
|
411 (progn
|
|
412 (setq mode-motion+-religion 'highlight)
|
|
413 (mode-motion-init-handlers-according-to-religion 'force))
|
|
414 :style radio
|
|
415 :selected (eq mode-motion+-religion 'highlight)
|
|
416 :active (mode-motion+-active-p)]
|
|
417 ["Invert"
|
|
418 (progn
|
|
419 (setq mode-motion+-religion 'invert)
|
|
420 (mode-motion-init-handlers-according-to-religion 'force))
|
|
421 :style radio
|
|
422 :selected (eq mode-motion+-religion 'invert)
|
|
423 :active (mode-motion+-active-p)]
|
|
424 "---"
|
|
425 ["Minibuffer highlighting" (setq mode-motion-use-minibuffer-motion-handler
|
|
426 (not mode-motion-use-minibuffer-motion-handler))
|
|
427 :style toggle :selected mode-motion-use-minibuffer-motion-handler]
|
|
428
|
|
429 ["Customize..."
|
|
430 (list-motion-handlers)
|
|
431 t
|
|
432 ;; nil
|
|
433 ]
|
|
434 ["Revert Customization"
|
|
435 (call-interactively 'mode-motion+-motion-hook-revert)
|
|
436 (and (boundp 'mode-motion+-previous-hook) mode-motion+-previous-hook)
|
|
437 ])
|
|
438 "Menu for changing mode-motion+ religion and other things.")
|
|
439
|
|
440 (defun mode-motion+-active-p ()
|
|
441 (cond ((symbolp mode-motion-hook)
|
|
442 (eq mode-motion-hook 'mode-motion+-highlight))
|
|
443 ((listp mode-motion-hook)
|
|
444 (memq 'mode-motion+-highlight mode-motion-hook))
|
|
445 (t nil)))
|
|
446
|
|
447 (defun mode-motion+-buffer-handler-religion (buffer)
|
|
448 (let* ((current-handler-name (symbol-name (motion-handler-name
|
|
449 (get-current-motion-handler))))
|
|
450 (religion-name (substring current-handler-name
|
|
451 0
|
|
452 (string-match "-" current-handler-name))))
|
|
453 (intern-soft religion-name)))
|
|
454
|
|
455 (defun mode-motion+-mode-handler-religion (buffer)
|
|
456 (let* ((mode-handler (or (get major-mode 'mode-motion-handler)
|
|
457 default-motion-handler))
|
|
458 (current-handler (symbol-name (motion-handler-name mode-handler)))
|
|
459 (religion (substring current-handler
|
|
460 0
|
|
461 (string-match "-" current-handler))))
|
|
462 (intern-soft religion)))
|
|
463
|
|
464 (defun modify-buffer-motion-handler (buffer religion)
|
|
465 (let* ((current-handler (symbol-name (motion-handler-name
|
|
466 (get-current-motion-handler))))
|
|
467 (suffix (substring current-handler
|
|
468 (string-match "-" current-handler))))
|
|
469 (set-buffer-motion-handler buffer
|
|
470 (intern-soft (concat (symbol-name religion)
|
|
471 suffix)))))
|
|
472
|
|
473 (defun modify-mode-motion-handler (mode religion)
|
|
474 (let* ((mode-handler (or (get major-mode 'mode-motion-handler)
|
|
475 default-motion-handler))
|
|
476 (current-handler (symbol-name (motion-handler-name mode-handler)))
|
|
477 (suffix (substring current-handler
|
|
478 (string-match "-" current-handler))))
|
|
479 (set-mode-motion-handler mode (intern-soft (concat (symbol-name
|
|
480 religion)
|
|
481 suffix)))))
|
|
482
|
|
483 ;;;; This does not work. I would like to be able to modify in-place
|
|
484 ;;;; the non-selectable items, but I don't know how.
|
|
485 ;;;; --paquette, Wed Mar 8 23:32:32 1995 (Marc Paquette)
|
|
486 ;;; Sensitize the mode motion+ options submenu, a la
|
|
487 ;;; sensitize-file-and-edit-menus-hook.
|
|
488 (defun mode-motion+-sensitize-options-menu-hook ()
|
|
489 "Hook function that will adjust title items in the mode-motion+ submenu in Options"
|
|
490 (let* ((mm+-menu (cdr (car (find-menu-item
|
|
491 current-menubar
|
|
492 '("Options" "Motion Highlighting")))))
|
|
493 (buffer-item (find-menu-item mm+-menu '("For Current Buffer")))
|
|
494 (mode-item (find-menu-item mm+-menu '("For Current Mode"))))
|
|
495 (setcar buffer-item (format "For Buffer `%s'" (buffer-name nil)))
|
|
496 (setcar mode-item (format "For Mode `%s'" major-mode))
|
|
497 nil))
|
|
498
|
|
499 ;;(add-hook 'activate-menubar-hook 'mode-motion+-sensitize-options-menu-hook)
|
|
500
|
|
501
|
|
502 ;; Motion Handler Format:
|
|
503 ;;
|
|
504 ;; A motion handler is vector with the following format
|
|
505 ;; [<name> - a symbol
|
|
506 ;; <region computing function> - a function or name of function
|
|
507 ;; that returns (<startpos> . <endpos>)
|
|
508 ;; or nil.
|
|
509 ;; <face or face name> - as it says ...
|
|
510 ;; <highlight-p> - non-nil means that the motion extent
|
|
511 ;; will be highlighted using the function
|
|
512 ;; `highlight-extent'
|
|
513 ;; <follow-point-p> - non-nil means that point will follow the
|
|
514 ;; mouse motion.
|
|
515 ;; ]
|
|
516
|
|
517 ;; accessor functions
|
|
518 (defsubst motion-handler-name (handler) (aref handler 0))
|
|
519 (defsubst motion-handler-boundary-function (handler) (aref handler 1))
|
|
520 (defsubst motion-handler-face (handler) (aref handler 2))
|
|
521 (defsubst motion-handler-highlight (handler) (aref handler 3))
|
|
522 (defsubst motion-handler-follow-point (handler) (aref handler 4))
|
|
523
|
|
524 ;; modifier functions
|
|
525 (defsubst set-motion-handler-boundary-function (handler x) (aset handler 1 x))
|
|
526 (defsubst set-motion-handler-face (handler x) (aset handler 2 x))
|
|
527 (defsubst set-motion-handler-highlight (handler x) (aset handler 3 x))
|
|
528 (defsubst set-motion-handler-follow-point (handler x) (aset handler 4 x))
|
|
529
|
|
530 ;; Internal global variables
|
|
531 (defvar motion-handler-alist ()
|
|
532 "Alist with entries of the form \(<name> . <handler>\).")
|
|
533
|
|
534 ;; Minibuffer motion handler
|
|
535 (defvar mode-motion-use-minibuffer-motion-handler t
|
|
536 "*Enable mousable highlighting when the minibuffer is active. When false only extents with the
|
|
537 highlight property are selectable (*Completion*)")
|
|
538
|
|
539 (defvar mode-motion-extent nil)
|
|
540 (make-variable-buffer-local 'mode-motion-extent)
|
|
541 (defvar buffer-motion-handler nil)
|
|
542 (make-variable-buffer-local 'buffer-motion-handler)
|
|
543 (defvar mode-motion-last-extent nil "The last used mode motion extent.")
|
|
544 (defvar default-motion-handler nil) ; Initialised in mode-motion-init.
|
|
545
|
|
546 ;; Creation of motion handlers
|
|
547
|
|
548 (defun find-motion-handler (name)
|
|
549 (or (symbolp name)
|
|
550 (setq name (intern-soft name)))
|
|
551 (cdr (assq name motion-handler-alist)))
|
|
552
|
|
553 ;; internal motion handler creator
|
|
554 (defsubst make-motion-handler-internal
|
|
555 (name boundary-function face highlight follow-cursor)
|
|
556 (vector name boundary-function (get-face face) highlight follow-cursor))
|
|
557
|
|
558 (defun make-motion-handler
|
|
559 (name boundary-function &optional face highlight follow-cursor)
|
|
560 "Create a motion handler named NAME (a symbol or string) using REGION-FUNCTION.
|
|
561
|
|
562 REGION-FUNCTION is the function that computes the region to be highlighted.
|
|
563 Optional arguments are:
|
|
564
|
|
565 FACE: A face or face name to be used to highlight the region computed
|
|
566 by REGION-FUNCTION. 'default is the default.
|
|
567
|
|
568 HIGHLIGHT: Flag that indicates whether the highlight attribute of the
|
|
569 mode-motion-extent should be set or not. If FACE is the default face,
|
|
570 HIGHLIGHT defaults to t, otherwise to nil.
|
|
571
|
|
572 FOLLOW-CURSOR: Flag that indicates whether the cursor should follow
|
|
573 the mouse motion. Default is nil."
|
|
574
|
|
575 ;; required arguments
|
|
576 (or name (error "motion handler name required."))
|
|
577 (or (symbolp name)
|
|
578 (stringp name)
|
|
579 (error "motion handler name must be a string or symbol: %s" name))
|
|
580 (or boundary-function
|
|
581 (error "motion handler region function required."))
|
|
582 (or (fboundp boundary-function)
|
|
583 (error "not a function: %s." boundary-function))
|
|
584 ;; defaults
|
|
585 (or face (setq face 'default))
|
|
586
|
|
587 ;; store the mode motion handler on the 'mode-motion-handler property of
|
|
588 ;; its name symbol
|
|
589 (let ((old-handler (cdr (assq name motion-handler-alist)))
|
|
590 new-handler)
|
|
591 (if old-handler
|
|
592 (progn
|
|
593 (set-motion-handler-boundary-function old-handler boundary-function)
|
|
594 (set-motion-handler-face old-handler (get-face face))
|
|
595 (set-motion-handler-highlight old-handler highlight)
|
|
596 (set-motion-handler-follow-point old-handler follow-cursor))
|
|
597 (setq motion-handler-alist
|
|
598 (cons (cons name
|
|
599 (setq new-handler (make-motion-handler-internal
|
|
600 name
|
|
601 boundary-function
|
|
602 (get-face face)
|
|
603 highlight
|
|
604 follow-cursor)))
|
|
605 motion-handler-alist)))
|
|
606 (or old-handler new-handler)))
|
|
607
|
|
608 (defvar list-motion-handlers-buffer-to-customize nil
|
|
609 "Name of buffer from where list-motion-handlers was called.")
|
|
610 (make-variable-buffer-local 'list-motion-handlers-buffer-to-customize)
|
|
611 (defvar list-motion-handlers-buffer-mode nil
|
|
612 "Name of mode of buffer from where list-motion-handlers was called.")
|
|
613 (make-variable-buffer-local 'list-motion-handlers-buffer-mode)
|
|
614 ;; Listing available motion handlers in tabular form.
|
|
615
|
|
616 (defvar basic-motion-handlers (list 'mode-motion-highlight-line
|
|
617 'mode-motion-highlight-word
|
|
618 'mode-motion-highlight-symbol
|
|
619 'mode-motion-highlight-sexp)
|
|
620 "The basic motion handlers provided by the underlying XEmacs.")
|
|
621
|
|
622 (defun list-motion-handlers ()
|
|
623 "Display a list of available motion handlers.
|
|
624 The listing is in tabular form and contains the following columns:
|
|
625 NAME: the motion handlers name,
|
|
626 BOUNDARY FUNCTION: the name of the funtion used to compute the text
|
|
627 highlighted by the motion handler,
|
|
628 FACE: the face used to highlight the text.
|
|
629
|
|
630 Additionally, the following flags are used at the beginning of each line:
|
|
631 `*' Marks the motion handler current to the buffer this functions was called
|
|
632 from.
|
|
633 `H' Force highlighting of the selected text.
|
|
634 `F' Make point follow the mouse cursor as it moves."
|
|
635 (interactive)
|
|
636 (let ((current-handler (get-current-motion-handler))
|
|
637 (buffer (current-buffer))
|
|
638 (buffer-mode major-mode)
|
|
639 (bmmh (if (symbolp mode-motion-hook)
|
|
640 (car (memq mode-motion-hook basic-motion-handlers))
|
|
641 (if (and (listp mode-motion-hook)
|
|
642 (equal 1 (length mode-motion-hook)))
|
|
643 (car (memq (car mode-motion-hook)
|
|
644 basic-motion-handlers))))))
|
|
645 (save-excursion
|
|
646 (with-output-to-temp-buffer "*Mouse Motion Handlers*"
|
|
647 (let ((truncate-lines t))
|
|
648 (set-buffer "*Mouse Motion Handlers*")
|
|
649 (setq list-motion-handlers-buffer-to-customize buffer)
|
|
650 (setq list-motion-handlers-buffer-mode buffer-mode)
|
|
651 (let ((pos1 5)
|
|
652 (pos2 25)
|
|
653 (pos3 50)
|
|
654 (handlers
|
|
655 (sort
|
|
656 (mapcar 'cdr motion-handler-alist)
|
|
657 '(lambda (x y)
|
|
658 (string<
|
|
659 (symbol-name (motion-handler-boundary-function x))
|
|
660 (symbol-name (motion-handler-boundary-function y)))))))
|
|
661 (if bmmh
|
|
662 (let ((i 1)
|
|
663 (fw (frame-width)))
|
|
664 (while (< i fw)
|
|
665 (princ "*")
|
|
666 (setq i (1+ i)))
|
|
667 (princ "\nNote: this buffer is not using mode-motion+.\n\n")
|
|
668 (princ "It's using the `")
|
|
669 (princ bmmh)
|
|
670 (princ "' motion handler which claims it's:\n")
|
|
671 (insert (documentation bmmh))
|
|
672 (princ "\nSetting this motion handler will be irrevocable from this interface\n(but only for duration of this XEmacs session).\n")
|
|
673 (setq i 1)
|
|
674 (while (< i fw)
|
|
675 (princ "*")
|
|
676 (setq i (1+ i)))
|
|
677 (terpri)))
|
|
678 (princ " NAME BOUNDARY FUNCTION FACE\n")
|
|
679 (princ " ---- ----------------- ----\n")
|
|
680 (mapcar
|
|
681 #'(lambda (handler)
|
|
682 (let ((line-start (point)))
|
|
683 (princ (if (and (not bmmh) (eq handler current-handler))
|
|
684 "*" " "))
|
|
685 (princ (if (eq handler default-motion-handler) "D" " "))
|
|
686 (princ (if (motion-handler-highlight handler) "H" " "))
|
|
687 (princ (if (motion-handler-follow-point handler) "F" " "))
|
|
688 (indent-to-column pos1 1)
|
|
689 (princ (motion-handler-name handler))
|
|
690 (indent-to-column pos2 1)
|
|
691 (princ (motion-handler-boundary-function handler))
|
|
692 (indent-to-column pos3)
|
|
693 (let ((face-start (point)))
|
|
694 (princ (face-name (motion-handler-face handler)))
|
|
695 (let ((line-extent (make-extent line-start face-start))
|
|
696 (face-extent (make-extent face-start (point))))
|
|
697 (set-extent-face face-extent
|
|
698 (motion-handler-face handler))
|
|
699 (set-extent-property
|
|
700 face-extent
|
|
701 'mode-motion-handler (motion-handler-name handler))
|
|
702 (set-extent-property
|
|
703 line-extent
|
|
704 'mode-motion-handler (motion-handler-name handler))
|
|
705 (set-extent-property line-extent 'highlight t)))
|
|
706 (terpri)))
|
|
707 handlers)
|
|
708 (princ (format "
|
|
709 Flags: `D' the default motion handler
|
|
710 `H' handler with highlighting
|
|
711 `F' handler with `following' property
|
|
712 `*' the motion handler of buffer \"%s\""
|
|
713 list-motion-handlers-buffer-to-customize))))
|
|
714 (local-set-key 'button3 'mode-motion-set-handler)
|
|
715 (setq buffer-read-only t)))))
|
|
716
|
|
717 (defun mode-motion-set-handler (event)
|
|
718 (interactive "@e")
|
|
719 (let* ((handler (or (extent-property
|
|
720 (extent-at (event-point event) (current-buffer)
|
|
721 'mode-motion-handler)
|
|
722 'mode-motion-handler)
|
|
723 (error "Click on highlighted line to select a handler")))
|
|
724 (menu (list
|
|
725 (format "Make `%s' the Motion Handler of :" handler)
|
|
726 (vector (format "Buffer %s"
|
|
727 list-motion-handlers-buffer-to-customize)
|
|
728 (` (set-buffer-motion-handler
|
|
729 '(, list-motion-handlers-buffer-to-customize)
|
|
730 '(, handler))) t)
|
|
731 (vector "Another Buffer..."
|
|
732 (` (motion-handler-list-set-buffer-handler
|
|
733 '(, handler))) t)
|
|
734 "---"
|
|
735 (vector (format "Mode %s"
|
|
736 list-motion-handlers-buffer-mode)
|
|
737 (` (progn
|
|
738 (set-mode-motion-handler
|
|
739 '(, list-motion-handlers-buffer-mode)
|
|
740 '(, handler))
|
|
741 (save-excursion
|
|
742 (mapcar
|
|
743 (function
|
|
744 (lambda (buf)
|
|
745 (set-buffer buf)
|
|
746 (and (eq
|
|
747 '(, list-motion-handlers-buffer-mode)
|
|
748 major-mode)
|
|
749 (mode-motion+-hook-install buf t))))
|
|
750 (buffer-list))))) t)
|
|
751 (vector "Another Mode..."
|
|
752 (` (motion-handler-list-set-mode-handler
|
|
753 '(, handler))) t)
|
|
754 "---"
|
|
755 (vector "Default Motion Handler"
|
|
756 (` (set-default-motion-handler '(, handler))) t))))
|
|
757 (popup-menu menu)))
|
|
758
|
|
759 (defun motion-handler-list-set-buffer-handler (handler)
|
|
760 (let ((buffer (read-buffer-name
|
|
761 (format "Make `%s' the motion handler of buffer: " handler)
|
|
762 (buffer-name list-motion-handlers-buffer-to-customize))))
|
|
763 (set-buffer-motion-handler buffer handler)
|
|
764 (save-excursion
|
|
765 (set-buffer buffer)
|
|
766 (and (not (cond ((listp mode-motion-hook)
|
|
767 (memq 'mode-motion+-highlight mode-motion-hook))
|
|
768 ((symbolp mode-motion-hook)
|
|
769 (eq 'mode-motion+-highlight mode-motion-hook))
|
|
770 (t t)))
|
|
771 (y-or-n-p (format "Augment the default mode motion hook for `%s'? "
|
|
772 (buffer-name nil)))
|
|
773 (mode-motion+-hook-install buffer t)))))
|
|
774
|
|
775 (defvar mode-motion+-previous-hook nil
|
|
776 "Value of previous `mode-motion-hook' in current buffer.")
|
|
777 (make-variable-buffer-local 'mode-motion+-previous-hook)
|
|
778
|
|
779 (defun motion-handler-list-set-mode-handler (handler)
|
|
780 (let ((mode (intern (completing-read
|
|
781 (format "Make `%s' the motion handler of mode: " handler)
|
|
782 obarray
|
|
783 'fboundp
|
|
784 t
|
|
785 (symbol-name list-motion-handlers-buffer-mode)))))
|
|
786 (set-mode-motion-handler mode handler)
|
|
787 (save-excursion
|
|
788 (mapcar (function
|
|
789 (lambda (buf)
|
|
790 (set-buffer buf)
|
|
791 (and (eq mode major-mode)
|
|
792 (mode-motion+-hook-install buf t))))
|
|
793 (buffer-list)))))
|
|
794
|
|
795 (defun mode-motion+-hook-install (&optional buffer remove-highlight-line-p)
|
|
796 "Add `mode-motion+-highlight' to the BUFFER `mode-motion-hook'.
|
|
797 If the optional second arg REMOVE-HIGHLIGHT-LINE-P is t, remove
|
|
798 `mode-motion-highlight-line' from `mode-motion-hook'.
|
|
799 See `mode-motion+-hook-uninstall' for reverting this operation."
|
|
800 (interactive "bInstall mode-motion+ hook for buffer :
|
|
801 XRemove highlight-line from hook ? :")
|
|
802 ;; Check for the mode-motion-hook value to make sure it's under
|
|
803 ;; the control of mode-motion+.
|
|
804 ;; The reasonning here is that if the user went trough the hassles
|
|
805 ;; of list-motion-handlers (or if he's calling this directly from
|
|
806 ;; his .emacs) , he is prepared to give up on the current
|
|
807 ;; mode-motion-hook.
|
|
808 ;; However, we keep the previous hook value in a buffer-local
|
|
809 ;; variable: it will be then possible to revert to the old motion
|
|
810 ;; handling behavior with `mode-motion+-hook-uninstall'.
|
|
811 ;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
|
|
812 (setq buffer (or buffer (current-buffer)))
|
|
813 ;; force the uninstall of mode-motion-highlight since if its second
|
|
814 ;; you'll never see ours.
|
|
815 (setq remove-highlight-line-p t)
|
|
816 (save-excursion
|
|
817 (set-buffer buffer)
|
|
818 (if (boundp 'mode-motion-hook)
|
|
819 (progn
|
|
820 (setq mode-motion+-previous-hook
|
|
821 (cond ((sequencep mode-motion-hook)
|
|
822 (copy-sequence mode-motion-hook))
|
|
823 (t mode-motion-hook)))
|
|
824 ;; Make sure that the mode-motion+-highlight is not saved in
|
|
825 ;; the variable, otherwise, we could not revert back to the
|
|
826 ;; "factory settings" after having played with different
|
|
827 ;; handlers
|
|
828 ;; --paquette, Mon Feb 27 08:54:21 1995 (Marc Paquette)
|
|
829 (remove-hook 'mode-motion+-previous-hook 'mode-motion+-highlight)))
|
|
830 (add-hook 'mode-motion-hook 'mode-motion+-highlight)
|
|
831 (and remove-highlight-line-p
|
|
832 ;; Remove the standard mode-motion-highlight hook because we
|
|
833 ;; provide an alternative to this. I don't use setq here because
|
|
834 ;; something else could be hooked to mode-motion-hook.
|
|
835 ;; --paquette, Mon Feb 27 08:53:51 1995 (Marc Paquette)
|
|
836 (remove-hook 'mode-motion-hook 'mode-motion-highlight-line))
|
|
837 (and mode-motion-extent
|
|
838 (delete-extent mode-motion-extent)
|
|
839 (setq mode-motion-extent nil))
|
|
840 ;; Try to make this installed for any buffer of this mode
|
|
841 (let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
|
|
842 "-hook"))))
|
|
843 (and (boundp this-mode-hook)
|
|
844 (if remove-highlight-line-p
|
|
845 (add-hook this-mode-hook
|
|
846 #'(lambda () (mode-motion+-hook-install nil t))
|
|
847 'append)
|
|
848 (add-hook this-mode-hook 'mode-motion+-hook-install 'append)))))
|
|
849 mode-motion-hook)
|
|
850
|
|
851 (defun mode-motion+-hook-uninstall (buffer)
|
|
852 "Restore the value of `mode-motion-hook' in BUFFER to what it was at the time `mode-motion+-hook-install' was called.
|
|
853 See also `mode-motion+-hook-install'."
|
|
854 (interactive "bRestore `mode-motion-hook' of buffer :")
|
|
855 ;; Check for the mode-motion-hook value to make sure it's under
|
|
856 ;; the control of mode-motion+.
|
|
857 ;; The reasonning here is that if the user went trough the hassles
|
|
858 ;; of list-motion-handlers (or if he's calling this directly from
|
|
859 ;; his .emacs) , he is prepared to give up on the current
|
|
860 ;; mode-motion-hook.
|
|
861 ;; However, we keep the previous hook value in a buffer-local
|
|
862 ;; variable: it will be then possible to revert to the old motion
|
|
863 ;; handling behavior with `mode-motion+-hook-uninstall'.
|
|
864 ;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)
|
|
865 (save-excursion
|
|
866 (set-buffer buffer)
|
|
867 (and mode-motion-extent
|
|
868 (delete-extent mode-motion-extent)
|
|
869 (setq mode-motion-extent nil))
|
|
870 (if (boundp 'mode-motion+-previous-hook)
|
|
871 (progn
|
|
872 (setq mode-motion-hook mode-motion+-previous-hook)
|
|
873 (setq mode-motion+-previous-hook nil)
|
|
874 (let ((this-mode-hook (intern-soft (concat (symbol-name major-mode)
|
|
875 "-hook"))))
|
|
876 (and (boundp this-mode-hook)
|
|
877 (remove-hook this-mode-hook 'mode-motion+-hook-install))))
|
|
878 (error "No previous value for mode-motion-hook")))
|
|
879 mode-motion-hook)
|
|
880
|
|
881 (defun mode-motion+-motion-hook-revert (&optional buffer-only-p buffer mode)
|
|
882 "Revert the `mode-motion-hook' to its original value.
|
|
883 With optional arg BUFFER-ONLY-P non-nil, only revert in BUFFER
|
|
884 \(defaults to `\(current-buffer\)'\); otherwise, revert for all existing
|
|
885 buffers of MODE \(defaults to `major-mode' of BUFFER\)."
|
|
886 (interactive
|
|
887 (let* ((buffer-only-p
|
|
888 (y-or-n-p "Revert mode-motion-hook only for current buffer ? "))
|
|
889 (buffer (if buffer-only-p
|
|
890 (current-buffer)
|
|
891 (get-buffer (read-buffer-name
|
|
892 "Revert mode-motion-hook of buffer : "
|
|
893 (buffer-name (current-buffer))))))
|
|
894 (mode (if buffer-only-p
|
|
895 (save-excursion
|
|
896 (set-buffer buffer)
|
|
897 major-mode)
|
|
898 (intern-soft (completing-read "Major mode: "
|
|
899 obarray
|
|
900 'fboundp
|
|
901 nil
|
|
902 (symbol-name major-mode))))))
|
|
903 (list buffer-only-p buffer mode)))
|
|
904 (if buffer-only-p
|
|
905 (mode-motion+-hook-uninstall buffer)
|
|
906 (save-excursion
|
|
907 (mapcar (function
|
|
908 (lambda (buf)
|
|
909 (set-buffer buf)
|
|
910 (and (eq mode major-mode)
|
|
911 (mode-motion+-hook-uninstall buf))))
|
|
912 (buffer-list)))))
|
|
913
|
|
914
|
|
915 ;; Setting buffer, mode and default motion handlers
|
|
916
|
|
917 (defun set-buffer-motion-handler (buffer handler-name)
|
|
918 "Make the motion handler named HANDLER-NAME (a symbol) the buffer
|
|
919 motion handler of BUFFER. If HANDLER-NAME is nil, the corresponding
|
|
920 buffer motion handler is removed. If HANDLER-NAME isn't the name of a
|
|
921 known motion handler, an error is signaled. When called interactively,
|
|
922 completion is provided for available buffers and motion handlers.
|
|
923
|
|
924 1.\) buffer motion handler
|
|
925 2.\) mode motion handler
|
|
926 3.\) default motion handler"
|
|
927 (interactive (list (read-buffer-name "Set motion handler of buffer: "
|
|
928 (buffer-name (current-buffer)))
|
|
929 (read-motion-handler-name)))
|
|
930
|
|
931 ;; kill old mode motion extent, because the new handler
|
|
932 ;; might want to initialize it differently
|
|
933 (if mode-motion-extent
|
|
934 (progn
|
|
935 (detach-extent mode-motion-extent)
|
|
936 (setq mode-motion-extent nil)))
|
|
937 (or buffer (setq buffer (current-buffer)))
|
|
938 (or (get-buffer buffer)
|
|
939 (error "No such buffer: %s" buffer))
|
|
940 (save-excursion
|
|
941 (set-buffer buffer)
|
|
942 (setq buffer-motion-handler
|
|
943 ;; remove it if `nil'
|
|
944 (and handler-name
|
|
945 ;; set the handler if known
|
|
946 (or (find-motion-handler handler-name)
|
|
947 ;; error otherwise
|
|
948 (error "Not a known motion handler: %s"
|
|
949 handler-name)))))
|
|
950 (if (interactive-p)
|
|
951 (if handler-name
|
|
952 (message "Motion handler for buffer %s is `%s'."
|
|
953 (current-buffer) handler-name)
|
|
954 (message "Motion handler removed for buffer %s."
|
|
955 (current-buffer))))
|
|
956 handler-name)
|
|
957
|
|
958 (defun read-buffer-name (prompt &optional initial-input)
|
|
959 (completing-read prompt
|
|
960 (mapcar #'(lambda (buf) (list (buffer-name buf)))
|
|
961 (buffer-list))
|
|
962 ;; don't take buffers that start with a blank
|
|
963 #'(lambda (list) (not (eq (aref (car list) 0) ? )))
|
|
964 t
|
|
965 initial-input))
|
|
966
|
|
967 (defun set-mode-motion-handler (mode handler-name)
|
|
968 "Make the motion handler named HANDLER-NAME (a symbol) the mode motion
|
|
969 handler for all buffers with major-mode MODE. If HANDLER-NAME is nil,
|
|
970 the corresponding mode motion handler is removed. If HANDLER-NAME
|
|
971 isn't the name of a known motion handler, an error is signaled. When
|
|
972 called interactively, completion is provided for available motion
|
|
973 handlers.
|
|
974
|
|
975 1.\) buffer motion handler
|
|
976 2.\) mode motion handler
|
|
977 3.\) default motion handler"
|
|
978 (interactive (list (intern (completing-read "Major mode: "
|
|
979 obarray
|
|
980 'fboundp
|
|
981 nil
|
|
982 (symbol-name major-mode)))
|
|
983 (read-motion-handler-name)))
|
|
984 ;; kill old mode motion extent, because the new handler
|
|
985 ;; might want to initialize it differently
|
|
986 (if mode-motion-extent
|
|
987 (progn
|
|
988 (detach-extent mode-motion-extent)
|
|
989 (setq mode-motion-extent nil)))
|
|
990 (put mode 'mode-motion-handler
|
|
991 ;; remove it if `nil'
|
|
992 (and handler-name
|
|
993 ;; set the handler if known
|
|
994 (or (find-motion-handler handler-name)
|
|
995 ;; error otherwise
|
|
996 (error "Not a known mode motion handler: %s" handler-name))))
|
|
997 (if (interactive-p)
|
|
998 (if handler-name
|
|
999 (message "Motion handler for %s is `%s'." mode handler-name)
|
|
1000 (message "Mode motion handler for %s removed." mode)))
|
|
1001 handler-name)
|
|
1002
|
|
1003 (defun set-default-motion-handler (handler-name)
|
|
1004 "Make the motion handler named HANDLER-NAME (a symbol) the default.
|
|
1005
|
|
1006 If HANDLER-NAME is nil, the current default motion handler is removed. If
|
|
1007 HANDLER-NAME isn't the name of a known motion handler, an error is
|
|
1008 signalled. When called interactively, completion is provided for available
|
|
1009 motion handlers.
|
|
1010
|
|
1011 The motion handler used in a given buffer is determined by the following
|
|
1012 most-specific first list: buffer motion handler, mode motion handler, default
|
|
1013 motion handler."
|
|
1014 (interactive (list (read-motion-handler-name)))
|
|
1015 ;; kill old mode motion extent, because the new handler
|
|
1016 ;; might want to initialize it differently
|
|
1017 (if mode-motion-extent
|
|
1018 (progn
|
|
1019 (detach-extent mode-motion-extent)
|
|
1020 (setq mode-motion-extent nil)))
|
|
1021 (setq default-motion-handler
|
|
1022 ;; remove it if `nil'
|
|
1023 (and handler-name
|
|
1024 ;; set the handler if known
|
|
1025 (or (find-motion-handler handler-name)
|
|
1026 ;; error otherwise
|
|
1027 (error "Not a known motion handler: %s" handler-name))))
|
|
1028 (if (interactive-p)
|
|
1029 (if handler-name
|
|
1030 (message "Default motion handler is `%s'." handler-name)
|
|
1031 (message "Default motion handler removed.")))
|
|
1032 handler-name)
|
|
1033
|
|
1034 (defun read-motion-handler-name ()
|
|
1035 (intern-soft (completing-read "Motion handler: "
|
|
1036 (mapcar #'(lambda (entry)
|
|
1037 (list (symbol-name (car entry))))
|
|
1038 motion-handler-alist)
|
|
1039 nil t)))
|
|
1040
|
|
1041 ;; clear the last active motion extent when leaving a frame.
|
|
1042 (defun mode-motion-clear-extent (&optional extent)
|
|
1043 "Clear EXTENT, i.e. make it have no visible effects on the frame.
|
|
1044 EXTENT defaults to the current buffer's mode-motion-extent."
|
|
1045 (or extent (setq extent mode-motion-extent))
|
|
1046 (and extent
|
|
1047 (extent-live-p extent)
|
|
1048 (not (extent-detached-p extent))
|
|
1049 (extent-buffer extent)
|
|
1050 (buffer-name (extent-buffer extent))
|
|
1051 (progn
|
|
1052 ;; unhighlight it
|
|
1053 (highlight-extent extent nil)
|
|
1054 ;; make it span a region that isn't visible and selectable
|
|
1055 ;; Can this be done more elegantly?
|
|
1056 (detach-extent extent))))
|
|
1057
|
|
1058 (defun mode-motion-clear-last-extent (&optional frame)
|
|
1059 "Clear the mode-motion-last-extent."
|
|
1060 (or (popup-menu-up-p) (mode-motion-clear-extent mode-motion-last-extent)))
|
|
1061
|
|
1062 (defun mode-motion+-highlight (event)
|
|
1063 "Highlight the thing under the mouse using a mode-specfic motion handler.
|
|
1064 See list-motion-handlers for more details."
|
|
1065 (mode-motion-clear-last-extent)
|
|
1066 (and (event-buffer event)
|
|
1067 (cond ((and mouse-grabbed-buffer
|
|
1068 ;; first try to do minibuffer specific highlighting
|
|
1069 (find-motion-handler 'minibuffer)
|
|
1070 (let ((mode-motion-highlight-lines-when-behind nil))
|
|
1071 (and (event-point event)
|
|
1072 (or (extent-at (event-point event)
|
|
1073 (event-buffer event) 'highlight)
|
|
1074 (mode-motion-highlight-with-handler
|
|
1075 (find-motion-handler 'minibuffer) event))))))
|
|
1076 (t (mode-motion-highlight-with-handler
|
|
1077 (get-current-motion-handler) event))))
|
|
1078 ;; Return nil since now this is used as a hook, and we want to let
|
|
1079 ;; any other hook run after us.
|
|
1080 nil)
|
|
1081
|
|
1082 (defun get-current-motion-handler ()
|
|
1083 (or (and (boundp 'buffer-motion-handler) buffer-motion-handler)
|
|
1084 (get major-mode 'mode-motion-handler)
|
|
1085 default-motion-handler))
|
|
1086
|
|
1087 (defun mode-motion-highlight-with-handler (handler event)
|
|
1088 ;; Perform motion highlighting using HANDLER. Information about the
|
|
1089 ;; current mouse position is taken form EVENT.
|
|
1090 (and handler
|
|
1091 (let ((point (event-point event))
|
|
1092 (buffer (event-buffer event))
|
|
1093 (window (event-window event))
|
|
1094 (window-config (current-window-configuration))
|
|
1095 (buffer-save (current-buffer))
|
|
1096 (point-save (point))
|
|
1097 region)
|
|
1098 ;; save-window-excursion and restore buffer
|
|
1099 (unwind-protect
|
|
1100 (progn
|
|
1101 (and buffer
|
|
1102 (set-buffer buffer)
|
|
1103 (select-window window))
|
|
1104
|
|
1105 ;; kludge: if point = end-of-window, then probably the mouse
|
|
1106 ;; is actually between the last line and the modeline. In
|
|
1107 ;; this case move point to back one
|
|
1108 (and point
|
|
1109 (not (< point (window-end window)))
|
|
1110 (setq point (1- point)))
|
|
1111 ;; Create a new mode-motion-extent if there isn't one
|
|
1112 ;; (or a destroyed one)
|
|
1113 (if (and (extent-live-p mode-motion-extent)
|
|
1114 (extent-buffer mode-motion-extent))
|
|
1115 ()
|
|
1116 (setq mode-motion-extent (make-extent nil nil buffer))
|
|
1117 (set-extent-priority mode-motion-extent 1))
|
|
1118 (if (and
|
|
1119 ;; compute the region to be highlighted
|
|
1120 (setq region
|
|
1121 (if point
|
|
1122 ;; compute the mode-motion region using the
|
|
1123 ;; handlers boundary function
|
|
1124 (condition-case nil;; c
|
|
1125 (funcall
|
|
1126 (motion-handler-boundary-function handler)
|
|
1127 point)
|
|
1128 ;; Messages that appear during computing the
|
|
1129 ;; region may be displayed not done
|
|
1130 ;; here because it's rather disturbing
|
|
1131 (error
|
|
1132 ;; (setq message (format "%s" (car (cdr c))))
|
|
1133 nil))
|
|
1134 ;; otherwise highlight the whole line mouse is
|
|
1135 ;; behind but only if the line isn't empty
|
|
1136 (if mode-motion-highlight-lines-when-behind
|
|
1137 (unwind-protect
|
|
1138 (progn
|
|
1139 ;; (message "%s" (event-window event))
|
|
1140 (move-to-window-line
|
|
1141 (if (< emacs-minor-version 12)
|
|
1142 (- (event-y event)
|
|
1143 (nth 1 (window-edges window)))
|
|
1144 (event-y event)))
|
|
1145 (beginning-of-line)
|
|
1146 (if (= (following-char) ?\n)
|
|
1147 ;; empty line
|
|
1148 ()
|
|
1149 (thing-region
|
|
1150 (point)
|
|
1151 (progn
|
|
1152 (end-of-line)
|
|
1153 ;; for `follow-point' behavoir
|
|
1154 (setq point (point))
|
|
1155 ;; fetch also the newline, if any
|
|
1156 ;; -- handy for copying >1 line
|
|
1157 (if (eobp) point (1+ point))))))
|
|
1158 (goto-char point-save)))))
|
|
1159 ;; (message "region: %s" region)
|
|
1160 ;; the region might be in reverse order. Stop in this case
|
|
1161 (<= (car region) (cdr region)))
|
|
1162 (if (or (not (motion-handler-follow-point handler))
|
|
1163 (pos-visible-in-window-p point))
|
|
1164 (progn
|
|
1165 ;; set the extent face
|
|
1166 (set-extent-face
|
|
1167 mode-motion-extent (motion-handler-face handler))
|
|
1168 ;; set the new boundary
|
|
1169 (set-extent-endpoints
|
|
1170 mode-motion-extent (car region) (cdr region))
|
|
1171 ;; highlight if required
|
|
1172 (set-extent-property
|
|
1173 mode-motion-extent 'highlight
|
|
1174 (motion-handler-highlight handler))
|
|
1175 (highlight-extent mode-motion-extent
|
|
1176 (motion-handler-highlight handler))
|
|
1177 ;; make point follow the mouse or point to
|
|
1178 ;; the beginning of the line do not move the
|
|
1179 ;; cursor if a mark is set.
|
|
1180 (cond ((and (motion-handler-follow-point handler)
|
|
1181 (not (mark)))
|
|
1182 (goto-char point)
|
|
1183 ;; kludge to keep the cursor out the way
|
|
1184 (if (or (eq (motion-handler-boundary-function
|
|
1185 handler)
|
|
1186 'line-boundaries)
|
|
1187 (eq (motion-handler-boundary-function
|
|
1188 handler)
|
|
1189 'visible-line-boundaries))
|
|
1190 (beginning-of-line))))
|
|
1191 (if (and mode-motion-focus-on-window
|
|
1192 (or (eq mode-motion-focus-on-window t)
|
|
1193 (motion-handler-follow-point handler)))
|
|
1194 ;; Select the current window FROM OUTSIDE the
|
|
1195 ;; `save-window-excursion' that surrounds the call
|
|
1196 ;; to the current function. This also avoids
|
|
1197 ;; conflicts with running process filters.
|
|
1198 (enqueue-eval-event 'select-window
|
|
1199 (selected-window)))
|
|
1200 ;; snap in effect, but it ain't yet workin'
|
|
1201 ;; (message "X: %sl; Y: %s"(event-x event)(event-y event))
|
|
1202 ;; (and motion-handler-snap-in
|
|
1203 ;; (set-mouse-position
|
|
1204 ;; (window-frame (event-window event))
|
|
1205 ;; (event-x event)
|
|
1206 ;; (event-y event)))
|
|
1207 (setq mode-motion-last-extent mode-motion-extent)
|
|
1208 ;; signal success
|
|
1209 t))
|
|
1210 ;; signal failiure
|
|
1211 nil))
|
|
1212 (set-window-configuration window-config)
|
|
1213 (set-buffer buffer-save)))))
|
|
1214
|
|
1215 ;; Motion Event debugging
|
|
1216 ;;
|
|
1217 ;; Useful to see what information is available from motion events
|
|
1218
|
|
1219 (defun debug-motion-handler (event)
|
|
1220 (let* ((window (event-window event))
|
|
1221 (frame (or (event-frame event) (selected-frame)))
|
|
1222 (buffer (and window (event-buffer event)))
|
|
1223 (point (and buffer (event-point event))))
|
|
1224 (with-output-to-temp-buffer "*Debug Motion Handler Output*"
|
|
1225 (princ
|
|
1226 (format "\
|
|
1227 Window: %s
|
|
1228 Frame: %s
|
|
1229 Buffer: %s
|
|
1230 (event-x, event-y): (%s, %s)
|
|
1231 (event-x-pixel, event-y-pixel): (%s, %s)
|
|
1232 Point: %s
|
|
1233 Timestamp: %s"
|
|
1234 window
|
|
1235 frame
|
|
1236 buffer
|
|
1237 (event-x event) (event-y event)
|
|
1238 (event-x-pixel event) (event-y-pixel event)
|
|
1239 point
|
|
1240 (event-timestamp event))))))
|
|
1241
|
|
1242 ;(let ((mouse-motion-handler 'debug-motion-handler)
|
|
1243 ; (temp-buffer-show-function nil))
|
|
1244 ; (read-char))
|
|
1245
|
|
1246 ;; Set of copy/kill/move functions for usage with highlighted regions
|
|
1247
|
|
1248 (put 'mode-motion-move 'pending-delete t)
|
|
1249 (put 'mode-motion-copy 'pending-delete t)
|
|
1250
|
|
1251 (defun mode-motion-move ()
|
|
1252 "Move the motion active region to point."
|
|
1253 (interactive)
|
|
1254 (mode-motion-insert-text (mode-motion-copy/delete t)))
|
|
1255
|
|
1256 (defun mode-motion-kill ()
|
|
1257 "Kill the motion active region and push it onto the kill ring."
|
|
1258 (interactive)
|
|
1259 (mode-motion-copy/delete t t t))
|
|
1260
|
|
1261 (defun mode-motion-copy ()
|
|
1262 "Copy the motion active region to point."
|
|
1263 (interactive)
|
|
1264 (mode-motion-insert-text (mode-motion-copy/delete)))
|
|
1265
|
|
1266 (defun mode-motion-copy-as-kill ()
|
|
1267 "Delete the motion active region and push it onto the kill ring.
|
|
1268 Set point to the place where deletion happened."
|
|
1269 (interactive)
|
|
1270 (mode-motion-copy/delete nil t)
|
|
1271 (message "Text copied to the to ring and cut buffer."))
|
|
1272
|
|
1273 (defun mode-motion-copy/delete (&optional delete copy-as-kill set-point)
|
|
1274 "Return the string that is designated by the current motion active region.
|
|
1275 Arguments are:
|
|
1276 EVENT - a mouse click event used to identify the buffer and window
|
|
1277 &optional DELETE - delete the motion active text region
|
|
1278 COPY-AS-KILL - copy the string to the kill ring
|
|
1279 SET-POINT - set point to the start of the motion active region."
|
|
1280 (let ((old-buf (current-buffer))
|
|
1281 (old-window (selected-window)))
|
|
1282 (unwind-protect
|
|
1283 (let ((extent (or primary-selection-extent
|
|
1284 (and (extentp mode-motion-last-extent)
|
|
1285 (not (extent-property mode-motion-last-extent
|
|
1286 'detached))
|
|
1287 mode-motion-last-extent))))
|
|
1288
|
|
1289 (if (and (extentp extent)
|
|
1290 (set-buffer (extent-buffer extent))
|
|
1291 (not
|
|
1292 ;; zero length extents
|
|
1293 (= (extent-start-position extent)
|
|
1294 (extent-end-position extent))))
|
|
1295
|
|
1296 (let* ((start (extent-start-position extent))
|
|
1297 (end (extent-end-position extent))
|
|
1298 (text
|
|
1299 (buffer-substring
|
|
1300 (extent-start-position extent)
|
|
1301 (extent-end-position extent))))
|
|
1302
|
|
1303 (cond (copy-as-kill
|
|
1304 (copy-region-as-kill start end)
|
|
1305 (if (or (not kill-hooks)
|
|
1306 (eq kill-hooks 'ignore))
|
|
1307 (progn
|
|
1308 (x-own-selection-internal 'PRIMARY text)
|
|
1309 (x-own-clipboard text)))))
|
|
1310
|
|
1311 (cond (delete
|
|
1312 (kill-region start end)
|
|
1313 (x-own-selection-internal 'PRIMARY text)
|
|
1314 ;; (select-window window)
|
|
1315 (if set-point
|
|
1316 (goto-char start))))
|
|
1317
|
|
1318 (setq this-command 'mode-motion+)
|
|
1319 text)
|
|
1320 (error "No current primary or motion selection.")
|
|
1321 ))
|
|
1322 (set-buffer old-buf)
|
|
1323 (select-window old-window))))
|
|
1324
|
|
1325 (defun mode-motion-insert-text (text)
|
|
1326 "Insert TEXT at point. Also insert one space if the
|
|
1327 preceeding character is a word constituent or a closing paren."
|
|
1328 (or text (error "No highlighted text to copy."))
|
|
1329 (let ((prec-char-syntax (char-syntax (preceding-char))))
|
|
1330 (if (memq prec-char-syntax '(?w ?\))) (insert " "))
|
|
1331 (insert text)))
|
|
1332
|
|
1333 ;; Boundary functions
|
|
1334 ;;
|
|
1335 ;; The following functions are already provided by the thing package:
|
|
1336 ;; thing-boundaries
|
|
1337 ;; thing-symbol
|
|
1338 ;; thing-word
|
|
1339
|
|
1340 (defun char-boundaries (point) (thing-region point (1+ point)))
|
|
1341
|
|
1342 (defun visible-line-boundaries (point)
|
|
1343 (save-excursion
|
|
1344 (goto-char point)
|
|
1345 (beginning-of-line)
|
|
1346 (skip-chars-forward " \t")
|
|
1347 (if (and (eq major-mode 'dired-mode)
|
|
1348 (save-excursion (dired-move-to-filename)))
|
|
1349 (let ((start (point)))
|
|
1350 (end-of-line)
|
|
1351 (skip-chars-backward " \t")
|
|
1352 (thing-region start (point))))))
|
|
1353
|
|
1354 (defun line-boundaries (point)
|
|
1355 (save-excursion
|
|
1356 (goto-char point)
|
|
1357 (beginning-of-line)
|
|
1358 (if (and (eq major-mode 'dired-mode)
|
|
1359 (save-excursion (dired-move-to-filename)))
|
|
1360 (let ((start (point)))
|
|
1361 (end-of-line)
|
|
1362 (thing-region start (point))))))
|
|
1363
|
|
1364 (defun cvs-line-boundaries (point)
|
|
1365 (save-excursion
|
|
1366 (goto-char point)
|
|
1367 (beginning-of-line)
|
|
1368 (if (looking-at "^[* ] ")
|
|
1369 (thing-region (point) (progn (end-of-line) (point))))))
|
|
1370
|
|
1371 (defun latex-boundaries (here)
|
|
1372 (setq *last-thing* 'sexp)
|
|
1373 (tex-boundaries
|
|
1374 here ?\\ "a-zA-Z"
|
|
1375 ;; begin-fwd-regexp
|
|
1376 "\\\\begin *{ *\\([a-z]*\\) *}"
|
|
1377 ;; end-fwd-regexp
|
|
1378 "\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
|
|
1379 ;; begin-bwd-regexp
|
|
1380 "\\\\end *{ *\\([a-z]*\\) *}"
|
|
1381 ;; begin-bwd-regexp
|
|
1382 "\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)"
|
|
1383 ;; param-cmd-regexp
|
|
1384 "\\\\[a-zA-Z]+[ \n\t]*{"))
|
|
1385
|
|
1386 (defvar texinfo-paired-commands
|
|
1387 (mapconcat
|
|
1388 'identity
|
|
1389 '(
|
|
1390 "enumerate"
|
|
1391 "example"
|
|
1392 "group"
|
|
1393 "ifinfo"
|
|
1394 "iftex"
|
|
1395 "ignore"
|
|
1396 "itemize"
|
|
1397 "menu"
|
|
1398 "quotation"
|
|
1399 "table"
|
|
1400 "tex"
|
|
1401 "titlepage"
|
|
1402 )
|
|
1403 "\\|"))
|
|
1404
|
|
1405 (defvar texinfo-begin-fwd-regexp
|
|
1406 (format "@\\(%s\\)" texinfo-paired-commands))
|
|
1407 (defvar texinfo-end-bwd-regexp
|
|
1408 (format "@end *\\(%s\\)" texinfo-paired-commands))
|
|
1409
|
|
1410 (defun texinfo-boundaries (here)
|
|
1411 (tex-boundaries
|
|
1412 here ?@ "a-z"
|
|
1413 texinfo-begin-fwd-regexp
|
|
1414 ;; end-fwd-regexp
|
|
1415 "\\(@end *%s\\)\\|\\(@%s\\)"
|
|
1416 ;; end-bwd-regexp
|
|
1417 texinfo-end-bwd-regexp
|
|
1418 ;; begin-bwd-regexp
|
|
1419 "\\(@end *%s\\)\\|\\(@%s\\)"
|
|
1420 ;; param-cmd-regexp
|
|
1421 "@\\(TeX\\|[a-zA]+\\)[ \n\t]*{"))
|
|
1422
|
|
1423 (defun tex-boundaries
|
|
1424 (here cmd-start-character cmd-word-character
|
|
1425 begin-fwd-regexp end-fwd-regexp
|
|
1426 end-bwd-regexp begin-bwd-regexp
|
|
1427 param-cmd-regexp)
|
|
1428 "Generic TeX dialect scanner.
|
|
1429 Parameters:
|
|
1430 cmd-start-character: character that starts a command
|
|
1431 (`\' in (La)TeX, `@' in Texinfo)
|
|
1432 cmd-word-character: regexpression to be used by the function
|
|
1433 `skip-chars-backward' allowing to skip over command
|
|
1434 characters other than `cmd-start-character'
|
|
1435 begin-fwd-regexp: regexpression matching the begin part of a
|
|
1436 text stretch, used in forward search.
|
|
1437 end-fwd-regexp: regexpression matching the end part of a
|
|
1438 text stretch, used in forward search
|
|
1439 end-bwd-regexp: regexpression matching the end part of a
|
|
1440 text stretch, used in backward search.
|
|
1441 begin-bwd-regexp: regexpression matching the begin part of a
|
|
1442 text stretch, used in backward search.
|
|
1443 param-cmd-regexp: regexpression matching a parameterized command
|
|
1444 \(including the open parenthesis\)"
|
|
1445 (save-excursion
|
|
1446 (goto-char here)
|
|
1447 (cond ((= (following-char) cmd-start-character)
|
|
1448 (forward-char 1))
|
|
1449 ((= (char-syntax (following-char)) ?w)
|
|
1450 (skip-chars-backward cmd-word-character)))
|
|
1451 (if (/= (preceding-char) cmd-start-character)
|
|
1452 (thing-boundaries here)
|
|
1453 (forward-char -1)
|
|
1454 (catch 'return
|
|
1455 (cond ((looking-at begin-fwd-regexp)
|
|
1456 (let* ((start (point))
|
|
1457 (env (buffer-substring
|
|
1458 (match-beginning 1) (match-end 1)))
|
|
1459 (regexp (format end-fwd-regexp env env))
|
|
1460 (count 0))
|
|
1461 (while (re-search-forward regexp nil t)
|
|
1462 (cond ((match-beginning 2) ; \begin
|
|
1463 (setq count (1+ count)))
|
|
1464 ((match-beginning 1) ; \end
|
|
1465 (setq count (1- count))
|
|
1466 (if (= count 0)
|
|
1467 (throw 'return
|
|
1468 (thing-region start (point)))))))))
|
|
1469 ((looking-at end-bwd-regexp)
|
|
1470 (let* ((end (match-end 0))
|
|
1471 (env (buffer-substring
|
|
1472 (match-beginning 1) (match-end 1)))
|
|
1473 (regexp
|
|
1474 (format begin-bwd-regexp env env))
|
|
1475 (count 1))
|
|
1476 (while (re-search-backward regexp nil t)
|
|
1477 (cond ((match-beginning 1) ; \end
|
|
1478 (setq count (1+ count)))
|
|
1479 ((match-beginning 2) ; \begin
|
|
1480 (setq count (1- count))
|
|
1481 (if (= count 0)
|
|
1482 (throw 'return (thing-region (point) end))))
|
|
1483 ))))
|
|
1484 ;; tex macros of the form \cmd {...}
|
|
1485 ((looking-at param-cmd-regexp)
|
|
1486 (thing-region
|
|
1487 (point)
|
|
1488 (progn
|
|
1489 (goto-char (1- (match-end 0)))
|
|
1490 (forward-sexp 1)
|
|
1491 (point))))
|
|
1492 ;; fetch the current macro (with backslash)
|
|
1493 (t (thing-region (point) (progn (forward-word 1) (point)))))))))
|
|
1494
|
|
1495 ;; special parse of buffer for valid selectable info
|
|
1496 (defun minibuffer-selection-boundaries (point)
|
|
1497 (let ((old-syntax (syntax-table)))
|
|
1498 (unwind-protect
|
|
1499 (progn
|
|
1500 ;; best syntax table for recognizing symbols
|
|
1501 (set-syntax-table emacs-lisp-mode-syntax-table)
|
|
1502 (let ((file-completion (eq minibuffer-completion-table
|
|
1503 'read-file-name-internal))
|
|
1504 region
|
|
1505 minibuf-string ;contents of minibuffer
|
|
1506 buffer-string ;string to be highlighted (or not)
|
|
1507 prefix ;prefix calculated from minibuf-string
|
|
1508 string ;string to be verified in the
|
|
1509 ;completion table
|
|
1510 )
|
|
1511 (and
|
|
1512
|
|
1513 (setq region (if file-completion
|
|
1514 (thing-filename point)
|
|
1515 (thing-symbol point)))
|
|
1516
|
|
1517 (setq
|
|
1518 minibuf-string ; contents of minibuffer
|
|
1519 (save-excursion
|
|
1520 (set-buffer mouse-grabbed-buffer)
|
|
1521 (buffer-string))
|
|
1522
|
|
1523 buffer-string ; string to be highlighted (or not)
|
|
1524 (buffer-substring (car region) (cdr region))
|
|
1525
|
|
1526 prefix
|
|
1527 (if file-completion
|
|
1528 (file-name-nondirectory minibuf-string)
|
|
1529 minibuf-string)
|
|
1530
|
|
1531 string
|
|
1532 (if file-completion
|
|
1533 (concat (file-name-directory minibuf-string) buffer-string)
|
|
1534 buffer-string))
|
|
1535
|
|
1536 (if (or (and (fboundp 'ange-ftp-ftp-path)
|
|
1537 (or (ange-ftp-ftp-path buffer-string)
|
|
1538 (ange-ftp-ftp-path string)))
|
|
1539 (and (fboundp 'efs-ftp-path)
|
|
1540 (or (efs-ftp-path buffer-string)
|
|
1541 (efs-ftp-path string))))
|
|
1542 ;; #### Like our counterpart in mode-motion: evil evil evil
|
|
1543 t
|
|
1544 (if file-completion
|
|
1545 (try-completion string
|
|
1546 minibuffer-completion-table
|
|
1547 minibuffer-completion-predicate)
|
|
1548 (eq 't (try-completion string
|
|
1549 minibuffer-completion-table
|
|
1550 minibuffer-completion-predicate))))
|
|
1551
|
|
1552 ;; the result is the region to be highlighted
|
|
1553 region)))
|
|
1554 (set-syntax-table old-syntax))))
|
|
1555
|
|
1556 ;; C source code scanner
|
|
1557 (defvar c-statement-starting-keyword-regexpr
|
|
1558 "\\(if\\|for\\|while\\|do\\|switch\\|break\\|continue\\)\\b")
|
|
1559
|
|
1560 (defun c-boundaries (here)
|
|
1561 (setq *last-thing* 'sexp)
|
|
1562 (save-excursion
|
|
1563 (goto-char here)
|
|
1564 (let ((following-char (following-char))
|
|
1565 (preceding-char (preceding-char))
|
|
1566 aux)
|
|
1567 (if (= (char-syntax following-char) ?w)
|
|
1568 (progn
|
|
1569 (skip-chars-backward "a-zA-Z")
|
|
1570 (setq aux (point))
|
|
1571 (skip-chars-backward "\n\t ")
|
|
1572 (if (= (preceding-char) ?#)
|
|
1573 (forward-char -1)
|
|
1574 (goto-char aux))))
|
|
1575 (if (and (= following-char ?*)
|
|
1576 (= preceding-char ?/))
|
|
1577 (forward-char -1))
|
|
1578 (if (and (= following-char ?/)
|
|
1579 (= preceding-char ?*))
|
|
1580 (forward-char -1))
|
|
1581 (cond
|
|
1582 ((= (following-char) ?#) (c-scan-preproc-macros))
|
|
1583 ((looking-at "/\\*") ; begin comment
|
|
1584 (let ((start (match-beginning 0)))
|
|
1585 (if (search-forward "*/" nil t)
|
|
1586 (thing-region start (match-end 0)))))
|
|
1587 ((looking-at "\\*/") ; end comment
|
|
1588 (let ((end (match-end 0)))
|
|
1589 (if (search-backward "/*" nil t)
|
|
1590 (thing-region (match-beginning 0) end))))
|
|
1591 ((looking-at c-statement-starting-keyword-regexpr) ; if for while do etc
|
|
1592 (thing-region (match-beginning 0)
|
|
1593 (c-forward-statement
|
|
1594 (buffer-substring (match-beginning 1) (match-end 1)))))
|
|
1595 ((looking-at "else\\b")
|
|
1596 (thing-region (match-beginning 0) (c-forward-else)))
|
|
1597 (t (if (= (char-syntax (following-char)) ?.)
|
|
1598 (thing-region here (1+ here))
|
|
1599 (thing-boundaries here)))))))
|
|
1600
|
|
1601
|
|
1602 (defun c-scan-preproc-macros ()
|
|
1603 (cond
|
|
1604 ((looking-at "^#[ \n\t]*include[ \n\t]*[<\"][^>\"]*[>\"]") ; #include
|
|
1605 (thing-region (match-beginning 0) (match-end 0)))
|
|
1606 ((looking-at "^#[ \n\t]*\\(define\\|undef\\)") ; #define, #undef
|
|
1607 (thing-region
|
|
1608 (match-beginning 0)
|
|
1609 (progn
|
|
1610 (end-of-line)
|
|
1611 (while (= (preceding-char) ?\\)
|
|
1612 (forward-line 1)
|
|
1613 (end-of-line))
|
|
1614 (point))))
|
|
1615 ;; #if, #ifdef, #ifndef, #else, #elif
|
|
1616 ((looking-at "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|else\\|elif\\)\\b")
|
|
1617 (let ((start (match-beginning 0))
|
|
1618 (counter 1)
|
|
1619 match)
|
|
1620 (goto-char (match-end 0))
|
|
1621 (while (and (>= counter 1)
|
|
1622 (re-search-forward
|
|
1623 "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
|
|
1624 nil t))
|
|
1625 (setq match
|
|
1626 (buffer-substring (match-beginning 1) (match-end 1)))
|
|
1627 (setq counter
|
|
1628 (if (string= match "endif")
|
|
1629 (1- counter)
|
|
1630 (1+ counter))))
|
|
1631 (if (= counter 0)
|
|
1632 (thing-region start (match-end 0)))))
|
|
1633 ((looking-at "^#[ \n\t]*endif\\b") ; #endif
|
|
1634 (let ((end (match-end 0))
|
|
1635 (counter 1)
|
|
1636 match)
|
|
1637 (goto-char (match-beginning 0))
|
|
1638 (while (and (>= counter 1)
|
|
1639 (re-search-backward
|
|
1640 "^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"
|
|
1641 nil t))
|
|
1642 (setq match
|
|
1643 (buffer-substring (match-beginning 1) (match-end 1)))
|
|
1644 (setq counter
|
|
1645 (if (string= match "endif")
|
|
1646 (1+ counter)
|
|
1647 (1- counter))))
|
|
1648 (if (= counter 0)
|
|
1649 (thing-region (match-beginning 0) end))))))
|
|
1650
|
|
1651 (defun c-skip-over-comment ()
|
|
1652 (let ((aux (point)))
|
|
1653 (skip-chars-forward "\n\t ")
|
|
1654 (or (and (= (following-char) ?/)
|
|
1655 (= (char-after (1+ (point))) ?*)
|
|
1656 (search-forward "*/" nil t)
|
|
1657 (point))
|
|
1658 (goto-char aux))))
|
|
1659
|
|
1660 (defun c-forward-statement (&optional keyword)
|
|
1661 (c-skip-over-comment)
|
|
1662 (skip-chars-forward " \n\t")
|
|
1663 (or keyword (setq keyword
|
|
1664 (if (looking-at c-statement-starting-keyword-regexpr)
|
|
1665 (buffer-substring
|
|
1666 (match-beginning 1)
|
|
1667 (match-end 1)))))
|
|
1668 (if keyword
|
|
1669 (cond ((string= keyword "if")
|
|
1670 (c-forward-if))
|
|
1671 ((string= keyword "do")
|
|
1672 (c-forward-do-while))
|
|
1673 ((member keyword '("for" "while" "switch"))
|
|
1674 (c-forward-for/while/switch))
|
|
1675 ((member keyword '("break" "continue"))
|
|
1676 (c-forward-break/continue)))
|
|
1677 (cond ((= (following-char) ?\{)
|
|
1678 (forward-list 1)
|
|
1679 (point))
|
|
1680 (t
|
|
1681 ;; Here I use that each C statement other then
|
|
1682 ;; a bloc, if, while, for, do ... ends in a `;'
|
|
1683 (let (char)
|
|
1684 (catch 'exit
|
|
1685 (while t
|
|
1686 (if (eobp) (throw 'exit nil))
|
|
1687 (setq char (following-char))
|
|
1688 (cond ((= (char-syntax char) ?.)
|
|
1689 (forward-char 1)
|
|
1690 (if (= char ?\;) (throw 'exit (point))))
|
|
1691 (t (forward-sexp 1)
|
|
1692 (skip-chars-forward " \n\t"))))))))))
|
|
1693
|
|
1694 (defun c-forward-if ()
|
|
1695 (let (aux)
|
|
1696 (forward-word 1) ; if
|
|
1697 (forward-list 1)
|
|
1698 (c-forward-statement)
|
|
1699 (setq aux (point))
|
|
1700 (skip-chars-forward "\n\t ")
|
|
1701 (if (looking-at "else\\b")
|
|
1702 (c-forward-else)
|
|
1703 (goto-char aux))))
|
|
1704
|
|
1705 (defun c-forward-else ()
|
|
1706 (forward-word 1) ; else
|
|
1707 (c-forward-statement))
|
|
1708
|
|
1709 (defun c-forward-for/while/switch ()
|
|
1710 (forward-word 1) ; for
|
|
1711 (forward-list 1)
|
|
1712 (c-forward-statement))
|
|
1713
|
|
1714 (defun c-forward-do-while ()
|
|
1715 (forward-word 1) ; do ... while
|
|
1716 (c-forward-statement)
|
|
1717 (c-forward-for/while/switch))
|
|
1718
|
|
1719 (defun c-forward-switch ()
|
|
1720 (forward-word 1) ; switch
|
|
1721 (forward-list 2)
|
|
1722 (point))
|
|
1723
|
|
1724 (defun c-forward-break/continue ()
|
|
1725 (forward-word 1) ; keyword
|
|
1726 (c-skip-over-comment)
|
|
1727 (skip-chars-forward "\n\t ")
|
|
1728 (if (= (following-char) ?\;)
|
|
1729 (goto-char (1+ (point)))))
|
|
1730
|
|
1731 ;; Tcl syntax scanner
|
|
1732 (defvar tcl-builtin-commands nil
|
|
1733 "Alist of information about tcl syntax for the tcl-boundaries function.
|
|
1734 An entry has the form
|
|
1735 \(<command-string> . <syntax description>\)
|
|
1736 where
|
|
1737 <command-string> is the name of a tcl command
|
|
1738 <syntax description> is one of
|
|
1739 list of integers: the number of possible arguments
|
|
1740 t: any number of arguments")
|
|
1741
|
|
1742 (defconst tcl-commands
|
|
1743 '(
|
|
1744 ("append" . (2 . nil))
|
|
1745 ("array" . (2 . 3))
|
|
1746 ("break" . 0)
|
|
1747 ("case" . 3)
|
|
1748 ("catch" . 1)
|
|
1749 ("cd" . 1)
|
|
1750 ("close" . 1)
|
|
1751 ("concat" . t)
|
|
1752 ("continue" . 0)
|
|
1753 ("else" . (1 . nil))
|
|
1754 ("elseif" . (1 . nil))
|
|
1755 ("eof" . 1)
|
|
1756 ("error" . t)
|
|
1757 ("eval" . t)
|
|
1758 ("exec" . t)
|
|
1759 ("exit" . (0 . 1))
|
|
1760 ("expr" . 1)
|
|
1761 ("file" . (2 . nil))
|
|
1762 ("flush" . 1)
|
|
1763 ("for" . 4)
|
|
1764 ("foreach" . 3)
|
|
1765 ("format" . (1 . nil))
|
|
1766 ("gets" . (1 . 2))
|
|
1767 ("glob" . t)
|
|
1768 ("global" . (1 . nil))
|
|
1769 ("history" . t)
|
|
1770 ("if" . (2 . nil))
|
|
1771 ("incr" . (1 . 2))
|
|
1772 ("info" . (1 . 4))
|
|
1773 ("join" . (1 . 2))
|
|
1774 ("lappend" . (2 . nil))
|
|
1775 ("lindex" . 2)
|
|
1776 ("linsert" . (3 . nil))
|
|
1777 ("list" . t)
|
|
1778 ("llength" . 1)
|
|
1779 ("lrange" . 3)
|
|
1780 ("lreplace" . (3 . nil))
|
|
1781 ("lsearch" . 2)
|
|
1782 ("lsort" . 1)
|
|
1783 ("open" . (1 . 2))
|
|
1784 ("proc" . 3)
|
|
1785 ("puts" . (1 . 3))
|
|
1786 ("pwd" . 0)
|
|
1787 ("read" . (1 . 2))
|
|
1788 ("regexp" . (2 . nil))
|
|
1789 ("regsub" . (4 . 6))
|
|
1790 ("rename" . 2)
|
|
1791 ("return" . (0 .1))
|
|
1792 ("scan" . (3 . nil))
|
|
1793 ("seek" . (2 . 3))
|
|
1794 ("set" . (1 . 2))
|
|
1795 ("source" . 1)
|
|
1796 ("split" . (1 . 2))
|
|
1797 ("string" . (2 . 4))
|
|
1798 ("tell" . 1)
|
|
1799 ("time" . (1 .2))
|
|
1800 ("trace" . (1 . nil))
|
|
1801 ("unknown" . (1 . nil))
|
|
1802 ("unset" . (1 . nil))
|
|
1803 ("uplevel" . (1 . nil))
|
|
1804 ("upvar" . (2 . nil))
|
|
1805 ("while" . 2)
|
|
1806 ))
|
|
1807
|
|
1808 (defconst tk-commands
|
|
1809 '(("bind" . 3)
|
|
1810 ("button" . t)
|
|
1811 ("canvas" . t)
|
|
1812 ("frame" . t)
|
|
1813 ("label" . t)
|
|
1814 ("listbox" . t)
|
|
1815 ("menu" . t)
|
|
1816 ("menubutton" . t)
|
|
1817 ("pack" . t)
|
|
1818 ("scrollbar" . t)
|
|
1819 ("tree" . t)
|
|
1820 ("wm" . t)
|
|
1821 ))
|
|
1822
|
|
1823 (defconst tcl-tk-commands
|
|
1824 (nconc tcl-commands tk-commands))
|
|
1825
|
|
1826 (defconst tcl-tk-commands-regexp
|
|
1827 (format "\\(%s\\\)\\W" (mapconcat 'car tcl-tk-commands "\\|")))
|
|
1828
|
|
1829 (defun tcl-boundaries (here)
|
|
1830 (save-excursion
|
|
1831 (goto-char here)
|
|
1832 (skip-chars-backward "a-z")
|
|
1833 (if (looking-at
|
|
1834 tcl-tk-commands-regexp)
|
|
1835 (let* ((count 0)
|
|
1836 (start (point))
|
|
1837 (keyword (buffer-substring
|
|
1838 (match-beginning 1)
|
|
1839 (match-end 1)))
|
|
1840 (syntax-description
|
|
1841 (cdr (assoc keyword tcl-tk-commands))))
|
|
1842 (goto-char (match-end 0))
|
|
1843 (while (not (looking-at "[ \t]*[]\n;}]"))
|
|
1844 (setq count (1+ count))
|
|
1845 (tcl-forward-sexp1)
|
|
1846 ;; skipping over the parentheses of array expressions:
|
|
1847 (while (not (or (looking-at "[ \t]*[]\n;}]")
|
|
1848 (= (char-syntax (following-char)) ? )))
|
|
1849 (tcl-forward-sexp1)))
|
|
1850
|
|
1851 (if (cond ((eq syntax-description t))
|
|
1852 ((integerp syntax-description)
|
|
1853 (= syntax-description count))
|
|
1854 ((consp syntax-description)
|
|
1855 (and (<= (car syntax-description) count)
|
|
1856 (or (null (cdr syntax-description))
|
|
1857 (<= count (cdr syntax-description))))))
|
|
1858 (progn
|
|
1859 (message "`%s' matched." keyword)
|
|
1860 (thing-region start (point)))
|
|
1861 (progn
|
|
1862 (message "wrong syntax: `%s'." keyword)
|
|
1863 nil)))
|
|
1864 (message "")
|
|
1865 (thing-boundaries here))))
|
|
1866
|
|
1867 (defun tcl-forward-sexp (&optional arg)
|
|
1868 "Move forward across one balanced tcl expression.
|
|
1869 With argument, do it that many times."
|
|
1870 (interactive "p")
|
|
1871 (if (< arg 0) (error "negative argument not allowed"))
|
|
1872 (or arg (setq arg 1))
|
|
1873 (while (> arg 0)
|
|
1874 (tcl-forward-sexp1)
|
|
1875 (setq arg (1- arg))))
|
|
1876
|
|
1877 (defun tcl-forward-sexp1 ()
|
|
1878 (interactive "")
|
|
1879 (let ((start (point))
|
|
1880 next-char syntax (first-scan t))
|
|
1881 (setq next-char (following-char)
|
|
1882 syntax (char-syntax next-char))
|
|
1883
|
|
1884 (while (or (= next-char ?\;)
|
|
1885 (memq syntax '(? ?>)))
|
|
1886 (forward-char 1)
|
|
1887 (setq next-char (following-char)
|
|
1888 syntax (char-syntax next-char)))
|
|
1889
|
|
1890 (condition-case var
|
|
1891 (catch 'exit
|
|
1892 (while t
|
|
1893 (setq next-char (following-char)
|
|
1894 syntax (char-syntax next-char))
|
|
1895 (cond ((= next-char ?\;)
|
|
1896 (throw 'exit nil))
|
|
1897 ((memq syntax (if first-scan '(? ?>) '(? ?> ?\))))
|
|
1898 (throw 'exit nil))
|
|
1899 (t
|
|
1900 (goto-char (or (scan-sexps (point) 1)
|
|
1901 (point-max)))))
|
|
1902 (setq first-scan nil)))
|
|
1903 (error (goto-char start)
|
|
1904 (error (car (cdr var)))))))
|
|
1905
|
|
1906 ;; (define-key tcl-mode-map "\M-\C-f" 'tcl-forward-sexp)
|
|
1907
|
|
1908 (defun mode-motion-eval-func (eval-func)
|
|
1909 (let ((old-buf (current-buffer))
|
|
1910 (old-window (selected-window)))
|
|
1911 (unwind-protect
|
|
1912 (let ((extent (or primary-selection-extent
|
|
1913 (and (extentp mode-motion-last-extent)
|
|
1914 (not (extent-property mode-motion-last-extent
|
|
1915 'detached))
|
|
1916 mode-motion-last-extent))))
|
|
1917
|
|
1918 (if (and (extentp extent)
|
|
1919 (set-buffer (extent-buffer extent))
|
|
1920 (not
|
|
1921 ;; zero length extents
|
|
1922 (= (extent-start-position extent)
|
|
1923 (extent-end-position extent))))
|
|
1924
|
|
1925 (let* ((start (extent-start-position extent))
|
|
1926 (end (extent-end-position extent)))
|
|
1927
|
|
1928 (funcall eval-func start end))
|
|
1929
|
|
1930 (error "No current primary or motion selection.")
|
|
1931 ))
|
|
1932 (set-buffer old-buf)
|
|
1933 (select-window old-window))))
|
|
1934
|
|
1935 (defun mode-motion-eval-region ()
|
|
1936 (interactive)
|
|
1937 (mode-motion-eval-func 'eval-region))
|
|
1938
|
|
1939
|
|
1940 ;; Motion highlight faces and initialization.
|
|
1941
|
|
1942 (defun sect-handler (string)
|
|
1943 "Return the symbol corresponding to the foo-STRING handler for this sect."
|
|
1944 (intern-soft (concat (symbol-name mode-motion+-religion) string)))
|
|
1945
|
|
1946 (defun mode-motion-init-handlers-according-to-religion (&optional forcep)
|
|
1947 (interactive)
|
|
1948 ;; Initialise default motion handlers depending on religious sect!
|
|
1949 (let ((foo-thing (sect-handler "-thing"))
|
|
1950 (foo-c (sect-handler "-c"))
|
|
1951 (foo-LaTeX (sect-handler "-laTeX"))
|
|
1952 (foo-line@ (sect-handler "-line@"))
|
|
1953 (foo-vline@ (sect-handler "-vline@")))
|
|
1954 (if forcep
|
|
1955 (progn
|
|
1956 (setq default-motion-handler (find-motion-handler foo-thing))
|
|
1957 (set-mode-motion-handler 'emacs-lisp-mode foo-thing)
|
|
1958 (set-mode-motion-handler 'lisp-interaction-mode foo-thing)
|
|
1959 (set-mode-motion-handler 'c-mode foo-c)
|
|
1960 (set-mode-motion-handler 'c++-mode foo-c)
|
|
1961 (set-mode-motion-handler 'c++-c-mode foo-c)
|
|
1962 (set-mode-motion-handler 'tex-mode foo-LaTeX)
|
|
1963 (set-mode-motion-handler 'latex-mode foo-LaTeX)
|
|
1964 (set-mode-motion-handler 'Buffer-menu-mode foo-vline@)
|
|
1965 (set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@)
|
|
1966 (set-mode-motion-handler 'gnus-Group-mode foo-vline@)
|
|
1967 (set-mode-motion-handler 'gnus-Subject-mode foo-vline@)
|
|
1968 (set-mode-motion-handler 'gnus-group-mode foo-vline@)
|
|
1969 (set-mode-motion-handler 'gnus-subject-mode foo-vline@)
|
|
1970 (set-mode-motion-handler 'gnus-summary-mode foo-vline@)
|
|
1971 (set-mode-motion-handler 'dired-mode foo-line@)
|
|
1972 (set-mode-motion-handler 'compilation-mode foo-line@)
|
|
1973 (set-mode-motion-handler 'occur-mode foo-line@)
|
|
1974 (set-mode-motion-handler 'tar-mode foo-vline@)
|
|
1975 (set-mode-motion-handler 'rmail-summary-mode foo-vline@)
|
|
1976 (set-mode-motion-handler 'vm-summary-mode (sect-handler "-line"))
|
|
1977 (set-mode-motion-handler 'tcl-mode (sect-handler "-tcl"))
|
|
1978 (set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo"))
|
|
1979 (set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line")))
|
|
1980 (setq default-motion-handler
|
|
1981 (or default-motion-handler (find-motion-handler foo-thing)))
|
|
1982 (or (get 'emacs-lisp-mode 'mode-motion-handler)
|
|
1983 (set-mode-motion-handler 'emacs-lisp-mode foo-thing))
|
|
1984 (or (get 'lisp-interaction-mode 'mode-motion-handler)
|
|
1985 (set-mode-motion-handler 'lisp-interaction-mode foo-thing))
|
|
1986 (or (get 'c-mode 'mode-motion-handler)
|
|
1987 (set-mode-motion-handler 'c-mode foo-c))
|
|
1988 (or (get 'c++-mode 'mode-motion-handler)
|
|
1989 (set-mode-motion-handler 'c++-mode foo-c))
|
|
1990 (or (get 'c++-c-mode 'mode-motion-handler)
|
|
1991 (set-mode-motion-handler 'c++-c-mode foo-c))
|
|
1992 (or (get 'tex-mode 'mode-motion-handler)
|
|
1993 (set-mode-motion-handler 'tex-mode foo-LaTeX))
|
|
1994 (or (get 'latex-mode 'mode-motion-handler)
|
|
1995 (set-mode-motion-handler 'latex-mode foo-LaTeX))
|
|
1996 (or (get 'Buffer-menu-mode 'mode-motion-handler)
|
|
1997 (set-mode-motion-handler 'Buffer-menu-mode foo-vline@))
|
|
1998 (or (get 'Electric-Buffer-menu-mode 'mode-motion-handler)
|
|
1999 (set-mode-motion-handler 'Electric-Buffer-menu-mode foo-vline@))
|
|
2000 (or (get 'gnus-Group-mode 'mode-motion-handler)
|
|
2001 (set-mode-motion-handler 'gnus-Group-mode foo-vline@))
|
|
2002 (or (get 'gnus-Subject-mode 'mode-motion-handler)
|
|
2003 (set-mode-motion-handler 'gnus-Subject-mode foo-vline@))
|
|
2004 (or (get 'gnus-group-mode 'mode-motion-handler)
|
|
2005 (set-mode-motion-handler 'gnus-group-mode foo-vline@))
|
|
2006 (or (get 'gnus-subject-mode 'mode-motion-handler)
|
|
2007 (set-mode-motion-handler 'gnus-subject-mode foo-vline@))
|
|
2008 (or (get 'gnus-summary-mode 'mode-motion-handler)
|
|
2009 (set-mode-motion-handler 'gnus-summary-mode foo-vline@))
|
|
2010 (or (get 'dired-mode 'mode-motion-handler)
|
|
2011 (set-mode-motion-handler 'dired-mode foo-line@))
|
|
2012 (or (get 'compilation-mode 'mode-motion-handler)
|
|
2013 (set-mode-motion-handler 'compilation-mode foo-line@))
|
|
2014 (or (get 'occur-mode 'mode-motion-handler)
|
|
2015 (set-mode-motion-handler 'occur-mode foo-line@))
|
|
2016 (or (get 'tar-mode 'mode-motion-handler)
|
|
2017 (set-mode-motion-handler 'tar-mode foo-vline@))
|
|
2018 (or (get 'rmail-summary-mode 'mode-motion-handler)
|
|
2019 (set-mode-motion-handler 'rmail-summary-mode foo-vline@))
|
|
2020 (or (get 'vm-summary-mode 'mode-motion-handler)
|
|
2021 (set-mode-motion-handler 'vm-summary-mode (sect-handler "-line")))
|
|
2022 (or (get 'tcl-mode 'mode-motion-handler)
|
|
2023 (set-mode-motion-handler 'tcl-mode (sect-handler "-tcl")))
|
|
2024 (or (get 'texinfo-mode 'mode-motion-handler)
|
|
2025 (set-mode-motion-handler 'texinfo-mode (sect-handler "-TeXinfo")))
|
|
2026 (or (get 'cvs-mode 'mode-motion-handler)
|
|
2027 (set-mode-motion-handler 'cvs-mode (sect-handler "-cvs-line"))))))
|
|
2028
|
|
2029 ;; Null Handlers (for disabling motion highlighting)
|
|
2030 (defun thing-null (here) nil)
|
|
2031 (make-motion-handler 'no-thing 'thing-null)
|
|
2032 (make-motion-handler 'no-c 'thing-null)
|
|
2033 (make-motion-handler 'no-laTeX 'thing-null)
|
|
2034 (make-motion-handler 'no-line 'thing-null)
|
|
2035 (make-motion-handler 'no-line@ 'thing-null)
|
|
2036 (make-motion-handler 'no-vline 'thing-null)
|
|
2037 (make-motion-handler 'no-vline@ 'thing-null)
|
|
2038 (make-motion-handler 'no-tcl 'thing-null)
|
|
2039 (make-motion-handler 'no-TeXinfo 'thing-null)
|
|
2040 (make-motion-handler 'no-cvs-line 'thing-null)
|
|
2041
|
|
2042 (defun mode-motion-init ()
|
|
2043 "enable mode-motion+ package"
|
|
2044 (interactive)
|
|
2045
|
|
2046 (setq mode-motion-last-extent nil)
|
|
2047
|
|
2048 (global-set-key '(meta button2) 'mode-motion-copy)
|
|
2049 (global-set-key '(meta shift button2) 'mode-motion-move)
|
|
2050 (global-set-key '(meta control button2) 'mode-motion-kill)
|
|
2051 (global-set-key '(meta control shift button2) 'mode-motion-copy-as-kill)
|
|
2052 (global-set-key '(meta control symbol button2) 'mode-motion-copy-as-kill)
|
|
2053
|
|
2054 (if mode-motion-setup-cut-and-paste-bindings
|
|
2055 (progn
|
|
2056 (global-set-key 'f16 'mode-motion-copy-as-kill) ; Copy
|
|
2057 (global-set-key 'f18 'yank) ; Paste
|
|
2058 (global-set-key 'f20 'mode-motion-kill))) ; Cut
|
|
2059
|
|
2060 ;; I don't want the thing-boundaries function select whitespaces
|
|
2061 (setq thing-report-whitespace nil thing-report-char-p nil)
|
|
2062
|
|
2063 ;; bold motion face (bold, if this is not the default, unbold otherwise)
|
|
2064 (if (find-face 'motion-bold)
|
|
2065 ()
|
|
2066 (make-face 'motion-bold)
|
|
2067 (make-face-bold 'motion-bold)
|
|
2068 (or (face-differs-from-default-p 'motion-bold)
|
|
2069 (make-face-unbold 'motion-bold)))
|
|
2070
|
|
2071 ;; an underline face
|
|
2072 (if (find-face 'motion-underline)
|
|
2073 ()
|
|
2074 (make-face 'motion-underline)
|
|
2075 (set-face-underline-p 'motion-underline t))
|
|
2076
|
|
2077 ;; an inverted face
|
|
2078 (if (find-face 'motion-inverted)
|
|
2079 ()
|
|
2080 (make-face 'motion-inverted)
|
|
2081 (make-face-bold 'motion-inverted)
|
|
2082 (invert-face 'motion-inverted))
|
|
2083
|
|
2084 (if (find-face 'motion-gray)
|
|
2085 ()
|
|
2086 (make-face 'motion-gray)
|
|
2087 (set-face-background-pixmap 'motion-gray "gray1.xbm"))
|
|
2088
|
|
2089 ;; Motion Handlers
|
|
2090
|
|
2091 ;; Special Minibuffer handler
|
|
2092
|
|
2093 (make-motion-handler 'minibuffer 'minibuffer-selection-boundaries 'highlight t nil)
|
|
2094
|
|
2095 ;; Things
|
|
2096 (make-motion-handler 'bold-thing 'thing-boundaries 'motion-bold)
|
|
2097 (make-motion-handler 'gray-thing 'thing-boundaries 'motion-gray)
|
|
2098 (make-motion-handler 'highlight-thing 'thing-boundaries 'highlight)
|
|
2099 (make-motion-handler 'invert-thing 'thing-boundaries 'motion-inverted)
|
|
2100 (make-motion-handler 'underline-thing 'thing-boundaries 'motion-underline)
|
|
2101
|
|
2102 ;; Lines
|
|
2103 (make-motion-handler 'bold-line 'line-boundaries 'motion-bold)
|
|
2104 (make-motion-handler 'gray-line 'line-boundaries 'motion-gray)
|
|
2105 (make-motion-handler 'highlight-line 'line-boundaries 'highlight)
|
|
2106 (make-motion-handler 'invert-line 'line-boundaries 'motion-inverted)
|
|
2107 (make-motion-handler 'underline-line 'line-boundaries 'motion-underline)
|
|
2108 (make-motion-handler 'bold-line@ 'line-boundaries 'motion-bold t t)
|
|
2109 (make-motion-handler 'gray-line@ 'line-boundaries 'motion-gray nil t)
|
|
2110 (make-motion-handler 'highlight-line@ 'line-boundaries 'highlight nil t)
|
|
2111 (make-motion-handler 'invert-line@ 'line-boundaries 'motion-inverted nil t)
|
|
2112 (make-motion-handler 'underline-line@ 'line-boundaries 'motion-underline nil t)
|
|
2113
|
|
2114 ;; Visible text of line
|
|
2115 (make-motion-handler 'bold-vline 'visible-line-boundaries 'motion-bold)
|
|
2116 (make-motion-handler 'gray-vline 'visible-line-boundaries 'motion-gray)
|
|
2117 (make-motion-handler 'highlight-vline 'visible-line-boundaries 'highlight)
|
|
2118 (make-motion-handler 'invert-vline 'visible-line-boundaries 'motion-inverted)
|
|
2119 (make-motion-handler 'underline-vline 'visible-line-boundaries 'motion-underline)
|
|
2120 (make-motion-handler 'bold-vline@ 'visible-line-boundaries 'motion-bold t t)
|
|
2121 (make-motion-handler 'gray-vline@ 'visible-line-boundaries 'motion-gray nil t)
|
|
2122 (make-motion-handler 'highlight-vline@ 'visible-line-boundaries 'highlight nil t)
|
|
2123 (make-motion-handler 'invert-vline@ 'visible-line-boundaries 'motion-inverted nil t)
|
|
2124 (make-motion-handler 'underline-vline@ 'visible-line-boundaries 'motion-underline nil t)
|
|
2125
|
|
2126 ;; CVS lines
|
|
2127 (make-motion-handler 'bold-cvs-line 'cvs-line-boundaries 'motion-bold)
|
|
2128 (make-motion-handler 'gray-cvs-line 'cvs-line-boundaries 'motion-gray)
|
|
2129 (make-motion-handler 'highlight-cvs-line 'cvs-line-boundaries 'highlight)
|
|
2130 (make-motion-handler 'invert-cvs-line 'cvs-line-boundaries 'motion-inverted)
|
|
2131 (make-motion-handler
|
|
2132 'underline-cvs-line 'cvs-line-boundaries 'motion-underline)
|
|
2133
|
|
2134 ;; (La)TeX
|
|
2135 (make-motion-handler 'bold-LaTeX 'latex-boundaries 'motion-bold)
|
|
2136 (make-motion-handler 'gray-LaTeX 'latex-boundaries 'motion-gray)
|
|
2137 (make-motion-handler 'highlight-LaTeX 'latex-boundaries 'highlight)
|
|
2138 (make-motion-handler 'invert-LaTeX 'latex-boundaries 'motion-inverted)
|
|
2139 (make-motion-handler 'underline-LaTeX 'latex-boundaries 'motion-underline)
|
|
2140
|
|
2141 ;; TeXinfo
|
|
2142 (make-motion-handler 'bold-TeXinfo 'texinfo-boundaries 'motion-bold)
|
|
2143 (make-motion-handler 'gray-TeXinfo 'texinfo-boundaries 'motion-gray)
|
|
2144 (make-motion-handler 'highlight-TeXinfo 'texinfo-boundaries 'highlight)
|
|
2145 (make-motion-handler 'invert-TeXinfo 'texinfo-boundaries 'motion-inverted)
|
|
2146 (make-motion-handler 'underline-TeXinfo 'texinfo-boundaries 'motion-underline)
|
|
2147
|
|
2148 ;; C and C++
|
|
2149 (make-motion-handler 'bold-c 'c-boundaries 'motion-bold)
|
|
2150 (make-motion-handler 'gray-c 'c-boundaries 'motion-gray)
|
|
2151 (make-motion-handler 'highlight-c 'c-boundaries 'highlight)
|
|
2152 (make-motion-handler 'invert-c 'c-boundaries 'motion-inverted)
|
|
2153 (make-motion-handler 'underline-c 'c-boundaries 'motion-underline)
|
|
2154
|
|
2155 ;; Tcl/Tk
|
|
2156 (make-motion-handler 'bold-tcl 'tcl-boundaries 'motion-bold)
|
|
2157 (make-motion-handler 'gray-tcl 'tcl-boundaries 'motion-gray)
|
|
2158 (make-motion-handler 'highlight-tcl 'tcl-boundaries 'highlight)
|
|
2159 (make-motion-handler 'invert-tcl 'tcl-boundaries 'motion-inverted)
|
|
2160 (make-motion-handler 'underline-tcl 'tcl-boundaries 'motion-underline)
|
|
2161
|
|
2162 ;; mouse tracker
|
|
2163 (make-motion-handler 'track-mouse@ 'char-boundaries nil nil t)
|
|
2164 (make-motion-handler 'highlight-char 'char-boundaries 'highlight)
|
|
2165
|
|
2166 ;; augment the basic mouse motion handler (if any)
|
|
2167 (setq-default mode-motion-hook
|
|
2168 (if (listp mode-motion-hook)
|
|
2169 (if (memq #'mode-motion+-highlight mode-motion-hook)
|
|
2170 mode-motion-hook
|
|
2171 (append mode-motion-hook (list #'mode-motion+-highlight)))
|
|
2172 (list mode-motion-hook #'mode-motion+-highlight)))
|
|
2173
|
|
2174 (or mode-motion+-religion
|
|
2175 (setq mode-motion+-religion (if (x-display-color-p) 'underline 'invert)))
|
|
2176
|
|
2177 (add-menu '("Options") (car mode-motion+-options-menu)
|
|
2178 (cdr mode-motion+-options-menu)
|
|
2179 "Paren Highlighting")
|
|
2180
|
|
2181 ;; shut your eyes, this is a kludge. I didn't have time to find/write
|
|
2182 ;; a function to do this.
|
|
2183 (or (member ["Eval Motion Region" mode-motion-eval-region t]
|
|
2184 lisp-interaction-mode-popup-menu)
|
|
2185 (and (setq lisp-interaction-mode-popup-menu
|
|
2186 (copy-sequence lisp-interaction-mode-popup-menu))
|
|
2187 (setcdr (nthcdr 1 lisp-interaction-mode-popup-menu)
|
|
2188 (cons ["Eval Motion Region" mode-motion-eval-region t]
|
|
2189 (nthcdr 2 lisp-interaction-mode-popup-menu)))))
|
|
2190
|
|
2191 (or (member ["Eval Motion Region" mode-motion-eval-region t]
|
|
2192 emacs-lisp-mode-popup-menu)
|
|
2193 (and (setq emacs-lisp-mode-popup-menu
|
|
2194 (copy-sequence emacs-lisp-mode-popup-menu))
|
|
2195 (setcdr (nthcdr 3 emacs-lisp-mode-popup-menu)
|
|
2196 (cons ["Eval Motion Region" mode-motion-eval-region t]
|
|
2197 (nthcdr 4 emacs-lisp-mode-popup-menu)))))
|
|
2198
|
|
2199 ;; Clear the last active motion extent when leaving a frame.
|
|
2200 (if (boundp 'mouse-leave-frame-hook)
|
|
2201 (add-hook 'mouse-leave-frame-hook 'mode-motion-clear-last-extent)
|
|
2202 (add-hook 'mouse-leave-screen-hook 'mode-motion-clear-last-extent))
|
|
2203
|
|
2204 (run-hooks 'mode-motion+-load-hook)
|
|
2205 (mode-motion-init-handlers-according-to-religion)
|
|
2206
|
|
2207 (if (interactive-p) (message "mode-motion+ enabled")))
|
|
2208
|
|
2209 (if (and (not purify-flag)
|
|
2210 (or (not (boundp 'opt-mode-motion+)) opt-mode-motion+))
|
|
2211 (mode-motion-init))
|
|
2212
|
|
2213 (provide 'mode-motion+)
|
|
2214 ;; end mode-motion+
|