GNU Info

Info Node: (viper)Key Bindings

(viper)Key Bindings


Next: Packages that Change Keymaps Prev: Rudimentary Changes Up: Customization
Enter node , (file) or (file)node

Key Bindings
============

   Viper lets you define hot keys, i.e., you can associate keyboard keys
such as F1, Help, PgDn, etc., with Emacs Lisp functions (that may
already exist or that you will write).  Each key has a "preferred form"
in Emacs.  For instance, the Up key's preferred form is [up], the Help
key's preferred form is [help], and the Undo key has the preferred form
[f14].  You can find out the preferred form of a key by typing `M-x
describe-key-briefly' and then typing the key you want to know about.

   Under the X Window System, every keyboard key emits its preferred
form, so you can just type

     (global-set-key [f11] 'calendar)                        ; L1, Stop
     (global-set-key [f14] 'undo)                            ; L4, Undo

to bind L1 so it will invoke the Emacs Calendar and to bind L4 so it
will undo changes.  However, on a dumb terminal or in an Xterm window,
even the standard arrow keys may not emit the right signals for Emacs
to understand.  To let Emacs know about those keys, you will have to
find out which key sequences they emit by typing `C-q' and then the key
(you should switch to Emacs state first).  Then you can bind those
sequences to their preferred forms using `function-key-map' as follows:

     (cond ((string= (getenv "TERM") "xterm")
     (define-key function-key-map "\e[192z" [f11])    ; L1
     (define-key function-key-map "\e[195z" [f14])    ; L4, Undo

   The above illustrates how to do this for Xterm.  On VT100, you would
have to replace "xterm" with "vt100" and also change the key sequences
(the same key may emit different sequences on different types of
terminals).

   The above keys are global, so they are overwritten by the local maps
defined by the major modes and by Viper itself.  Therefore, if you wish
to change a binding set by a major mode or by Viper, read this.

   Viper users who wish to specify their own key bindings should be
concerned only with the following three keymaps:
`viper-vi-global-user-map' for Vi state commands,
`viper-insert-global-user-map' for Insert state commands, and
`viper-emacs-global-user-map' for Emacs state commands (note:
customized bindings for Emacs state made to
`viper-emacs-global-user-map' are _not_ inherited by Insert state).

   For more information on Viper keymaps, see the header of the file
`viper.el'.  If you wish to change a Viper binding, you can use the
`define-key' command, to modify `viper-vi-global-user-map',
`viper-insert-global-user-map', and `viper-emacs-global-user-map', as
explained below.  Each of these key maps affects the corresponding
Viper state.  The keymap `viper-insert-global-user-map' also affects
Viper's Replace state.

If you want to bind a key, say `C-v', to the function that scrolls page
down and to make `0' display information on the current buffer, putting
this in `.viper' will do the trick in Vi state:
     (define-key viper-vi-global-user-map "\C-v" 'scroll-down)

To set a key globally,
     (define-key viper-emacs-global-user-map "\C-c m" 'smail)
     (define-key viper-vi-global-user-map "0" 'viper-info-on-file)

Note, however, that this binding may be overwritten by other keymaps,
since the global keymap has the lowest priority.  To make sure that
nothing will override a binding in Emacs state, you can write this:
     (define-key viper-emacs-global-user-map "\C-c m" 'smail)

To customize the binding for `C-h' in Insert state:
     (define-key viper-insert-global-user-map "\C-h" 'my-del-backwards-function)

Each Emacs command key calls some lisp function.  If you have enabled
the Help, (Note: Rudimentary Changes) `C-h k' will show you the
function for each specific key; `C-h b' will show all bindings, and
`C-h m' will provide information on the major mode in effect.  If Help
is not enabled, you can still get help in Vi state by prefixing the
above commands with `\', e.g., `\ C-h k' (or you can use the Help menu
in the menu bar, if Emacs runs under X).

   Viper users can also change bindings on a per major mode basis.  As
with global bindings, this can be done separately for each of the three
main Viper states.  To this end, Viper provides the function
`viper-modify-major-mode'.

   To modify keys in Emacs state for `my-favorite-major-mode', the user
needs to create a sparse keymap, say, `my-fancy-map', bind whatever
keys necessary in that keymap, and put

     (viper-modify-major-mode 'dired-mode 'emacs-state my-fancy-map)

in `~/.viper'.  To do the same in Vi and Insert states, you should use
`vi-state' and `insert-state'.  Changes in Insert state are also in
effect in Replace state.  For instance, suppose that the user wants to
use `dd' in Vi state under Dired mode to delete files, `u' to unmark
files, etc.  The following code in `~/.viper' will then do the job:

     (setq my-dired-modifier-map (make-sparse-keymap))
     (define-key my-dired-modifier-map "dd" 'dired-flag-file-deletion)
     (define-key my-dired-modifier-map "u" 'dired-unmark)
     (viper-modify-major-mode 'dired-mode 'vi-state my-dired-modifier-map)

   A Vi purist may want to modify Emacs state under Dired mode so that
`k', `l', etc., will move around in directory buffers, as in Vi.
Although this is not recommended, as these keys are bound to useful
Dired functions, the trick can be accomplished via the following code:

     (setq my-dired-vi-purist-map (make-sparse-keymap))
     (define-key my-dired-vi-purist-map "k" 'viper-previous-line)
     (define-key my-dired-vi-purist-map "l" 'viper-forward-char)
     (viper-modify-major-mode 'dired-mode 'emacs-state my-dired-vi-purist-map)

   Yet another way to customize key bindings in a major mode is to edit
the list `viper-major-mode-modifier-list' using the customization
widget.  (This variable is in the Viper-misc customization group.)  The
elements of this list are triples of the form: (major-mode viper-state
keymap), where the keymap contains bindings that are supposed to be
active in the given major mode and the given viper-state.

   Effects similar to key binding changes can be achieved by defining Vi
keyboard macros using the Ex commands `:map' and `:map!'.  The
difference is that multi-key Vi macros do not override the keys they are
bound to, unless these keys are typed in quick succession.  So, with
macros, one can use the normal keys alongside with the macros.  If
per-mode modifications are needed, the user can try both ways and see
which one is more convenient.  Note: Vi Macros, for details.

   Note: in major modes that come up in _Emacs state_ by default, the
aforesaid modifications may not take place immediately (but only after
the buffer switches to some other Viper state and then back to Emacs
state).  To avoid this, one should add `viper-change-state-to-emacs' to
an appropriate hook of that major mode.  (Check the function
`viper-set-hooks' in `viper.el' for examples.)  However, if you have
set `viper-always' to `t', chances are that you won't need to perform
the above procedure, because Viper will take care of most useful
defaults.

   Finally, Viper has a facility that lets the user define per-buffer
bindings, i.e., bindings that are in effect in some specific buffers
only.  Unlike per-mode bindings described above, per-buffer bindings
can be defined based on considerations other than the major mode.  This
is done via the function `viper-add-local-keys', which lets one specify
bindings that should be in effect in the current buffer only and for a
specific Viper state.  For instance,
     (viper-add-local-keys 'vi-state '(("ZZ" . TeX-command-master)
                                      ("ZQ" . viper-save-kill-buffer)))

redefines `ZZ' to invoke `TeX-command-master' in `vi-state' and `ZQ' to
save-then-kill the current buffer.  These bindings take effect only in
the buffer where this command is executed.  The typical use of this
function is to execute the above expression from within a function that
is included in a hook to some major mode.  For instance, the above
expression could be called from a function, `my-tex-init', which may be
added to `tex-mode-hook' as follows:
     (add-hook 'tex-mode-hook 'my-tex-init)

When TeX mode starts, the hook is executed and the above Lisp
expression is evaluated.  Then, the bindings for `ZZ' and `ZQ' are
changed in Vi command mode for all buffers in TeX mode.

   Another useful application is to bind `ZZ' to `send-mail' in the
Mail mode buffers (the specifics of this depend on which mail package
you are using, `rmail', `mh-e', `vm', etc.  For instance, here is how
to do this for `mh-e', the Emacs interface to MH:
     (defun mh-add-vi-keys ()
       "Set up ZZ for MH-e and XMH."
       (viper-add-local-keys 'vi-state '(("ZZ" . mh-send-letter))))
     (add-hook 'mh-letter-mode-hook 'mh-add-vi-keys)

   You can also use `viper-add-local-keys' to set per buffer bindings
in Insert state and Emacs state by passing as a parameter the symbols
`insert-state' and `emacs-state', respectively.  As with global
bindings, customized local bindings done to Emacs state are not
inherited by Insert state.

   On rare occasions, local keys may be added by mistake.  Usually this
is done indirectly, by invoking a major mode that adds local keys (e.g.,
`shell-mode' redefines <RET>).  In such a case, exiting the wrong major
mode won't rid you from unwanted local keys, since these keys are local
to Viper state and the current buffer, not to the major mode.  In such
situations, the remedy is to type `M-x viper-zap-local-keys'.

   So much about Viper-specific bindings.  *Note Customization:
(emacs)Customization, and the Emacs quick reference card for the
general info on key bindings in Emacs.


automatically generated by info2www version 1.2.2.9