;; -*- Syntax: Emacs-Lisp; Mode: emacs-lisp -*-;;;; Per mode and per buffer mouse tracking with highlighting;;;; Copyright (C) 1992, 1993 by Guido Bosch <Guido.Bosch@loria.fr>;; This file is written in GNU Emacs Lisp, It is a part of XEmacs.;; The software contained in this file is free software; you can;; redistribute it and/or modify it under the terms of the GNU General;; Public License as published by the Free Software Foundation; either;; version 2, or (at your option) any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs; see the file COPYING. If not, write to;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.;;;;; Synched up with: Not in FSF.;; Please send bugs and comments to Russell.Ritchie@gssec.bt.co.uk or;; tlp00@spg.amdahl.com.;;;; <DISCLAIMER>;; This program is still under development. Neither the author nor any;; of the maintainers accepts responsibility to anyone for the consequences of;; using it or for whether it serves any particular purpose or works;; at all.; Change History; Revision 3.16 Fri Jun 28 13:01:12 1996 ritchier@msc.ie; Stop multiple highlighting lossage with 19.14 release.; Revision 3.15 Thu Feb 15 14:26:34 GMT 1996 Russell.Ritchie@gssec.bt.co.uk; lisp-interaction-popup-menu => lisp-interaction-mode-popup-menu,; emacs-lisp-popup-menu => emacs-lisp-mode-popup-menu.; Revision 3.14 Tue Nov 14 11:14:38 GMT 1995 Russell.Ritchie@gssec.bt.co.uk; Made nil the default value for mode-motion-focus-on-window. Too many people; hate it when the cursor warps into Dired and GNUS buffers because some; window managers auto-raise the window with keyboard focus with predictably; nauseous results.; Revision 3.13 Thu Sep 14 10:30:04 1995 Russell.Ritchie@gssec.bt.co.uk; Fix the `spontaneous scrolling' problem (at last). It's funny how; easy things are once you actually understand the issues involved.; As ever, what we sought was the right question...; Revision 3.12 Wed Jul 12 11:30:43 1995 Russell.Ritchie@gssec.bt.co.uk; Track `don't highlight non-file lines in dired buffers' functionality (in a; pretty tasteless manner if I say so myself :-)).; Revision 3.11 Fri Jul 7 16:26:56 1995 Russell.Ritchie@gssec.bt.co.uk; Minor extent detaching bug fix.; Revision 3.10 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk; Quiet, faster, non-interactive initialistion, mild list-motion-handlers; chrome and minor formatting clean-ups.; Revision 3.9 Thu Jun 15 11:36:56 1995 Russell.Ritchie@gssec.bt.co.uk; Fixed the `mouse-motion whilst reading filename in minibuffer auto-ftp' bug.; Revision 3.8 Thus Mar 23 1995 tlp00@spg.amdahl.com; added in menu controls from paquette@atomas.crim.ca; re-added minibuffer support (from 3.5);; Revision 3.7 Tue Feb 21 11:06:38 1995 Russell.Ritchie@gssec.bt.co.uk; Extended mode-motion+-religion and made the defaulting frame-buffer aware.; Reworked and added new mode-motion-handlers.; Doc string clean up.; Fixed unintentional frame/screen reversion.; Revision 3.6 Mon Feb 20 11:46:32 1995 Russell.Ritchie@gssec.bt.co.uk; Made mouse tracking use mode-motion-hook for better integration with; the default mouse-motion system (help-echo and friends now work).; Revision 3.5 1995/02/16 13:40:00 tlp00@spg.amdahl.com; fixed sporatic scroll bug; added M-button2 binding for mode-motion-copy;; Revision 3.4 1995/02/14 14:30:15 Russell.Ritchie@gssec.bt.co.uk; Small code cleanups: let* -> let, duplicate defvars.; Chromed list-motion-handlers a little.; Added variable mode-motion+-religion for easy choice twixt underline & bold.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tlp00 changes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; tlp00@spg.amdahl.com 2/11/93; modified mode-motion-track-pointer to move cursor cross windows; renamed mode-motion-delete to mode-motion-kill to follow kill; convention; mode-motion-highlight-with-handler to put cursor at beginning of line ; follow operations.; mode-motion-copy/delete and mode-motion-kill to position cursor at ; delete point start. Also set this-command to avoid appends; set mode-motion-extent priority to 1, so it will override font-lock; changed default handlers for buffer-mode, c-mode, dired-mode, added occur ; and compilation mode.; fixed bug in minibuffer-selection-boundaries where C-g was leaving the wrong; syntax table.; added support for pending-delete.; adds the copy/delete motion-extent to the clipboard even if kill-hooks is nil.;; Revision 3.3 1995/02/13 tlp00@spg.amdahl.com; merged Russell.Ritchie@gssec.bt.co.uk versions with molli/bosch versions; renamed versioning 3.0+ for molli/bosch versions. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Russell Ritchie changes;;;;;;;;;;;;;;;;;;;;;;;;; !Log: mode-motion+.el,v !; Revision 2.14.R 1994/09/09 10:19:18 rieke@darmstadt.gmd.de; Merged in my changes to support motion-gray. This needs a file; named "gray1.xbm" in your data-directory (etc) like the following.; -------------------------------snip--------------------------; #define bg2_width 16; #define bg2_height 16; static char bg2_bits[] = {; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,; 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00};; -------------------------------snip--------------------------; This one looks good on SUN 19'' screens with 10x20 font, ; black foreground and khaki background. ; To use the gray-handlers instead of the underline-handlers; include the following into your .emacs:; (set-mode-motion-handler 'emacs-lisp-mode 'gray-thing); (set-mode-motion-handler 'lisp-interaction-mode 'gray-thing); (set-mode-motion-handler 'c++-mode 'gray-c); (set-mode-motion-handler 'c-mode 'gray-c); (set-mode-motion-handler 'tcl-mode 'gray-tcl); (set-mode-motion-handler 'dired-mode 'gray-line@); (set-mode-motion-handler 'gnus-group-mode 'gray-vline@); (set-mode-motion-handler 'gnus-summary-mode 'gray-vline@); (set-mode-motion-handler 'texinfo-mode 'gray-Texinfo); (setq default-motion-handler (find-motion-handler 'gray-thing));;; Revision 2.13.R 1994/08/08 19:47:34 Russell.Ritchie@gssec.bt.co.uk; Made default handler be underline-thing, as most bold fonts seem to; be greater in height than their corresponding normal versions,; causing irritating screen flicker.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Molli/bosch changes;;;;;;;;;;;;;;;;;;;;;;;;;; Revision 3.2 1994/09/28 15:14:29 molli; add "(set-mode-motion-handler 'latex-mode 'raise-LaTeX)". Barry; Waraw's C/C++ mode is now changed to cc-mode ...;; Revision 3.1 1994/09/28 15:10:36 molli; Initial revision;; Revision 2.15 1993/11/18 08:13:28 bosch; Constant `mode-motion+-version' added.; Minor bug fix in `tcl-forward-sexp1'.;; Revision 2.14 1993/10/29 20:04:59 bosch; Minibuffer name matching improved. Made `tcl-boundaries' smarter by; use of new function `tcl-forward-sexp1'. `tcl-commands' list updated; -- should be complete now. A message is printed if the syntax scanner; matched or failed for known tcl/tk commands. Separated `tcl-commands'; from `tk-commands' -- `tk-commands' not yet complete. New motion; handler `raise-LaTeX' added, for tex-mode.;; Revision 2.13 1993/10/08 09:43:00 bosch; New user option `mode-motion-setup-cut-and-paste-bindings'. Function; `mode-motion-copy/delete' now takes into account the primary and the; motion selection.;; Revision 2.12 1993/10/08 09:08:46 bosch; Avoid highlighting empty lines, even if; `mode-motion-highlight-lines-when-behind' is non-nil.; Revision 2.12 1994/07/07 18:33:38 Russell.Ritchie@gssec.bt.co.uk; Made list-motion-handlers and mode-motion-set-handler work in lemacs-19.10.; ; Revision 2.11 1993/09/20 08:29:15 bosch; Code reorganized: variables declared before used.; Compatibility hack patched again.;; Revision 2.10 1993/09/17 18:50:33 bosch; Bug in the compatibility hack fixed. Call to `make-cursor' replaced by; `x-pointer-cache'. Compatibility hack for Lemacs 19.8 removed. Tcl; motion handler improved (needs still some work).;; Revision 2.9 1993/09/15 17:52:53 bosch; Compatibility patch for Lucid Emacs 19.8. tcl motion handler added.;; Revision 2.8 1993/08/27 15:17:07 bosch; Select window conflict between motion handlers and process filters; resolved by using `enqueue-eval-event' for selecting a different; window (functions `mode-motion-track-pointer' and; `mode-motion-highlight-with-handler' modified). This fixes the nasty; bug that made GNUS hanging during NNTP activity while the mouse was; moved.;; Revision 2.7 1993/08/27 12:50:10 bosch; TeX and LaTeX motion handler generalized. Motion handler; `highlight-Texinfo' added.;; Revision 2.6 1993/06/24 11:58:52 bosch; Mode motion+ support for pcl-cvs added. #undef syntax for C added.;; Revision 2.5 1993/06/09 12:04:31 bosch; Delivery motion handlers for `c++-c-mode', `gnus-group-mode', and; `gnus-summary-mode' added. Mode motion commands bound to copy/cut/past; keys for Sun keyboards (f16, f18, f20). Comment added.;; Revision 2.4 1993/02/15 12:59:47 bosch; Modifications sent by Tibor Polgar integrated:; Optional parameter added to `mode-motion-copy/delete'. User option; `mode-motion-focus-on-window' added. It controls window selection for; the motion handlers. Minor changes of the delivery motion handlers.;; Revision 2.3 1993/02/04 18:10:09 bosch; User option `mode-motion-minibuffer-completion' added. It controls; the minibuffer completion highlighting.;; Revision 2.2 1993/01/27 13:08:12 bosch; Improved clearing of `sticky' mode-motion-extents when leaving screen; or buffer. Function `mode-motion-clear-extent' added.; Highlight line mouse cursor is behind.; `mode-motion-highlight-with-handler' now takes an event as argument.; Cut and paste functions renamed and rewritten. Now they are called:; `mode-motion-move', `mode-motion-delete', `mode-motion-copy',; `mode-motion-copy-as-kill'. Bug fixes in the C scanner stuff.; Motion handler `underline-c' added.;; Revision 2.1 1993/01/19 18:29:58 bosch; Scanner and motion handler for C syntax added.; Function `set-default-motion-handler' added.; Minor improvements on the `list-motion-handlers' interface done.; Minor bug fixes.;; Revision 2.0 1993/01/14 19:17:29 bosch; Lot of things rewritten and reorganized. This version fits in only; one file (beside the required package thing.el).;; New basic features are:; - buffer, mode and default motion handlers; - easy composition of own motion handlers; - listing of motion handlers in tabular form; - menu interface for changing motion handlers; - only two elisp files: mode-motion+.el, thing.el; (require'thing)(require'mode-motion)(defconstmode-motion+-version"3.16");;; This file defines a set of mouse motion handlers that do some;;; highlighting of the text when the mouse moves over.;;; An exhaustive list of the motion handlers defined in this file may be;;; obtained with M-x list-motion-handlers.;;; User Options and their Custommisation;;;;;; Mode-motion+ provides four user options, defined beyond. See their;;; documentation string to know what they are good for. If you want;;; to modify their default values, just setq them in your ~/.emacs.(defvarmode-motion+-religionnil; Initialised in mode-motion-init."*Default highlight religion: one of bold, gray, highlight, invert or underline.Unless you setq this otherwise, it defaults to underline when(x-display-color-p) is non-nil and invert otherwise.Setting it to 'highlight should cause mode-motion+ extents to beindistinguishable from any other type of highlighted extent which may or maynot be advisable, depending on your point of view.")(defvarmode-motion-highlight-lines-when-behindt"*If non-nil highlight the whole line if the mouse is past the end.")(defvarmode-motion-focus-on-windownil"*Controls whether moving the mouse into another window selects this window.The following values are possible:nil - Window selection isn't influenced at all by mode motion.t - Window selection always follows the mouse cursor. Copying motion active regions doesn't work any longer between different buffers.any other - window selection follows the mouse cursor if the motion handler of the buffer under the mouse has the follow-point property set. Useful for selecting line mode buffers just by moving the mouse inside in order to execute commands there (VM summary, GNUS Group and Subject, DIRED, Buffer menu etc.)")(defvarmode-motion-setup-cut-and-paste-bindingst"*If non-nil, bind commands to the Copy, Paste and Cut keys.");; Options sub-menu for mode-motion+(defvarmode-motion+-options-menu'("Motion Highlighting""For Current Buffer""---"["None"(progn(set-buffer-motion-handler(current-buffer)'no-thing)(mode-motion-clear-extent)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'no):active(mode-motion+-active-p)]["Bold"(progn(modify-buffer-motion-handler(current-buffer)'bold)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'bold):active(mode-motion+-active-p)]["Underline"(progn(modify-buffer-motion-handler(current-buffer)'underline)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'underline):active(mode-motion+-active-p)]["Gray"(progn(modify-buffer-motion-handler(current-buffer)'gray)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'gray):active(mode-motion+-active-p)]["Highlight"(progn(modify-buffer-motion-handler(current-buffer)'highlight)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'highlight):active(mode-motion+-active-p)]["Invert"(progn(modify-buffer-motion-handler(current-buffer)'invert)):styleradio:selected(eq(mode-motion+-buffer-handler-religion(current-buffer))'invert):active(mode-motion+-active-p)]"---""For Current Mode""---"["None"(progn(set-mode-motion-handlermajor-mode'no-thing)(mode-motion-clear-extent)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'no):active(mode-motion+-active-p)]["Bold"(progn(modify-mode-motion-handlermajor-mode'bold)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'bold):active(mode-motion+-active-p)]["Underline"(progn(modify-mode-motion-handlermajor-mode'underline)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'underline):active(mode-motion+-active-p)]["Gray"(progn(modify-mode-motion-handlermajor-mode'gray)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'gray):active(mode-motion+-active-p)]["Highlight"(progn(modify-mode-motion-handlermajor-mode'highlight)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'highlight):active(mode-motion+-active-p)]["Invert"(progn(modify-mode-motion-handlermajor-mode'invert)):styleradio:selected(eq(mode-motion+-mode-handler-religionmajor-mode)'invert):active(mode-motion+-active-p)]"---""For All""---"["None"(progn(setqmode-motion+-religion'no)(mode-motion-init-handlers-according-to-religion'force)(mode-motion-clear-extent)):styleradio:selected(eqmode-motion+-religion'no):active(mode-motion+-active-p)]["Bold"(progn(setqmode-motion+-religion'bold)(mode-motion-init-handlers-according-to-religion'force)):styleradio:selected(eqmode-motion+-religion'bold):active(mode-motion+-active-p)]["Underline"(progn(setqmode-motion+-religion'underline)(mode-motion-init-handlers-according-to-religion'force)):styleradio:selected(eqmode-motion+-religion'underline):active(mode-motion+-active-p)]["Gray"(progn(setqmode-motion+-religion'gray)(mode-motion-init-handlers-according-to-religion'force)):styleradio:selected(eqmode-motion+-religion'gray):active(mode-motion+-active-p)]["Highlight"(progn(setqmode-motion+-religion'highlight)(mode-motion-init-handlers-according-to-religion'force)):styleradio:selected(eqmode-motion+-religion'highlight):active(mode-motion+-active-p)]["Invert"(progn(setqmode-motion+-religion'invert)(mode-motion-init-handlers-according-to-religion'force)):styleradio:selected(eqmode-motion+-religion'invert):active(mode-motion+-active-p)]"---"["Minibuffer highlighting"(setqmode-motion-use-minibuffer-motion-handler(notmode-motion-use-minibuffer-motion-handler)):styletoggle:selectedmode-motion-use-minibuffer-motion-handler]["Customize..."(list-motion-handlers)t;; nil]["Revert Customization"(call-interactively'mode-motion+-motion-hook-revert)(and(boundp'mode-motion+-previous-hook)mode-motion+-previous-hook)])"Menu for changing mode-motion+ religion and other things.")(defunmode-motion+-active-p()(cond((symbolpmode-motion-hook)(eqmode-motion-hook'mode-motion+-highlight))((listpmode-motion-hook)(memq'mode-motion+-highlightmode-motion-hook))(tnil)))(defunmode-motion+-buffer-handler-religion(buffer)(let*((current-handler-name(symbol-name(motion-handler-name(get-current-motion-handler))))(religion-name(substringcurrent-handler-name0(string-match"-"current-handler-name))))(intern-softreligion-name)))(defunmode-motion+-mode-handler-religion(buffer)(let*((mode-handler(or(getmajor-mode'mode-motion-handler)default-motion-handler))(current-handler(symbol-name(motion-handler-namemode-handler)))(religion(substringcurrent-handler0(string-match"-"current-handler))))(intern-softreligion)))(defunmodify-buffer-motion-handler(bufferreligion)(let*((current-handler(symbol-name(motion-handler-name(get-current-motion-handler))))(suffix(substringcurrent-handler(string-match"-"current-handler))))(set-buffer-motion-handlerbuffer(intern-soft(concat(symbol-namereligion)suffix)))))(defunmodify-mode-motion-handler(modereligion)(let*((mode-handler(or(getmajor-mode'mode-motion-handler)default-motion-handler))(current-handler(symbol-name(motion-handler-namemode-handler)))(suffix(substringcurrent-handler(string-match"-"current-handler))))(set-mode-motion-handlermode(intern-soft(concat(symbol-namereligion)suffix)))));;;; This does not work. I would like to be able to modify in-place;;;; the non-selectable items, but I don't know how.;;;; --paquette, Wed Mar 8 23:32:32 1995 (Marc Paquette) ;;; Sensitize the mode motion+ options submenu, a la;;; sensitize-file-and-edit-menus-hook.(defunmode-motion+-sensitize-options-menu-hook()"Hook function that will adjust title items in the mode-motion+ submenu in Options"(let*((mm+-menu(cdr(car(find-menu-itemcurrent-menubar'("Options""Motion Highlighting")))))(buffer-item(find-menu-itemmm+-menu'("For Current Buffer")))(mode-item(find-menu-itemmm+-menu'("For Current Mode"))))(setcarbuffer-item(format"For Buffer `%s'"(buffer-namenil)))(setcarmode-item(format"For Mode `%s'"major-mode))nil));;(add-hook 'activate-menubar-hook 'mode-motion+-sensitize-options-menu-hook);; Motion Handler Format:;; ;; A motion handler is vector with the following format ;; [<name> - a symbol;; <region computing function> - a function or name of function ;; that returns (<startpos> . <endpos>) ;; or nil.;; <face or face name> - as it says ...;; <highlight-p> - non-nil means that the motion extent;; will be highlighted using the function ;; `highlight-extent';; <follow-point-p> - non-nil means that point will follow the;; mouse motion. ;; ];; accessor functions(defsubstmotion-handler-name(handler)(arefhandler0))(defsubstmotion-handler-boundary-function(handler)(arefhandler1))(defsubstmotion-handler-face(handler)(arefhandler2))(defsubstmotion-handler-highlight(handler)(arefhandler3))(defsubstmotion-handler-follow-point(handler)(arefhandler4));; modifier functions(defsubstset-motion-handler-boundary-function(handlerx)(asethandler1x))(defsubstset-motion-handler-face(handlerx)(asethandler2x))(defsubstset-motion-handler-highlight(handlerx)(asethandler3x))(defsubstset-motion-handler-follow-point(handlerx)(asethandler4x));; Internal global variables (defvarmotion-handler-alist()"Alist with entries of the form \(<name> . <handler>\).");; Minibuffer motion handler(defvarmode-motion-use-minibuffer-motion-handlert"*Enable mousable highlighting when the minibuffer is active. When false only extents with thehighlight property are selectable (*Completion*)")(defvarmode-motion-extentnil)(make-variable-buffer-local'mode-motion-extent)(defvarbuffer-motion-handlernil)(make-variable-buffer-local'buffer-motion-handler)(defvarmode-motion-last-extentnil"The last used mode motion extent.")(defvardefault-motion-handlernil); Initialised in mode-motion-init.;; Creation of motion handlers(defunfind-motion-handler(name)(or(symbolpname)(setqname(intern-softname)))(cdr(assqnamemotion-handler-alist)));; internal motion handler creator(defsubstmake-motion-handler-internal(nameboundary-functionfacehighlightfollow-cursor)(vectornameboundary-function(get-faceface)highlightfollow-cursor))(defunmake-motion-handler(nameboundary-function&optionalfacehighlightfollow-cursor)"Create a motion handler named NAME (a symbol or string) using REGION-FUNCTION.REGION-FUNCTION is the function that computes the region to be highlighted. Optional arguments are: FACE: A face or face name to be used to highlight the region computed by REGION-FUNCTION. 'default is the default.HIGHLIGHT: Flag that indicates whether the highlight attribute of the mode-motion-extent should be set or not. If FACE is the default face, HIGHLIGHT defaults to t, otherwise to nil.FOLLOW-CURSOR: Flag that indicates whether the cursor should follow the mouse motion. Default is nil.";; required arguments(orname(error"motion handler name required."))(or(symbolpname)(stringpname)(error"motion handler name must be a string or symbol: %s"name))(orboundary-function(error"motion handler region function required."))(or(fboundpboundary-function)(error"not a function: %s."boundary-function));; defaults(orface(setqface'default));; store the mode motion handler on the 'mode-motion-handler property of;; its name symbol(let((old-handler(cdr(assqnamemotion-handler-alist)))new-handler)(ifold-handler(progn(set-motion-handler-boundary-functionold-handlerboundary-function)(set-motion-handler-faceold-handler(get-faceface))(set-motion-handler-highlightold-handlerhighlight)(set-motion-handler-follow-pointold-handlerfollow-cursor))(setqmotion-handler-alist(cons(consname(setqnew-handler(make-motion-handler-internalnameboundary-function(get-faceface)highlightfollow-cursor)))motion-handler-alist)))(orold-handlernew-handler)))(defvarlist-motion-handlers-buffer-to-customizenil"Name of buffer from where list-motion-handlers was called.")(make-variable-buffer-local'list-motion-handlers-buffer-to-customize)(defvarlist-motion-handlers-buffer-modenil"Name of mode of buffer from where list-motion-handlers was called.")(make-variable-buffer-local'list-motion-handlers-buffer-mode);; Listing available motion handlers in tabular form. (defvarbasic-motion-handlers(list'mode-motion-highlight-line'mode-motion-highlight-word'mode-motion-highlight-symbol'mode-motion-highlight-sexp)"The basic motion handlers provided by the underlying XEmacs.")(defunlist-motion-handlers()"Display a list of available motion handlers.The listing is in tabular form and contains the following columns:NAME: the motion handlers name,BOUNDARY FUNCTION: the name of the function used to compute the text highlighted by the motion handler,FACE: the face used to highlight the text.Additionally, the following flags are used at the beginning of each line:`*' Marks the motion handler current to the buffer this functions was called from.`H' Force highlighting of the selected text.`F' Make point follow the mouse cursor as it moves."(interactive)(let((current-handler(get-current-motion-handler))(buffer(current-buffer))(buffer-modemajor-mode)(bmmh(if(symbolpmode-motion-hook)(car(memqmode-motion-hookbasic-motion-handlers))(if(and(listpmode-motion-hook)(equal1(lengthmode-motion-hook)))(car(memq(carmode-motion-hook)basic-motion-handlers))))))(save-excursion(with-output-to-temp-buffer"*Mouse Motion Handlers*"(let((truncate-linest))(set-buffer"*Mouse Motion Handlers*")(setqlist-motion-handlers-buffer-to-customizebuffer)(setqlist-motion-handlers-buffer-modebuffer-mode)(let((pos15)(pos225)(pos350)(handlers(sort(mapcar'cdrmotion-handler-alist)'(lambda(xy)(string<(symbol-name(motion-handler-boundary-functionx))(symbol-name(motion-handler-boundary-functiony)))))))(ifbmmh(let((i1)(fw(frame-width)))(while(<ifw)(princ"*")(setqi(1+i)))(princ"\nNote: this buffer is not using mode-motion+.\n\n")(princ"It's using the `")(princbmmh)(princ"' motion handler which claims it's:\n")(insert(documentationbmmh))(princ"\nSetting this motion handler will be irrevocable from this interface\n(but only for duration of this XEmacs session).\n")(setqi1)(while(<ifw)(princ"*")(setqi(1+i)))(terpri)))(princ" NAME BOUNDARY FUNCTION FACE\n")(princ" ---- ----------------- ----\n")(mapcar#'(lambda(handler)(let((line-start(point)))(princ(if(and(notbmmh)(eqhandlercurrent-handler))"*"" "))(princ(if(eqhandlerdefault-motion-handler)"D"" "))(princ(if(motion-handler-highlighthandler)"H"" "))(princ(if(motion-handler-follow-pointhandler)"F"" "))(indent-to-columnpos11)(princ(motion-handler-namehandler))(indent-to-columnpos21)(princ(motion-handler-boundary-functionhandler))(indent-to-columnpos3)(let((face-start(point)))(princ(face-name(motion-handler-facehandler)))(let((line-extent(make-extentline-startface-start))(face-extent(make-extentface-start(point))))(set-extent-faceface-extent(motion-handler-facehandler))(set-extent-propertyface-extent'mode-motion-handler(motion-handler-namehandler))(set-extent-propertyline-extent'mode-motion-handler(motion-handler-namehandler))(set-extent-propertyline-extent'highlightt)))(terpri)))handlers)(princ(format"Flags: `D' the default motion handler `H' handler with highlighting `F' handler with `following' property `*' the motion handler of buffer \"%s\""list-motion-handlers-buffer-to-customize))))(local-set-key'button3'mode-motion-set-handler)(setqbuffer-read-onlyt)))))(defunmode-motion-set-handler(event)(interactive"@e")(let*((handler(or(extent-property(extent-at(event-pointevent)(current-buffer)'mode-motion-handler)'mode-motion-handler)(error"Click on highlighted line to select a handler")))(menu(list(format"Make `%s' the Motion Handler of :"handler)(vector(format"Buffer %s"list-motion-handlers-buffer-to-customize)(`(set-buffer-motion-handler'(,list-motion-handlers-buffer-to-customize)'(,handler)))t)(vector"Another Buffer..."(`(motion-handler-list-set-buffer-handler'(,handler)))t)"---"(vector(format"Mode %s"list-motion-handlers-buffer-mode)(`(progn(set-mode-motion-handler'(,list-motion-handlers-buffer-mode)'(,handler))(save-excursion(mapcar(function(lambda(buf)(set-bufferbuf)(and(eq'(,list-motion-handlers-buffer-mode)major-mode)(mode-motion+-hook-installbuft))))(buffer-list)))))t)(vector"Another Mode..."(`(motion-handler-list-set-mode-handler'(,handler)))t)"---"(vector"Default Motion Handler"(`(set-default-motion-handler'(,handler)))t))))(popup-menumenu)))(defunmotion-handler-list-set-buffer-handler(handler)(let((buffer(read-buffer-name(format"Make `%s' the motion handler of buffer: "handler)(buffer-namelist-motion-handlers-buffer-to-customize))))(set-buffer-motion-handlerbufferhandler)(save-excursion(set-bufferbuffer)(and(not(cond((listpmode-motion-hook)(memq'mode-motion+-highlightmode-motion-hook))((symbolpmode-motion-hook)(eq'mode-motion+-highlightmode-motion-hook))(tt)))(y-or-n-p(format"Augment the default mode motion hook for `%s'? "(buffer-namenil)))(mode-motion+-hook-installbuffert)))))(defvarmode-motion+-previous-hooknil"Value of previous `mode-motion-hook' in current buffer.")(make-variable-buffer-local'mode-motion+-previous-hook)(defunmotion-handler-list-set-mode-handler(handler)(let((mode(intern(completing-read(format"Make `%s' the motion handler of mode: "handler)obarray'fboundpt(symbol-namelist-motion-handlers-buffer-mode)))))(set-mode-motion-handlermodehandler)(save-excursion(mapcar(function(lambda(buf)(set-bufferbuf)(and(eqmodemajor-mode)(mode-motion+-hook-installbuft))))(buffer-list)))))(defunmode-motion+-hook-install(&optionalbufferremove-highlight-line-p)"Add `mode-motion+-highlight' to the BUFFER `mode-motion-hook'.If the optional second arg REMOVE-HIGHLIGHT-LINE-P is t, remove`mode-motion-highlight-line' from `mode-motion-hook'.See `mode-motion+-hook-uninstall' for reverting this operation."(interactive"bInstall mode-motion+ hook for buffer :XRemove highlight-line from hook ? :");; Check for the mode-motion-hook value to make sure it's under;; the control of mode-motion+.;; The reasonning here is that if the user went trough the hassles;; of list-motion-handlers (or if he's calling this directly from;; his .emacs) , he is prepared to give up on the current;; mode-motion-hook.;; However, we keep the previous hook value in a buffer-local;; variable: it will be then possible to revert to the old motion;; handling behavior with `mode-motion+-hook-uninstall'.;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)(setqbuffer(orbuffer(current-buffer)));; force the uninstall of mode-motion-highlight since if its second;; you'll never see ours.(setqremove-highlight-line-pt)(save-excursion(set-bufferbuffer)(if(boundp'mode-motion-hook)(progn(setqmode-motion+-previous-hook(cond((sequencepmode-motion-hook)(copy-sequencemode-motion-hook))(tmode-motion-hook)));; Make sure that the mode-motion+-highlight is not saved in;; the variable, otherwise, we could not revert back to the;; "factory settings" after having played with different;; handlers;; --paquette, Mon Feb 27 08:54:21 1995 (Marc Paquette)(remove-hook'mode-motion+-previous-hook'mode-motion+-highlight)))(add-hook'mode-motion-hook'mode-motion+-highlight)(andremove-highlight-line-p;; Remove the standard mode-motion-highlight hook because we;; provide an alternative to this. I don't use setq here because;; something else could be hooked to mode-motion-hook.;; --paquette, Mon Feb 27 08:53:51 1995 (Marc Paquette)(remove-hook'mode-motion-hook'mode-motion-highlight-line))(andmode-motion-extent(delete-extentmode-motion-extent)(setqmode-motion-extentnil));; Try to make this installed for any buffer of this mode(let((this-mode-hook(intern-soft(concat(symbol-namemajor-mode)"-hook"))))(and(boundpthis-mode-hook)(ifremove-highlight-line-p(add-hookthis-mode-hook#'(lambda()(mode-motion+-hook-installnilt))'append)(add-hookthis-mode-hook'mode-motion+-hook-install'append)))))mode-motion-hook)(defunmode-motion+-hook-uninstall(buffer)"Restore the value of `mode-motion-hook' in BUFFER to what it was at the time `mode-motion+-hook-install' was called.See also `mode-motion+-hook-install'."(interactive"bRestore `mode-motion-hook' of buffer :");; Check for the mode-motion-hook value to make sure it's under;; the control of mode-motion+.;; The reasonning here is that if the user went trough the hassles;; of list-motion-handlers (or if he's calling this directly from;; his .emacs) , he is prepared to give up on the current;; mode-motion-hook.;; However, we keep the previous hook value in a buffer-local;; variable: it will be then possible to revert to the old motion;; handling behavior with `mode-motion+-hook-uninstall'.;; --paquette, Mon Feb 27 08:54:30 1995 (Marc Paquette)(save-excursion(set-bufferbuffer)(andmode-motion-extent(delete-extentmode-motion-extent)(setqmode-motion-extentnil))(if(boundp'mode-motion+-previous-hook)(progn(setqmode-motion-hookmode-motion+-previous-hook)(setqmode-motion+-previous-hooknil)(let((this-mode-hook(intern-soft(concat(symbol-namemajor-mode)"-hook"))))(and(boundpthis-mode-hook)(remove-hookthis-mode-hook'mode-motion+-hook-install))))(error"No previous value for mode-motion-hook")))mode-motion-hook)(defunmode-motion+-motion-hook-revert(&optionalbuffer-only-pbuffermode)"Revert the `mode-motion-hook' to its original value.With optional arg BUFFER-ONLY-P non-nil, only revert in BUFFER\(defaults to `\(current-buffer\)'\); otherwise, revert for all existingbuffers of MODE \(defaults to `major-mode' of BUFFER\)."(interactive(let*((buffer-only-p(y-or-n-p"Revert mode-motion-hook only for current buffer ? "))(buffer(ifbuffer-only-p(current-buffer)(get-buffer(read-buffer-name"Revert mode-motion-hook of buffer : "(buffer-name(current-buffer))))))(mode(ifbuffer-only-p(save-excursion(set-bufferbuffer)major-mode)(intern-soft(completing-read"Major mode: "obarray'fboundpnil(symbol-namemajor-mode))))))(listbuffer-only-pbuffermode)))(ifbuffer-only-p(mode-motion+-hook-uninstallbuffer)(save-excursion(mapcar(function(lambda(buf)(set-bufferbuf)(and(eqmodemajor-mode)(mode-motion+-hook-uninstallbuf))))(buffer-list)))));; Setting buffer, mode and default motion handlers(defunset-buffer-motion-handler(bufferhandler-name)"Make the motion handler named HANDLER-NAME (a symbol) the buffermotion handler of BUFFER. If HANDLER-NAME is nil, the correspondingbuffer motion handler is removed. If HANDLER-NAME isn't the name of aknown motion handler, an error is signaled. When called interactively,completion is provided for available buffers and motion handlers. 1.\) buffer motion handler 2.\) mode motion handler 3.\) default motion handler"(interactive(list(read-buffer-name"Set motion handler of buffer: "(buffer-name(current-buffer)))(read-motion-handler-name)));; kill old mode motion extent, because the new handler;; might want to initialize it differently(ifmode-motion-extent(progn(detach-extentmode-motion-extent)(setqmode-motion-extentnil)))(orbuffer(setqbuffer(current-buffer)))(or(get-bufferbuffer)(error"No such buffer: %s"buffer))(save-excursion(set-bufferbuffer)(setqbuffer-motion-handler;; remove it if `nil'(andhandler-name;; set the handler if known(or(find-motion-handlerhandler-name);; error otherwise(error"Not a known motion handler: %s"handler-name)))))(if(interactive-p)(ifhandler-name(message"Motion handler for buffer %s is `%s'."(current-buffer)handler-name)(message"Motion handler removed for buffer %s."(current-buffer))))handler-name)(defunread-buffer-name(prompt&optionalinitial-input)(completing-readprompt(mapcar#'(lambda(buf)(list(buffer-namebuf)))(buffer-list));; don't take buffers that start with a blank#'(lambda(list)(not(eq(aref(carlist)0)?)))tinitial-input))(defunset-mode-motion-handler(modehandler-name)"Make the motion handler named HANDLER-NAME (a symbol) the mode motionhandler for all buffers with major-mode MODE. If HANDLER-NAME is nil,the corresponding mode motion handler is removed. If HANDLER-NAMEisn't the name of a known motion handler, an error is signaled. Whencalled interactively, completion is provided for available motionhandlers. 1.\) buffer motion handler 2.\) mode motion handler 3.\) default motion handler"(interactive(list(intern(completing-read"Major mode: "obarray'fboundpnil(symbol-namemajor-mode)))(read-motion-handler-name)));; kill old mode motion extent, because the new handler;; might want to initialize it differently(ifmode-motion-extent(progn(detach-extentmode-motion-extent)(setqmode-motion-extentnil)))(putmode'mode-motion-handler;; remove it if `nil'(andhandler-name;; set the handler if known(or(find-motion-handlerhandler-name);; error otherwise(error"Not a known mode motion handler: %s"handler-name))))(if(interactive-p)(ifhandler-name(message"Motion handler for %s is `%s'."modehandler-name)(message"Mode motion handler for %s removed."mode)))handler-name)(defunset-default-motion-handler(handler-name)"Make the motion handler named HANDLER-NAME (a symbol) the default.If HANDLER-NAME is nil, the current default motion handler is removed. IfHANDLER-NAME isn't the name of a known motion handler, an error issignalled. When called interactively, completion is provided for availablemotion handlers.The motion handler used in a given buffer is determined by the followingmost-specific first list: buffer motion handler, mode motion handler, defaultmotion handler."(interactive(list(read-motion-handler-name)));; kill old mode motion extent, because the new handler;; might want to initialize it differently(ifmode-motion-extent(progn(detach-extentmode-motion-extent)(setqmode-motion-extentnil)))(setqdefault-motion-handler;; remove it if `nil'(andhandler-name;; set the handler if known(or(find-motion-handlerhandler-name);; error otherwise(error"Not a known motion handler: %s"handler-name))))(if(interactive-p)(ifhandler-name(message"Default motion handler is `%s'."handler-name)(message"Default motion handler removed.")))handler-name)(defunread-motion-handler-name()(intern-soft(completing-read"Motion handler: "(mapcar#'(lambda(entry)(list(symbol-name(carentry))))motion-handler-alist)nilt)));; clear the last active motion extent when leaving a frame.(defunmode-motion-clear-extent(&optionalextent)"Clear EXTENT, i.e. make it have no visible effects on the frame.EXTENT defaults to the current buffer's mode-motion-extent."(orextent(setqextentmode-motion-extent))(andextent(extent-live-pextent)(not(extent-detached-pextent))(extent-bufferextent)(buffer-name(extent-bufferextent))(progn;; unhighlight it (highlight-extentextentnil);; make it span a region that isn't visible and selectable;; Can this be done more elegantly? (detach-extentextent))))(defunmode-motion-clear-last-extent(&optionalframe)"Clear the mode-motion-last-extent."(or(popup-up-p)(mode-motion-clear-extentmode-motion-last-extent)))(defunmode-motion+-highlight(event)"Highlight the thing under the mouse using a mode-specific motion handler.See list-motion-handlers for more details."(mode-motion-clear-last-extent)(and(event-bufferevent)(cond((andmouse-grabbed-buffer;; first try to do minibuffer specific highlighting(find-motion-handler'minibuffer)(let((mode-motion-highlight-lines-when-behindnil))(and(event-pointevent)(or(extent-at(event-pointevent)(event-bufferevent)'highlight)(mode-motion-highlight-with-handler(find-motion-handler'minibuffer)event))))))(t(mode-motion-highlight-with-handler(get-current-motion-handler)event))));; Return nil since now this is used as a hook, and we want to let;; any other hook run after us.nil)(defunget-current-motion-handler()(or(and(boundp'buffer-motion-handler)buffer-motion-handler)(getmajor-mode'mode-motion-handler)default-motion-handler))(defunmode-motion-highlight-with-handler(handlerevent);; Perform motion highlighting using HANDLER. Information about the;; current mouse position is taken form EVENT. (andhandler(let((point(event-pointevent))(buffer(event-bufferevent))(window(event-windowevent))(window-config(current-window-configuration))(buffer-save(current-buffer))(point-save(point))region);; save-window-excursion and restore buffer(unwind-protect(progn(andbuffer(set-bufferbuffer)(select-windowwindow));; Create a new mode-motion-extent if there isn't one ;; (or a destroyed one)(if(and(extent-live-pmode-motion-extent)(extent-buffermode-motion-extent))()(setqmode-motion-extent(make-extentnilnilbuffer))(set-extent-prioritymode-motion-extent1))(if(and;; compute the region to be highlighted(setqregion(ifpoint;; compute the mode-motion region using the ;; handlers boundary function(condition-casenil;; c(funcall(motion-handler-boundary-functionhandler)point);; Messages that appear during computing the;; region may be displayed not done;; here because it's rather disturbing(error;; (setq message (format "%s" (car (cdr c))))nil));; otherwise highlight the whole line mouse is;; behind but only if the line isn't empty(ifmode-motion-highlight-lines-when-behind(unwind-protect(progn;; (message "%s" (event-window event))(move-to-window-line(if(and(=emacs-major-version19)(<emacs-minor-version12))(-(event-yevent)(nth1(window-edgeswindow)))(event-yevent)))(beginning-of-line)(if(=(following-char)?\n);; empty line ()(thing-region(point)(progn(end-of-line);; for `follow-point' behavoir(setqpoint(point));; fetch also the newline, if any;; -- handy for copying >1 line(if(eobp)point(1+point))))))(goto-charpoint-save)))));; (message "region: %s" region);; the region might be in reverse order. Stop in this case(<=(carregion)(cdrregion)))(if(or(not(motion-handler-follow-pointhandler))(pos-visible-in-window-ppoint))(progn(set-extent-endpointsmode-motion-extent(carregion)(cdrregion))(set-extent-facemode-motion-extent(motion-handler-facehandler));; make point follow the mouse or point to;; the beginning of the line do not move the;; cursor if a mark is set.(cond((and(motion-handler-follow-pointhandler)(not(mark)))(goto-charpoint);; kludge to keep the cursor out the way(if(or(eq(motion-handler-boundary-functionhandler)'line-boundaries)(eq(motion-handler-boundary-functionhandler)'visible-line-boundaries))(beginning-of-line))))(if(andmode-motion-focus-on-window(or(eqmode-motion-focus-on-windowt)(motion-handler-follow-pointhandler)));; Select the current window FROM OUTSIDE the;; `save-window-excursion' that surrounds the call;; to the current function. This also avoids;; conflicts with running process filters.(enqueue-eval-event'select-window(selected-window)));; snap in effect, but it ain't yet workin';; (message "X: %sl; Y: %s"(event-x event)(event-y event));; (and motion-handler-snap-in;; (set-mouse-position;; (window-frame (event-window event));; (event-x event);; (event-y event)))(setqmode-motion-last-extentmode-motion-extent);; signal successt));; signal failiurenil))(set-window-configurationwindow-config)(set-bufferbuffer-save)))));; Motion Event debugging;;;; Useful to see what information is available from motion events(defundebug-motion-handler(event)(let*((window(event-windowevent))(frame(or(event-frameevent)(selected-frame)))(buffer(andwindow(event-bufferevent)))(point(andbuffer(event-pointevent))))(with-output-to-temp-buffer"*Debug Motion Handler Output*"(princ(format"\ Window: %s Frame: %s Buffer: %s (event-x, event-y): (%s, %s) (event-x-pixel, event-y-pixel): (%s, %s) Point: %s Timestamp: %s"windowframebuffer(event-xevent)(event-yevent)(event-x-pixelevent)(event-y-pixelevent)point(event-timestampevent))))));(let ((mouse-motion-handler 'debug-motion-handler); (temp-buffer-show-function nil)); (read-char));; Set of copy/kill/move functions for usage with highlighted regions(put'mode-motion-move'pending-deletet)(put'mode-motion-copy'pending-deletet)(defunmode-motion-move()"Move the motion active region to point."(interactive)(mode-motion-insert-text(mode-motion-copy/deletet)))(defunmode-motion-kill()"Kill the motion active region and push it onto the kill ring."(interactive)(mode-motion-copy/deletettt))(defunmode-motion-copy()"Copy the motion active region to point."(interactive)(mode-motion-insert-text(mode-motion-copy/delete)))(defunmode-motion-copy-as-kill()"Delete the motion active region and push it onto the kill ring.Set point to the place where deletion happened."(interactive)(mode-motion-copy/deletenilt)(message"Text copied to the to ring and cut buffer."))(defunmode-motion-copy/delete(&optionaldeletecopy-as-killset-point)"Return the string that is designated by the current motion active region. Arguments are: EVENT - a mouse click event used to identify the buffer and window &optional DELETE - delete the motion active text region COPY-AS-KILL - copy the string to the kill ring SET-POINT - set point to the start of the motion active region."(let((old-buf(current-buffer))(old-window(selected-window)))(unwind-protect(let((extent(orprimary-selection-extent(and(extentpmode-motion-last-extent)(not(extent-propertymode-motion-last-extent'detached))mode-motion-last-extent))))(if(and(extentpextent)(set-buffer(extent-bufferextent))(not;; zero length extents(=(extent-start-positionextent)(extent-end-positionextent))))(let*((start(extent-start-positionextent))(end(extent-end-positionextent))(text(buffer-substring(extent-start-positionextent)(extent-end-positionextent))))(cond(copy-as-kill(copy-region-as-killstartend)(if(or(notkill-hooks)(eqkill-hooks'ignore))(progn(x-own-selection-internal'PRIMARYtext)(x-own-clipboardtext)))))(cond(delete(kill-regionstartend)(x-own-selection-internal'PRIMARYtext);; (select-window window)(ifset-point(goto-charstart))))(setqthis-command'mode-motion+)text)(error"No current primary or motion selection.")))(set-bufferold-buf)(select-windowold-window))))(defunmode-motion-insert-text(text)"Insert TEXT at point. Also insert one space if the preceding character is a word constituent or a closing paren."(ortext(error"No highlighted text to copy."))(let((prec-char-syntax(char-syntax(preceding-char))))(if(memqprec-char-syntax'(?w?\)))(insert" "))(inserttext)));; Boundary functions;;;; The following functions are already provided by the thing package:;; thing-boundaries;; thing-symbol;; thing-word(defunchar-boundaries(point)(thing-regionpoint(1+point)))(defunvisible-line-boundaries(point)(save-excursion(goto-charpoint)(beginning-of-line)(skip-chars-forward" \t")(if(and(eqmajor-mode'dired-mode)(save-excursion(dired-move-to-filename)))(let((start(point)))(end-of-line)(skip-chars-backward" \t")(thing-regionstart(point))))))(defunline-boundaries(point)(save-excursion(goto-charpoint)(beginning-of-line)(if(and(eqmajor-mode'dired-mode)(save-excursion(dired-move-to-filename)))(let((start(point)))(end-of-line)(thing-regionstart(point))))))(defuncvs-line-boundaries(point)(save-excursion(goto-charpoint)(beginning-of-line)(if(looking-at"^[* ] ")(thing-region(point)(progn(end-of-line)(point))))))(defunlatex-boundaries(here)(setq*last-thing*'sexp)(tex-boundarieshere?\\"a-zA-Z";; begin-fwd-regexp"\\\\begin *{ *\\([a-z]*\\) *}";; end-fwd-regexp"\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)";; begin-bwd-regexp"\\\\end *{ *\\([a-z]*\\) *}";; begin-bwd-regexp"\\(\\\\end *{ *%s *}\\)\\|\\(\\\\begin *{ *%s *}\\)";; param-cmd-regexp"\\\\[a-zA-Z]+[ \n\t]*{"))(defvartexinfo-paired-commands(mapconcat'identity'("enumerate""example""group""ifinfo""iftex""ignore""itemize""menu""quotation""table""tex""titlepage")"\\|"))(defvartexinfo-begin-fwd-regexp(format"@\\(%s\\)"texinfo-paired-commands))(defvartexinfo-end-bwd-regexp(format"@end *\\(%s\\)"texinfo-paired-commands))(defuntexinfo-boundaries(here)(tex-boundarieshere?@"a-z"texinfo-begin-fwd-regexp;; end-fwd-regexp"\\(@end *%s\\)\\|\\(@%s\\)";; end-bwd-regexptexinfo-end-bwd-regexp;; begin-bwd-regexp"\\(@end *%s\\)\\|\\(@%s\\)";; param-cmd-regexp"@\\(TeX\\|[a-zA]+\\)[ \n\t]*{"))(defuntex-boundaries(herecmd-start-charactercmd-word-characterbegin-fwd-regexpend-fwd-regexpend-bwd-regexpbegin-bwd-regexpparam-cmd-regexp)"Generic TeX dialect scanner.Parameters: cmd-start-character: character that starts a command (`\' in (La)TeX, `@' in Texinfo)cmd-word-character: regexpression to be used by the function `skip-chars-backward' allowing to skip over command characters other than `cmd-start-character'begin-fwd-regexp: regexpression matching the begin part of a text stretch, used in forward search. end-fwd-regexp: regexpression matching the end part of a text stretch, used in forward searchend-bwd-regexp: regexpression matching the end part of a text stretch, used in backward search.begin-bwd-regexp: regexpression matching the begin part of a text stretch, used in backward search.param-cmd-regexp: regexpression matching a parameterized command \(including the open parenthesis\)"(save-excursion(goto-charhere)(cond((=(following-char)cmd-start-character)(forward-char1))((=(char-syntax(following-char))?w)(skip-chars-backwardcmd-word-character)))(if(/=(preceding-char)cmd-start-character)(thing-boundarieshere)(forward-char-1)(catch'return(cond((looking-atbegin-fwd-regexp)(let*((start(point))(env(buffer-substring(match-beginning1)(match-end1)))(regexp(formatend-fwd-regexpenvenv))(count0))(while(re-search-forwardregexpnilt)(cond((match-beginning2); \begin(setqcount(1+count)))((match-beginning1); \end(setqcount(1-count))(if(=count0)(throw'return(thing-regionstart(point)))))))))((looking-atend-bwd-regexp)(let*((end(match-end0))(env(buffer-substring(match-beginning1)(match-end1)))(regexp(formatbegin-bwd-regexpenvenv))(count1))(while(re-search-backwardregexpnilt)(cond((match-beginning1); \end(setqcount(1+count)))((match-beginning2); \begin(setqcount(1-count))(if(=count0)(throw'return(thing-region(point)end))))))));; tex macros of the form \cmd {...}((looking-atparam-cmd-regexp)(thing-region(point)(progn(goto-char(1-(match-end0)))(forward-sexp1)(point))));; fetch the current macro (with backslash)(t(thing-region(point)(progn(forward-word1)(point)))))))));; special parse of buffer for valid selectable info(defunminibuffer-selection-boundaries(point)(let((old-syntax(syntax-table)))(unwind-protect(progn;; best syntax table for recognizing symbols(set-syntax-tableemacs-lisp-mode-syntax-table)(let((file-completion(eqminibuffer-completion-table'read-file-name-internal))regionminibuf-string;contents of minibufferbuffer-string;string to be highlighted (or not)prefix;prefix calculated from minibuf-stringstring;string to be verified in the;completion table )(and(setqregion(iffile-completion(thing-filenamepoint)(thing-symbolpoint)))(setqminibuf-string; contents of minibuffer(save-excursion(set-buffermouse-grabbed-buffer)(buffer-string))buffer-string; string to be highlighted (or not)(buffer-substring(carregion)(cdrregion))prefix(iffile-completion(file-name-nondirectoryminibuf-string)minibuf-string)string(iffile-completion(concat(file-name-directoryminibuf-string)buffer-string)buffer-string))(if(or(and(fboundp'ange-ftp-ftp-path)(or(ange-ftp-ftp-pathbuffer-string)(ange-ftp-ftp-pathstring)))(and(fboundp'efs-ftp-path)(or(efs-ftp-pathbuffer-string)(efs-ftp-pathstring))));; #### Like our counterpart in mode-motion: evil evil evilt(iffile-completion(try-completionstringminibuffer-completion-tableminibuffer-completion-predicate)(eq't(try-completionstringminibuffer-completion-tableminibuffer-completion-predicate))));; the result is the region to be highlightedregion)))(set-syntax-tableold-syntax))));; C source code scanner (defvarc-statement-starting-keyword-regexpr"\\(if\\|for\\|while\\|do\\|switch\\|break\\|continue\\)\\b")(defunc-boundaries(here)(setq*last-thing*'sexp)(save-excursion(goto-charhere)(let((following-char(following-char))(preceding-char(preceding-char))aux)(if(=(char-syntaxfollowing-char)?w)(progn(skip-chars-backward"a-zA-Z")(setqaux(point))(skip-chars-backward"\n\t ")(if(=(preceding-char)?#)(forward-char-1)(goto-charaux))))(if(and(=following-char?*)(=preceding-char?/))(forward-char-1))(if(and(=following-char?/)(=preceding-char?*))(forward-char-1))(cond((=(following-char)?#)(c-scan-preproc-macros))((looking-at"/\\*"); begin comment(let((start(match-beginning0)))(if(search-forward"*/"nilt)(thing-regionstart(match-end0)))))((looking-at"\\*/"); end comment(let((end(match-end0)))(if(search-backward"/*"nilt)(thing-region(match-beginning0)end))))((looking-atc-statement-starting-keyword-regexpr); if for while do etc(thing-region(match-beginning0)(c-forward-statement(buffer-substring(match-beginning1)(match-end1)))))((looking-at"else\\b")(thing-region(match-beginning0)(c-forward-else)))(t(if(=(char-syntax(following-char))?.)(thing-regionhere(1+here))(thing-boundarieshere)))))))(defunc-scan-preproc-macros()(cond((looking-at"^#[ \n\t]*include[ \n\t]*[<\"][^>\"]*[>\"]"); #include(thing-region(match-beginning0)(match-end0)))((looking-at"^#[ \n\t]*\\(define\\|undef\\)"); #define, #undef(thing-region(match-beginning0)(progn(end-of-line)(while(=(preceding-char)?\\)(forward-line1)(end-of-line))(point))));; #if, #ifdef, #ifndef, #else, #elif((looking-at"^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|else\\|elif\\)\\b")(let((start(match-beginning0))(counter1)match)(goto-char(match-end0))(while(and(>=counter1)(re-search-forward"^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"nilt))(setqmatch(buffer-substring(match-beginning1)(match-end1)))(setqcounter(if(string=match"endif")(1-counter)(1+counter))))(if(=counter0)(thing-regionstart(match-end0)))))((looking-at"^#[ \n\t]*endif\\b"); #endif(let((end(match-end0))(counter1)match)(goto-char(match-beginning0))(while(and(>=counter1)(re-search-backward"^#[ \n\t]*\\(if\\|ifdef\\|ifndef\\|endif\\)\\b"nilt))(setqmatch(buffer-substring(match-beginning1)(match-end1)))(setqcounter(if(string=match"endif")(1+counter)(1-counter))))(if(=counter0)(thing-region(match-beginning0)end))))))(defunc-skip-over-comment()(let((aux(point)))(skip-chars-forward"\n\t ")(or(and(=(following-char)?/)(=(char-after(1+(point)))?*)(search-forward"*/"nilt)(point))(goto-charaux))))(defunc-forward-statement(&optionalkeyword)(c-skip-over-comment)(skip-chars-forward" \n\t")(orkeyword(setqkeyword(if(looking-atc-statement-starting-keyword-regexpr)(buffer-substring(match-beginning1)(match-end1)))))(ifkeyword(cond((string=keyword"if")(c-forward-if))((string=keyword"do")(c-forward-do-while))((memberkeyword'("for""while""switch"))(c-forward-for/while/switch))((memberkeyword'("break""continue"))(c-forward-break/continue)))(cond((=(following-char)?\{)(forward-list1)(point))(t;; Here I use that each C statement other then ;; a bloc, if, while, for, do ... ends in a `;'(let(char)(catch'exit(whilet(if(eobp)(throw'exitnil))(setqchar(following-char))(cond((=(char-syntaxchar)?.)(forward-char1)(if(=char?\;)(throw'exit(point))))(t(forward-sexp1)(skip-chars-forward" \n\t"))))))))))(defunc-forward-if()(let(aux)(forward-word1); if(forward-list1)(c-forward-statement)(setqaux(point))(skip-chars-forward"\n\t ")(if(looking-at"else\\b")(c-forward-else)(goto-charaux))))(defunc-forward-else()(forward-word1); else(c-forward-statement))(defunc-forward-for/while/switch()(forward-word1); for(forward-list1)(c-forward-statement))(defunc-forward-do-while()(forward-word1); do ... while(c-forward-statement)(c-forward-for/while/switch))(defunc-forward-switch()(forward-word1); switch(forward-list2)(point))(defunc-forward-break/continue()(forward-word1); keyword(c-skip-over-comment)(skip-chars-forward"\n\t ")(if(=(following-char)?\;)(goto-char(1+(point)))));; Tcl syntax scanner(defvartcl-builtin-commandsnil"Alist of information about tcl syntax for the tcl-boundaries function. An entry has the form \(<command-string> . <syntax description>\) where <command-string> is the name of a tcl command <syntax description> is one of list of integers: the number of possible arguments t: any number of arguments")(defconsttcl-commands'(("append".(2.nil))("array".(2.3))("break".0)("case".3)("catch".1)("cd".1)("close".1)("concat".t)("continue".0)("else".(1.nil))("elseif".(1.nil))("eof".1)("error".t)("eval".t)("exec".t)("exit".(0.1))("expr".1)("file".(2.nil))("flush".1)("for".4)("foreach".3)("format".(1.nil))("gets".(1.2))("glob".t)("global".(1.nil))("history".t)("if".(2.nil))("incr".(1.2))("info".(1.4))("join".(1.2))("lappend".(2.nil))("lindex".2)("linsert".(3.nil))("list".t)("llength".1)("lrange".3)("lreplace".(3.nil))("lsearch".2)("lsort".1)("open".(1.2))("proc".3)("puts".(1.3))("pwd".0)("read".(1.2))("regexp".(2.nil))("regsub".(4.6))("rename".2)("return".(0.1))("scan".(3.nil))("seek".(2.3))("set".(1.2))("source".1)("split".(1.2))("string".(2.4))("tell".1)("time".(1.2))("trace".(1.nil))("unknown".(1.nil))("unset".(1.nil))("uplevel".(1.nil))("upvar".(2.nil))("while".2)))(defconsttk-commands'(("bind".3)("button".t)("canvas".t)("frame".t)("label".t)("listbox".t)("menu".t)("menubutton".t)("pack".t)("scrollbar".t)("tree".t)("wm".t)))(defconsttcl-tk-commands(nconctcl-commandstk-commands))(defconsttcl-tk-commands-regexp(format"\\(%s\\\)\\W"(mapconcat'cartcl-tk-commands"\\|")))(defuntcl-boundaries(here)(save-excursion(goto-charhere)(skip-chars-backward"a-z")(if(looking-attcl-tk-commands-regexp)(let*((count0)(start(point))(keyword(buffer-substring(match-beginning1)(match-end1)))(syntax-description(cdr(assockeywordtcl-tk-commands))))(goto-char(match-end0))(while(not(looking-at"[ \t]*[]\n;}]"))(setqcount(1+count))(tcl-forward-sexp1);; skipping over the parentheses of array expressions:(while(not(or(looking-at"[ \t]*[]\n;}]")(=(char-syntax(following-char))?)))(tcl-forward-sexp1)))(if(cond((eqsyntax-descriptiont))((integerpsyntax-description)(=syntax-descriptioncount))((conspsyntax-description)(and(<=(carsyntax-description)count)(or(null(cdrsyntax-description))(<=count(cdrsyntax-description))))))(progn(message"`%s' matched."keyword)(thing-regionstart(point)))(progn(message"wrong syntax: `%s'."keyword)nil)))(message"")(thing-boundarieshere))))(defuntcl-forward-sexp(&optionalarg)"Move forward across one balanced tcl expression.With argument, do it that many times."(interactive"p")(if(<arg0)(error"negative argument not allowed"))(orarg(setqarg1))(while(>arg0)(tcl-forward-sexp1)(setqarg(1-arg))))(defuntcl-forward-sexp1()(interactive"")(let((start(point))next-charsyntax(first-scant))(setqnext-char(following-char)syntax(char-syntaxnext-char))(while(or(=next-char?\;)(memqsyntax'(??>)))(forward-char1)(setqnext-char(following-char)syntax(char-syntaxnext-char)))(condition-casevar(catch'exit(whilet(setqnext-char(following-char)syntax(char-syntaxnext-char))(cond((=next-char?\;)(throw'exitnil))((memqsyntax(iffirst-scan'(??>)'(??>?\))))(throw'exitnil))(t(goto-char(or(scan-sexps(point)1)(point-max)))))(setqfirst-scannil)))(error(goto-charstart)(error(car(cdrvar)))))));; (define-key tcl-mode-map "\M-\C-f" 'tcl-forward-sexp)(defunmode-motion-eval-func(eval-func)(let((old-buf(current-buffer))(old-window(selected-window)))(unwind-protect(let((extent(orprimary-selection-extent(and(extentpmode-motion-last-extent)(not(extent-propertymode-motion-last-extent'detached))mode-motion-last-extent))))(if(and(extentpextent)(set-buffer(extent-bufferextent))(not;; zero length extents(=(extent-start-positionextent)(extent-end-positionextent))))(let*((start(extent-start-positionextent))(end(extent-end-positionextent)))(funcalleval-funcstartend))(error"No current primary or motion selection.")))(set-bufferold-buf)(select-windowold-window))))(defunmode-motion-eval-region()(interactive)(mode-motion-eval-func'eval-region));; Motion highlight faces and initialization.(defunsect-handler(string)"Return the symbol corresponding to the foo-STRING handler for this sect."(intern-soft(concat(symbol-namemode-motion+-religion)string)))(defunmode-motion-init-handlers-according-to-religion(&optionalforcep)(interactive);; Initialise default motion handlers depending on religious sect!(let((foo-thing(sect-handler"-thing"))(foo-c(sect-handler"-c"))(foo-LaTeX(sect-handler"-laTeX"))(foo-line@(sect-handler"-line@"))(foo-vline@(sect-handler"-vline@")))(ifforcep(progn(setqdefault-motion-handler(find-motion-handlerfoo-thing))(set-mode-motion-handler'emacs-lisp-modefoo-thing)(set-mode-motion-handler'lisp-interaction-modefoo-thing)(set-mode-motion-handler'c-modefoo-c)(set-mode-motion-handler'c++-modefoo-c)(set-mode-motion-handler'c++-c-modefoo-c)(set-mode-motion-handler'tex-modefoo-LaTeX)(set-mode-motion-handler'latex-modefoo-LaTeX)(set-mode-motion-handler'Buffer-menu-modefoo-vline@)(set-mode-motion-handler'Electric-Buffer-menu-modefoo-vline@)(set-mode-motion-handler'gnus-Group-modefoo-vline@)(set-mode-motion-handler'gnus-Subject-modefoo-vline@)(set-mode-motion-handler'gnus-group-modefoo-vline@)(set-mode-motion-handler'gnus-subject-modefoo-vline@)(set-mode-motion-handler'gnus-summary-modefoo-vline@)(set-mode-motion-handler'dired-modefoo-line@)(set-mode-motion-handler'compilation-modefoo-line@)(set-mode-motion-handler'occur-modefoo-line@)(set-mode-motion-handler'tar-modefoo-vline@)(set-mode-motion-handler'rmail-summary-modefoo-vline@)(set-mode-motion-handler'vm-summary-mode(sect-handler"-line"))(set-mode-motion-handler'tcl-mode(sect-handler"-tcl"))(set-mode-motion-handler'texinfo-mode(sect-handler"-TeXinfo"))(set-mode-motion-handler'cvs-mode(sect-handler"-cvs-line")))(setqdefault-motion-handler(ordefault-motion-handler(find-motion-handlerfoo-thing)))(or(get'emacs-lisp-mode'mode-motion-handler)(set-mode-motion-handler'emacs-lisp-modefoo-thing))(or(get'lisp-interaction-mode'mode-motion-handler)(set-mode-motion-handler'lisp-interaction-modefoo-thing))(or(get'c-mode'mode-motion-handler)(set-mode-motion-handler'c-modefoo-c))(or(get'c++-mode'mode-motion-handler)(set-mode-motion-handler'c++-modefoo-c))(or(get'c++-c-mode'mode-motion-handler)(set-mode-motion-handler'c++-c-modefoo-c))(or(get'tex-mode'mode-motion-handler)(set-mode-motion-handler'tex-modefoo-LaTeX))(or(get'latex-mode'mode-motion-handler)(set-mode-motion-handler'latex-modefoo-LaTeX))(or(get'Buffer-menu-mode'mode-motion-handler)(set-mode-motion-handler'Buffer-menu-modefoo-vline@))(or(get'Electric-Buffer-menu-mode'mode-motion-handler)(set-mode-motion-handler'Electric-Buffer-menu-modefoo-vline@))(or(get'gnus-Group-mode'mode-motion-handler)(set-mode-motion-handler'gnus-Group-modefoo-vline@))(or(get'gnus-Subject-mode'mode-motion-handler)(set-mode-motion-handler'gnus-Subject-modefoo-vline@))(or(get'gnus-group-mode'mode-motion-handler)(set-mode-motion-handler'gnus-group-modefoo-vline@))(or(get'gnus-subject-mode'mode-motion-handler)(set-mode-motion-handler'gnus-subject-modefoo-vline@))(or(get'gnus-summary-mode'mode-motion-handler)(set-mode-motion-handler'gnus-summary-modefoo-vline@))(or(get'dired-mode'mode-motion-handler)(set-mode-motion-handler'dired-modefoo-line@))(or(get'compilation-mode'mode-motion-handler)(set-mode-motion-handler'compilation-modefoo-line@))(or(get'occur-mode'mode-motion-handler)(set-mode-motion-handler'occur-modefoo-line@))(or(get'tar-mode'mode-motion-handler)(set-mode-motion-handler'tar-modefoo-vline@))(or(get'rmail-summary-mode'mode-motion-handler)(set-mode-motion-handler'rmail-summary-modefoo-vline@))(or(get'vm-summary-mode'mode-motion-handler)(set-mode-motion-handler'vm-summary-mode(sect-handler"-line")))(or(get'tcl-mode'mode-motion-handler)(set-mode-motion-handler'tcl-mode(sect-handler"-tcl")))(or(get'texinfo-mode'mode-motion-handler)(set-mode-motion-handler'texinfo-mode(sect-handler"-TeXinfo")))(or(get'cvs-mode'mode-motion-handler)(set-mode-motion-handler'cvs-mode(sect-handler"-cvs-line"))))));; Null Handlers (for disabling motion highlighting)(defunthing-null(here)nil)(make-motion-handler'no-thing'thing-null)(make-motion-handler'no-c'thing-null)(make-motion-handler'no-laTeX'thing-null)(make-motion-handler'no-line'thing-null)(make-motion-handler'no-line@'thing-null)(make-motion-handler'no-vline'thing-null)(make-motion-handler'no-vline@'thing-null)(make-motion-handler'no-tcl'thing-null)(make-motion-handler'no-TeXinfo'thing-null)(make-motion-handler'no-cvs-line'thing-null)(defunmode-motion-init()"enable mode-motion+ package"(interactive)(setqmode-motion-last-extentnil)(global-set-key'(metabutton2)'mode-motion-copy)(global-set-key'(metashiftbutton2)'mode-motion-move)(global-set-key'(metacontrolbutton2)'mode-motion-kill)(global-set-key'(metacontrolshiftbutton2)'mode-motion-copy-as-kill)(global-set-key'(metacontrolsymbolbutton2)'mode-motion-copy-as-kill)(ifmode-motion-setup-cut-and-paste-bindings(progn(global-set-key'f16'mode-motion-copy-as-kill); Copy(global-set-key'f18'yank); Paste(global-set-key'f20'mode-motion-kill))); Cut;; I don't want the thing-boundaries function select whitespaces (setqthing-report-whitespacenilthing-report-char-pnil);; bold motion face (bold, if this is not the default, unbold otherwise)(if(find-face'motion-bold)()(make-face'motion-bold)(make-face-bold'motion-bold)(or(face-differs-from-default-p'motion-bold)(make-face-unbold'motion-bold)));; an underline face(if(find-face'motion-underline)()(make-face'motion-underline)(set-face-underline-p'motion-underlinet));; an inverted face(if(find-face'motion-inverted)()(make-face'motion-inverted)(make-face-bold'motion-inverted)(invert-face'motion-inverted))(if(find-face'motion-gray)()(make-face'motion-gray)(set-face-background-pixmap'motion-gray"gray1.xbm"));; Motion Handlers;; Special Minibuffer handler(make-motion-handler'minibuffer'minibuffer-selection-boundaries'highlighttnil);; Things(make-motion-handler'bold-thing'thing-boundaries'motion-bold)(make-motion-handler'gray-thing'thing-boundaries'motion-gray)(make-motion-handler'highlight-thing'thing-boundaries'highlight)(make-motion-handler'invert-thing'thing-boundaries'motion-inverted)(make-motion-handler'underline-thing'thing-boundaries'motion-underline);; Lines(make-motion-handler'bold-line'line-boundaries'motion-bold)(make-motion-handler'gray-line'line-boundaries'motion-gray)(make-motion-handler'highlight-line'line-boundaries'highlight)(make-motion-handler'invert-line'line-boundaries'motion-inverted)(make-motion-handler'underline-line'line-boundaries'motion-underline)(make-motion-handler'bold-line@'line-boundaries'motion-boldtt)(make-motion-handler'gray-line@'line-boundaries'motion-graynilt)(make-motion-handler'highlight-line@'line-boundaries'highlightnilt)(make-motion-handler'invert-line@'line-boundaries'motion-invertednilt)(make-motion-handler'underline-line@'line-boundaries'motion-underlinenilt);; Visible text of line(make-motion-handler'bold-vline'visible-line-boundaries'motion-bold)(make-motion-handler'gray-vline'visible-line-boundaries'motion-gray)(make-motion-handler'highlight-vline'visible-line-boundaries'highlight)(make-motion-handler'invert-vline'visible-line-boundaries'motion-inverted)(make-motion-handler'underline-vline'visible-line-boundaries'motion-underline)(make-motion-handler'bold-vline@'visible-line-boundaries'motion-boldtt)(make-motion-handler'gray-vline@'visible-line-boundaries'motion-graynilt)(make-motion-handler'highlight-vline@'visible-line-boundaries'highlightnilt)(make-motion-handler'invert-vline@'visible-line-boundaries'motion-invertednilt)(make-motion-handler'underline-vline@'visible-line-boundaries'motion-underlinenilt);; CVS lines(make-motion-handler'bold-cvs-line'cvs-line-boundaries'motion-bold)(make-motion-handler'gray-cvs-line'cvs-line-boundaries'motion-gray)(make-motion-handler'highlight-cvs-line'cvs-line-boundaries'highlight)(make-motion-handler'invert-cvs-line'cvs-line-boundaries'motion-inverted)(make-motion-handler'underline-cvs-line'cvs-line-boundaries'motion-underline);; (La)TeX (make-motion-handler'bold-LaTeX'latex-boundaries'motion-bold)(make-motion-handler'gray-LaTeX'latex-boundaries'motion-gray)(make-motion-handler'highlight-LaTeX'latex-boundaries'highlight)(make-motion-handler'invert-LaTeX'latex-boundaries'motion-inverted)(make-motion-handler'underline-LaTeX'latex-boundaries'motion-underline);; TeXinfo(make-motion-handler'bold-TeXinfo'texinfo-boundaries'motion-bold)(make-motion-handler'gray-TeXinfo'texinfo-boundaries'motion-gray)(make-motion-handler'highlight-TeXinfo'texinfo-boundaries'highlight)(make-motion-handler'invert-TeXinfo'texinfo-boundaries'motion-inverted)(make-motion-handler'underline-TeXinfo'texinfo-boundaries'motion-underline);; C and C++(make-motion-handler'bold-c'c-boundaries'motion-bold)(make-motion-handler'gray-c'c-boundaries'motion-gray)(make-motion-handler'highlight-c'c-boundaries'highlight)(make-motion-handler'invert-c'c-boundaries'motion-inverted)(make-motion-handler'underline-c'c-boundaries'motion-underline);; Tcl/Tk(make-motion-handler'bold-tcl'tcl-boundaries'motion-bold)(make-motion-handler'gray-tcl'tcl-boundaries'motion-gray)(make-motion-handler'highlight-tcl'tcl-boundaries'highlight)(make-motion-handler'invert-tcl'tcl-boundaries'motion-inverted)(make-motion-handler'underline-tcl'tcl-boundaries'motion-underline);; mouse tracker(make-motion-handler'track-mouse@'char-boundariesnilnilt)(make-motion-handler'highlight-char'char-boundaries'highlight);; augment the basic mouse motion handler (if any)(setq-defaultmode-motion-hook(if(listpmode-motion-hook)(if(memq#'mode-motion+-highlightmode-motion-hook)mode-motion-hook(appendmode-motion-hook(list#'mode-motion+-highlight)))(listmode-motion-hook#'mode-motion+-highlight)))(ormode-motion+-religion(setqmode-motion+-religion(if(x-display-color-p)'underline'invert)))(add-menu'("Options")(carmode-motion+-options-menu)(cdrmode-motion+-options-menu)"Paren Highlighting");; shut your eyes, this is a kludge. I didn't have time to find/write;; a function to do this.(or(member["Eval Motion Region"mode-motion-eval-regiont]lisp-interaction-mode-popup-menu)(and(setqlisp-interaction-mode-popup-menu(copy-sequencelisp-interaction-mode-popup-menu))(setcdr(nthcdr1lisp-interaction-mode-popup-menu)(cons["Eval Motion Region"mode-motion-eval-regiont](nthcdr2lisp-interaction-mode-popup-menu)))))(or(member["Eval Motion Region"mode-motion-eval-regiont]emacs-lisp-mode-popup-menu)(and(setqemacs-lisp-mode-popup-menu(copy-sequenceemacs-lisp-mode-popup-menu))(setcdr(nthcdr3emacs-lisp-mode-popup-menu)(cons["Eval Motion Region"mode-motion-eval-regiont](nthcdr4emacs-lisp-mode-popup-menu)))));; Clear the last active motion extent when leaving a frame.(if(boundp'mouse-leave-frame-hook)(add-hook'mouse-leave-frame-hook'mode-motion-clear-last-extent)(add-hook'mouse-leave-screen-hook'mode-motion-clear-last-extent))(run-hooks'mode-motion+-load-hook)(mode-motion-init-handlers-according-to-religion)(if(interactive-p)(message"mode-motion+ enabled")))(if(and(notpurify-flag)(or(not(boundp'opt-mode-motion+))opt-mode-motion+))(mode-motion-init))(provide'mode-motion+);; end mode-motion+