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