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