mouse3

Homepage: https://www.emacswiki.org/emacs/download/mouse3.el

Author: Drew Adams

Updated:

Summary

Customizable behavior for `mouse-3'

Commentary

This library lets you customize the behavior of `mouse-3' in
several ways.

It redefines standard command `mouse-save-then-kill' in a trivial
way to give you custom behavior for a second `mouse-3' click at the
same spot.

Vanilla Emacs hard-wires the `mouse-3' behavior.  For example, if
you click it twice at the same spot then it kills or deletes the
region (depending on the value of `mouse-drag-copy-region').

The hard-wired action can be handy, but sometimes (e.g., deleting
in a read-only buffer) it's inappropriate.  In any case, it's only
one possible action.  There are often other actions that you might
want to take instead, either regarding text selection or something
else.

The redefined `mouse-save-then-kill' command in `mouse3.el' uses
function `mouse3-second-click-command' to handle a `mouse-3' click.

By default, only a second click at the same spot does this.  This
lets you take advantage of both the usual Emacs `mouse-3' behavior
of selecting or deleting text, and then, with a second click at the
same spot, to get another behavior, typically to show a popup menu.

I recommend this default behavior.  But if you customize option
`mouse3-menu-always-flag' to non-nil then every `mouse-3' click
gives you only that other behavior (e.g. show a menu).  In this
case, you can't take advantage of `mouse-3' clicks to select, or
extend/reduce/delete the selection.  This includes the ability to
extend/reduce by increments determined by multiple-click selection.

If you're sure that you never want the usual `mouse-3' behavior
(select, delete, or extend/reduce the region), then an alternative
way to get the same behavior as setting option
`mouse3-menu-always-flag' to non-nil is to bind `mouse-3' to
command `mouse3-action-wo-save-then-kill':

  (global-set-key [mouse-3] 'mouse3-action-wo-save-then-kill).

But the option lets you leave the standard key binding
(`mouse-save-then-kill') as is.  Then you can easily change the
behavior by changing the option value.  Again, though, I don't
recommend such behavior.

If you're not used to the Emacs `mouse-3' behavior of
extending/reducing/deleting the existing selection, take some time
to read about it on the `Mouse Commands' page of the Emacs manual:
`C-h r g Mouse Commands'.  You might be surprised how useful it is.
In particular:

  If you originally specified the region using a double or triple
  `mouse-1', so that the region is defined to consist of entire
  words or lines, then adjusting the region with `mouse-3' also
  proceeds by entire words or lines.

You can triple-click to select a line, then click `mouse-3' to add
the `mouse-3'-clicked line and all intervening lines to the
selection.  Or if you click `mouse-3' within the existing selection
of lines then the selection loses, instead of gains, lines.

Library `mouse3.el' is specially designed to let you take advantage
of this feature but _also_ be able to use `mouse-3' to show a
context menu or perform some other action.  Setting option
`mouse3-menu-always-flag' to non-nil gives you the alternative
action (e.g. show a menu), but it removes the Emacs `mouse-3'
selection features.

Function `mouse3-second-click-command' returns the command that
`mouse-save-then-kill' invokes: either the command that is the
value of variable `mouse3-save-then-kill-command' or, if that is
nil then the command that is the value of user option
`mouse3-second-click-default-command'.

Special contexts can bind variable `mouse3-save-then-kill-command'
to provide particular behavior.  For example, Icicles does this
during minibuffer completion so that a second `mouse-3' at the same
spot in buffer `*Completions*' marks the selected completions
(saves them for later reuse).

You can use option `mouse3-second-click-default-command' to
customize the behavior to either pop up a menu or invoke any
command you choose.  The default value is `mouse3-popup-menu',
which pops up a menu.  To obtain the vanilla Emacs behavior,
customize the option value to command `mouse3-kill/delete-region'.

Option `mouse3-double-click-command' associates a command with a
`mouse-3' double-click.  The default value is command
`mouse3-kill/delete-region', so with the default setup you can kill
or delete the selected text by double-clicking `mouse-3' instead of
single clicking.  In other words, in the default setup you have two
possibilities:

 2nd single-click: Pop up a menu so you can choose how to act on
                   the selected text.

 double-click:     Kill or delete the selection, according to
                   standard option `mouse-drag-copy-region'.

If you choose to customize one of these two options,
`mouse3-second-click-default-command' or
`mouse3-double-click-command', then you will probably want to
customize both of them.

To make either a single-click or a double-click do nothing,
customize the appropriate option to the command `ignore'.

Note:

I do not recommend that you try reversing the option values from
their defaults, so that a double-click pops up a menu and the
second single-click at the same spot deletes the selected text.
That does not work well in general because of a flaw (or a feature,
depending on your view) in the Emacs design.

Here's the problem: When you double-click to get the menu, Emacs
first sends a single-click event, before the double-click event.
(That's the flaw/feature.)  So if you double-click at the same spot
then the selection is first deleted, before the menu pops up.

If you double-click at a different spot then this does not happen,
but instead the selection is extended or reduced to match the
double-click position.  The selection might then not be the region
you want the menu items to act on.  Things work pretty well,
however, if you start selecting by double-clicking `mouse-1', click
`mouse-3' here and there to extend, and finally double-click
`mouse-3' near the end of the selection, because in that case the
double-click position does not extend the selection any more.

In sum, in general I do not recommend that you reverse the default
values.  If you want `mouse-3' to pop up a menu, it is better to
either (a) use the default setup so that the menu pops up on the
second single-click, not on a double-click or (b) let
`mouse3-double-click-command' pop up the menu, but set
`mouse3-second-click-default-command' to a command other than
`mouse3-kill/delete-region'.


Customized Pop-Up Menu
----------------------

If you choose for `mouse-3' to pop up a menu then you can customize
that menu using various user options.  The command that pops up the
menu is `mouse3-popup-menu'.  See the documentation for that
command for more explanation of the use of options.

A fairly complete default menu is provided out of the box, so you
do not need to customize anything unless you want to.

`mouse3-popup-menu' ultimately invokes standard function
`x-popup-menu' to do its work.  The menu definition used by
`x-popup-menu' can take two alternative forms, which are quite
different.  Which form you choose to use is controlled by option
`mouse3-popup-x-popup-panes-flag'.

If that option is nil (the default value), you can use keymaps and
extended menu items to define the popup menu.  This is recommended.
If the value is non-nil then you can use options
`mouse3-region-popup-x-popup-panes' and
`mouse3-noregion-popup-x-popup-panes' to make use of the
alternative, `x-popup-menu'-specific form.

That alternative form is easy to use, but it does not offer you all
of the possibilities that a standard menu definition does.  In
particular, it does not let you provide keywords such as `:visible'
and `:enable' that control the display and makeup of submenus and
menu items.  Examples of both methods are provided in this file.

The default behavior takes advantage of keywords to dynamically
remove or disable submenus and menu items that are inappropriate
for the current context.  For example, it removes or disables
buffer-modifying items and submenus if the current buffer is
read-only.

The rest of the description here assumes that
`mouse3-popup-x-popup-panes-flag' is nil (the default value and
recommended).

You can optionally include, at the beginning of the menu, a submenu
that has, as its own submenus, the global menus that are currently
available.  (These are the same menus that are popped up by
`C-mouse-3'.)  This is controlled by option
`mouse3-popup-include-global-menus-flag'.  If the menu bar is not
shown currently, then these submenus are the menu-bar menus.
Otherwise they are the major-mode menus.

For example, if the menu bar is showing, then in Dired mode the
first submenu is `Dired by name', which itself has submenus
`Operate', `Mark', `Regexp', `Immediate', and `Subdir'.

You define the rest of the popup menu (other than the global part)
using submenu keymaps and `menu-item' bindings (extended menu
items).  You do this by customizing options
`mouse3-region-popup-entries' and `mouse3-noregion-popup-entries'.
You can reuse existing keymaps or create menu items and submenus
from scratch.  See the documentation for
`mouse3-(no)region-popup-entries'.  If you reuse existing keymaps
you can add their menu items either as a submenu or as individual
items.


Mode-Specific Popup Menu
------------------------

You can provide mode-specific behavior by either replacing the
default `mouse-3' popup menu or augmenting it with mode-specific
entries.

`mouse3.el' provides useful behavior for Dired mode.  You can do
the same for other modes you use.  Simple example code is also
provided here for Picture mode.  The menu implementation for these
two modes is different, to give you an idea of what is possible.
For Dired mode, `mouse3-region-popup-entries' is used.  For Picture
mode, `mouse3-region-popup-x-popup-panes' is used, and both
`mouse3-popup-x-popup-panes-flag' and
`mouse3-region-popup-x-popup-panes' are made buffer-local.

The example code for Picture mode provides actions on the rectangle
defined by the region: items such as `Draw Rectangle' and `Clear
Rectangle'.

Let's look at the behavior for Dired mode in more detail.  The
vanilla Emacs behavior just raises an error, because Dired is
read-only.  Why not let a second `mouse-3' click at the same spot
do something wrt the selected file and dir names?  Two obvious
possibilities come to mind: toggle whether each file/dir is marked,
or pop up a menu that lets you act in various ways on each of the
selected files and dirs.

Option `mouse3-dired-function' lets you choose between these two
behaviors.  The default value is `mouse3-dired-use-menu', which
means to pop up a menu.  This is just like the default popup menu
except that it has an additional submenu, `Selected Files', that is
Dired-specific.  The first submenu is the global major-mode menu,
`Dired by name'.  The second, `Selected Files', has items that act
on the files and directories that are selected (in the region):

 `Mark'
 `Unmark'
 `Toggle Marked/Unmarked'
 `Flag for Deletion'
 `Stop Using Menu'

That last item just switches from having `mouse-3' pop up a menu to
having it toggle the markings of the selected files (the
alternative behavior of `mouse3-dired-function').

If you also use library Dired+ (`dired+.el'), which I recommend,
then that last menu item is not present, and when the region is
empty you get a different popup menu which pertains only to the
file where you clicked `mouse-3'.


Context-Specific Behavior (for Emacs-Lisp Programmers)
------------------------------------------------------

As mentioned above, Icicles provides an example of a program
imposing context-specific behavior for the second `mouse-3' click
at the same spot.  The context in this case is (a) completion and
(b) clicking in buffer `*Completions*'.  For that, Icicles sets a
buffer-local value of variable `mouse3-save-then-kill-command'.

If you write Emacs-Lisp code, note that this is an example where
the text is a set of entries in tabular format (columns).  Each
`*Completions*' entry (candidate) is defined by its `mouse-face'
property, not by its text.  For example, it is not delimited by
whitespace (completion candidates can contain spaces and newlines).
A context-specific function picks up the set of selected
completions as a list.

Similar opportunities can exist for other tabular or line-list
data: `*Buffer List*', compile/grep output, Info breadcrumbs,...
Use your imagination.  The Dired example is typical here: the
region sweeps out text linearly, but the only thing we are really
interested in are the file and subdirectory names that are inside
the region.

-------------------------------------------------------------------


User options defined here:

  `mouse3-dired-function', `mouse3-double-click-command',
  `mouse3-menu-always-flag', `mouse3-noregion-popup-entries',
  `mouse3-noregion-popup-x-popup-panes',
  `mouse3-picture-mode-x-popup-panes',
  `mouse3-popup-include-global-menus-flag',
  `mouse3-popup-x-popup-panes-flag', `mouse3-region-popup-entries',
  `mouse3-region-popup-x-popup-panes',
  `mouse3-second-click-default-command'.

Commands defined here:

  `mouse3-action-wo-save-then-kill', `mouse3-dired',
  `mouse3-dired-flag-region-files-for-deletion',
  `mouse3-dired-mark-region-files', `mouse3-dired-other-window',
  `mouse3-dired-toggle-marks-in-region',
  `mouse3-dired-toggle-marks-in-region-from-mouse',
  `mouse3-dired-unmark-region-files', `mouse3-dired-use-menu',
  `mouse3-dired-use-toggle-marks', `mouse3-kill/delete-region',
  `mouse3-popup-menu', `mouse3-pp-eval-sexp'.

Non-interactive functions defined here:

  `mouse3-dired-add-region-menu',
  `mouse3-dired-set-to-toggle-marks',
  `mouse3-dired-this-file-marked-p',
  `mouse3-dired-this-file-unmarked-p', `mouse3-ffap-guesser',
  `mouse3-file-or-dir', `mouse3-nonempty-region-p',
  `mouse3-region-popup-choice', `mouse3-region-popup-choice-1',
  `mouse3-region-popup-custom-entries',
  `mouse3-second-click-command'.

Internal variables defined here:

  `mouse3-ffap-max-region-size',
  `mouse3-noregion-popup-misc-submenu',
  `mouse3-region-popup-change-text-submenu',
  `mouse3-region-popup-check-convert-submenu',
  `mouse3-region-popup-copy-submenu',
  `mouse3-region-popup-highlight-submenu',
  `mouse3-region-popup-misc-submenu',
  `mouse3-region-popup-print-submenu',
  `mouse3-region-popup-rectangle-submenu',
  `mouse3-region-popup-register-submenu',
  `mouse3-region-popup-remove/replace-items',
  `mouse3-region-popup-remove/replace-rect-submenu',
  `mouse3-region-popup-search/replace-submenu',
  `mouse3-save-then-kill-command'.


 ***** NOTE: The following functions defined in `mouse.el' have
             been REDEFINED HERE:

 `mouse-save-then-kill' - Uses `mouse3-second-click-command' to
                          define second `mouse-3' click behavior.

Dependencies

Reverse dependencies