Switch to recommended form of GPLv3 permissions notice.
[bpt/emacs.git] / lisp / emulation / viper-keym.el
CommitLineData
d3e1167f 1;;; viper-keym.el --- Viper keymaps
be010748 2
5fd6d89f 3;; Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001, 2002, 2003, 2004,
8b72699e 4;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
d6fd318f 5
50a07e18 6;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
02f34c70 7
6c2e12f4
KH
8;; This file is part of GNU Emacs.
9
ed0f493f 10;; GNU Emacs is free software: you can redistribute it and/or modify
6c2e12f4 11;; it under the terms of the GNU General Public License as published by
ed0f493f
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
6c2e12f4
KH
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
ed0f493f 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
6c2e12f4 22
60370d40
PJ
23;;; Commentary:
24
25;;; Code:
03fc1246 26
9b70a748 27;; compiler pacifier
e36a387d 28(defvar viper-always)
8626cfa2
MK
29(defvar viper-current-state)
30(defvar viper-mode-string)
1e70790f 31(defvar viper-expert-level)
34317da2 32(defvar viper-ex-style-editing)
8626cfa2 33(defvar viper-ex-style-motion)
acb93bb2
MK
34
35(eval-and-compile
36 (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
9b70a748
MK
37;; end pacifier
38
6c2e12f4
KH
39(require 'viper-util)
40
acb93bb2
MK
41(declare-function viper-ex "viper-ex" (arg &optional string))
42(declare-function viper-normalize-minor-mode-map-alist "viper-cmd" ())
43(declare-function viper-set-mode-vars-for "viper-cmd" (state))
9b70a748 44
6c2e12f4
KH
45;;; Variables
46
a1506d29
JB
47
48;;; Emacs keys in other states.
9b70a748 49
8626cfa2 50(defcustom viper-want-emacs-keys-in-insert t
9b70a748 51 "*Set to nil if you want complete Vi compatibility in insert mode.
1e70790f
MK
52Complete compatibility with Vi is not recommended for power use of Viper."
53 :type 'boolean
54 :group 'viper)
9b70a748 55
8626cfa2 56(defcustom viper-want-emacs-keys-in-vi t
9b70a748 57 "*Set to nil if you want complete Vi compatibility in Vi mode.
1e70790f
MK
58Full Vi compatibility is not recommended for power use of Viper."
59 :type 'boolean
60 :group 'viper)
9b70a748 61
8626cfa2 62(defcustom viper-no-multiple-ESC t
9b70a748
MK
63 "*If true, multiple ESC in Vi mode will cause bell to ring.
64This is set to t on a windowing terminal and to 'twice on a dumb
3af0304a 65terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this
9b70a748
MK
66enables cursor keys and is generally more convenient, as terminals usually
67don't have a convenient Meta key.
8626cfa2 68Setting viper-no-multiple-ESC to nil will allow as many multiple ESC,
1e70790f
MK
69as is allowed by the major mode in effect."
70 :type 'boolean
a1506d29 71 :group 'viper)
9b70a748 72
8626cfa2 73(defcustom viper-want-ctl-h-help nil
5ce05788 74 "*If non-nil, C-h gets bound to help-command; otherwise, C-h gets the usual Vi bindings."
1e70790f
MK
75 :type 'boolean
76 :group 'viper)
ab124470
MK
77
78
6c2e12f4
KH
79;;; Keymaps
80
81;; Keymaps for vital things like \e and C-z.
82;; Not for users
8626cfa2
MK
83(defvar viper-vi-intercept-map (make-sparse-keymap))
84(defvar viper-insert-intercept-map (make-sparse-keymap))
85(defvar viper-emacs-intercept-map (make-sparse-keymap))
73d449a2 86
d3e1167f
MK
87;; keymap used to zap all keymaps other than function-key-map,
88;; device-function-key-map, etc.
8626cfa2 89(defvar viper-overriding-map (make-sparse-keymap))
a1506d29 90
8626cfa2 91(viper-deflocalvar viper-vi-local-user-map (make-sparse-keymap)
6c2e12f4
KH
92 "Keymap for user-defined local bindings.
93Useful for changing bindings such as ZZ in certain major modes.
94For instance, in letter-mode, one may want to bind ZZ to
3af0304a 95mh-send-letter. In a newsreader such as gnus, tin, or rn, ZZ could be bound
6c2e12f4 96to save-buffers-kill-emacs then post article, etc.")
a1506d29 97(put 'viper-vi-local-user-map 'permanent-local t)
6c2e12f4 98
8626cfa2 99(defvar viper-vi-global-user-map (make-sparse-keymap)
6c2e12f4
KH
100 "Keymap for user-defined global bindings.
101These bindings are seen in all Viper buffers.")
102
8626cfa2 103(defvar viper-vi-basic-map (make-keymap)
6c2e12f4
KH
104 "This is the main keymap in effect in Viper's Vi state.
105This map is global, shared by all buffers.")
106
8626cfa2 107(defvar viper-vi-kbd-map (make-sparse-keymap)
6c2e12f4
KH
108 "This keymap keeps keyboard macros defined via the :map command.")
109
8626cfa2 110(defvar viper-vi-diehard-map (make-sparse-keymap)
6c2e12f4 111 "This keymap is in use when the user asks Viper to simulate Vi very closely.
3af0304a 112This happens when viper-expert-level is 1 or 2. See viper-set-expert-level.")
a1506d29 113
6c2e12f4 114
8626cfa2 115(viper-deflocalvar viper-insert-local-user-map (make-sparse-keymap)
6c2e12f4 116 "Auxiliary map for per-buffer user-defined keybindings in Insert state.")
a1506d29 117(put 'viper-insert-local-user-map 'permanent-local t)
6c2e12f4 118
8626cfa2 119(defvar viper-insert-global-user-map (make-sparse-keymap)
6c2e12f4
KH
120 "Auxiliary map for global user-defined bindings in Insert state.")
121
8626cfa2 122(defvar viper-insert-basic-map (make-sparse-keymap)
6c2e12f4
KH
123 "The basic insert-mode keymap.")
124
8626cfa2 125(defvar viper-insert-diehard-map (make-keymap)
6c2e12f4 126 "Map used when user wants vi-style keys in insert mode.
3af0304a
MK
127Most of the Emacs keys are suppressed. This map overshadows
128viper-insert-basic-map. Not recommended, except for novice users.")
6c2e12f4 129
8626cfa2 130(defvar viper-insert-kbd-map (make-sparse-keymap)
6c2e12f4
KH
131 "This keymap keeps VI-style kbd macros for insert mode.")
132
8626cfa2 133(defvar viper-replace-map (make-sparse-keymap)
6c2e12f4 134 "Map used in Viper's replace state.")
a1506d29 135
8626cfa2 136(defvar viper-emacs-global-user-map (make-sparse-keymap)
6c2e12f4
KH
137 "Auxiliary map for global user-defined bindings in Emacs state.")
138
8626cfa2 139(defvar viper-emacs-kbd-map (make-sparse-keymap)
bb3a9234 140 "This keymap keeps Vi-style kbd macros for Emacs mode.")
a1506d29 141
8626cfa2 142(viper-deflocalvar viper-emacs-local-user-map (make-sparse-keymap)
6c2e12f4 143 "Auxiliary map for local user-defined bindings in Emacs state.")
a1506d29 144(put 'viper-emacs-local-user-map 'permanent-local t)
6c2e12f4
KH
145
146;; This keymap should stay empty
8626cfa2 147(defvar viper-empty-keymap (make-sparse-keymap))
6c2e12f4 148
546fe085 149;; This was the main Vi mode in old versions of VIP which may have been
3af0304a 150;; extensively used by VIP users. We declare it as a global var
8626cfa2
MK
151;; and, after .viper is loaded, we add this keymap to viper-vi-basic-map.
152(defvar viper-mode-map (make-sparse-keymap))
546fe085 153
8ea74b0e
MK
154;; Some important keys used in viper
155(defcustom viper-toggle-key [(control ?z)] ; "\C-z"
bb3a9234 156 "The key used to change states from Emacs to Vi and back.
8ea74b0e
MK
157In insert mode, this key also functions as Meta.
158
bb3a9234 159Enter as a sexp. Examples: \"\\C-z\", [(control ?z)]."
8ea74b0e
MK
160 :type 'sexp
161 :group 'viper
162 :set (lambda (symbol value)
163 (let ((old-value (if (boundp 'viper-toggle-key)
164 viper-toggle-key
165 [(control ?z)])))
60e7e896 166 (mapc
8ea74b0e
MK
167 (lambda (buf)
168 (save-excursion
169 (set-buffer buf)
170 (when (and (boundp 'viper-insert-basic-map)
171 (keymapp viper-insert-basic-map))
172 (when old-value
173 (define-key viper-insert-basic-map old-value nil))
174 (define-key viper-insert-basic-map value 'viper-escape-to-vi))
175 (when (and (boundp 'viper-vi-intercept-map)
176 (keymapp viper-vi-intercept-map))
177 (when old-value
178 (define-key viper-vi-intercept-map old-value nil))
179 (define-key
180 viper-vi-intercept-map value 'viper-toggle-key-action))
181 (when (and (boundp 'viper-emacs-intercept-map)
182 (keymapp viper-emacs-intercept-map))
183 (define-key viper-emacs-intercept-map old-value nil)
184 (define-key
185 viper-emacs-intercept-map value 'viper-change-state-to-vi))
186 ))
187 (buffer-list))
188 (set-default symbol value)
189 )))
190
191(defcustom viper-quoted-insert-key "\C-v"
192 "The key used to quote special characters when inserting them in Insert state."
193 :type 'string
194 :group 'viper)
195
0680ea10 196(defcustom viper-ESC-key (if (viper-window-display-p) [(escape)] "\e")
8ea74b0e 197 "Key used to ESC.
0680ea10
MK
198Enter as a sexp. Examples: \"\\e\", [(escape)].
199If running in a terminal, [(escape)] is not understood, so must use \"\\e\"."
8ea74b0e
MK
200 :type 'sexp
201 :group 'viper
202 :set (lambda (symbol value)
203 (let ((old-value (if (boundp 'viper-ESC-key)
204 viper-ESC-key
205 [(escape)])))
60e7e896 206 (mapc
8ea74b0e
MK
207 (lambda (buf)
208 (save-excursion
209 (set-buffer buf)
210 (when (and (boundp 'viper-insert-intercept-map)
211 (keymapp viper-insert-intercept-map))
212 (when old-value
213 (define-key viper-insert-intercept-map old-value nil))
214 (define-key
215 viper-insert-intercept-map value 'viper-intercept-ESC-key))
216 (when (and (boundp 'viper-vi-intercept-map)
217 (keymapp viper-vi-intercept-map))
218 (when old-value
219 (define-key viper-vi-intercept-map old-value nil))
220 (define-key
221 viper-vi-intercept-map value 'viper-intercept-ESC-key))
222 ))
223 (buffer-list))
224 (set-default symbol value)
225 )))
226
6c2e12f4
KH
227
228;;; Variables used by minor modes
229
a1506d29 230;; Association list of the form
6c2e12f4
KH
231;; ((major-mode . keymap) (major-mode . keymap) ...)
232;; Viper uses these keymaps to make user-requested adjustments
233;; to its Vi state in various major modes.")
8626cfa2 234(defvar viper-vi-state-modifier-alist nil)
6c2e12f4 235
a1506d29 236;; Association list of the form
6c2e12f4
KH
237;; ((major-mode . keymap) (major-mode . keymap) ...)
238;; Viper uses these keymaps to make user-requested adjustments
239;; to its Insert state in various major modes.")
8626cfa2 240(defvar viper-insert-state-modifier-alist nil)
6c2e12f4 241
a1506d29 242;; Association list of the form
6c2e12f4
KH
243;; ((major-mode . keymap) (major-mode . keymap) ...)
244;; Viper uses these keymaps to make user-requested adjustments
245;; to its Emacs state in various major modes.
8626cfa2 246(defvar viper-emacs-state-modifier-alist nil)
6c2e12f4 247
8ea74b0e
MK
248;; The list of viper keymaps. Set by viper-normalize-minor-mode-map-alist
249(viper-deflocalvar viper--key-maps nil)
250(viper-deflocalvar viper--intercept-key-maps nil)
251
8626cfa2 252;; Tells viper-add-local-keys to create a new viper-vi-local-user-map for new
3af0304a 253;; buffers. Not a user option.
8626cfa2
MK
254(viper-deflocalvar viper-need-new-vi-local-map t "")
255(put 'viper-need-new-vi-local-map 'permanent-local t)
6c2e12f4 256
8626cfa2 257;; Tells viper-add-local-keys to create a new viper-insert-local-user-map for
3af0304a 258;; new buffers. Not a user option.
8626cfa2
MK
259(viper-deflocalvar viper-need-new-insert-local-map t "")
260(put 'viper-need-new-insert-local-map 'permanent-local t)
6c2e12f4 261
8626cfa2 262;; Tells viper-add-local-keys to create a new viper-emacs-local-user-map for
3af0304a 263;; new buffers. Not a user option.
8626cfa2
MK
264(viper-deflocalvar viper-need-new-emacs-local-map t "")
265(put 'viper-need-new-emacs-local-map 'permanent-local t)
6c2e12f4
KH
266
267
268\f
269;; Insert mode keymap
270
271;; for novice users, pretend you are the real vi.
8626cfa2
MK
272(define-key viper-insert-diehard-map "\t" 'viper-insert-tab)
273(define-key viper-insert-diehard-map "\C-a" 'self-insert-command)
274(define-key viper-insert-diehard-map "\C-b" 'self-insert-command)
275(define-key viper-insert-diehard-map "\C-c" 'viper-change-state-to-vi)
276(define-key viper-insert-diehard-map "\C-e" 'self-insert-command)
277(define-key viper-insert-diehard-map "\C-f" 'self-insert-command)
278(define-key viper-insert-diehard-map "\C-g" 'self-insert-command)
279(define-key viper-insert-diehard-map "\C-i" 'self-insert-command)
280(define-key viper-insert-diehard-map "\C-k" 'self-insert-command)
281(define-key viper-insert-diehard-map "\C-l" 'self-insert-command)
282(define-key viper-insert-diehard-map "\C-n" 'self-insert-command)
283(define-key viper-insert-diehard-map "\C-o" 'self-insert-command)
284(define-key viper-insert-diehard-map "\C-p" 'self-insert-command)
285(define-key viper-insert-diehard-map "\C-q" 'self-insert-command)
286(define-key viper-insert-diehard-map "\C-r" 'self-insert-command)
287(define-key viper-insert-diehard-map "\C-s" 'self-insert-command)
288(define-key viper-insert-diehard-map "\C-u" 'viper-erase-line)
289(define-key viper-insert-diehard-map "\C-x" 'self-insert-command)
290(define-key viper-insert-diehard-map "\C-y" 'self-insert-command)
291(define-key viper-insert-diehard-map "\C-z" 'self-insert-command)
292(define-key viper-insert-diehard-map "\C-]" 'self-insert-command)
293(define-key viper-insert-diehard-map "\C-_" 'self-insert-command)
6c2e12f4
KH
294
295(let ((i ?\ ))
296 (while (<= i ?~)
8626cfa2 297 (define-key viper-insert-diehard-map (make-string 1 i) 'self-insert-command)
6c2e12f4
KH
298 (setq i (1+ i))))
299
300;; Insert mode map when user wants emacs style
8626cfa2
MK
301(define-key viper-insert-basic-map "\C-d" 'viper-backward-indent)
302(define-key viper-insert-basic-map "\C-w" 'viper-delete-backward-word)
303(define-key viper-insert-basic-map "\C-t" 'viper-forward-indent)
899a431b 304(define-key viper-insert-basic-map viper-quoted-insert-key 'quoted-insert)
8626cfa2 305(define-key viper-insert-basic-map "\C-?" 'viper-del-backward-char-in-insert)
5ce05788 306(define-key viper-insert-basic-map [backspace] 'viper-del-backward-char-in-insert)
8626cfa2
MK
307(define-key viper-insert-basic-map "\C-\\" 'viper-alternate-Meta-key)
308(define-key viper-insert-basic-map viper-toggle-key 'viper-escape-to-vi)
309(define-key viper-insert-basic-map "\C-c\M-p"
310 'viper-insert-prev-from-insertion-ring)
311(define-key viper-insert-basic-map "\C-c\M-n"
312 'viper-insert-next-from-insertion-ring)
6c2e12f4
KH
313
314
315;; Replace keymap
8626cfa2
MK
316(define-key viper-replace-map "\C-t" 'viper-forward-indent)
317(define-key viper-replace-map "\C-j" 'viper-replace-state-carriage-return)
318(define-key viper-replace-map "\C-m" 'viper-replace-state-carriage-return)
319(define-key viper-replace-map "\C-?" 'viper-del-backward-char-in-replace)
5ce05788 320(define-key viper-replace-map [backspace] 'viper-del-backward-char-in-replace)
6c2e12f4
KH
321
322
323\f
324;; Vi keymaps
325
3af0304a
MK
326(define-key viper-vi-basic-map "\C-^" (lambda ()
327 (interactive) (viper-ex nil "e#")))
8626cfa2
MK
328(define-key viper-vi-basic-map "\C-b" 'viper-scroll-screen-back)
329(define-key viper-vi-basic-map "\C-d" 'viper-scroll-up)
330(define-key viper-vi-basic-map "\C-e" 'viper-scroll-up-one)
331(define-key viper-vi-basic-map "\C-f" 'viper-scroll-screen)
332(define-key viper-vi-basic-map "\C-m" 'viper-next-line-at-bol)
333(define-key viper-vi-basic-map "\C-u" 'viper-scroll-down)
334(define-key viper-vi-basic-map "\C-y" 'viper-scroll-down-one)
ac64a728
MK
335;;(define-key viper-vi-basic-map "\C-s" 'viper-isearch-forward)
336;;(define-key viper-vi-basic-map "\C-r" 'viper-isearch-backward)
8626cfa2 337(define-key viper-vi-basic-map "\C-c/" 'viper-toggle-search-style)
3af0304a 338(define-key viper-vi-basic-map "\C-c\C-g" 'viper-info-on-file)
8626cfa2
MK
339
340(define-key viper-vi-basic-map "\C-c\M-p" 'viper-prev-destructive-command)
341(define-key viper-vi-basic-map "\C-c\M-n" 'viper-next-destructive-command)
342
343
344(define-key viper-vi-basic-map " " 'viper-forward-char)
345(define-key viper-vi-basic-map "!" 'viper-command-argument)
346(define-key viper-vi-basic-map "\"" 'viper-command-argument)
347(define-key viper-vi-basic-map "#" 'viper-command-argument)
348(define-key viper-vi-basic-map "$" 'viper-goto-eol)
349(define-key viper-vi-basic-map "%" 'viper-paren-match)
3af0304a
MK
350(define-key viper-vi-basic-map "&" (lambda ()
351 (interactive) (viper-ex nil "&")))
8626cfa2
MK
352(define-key viper-vi-basic-map "'" 'viper-goto-mark-and-skip-white)
353(define-key viper-vi-basic-map "(" 'viper-backward-sentence)
354(define-key viper-vi-basic-map ")" 'viper-forward-sentence)
355(define-key viper-vi-basic-map "*" 'call-last-kbd-macro)
356(define-key viper-vi-basic-map "+" 'viper-next-line-at-bol)
357(define-key viper-vi-basic-map "," 'viper-repeat-find-opposite)
358(define-key viper-vi-basic-map "-" 'viper-previous-line-at-bol)
359(define-key viper-vi-basic-map "." 'viper-repeat)
360(define-key viper-vi-basic-map "/" 'viper-search-forward)
361
362(define-key viper-vi-basic-map "0" 'viper-beginning-of-line)
363(define-key viper-vi-basic-map "1" 'viper-digit-argument)
364(define-key viper-vi-basic-map "2" 'viper-digit-argument)
365(define-key viper-vi-basic-map "3" 'viper-digit-argument)
366(define-key viper-vi-basic-map "4" 'viper-digit-argument)
367(define-key viper-vi-basic-map "5" 'viper-digit-argument)
368(define-key viper-vi-basic-map "6" 'viper-digit-argument)
369(define-key viper-vi-basic-map "7" 'viper-digit-argument)
370(define-key viper-vi-basic-map "8" 'viper-digit-argument)
371(define-key viper-vi-basic-map "9" 'viper-digit-argument)
372
373(define-key viper-vi-basic-map ":" 'viper-ex)
374(define-key viper-vi-basic-map ";" 'viper-repeat-find)
375(define-key viper-vi-basic-map "<" 'viper-command-argument)
376(define-key viper-vi-basic-map "=" 'viper-command-argument)
377(define-key viper-vi-basic-map ">" 'viper-command-argument)
378(define-key viper-vi-basic-map "?" 'viper-search-backward)
379(define-key viper-vi-basic-map "@" 'viper-register-macro)
380
381(define-key viper-vi-basic-map "A" 'viper-Append)
382(define-key viper-vi-basic-map "B" 'viper-backward-Word)
383(define-key viper-vi-basic-map "C" 'viper-change-to-eol)
384(define-key viper-vi-basic-map "D" 'viper-kill-line)
385(define-key viper-vi-basic-map "E" 'viper-end-of-Word)
386(define-key viper-vi-basic-map "F" 'viper-find-char-backward)
387(define-key viper-vi-basic-map "G" 'viper-goto-line)
388(define-key viper-vi-basic-map "H" 'viper-window-top)
389(define-key viper-vi-basic-map "I" 'viper-Insert)
390(define-key viper-vi-basic-map "J" 'viper-join-lines)
391(define-key viper-vi-basic-map "K" 'viper-nil)
392(define-key viper-vi-basic-map "L" 'viper-window-bottom)
393(define-key viper-vi-basic-map "M" 'viper-window-middle)
394(define-key viper-vi-basic-map "N" 'viper-search-Next)
395(define-key viper-vi-basic-map "O" 'viper-Open-line)
396(define-key viper-vi-basic-map "P" 'viper-Put-back)
397(define-key viper-vi-basic-map "Q" 'viper-query-replace)
398(define-key viper-vi-basic-map "R" 'viper-overwrite)
399(define-key viper-vi-basic-map "S" 'viper-substitute-line)
400(define-key viper-vi-basic-map "T" 'viper-goto-char-backward)
401(define-key viper-vi-basic-map "U" 'viper-undo)
402(define-key viper-vi-basic-map "V" 'find-file-other-window)
403(define-key viper-vi-basic-map "W" 'viper-forward-Word)
404(define-key viper-vi-basic-map "X" 'viper-delete-backward-char)
405(define-key viper-vi-basic-map "Y" 'viper-yank-line)
406(define-key viper-vi-basic-map "ZZ" 'viper-save-kill-buffer)
407
408(define-key viper-vi-basic-map "\\" 'viper-escape-to-emacs)
409(define-key viper-vi-basic-map "[" 'viper-brac-function)
410(define-key viper-vi-basic-map "]" 'viper-ket-function)
411(define-key viper-vi-basic-map "\C-\\" 'viper-alternate-Meta-key)
412(define-key viper-vi-basic-map "^" 'viper-bol-and-skip-white)
413(define-key viper-vi-basic-map "`" 'viper-goto-mark)
414
415(define-key viper-vi-basic-map "a" 'viper-append)
416(define-key viper-vi-basic-map "b" 'viper-backward-word)
417(define-key viper-vi-basic-map "c" 'viper-command-argument)
418(define-key viper-vi-basic-map "d" 'viper-command-argument)
419(define-key viper-vi-basic-map "e" 'viper-end-of-word)
420(define-key viper-vi-basic-map "f" 'viper-find-char-forward)
421(define-key viper-vi-basic-map "g" 'viper-nil)
422(define-key viper-vi-basic-map "h" 'viper-backward-char)
5ce05788 423(define-key viper-vi-basic-map [backspace] 'viper-backward-char)
8626cfa2
MK
424(define-key viper-vi-basic-map "i" 'viper-insert)
425(define-key viper-vi-basic-map "j" 'viper-next-line)
426(define-key viper-vi-basic-map "k" 'viper-previous-line)
427(define-key viper-vi-basic-map "l" 'viper-forward-char)
428(define-key viper-vi-basic-map "m" 'viper-mark-point)
429(define-key viper-vi-basic-map "n" 'viper-search-next)
430(define-key viper-vi-basic-map "o" 'viper-open-line)
431(define-key viper-vi-basic-map "p" 'viper-put-back)
432(define-key viper-vi-basic-map "q" 'viper-nil)
433(define-key viper-vi-basic-map "r" 'viper-replace-char)
434(define-key viper-vi-basic-map "s" 'viper-substitute)
435(define-key viper-vi-basic-map "t" 'viper-goto-char-forward)
436(define-key viper-vi-basic-map "u" 'viper-undo)
437(define-key viper-vi-basic-map "v" 'find-file)
438(define-key viper-vi-basic-map "\C-v" 'find-file-other-frame)
439(define-key viper-vi-basic-map "w" 'viper-forward-word)
440(define-key viper-vi-basic-map "x" 'viper-delete-char)
441(define-key viper-vi-basic-map "y" 'viper-command-argument)
442(define-key viper-vi-basic-map "zH" 'viper-line-to-top)
443(define-key viper-vi-basic-map "zM" 'viper-line-to-middle)
444(define-key viper-vi-basic-map "zL" 'viper-line-to-bottom)
445(define-key viper-vi-basic-map "z\C-m" 'viper-line-to-top)
446(define-key viper-vi-basic-map "z." 'viper-line-to-middle)
447(define-key viper-vi-basic-map "z-" 'viper-line-to-bottom)
448
449(define-key viper-vi-basic-map "{" 'viper-backward-paragraph)
450(define-key viper-vi-basic-map "|" 'viper-goto-col)
451(define-key viper-vi-basic-map "}" 'viper-forward-paragraph)
452(define-key viper-vi-basic-map "~" 'viper-toggle-case)
453(define-key viper-vi-basic-map "\C-?" 'viper-backward-char)
454(define-key viper-vi-basic-map "_" 'viper-nil)
8626cfa2 455
3af0304a 456;;; This is viper-vi-diehard-map. Used when viper-vi-diehard-minor-mode is on.
8626cfa2
MK
457
458(define-key viper-vi-diehard-map "\C-a" 'viper-nil)
459(define-key viper-vi-diehard-map "\C-c" 'viper-nil)
460(define-key viper-vi-diehard-map "\C-g" 'viper-info-on-file)
461(define-key viper-vi-diehard-map "\C-i" 'viper-nil)
462(define-key viper-vi-diehard-map "\C-k" 'viper-nil)
463(define-key viper-vi-diehard-map "\C-l" 'redraw-display)
464(define-key viper-vi-diehard-map "\C-n" 'viper-next-line)
465(define-key viper-vi-diehard-map "\C-o" 'viper-nil)
466(define-key viper-vi-diehard-map "\C-p" 'viper-previous-line)
467(define-key viper-vi-diehard-map "\C-q" 'viper-nil)
468(define-key viper-vi-diehard-map "\C-r" 'redraw-display)
469(define-key viper-vi-diehard-map "\C-s" 'viper-nil)
470(define-key viper-vi-diehard-map "\C-t" 'viper-nil)
471(define-key viper-vi-diehard-map "\C-v" 'viper-nil)
472(define-key viper-vi-diehard-map "\C-w" 'viper-nil)
473(define-key viper-vi-diehard-map "@" 'viper-nil)
474(define-key viper-vi-diehard-map "_" 'viper-nil)
475(define-key viper-vi-diehard-map "*" 'viper-nil)
476(define-key viper-vi-diehard-map "#" 'viper-nil)
477(define-key viper-vi-diehard-map "\C-_" 'viper-nil)
478(define-key viper-vi-diehard-map "\C-]" 'viper-nil) ; This is actually tags.
6c2e12f4
KH
479
480\f
481;;; Minibuffer keymap
a1506d29 482
6c2e12f4 483
8626cfa2 484(defvar viper-minibuffer-map (make-sparse-keymap)
6c2e12f4 485 "Keymap used to modify keys when Minibuffer is in Insert state.")
a1506d29 486
8626cfa2
MK
487(define-key viper-minibuffer-map "\C-m" 'viper-exit-minibuffer)
488(define-key viper-minibuffer-map "\C-j" 'viper-exit-minibuffer)
6c2e12f4
KH
489
490;; Map used to read Ex-style commands.
8626cfa2
MK
491(defvar viper-ex-cmd-map (make-sparse-keymap))
492(define-key viper-ex-cmd-map " " 'ex-cmd-read-exit)
493(define-key viper-ex-cmd-map "\t" 'ex-cmd-complete)
6c2e12f4
KH
494
495;; Keymap for reading file names in Ex-style commands.
496(defvar ex-read-filename-map (make-sparse-keymap))
8626cfa2
MK
497(define-key ex-read-filename-map " " 'viper-complete-filename-or-exit)
498(define-key ex-read-filename-map "!" 'viper-handle-!)
6c2e12f4 499
ab124470 500;; Some other maps
8626cfa2 501(defvar viper-slash-and-colon-map (make-sparse-keymap)
ab124470
MK
502 "This map redefines `/' and `:' to behave as in Vi.
503Useful in some modes, such as Gnus, MH, etc.")
8626cfa2
MK
504(define-key viper-slash-and-colon-map ":" 'viper-ex)
505(define-key viper-slash-and-colon-map "/" 'viper-search-forward)
ab124470 506
8626cfa2 507(defvar viper-comint-mode-modifier-map (make-sparse-keymap)
ab124470 508 "This map modifies comint mode.")
4960e757
MK
509(define-key viper-comint-mode-modifier-map "\C-m" 'viper-exec-key-in-emacs)
510(define-key viper-comint-mode-modifier-map "\C-d" 'viper-exec-key-in-emacs)
ab124470 511
8626cfa2 512(defvar viper-dired-modifier-map (make-sparse-keymap)
ab124470 513 "This map modifies Dired behavior.")
8626cfa2
MK
514(define-key viper-dired-modifier-map ":" 'viper-ex)
515(define-key viper-dired-modifier-map "/" 'viper-search-forward)
ab124470 516
3f9526a3
MK
517(defvar viper-gnus-modifier-map (make-sparse-keymap)
518 "This map modifies Gnus behavior.")
519(define-key viper-gnus-modifier-map ":" 'viper-ex)
520
6c2e12f4 521
6c2e12f4
KH
522\f
523;;; Code
524
8626cfa2 525(defun viper-add-local-keys (state alist)
6c2e12f4
KH
526 "Override some vi-state or insert-state bindings in the current buffer.
527The effect is seen in the current buffer only.
528Useful for customizing mailer buffers, gnus, etc.
529STATE is 'vi-state, 'insert-state, or 'emacs-state
530ALIST is of the form ((key . func) (key . func) ...)
531Normally, this would be called from a hook to a major mode or
532on a per buffer basis.
533Usage:
8626cfa2 534 (viper-add-local-keys state '((key-str . func) (key-str . func)...)) "
a1506d29 535
6c2e12f4
KH
536 (let (map)
537 (cond ((eq state 'vi-state)
8626cfa2
MK
538 (if viper-need-new-vi-local-map
539 (setq viper-vi-local-user-map (make-sparse-keymap)))
540 (setq viper-need-new-vi-local-map nil
541 map viper-vi-local-user-map))
6c2e12f4 542 ((eq state 'insert-state)
8626cfa2
MK
543 (if viper-need-new-insert-local-map
544 (setq viper-insert-local-user-map (make-sparse-keymap)))
545 (setq viper-need-new-insert-local-map nil
546 map viper-insert-local-user-map))
6c2e12f4 547 ((eq state 'emacs-state)
8626cfa2
MK
548 (if viper-need-new-emacs-local-map
549 (setq viper-emacs-local-user-map (make-sparse-keymap)))
550 (setq viper-need-new-emacs-local-map nil
551 map viper-emacs-local-user-map))
a1506d29 552 (t
6c2e12f4 553 (error
3af0304a 554 "Invalid state in viper-add-local-keys: %S. Valid states: vi-state, insert-state or emacs-state" state)))
6c2e12f4 555
8626cfa2
MK
556 (viper-modify-keymap map alist)
557 (viper-normalize-minor-mode-map-alist)
558 (viper-set-mode-vars-for viper-current-state)))
d3e1167f 559
8626cfa2
MK
560(defun viper-zap-local-keys ()
561 "Unconditionally reset Viper viper-*-local-user-map's.
8ea74b0e 562Rarely useful, but if you made a mistake by switching to a mode that adds
ab124470
MK
563undesirable local keys, e.g., comint-mode, then this function can restore
564sanity."
d3e1167f 565 (interactive)
8626cfa2
MK
566 (setq viper-vi-local-user-map (make-sparse-keymap)
567 viper-need-new-vi-local-map nil
568 viper-insert-local-user-map (make-sparse-keymap)
569 viper-need-new-insert-local-map nil
570 viper-emacs-local-user-map (make-sparse-keymap)
571 viper-need-new-emacs-local-map nil)
572 (viper-normalize-minor-mode-map-alist))
a1506d29 573
6c2e12f4 574
8626cfa2 575(defun viper-modify-major-mode (mode state keymap)
6c2e12f4
KH
576 "Modify key bindings in a major-mode in a Viper state using a keymap.
577
578If the default for a major mode is emacs-state, then modifications to this
579major mode may not take effect until the buffer switches state to Vi,
3af0304a
MK
580Insert or Emacs. If this happens, add viper-change-state-to-emacs to this
581major mode's hook. If no such hook exists, you may have to put an advice on
582the function that invokes the major mode. See viper-set-hooks for hints.
6c2e12f4
KH
583
584The above needs not to be done for major modes that come up in Vi or Insert
585state by default.
586
8626cfa2 587Arguments: (major-mode viper-state keymap)"
6c2e12f4 588 (let ((alist
8626cfa2
MK
589 (cond ((eq state 'vi-state) 'viper-vi-state-modifier-alist)
590 ((eq state 'insert-state) 'viper-insert-state-modifier-alist)
591 ((eq state 'emacs-state) 'viper-emacs-state-modifier-alist)))
6c2e12f4
KH
592 elt)
593 (if (setq elt (assoc mode (eval alist)))
594 (set alist (delq elt (eval alist))))
595 (set alist (cons (cons mode keymap) (eval alist)))
a1506d29 596
6c2e12f4
KH
597 ;; Normalization usually doesn't help here, since one needs to
598 ;; normalize in the actual buffer where changes to the keymap are
3af0304a 599 ;; to take place. However, it doesn't hurt, and it helps whenever this
2eb4bdca 600 ;; function is actually called from within the affected buffer.
8626cfa2 601 (viper-normalize-minor-mode-map-alist)
a1506d29 602
8626cfa2 603 (viper-set-mode-vars-for viper-current-state)))
6c2e12f4 604
a1506d29 605
546fe085 606;; Displays variables that control Viper's keymaps
8626cfa2 607(defun viper-debug-keymaps ()
6c2e12f4 608 (interactive)
8626cfa2 609 (with-output-to-temp-buffer " *viper-debug*"
6c2e12f4
KH
610 (princ (format "Buffer name: %s\n\n" (buffer-name)))
611 (princ "Variables: \n")
612 (princ (format "major-mode: %S\n" major-mode))
8626cfa2
MK
613 (princ (format "viper-current-state: %S\n" viper-current-state))
614 (princ (format "viper-mode-string: %S\n\n" viper-mode-string))
615 (princ (format "viper-vi-intercept-minor-mode: %S\n"
616 viper-vi-intercept-minor-mode))
617 (princ (format "viper-insert-intercept-minor-mode: %S\n"
618 viper-insert-intercept-minor-mode))
619 (princ (format "viper-emacs-intercept-minor-mode: %S\n"
620 viper-emacs-intercept-minor-mode))
621 (princ (format "viper-vi-minibuffer-minor-mode: %S\n"
622 viper-vi-minibuffer-minor-mode))
623 (princ (format "viper-insert-minibuffer-minor-mode: %S\n\n"
624 viper-insert-minibuffer-minor-mode))
625 (princ (format "viper-vi-local-user-minor-mode: %S\n"
626 viper-vi-local-user-minor-mode))
627 (princ (format "viper-vi-global-user-minor-mode: %S\n"
628 viper-vi-global-user-minor-mode))
629 (princ (format "viper-vi-kbd-minor-mode: %S\n" viper-vi-kbd-minor-mode))
630 (princ (format "viper-vi-state-modifier-minor-mode: %S\n"
631 viper-vi-state-modifier-minor-mode))
632 (princ (format "viper-vi-diehard-minor-mode: %S\n"
633 viper-vi-diehard-minor-mode))
634 (princ (format "viper-vi-basic-minor-mode: %S\n" viper-vi-basic-minor-mode))
635 (princ (format "viper-replace-minor-mode: %S\n" viper-replace-minor-mode))
636 (princ (format "viper-insert-local-user-minor-mode: %S\n"
637 viper-insert-local-user-minor-mode))
638 (princ (format "viper-insert-global-user-minor-mode: %S\n"
639 viper-insert-global-user-minor-mode))
640 (princ (format "viper-insert-kbd-minor-mode: %S\n"
a1506d29 641 viper-insert-kbd-minor-mode))
8626cfa2
MK
642 (princ (format "viper-insert-state-modifier-minor-mode: %S\n"
643 viper-insert-state-modifier-minor-mode))
644 (princ (format "viper-insert-diehard-minor-mode: %S\n"
645 viper-insert-diehard-minor-mode))
646 (princ (format "viper-insert-basic-minor-mode: %S\n"
647 viper-insert-basic-minor-mode))
648 (princ (format "viper-emacs-local-user-minor-mode: %S\n"
649 viper-emacs-local-user-minor-mode))
650 (princ (format "viper-emacs-kbd-minor-mode: %S\n"
651 viper-emacs-kbd-minor-mode))
652 (princ (format "viper-emacs-global-user-minor-mode: %S\n"
653 viper-emacs-global-user-minor-mode))
654 (princ (format "viper-emacs-state-modifier-minor-mode: %S\n"
655 viper-emacs-state-modifier-minor-mode))
a1506d29 656
1e70790f 657 (princ (format "\nviper-expert-level %S\n" viper-expert-level))
8626cfa2 658 (princ (format "viper-no-multiple-ESC %S\n" viper-no-multiple-ESC))
e36a387d 659 (princ (format "viper-always %S\n" viper-always))
8626cfa2
MK
660 (princ (format "viper-ex-style-motion %S\n"
661 viper-ex-style-motion))
34317da2
MK
662 (princ (format "viper-ex-style-editing %S\n"
663 viper-ex-style-editing))
8626cfa2 664 (princ (format "viper-want-emacs-keys-in-vi %S\n"
a1506d29 665 viper-want-emacs-keys-in-vi))
8626cfa2 666 (princ (format "viper-want-emacs-keys-in-insert %S\n"
a1506d29 667 viper-want-emacs-keys-in-insert))
8626cfa2 668 (princ (format "viper-want-ctl-h-help %S\n" viper-want-ctl-h-help))
a1506d29 669
6c2e12f4
KH
670 (princ "\n\n\n")
671 (princ (format "Default value for minor-mode-map-alist: \n%S\n\n"
672 (default-value 'minor-mode-map-alist)))
673 (princ (format "Actual value for minor-mode-map-alist: \n%S\n"
674 minor-mode-map-alist))
675 ))
a1506d29 676
6c2e12f4
KH
677
678;;; Keymap utils
a1506d29
JB
679
680(defun viper-add-keymap (mapsrc mapdst)
3af0304a 681 "Add contents of mapsrc to mapdst. It is assumed that mapsrc is sparse."
fe4f1247
GM
682 (if (featurep 'xemacs)
683 ;; Emacs 22 has map-keymap.
684 (map-keymap (lambda (key binding) (define-key mapdst key binding))
685 mapsrc)
686 (mapc (lambda (p) (define-key mapdst (vector (car p)) (cdr p)))
687 (cdr mapsrc))))
a1506d29 688
8626cfa2 689(defun viper-modify-keymap (map alist)
3af0304a 690 "Modifies MAP with bindings specified in the ALIST. The alist has the
6c2e12f4 691form ((key . function) (key . function) ... )."
a1506d29 692 (mapcar (lambda (p) (define-key map (eval (car p)) (cdr p)))
6c2e12f4
KH
693 alist))
694
695
694bc3c6
GM
696(provide 'viper-keym)
697
698
1e70790f 699;;; Local Variables:
8626cfa2 700;;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun)
1e70790f
MK
701;;; End:
702
703
cbee283d 704;; arch-tag: 43af4b2f-0bea-400b-889e-221ebc00acb1
60370d40 705;;; viper-keym.el ends here