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