26263
|
1 ;;; viper.el --- A full-featured Vi emulator for GNU Emacs and XEmacs,
|
10789
|
2 ;; a VI Plan for Emacs Rescue,
|
|
3 ;; and a venomous VI PERil.
|
|
4 ;; Viper Is also a Package for Emacs Rebels.
|
14232
|
5 ;;
|
|
6 ;; Keywords: emulations
|
|
7 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
|
|
8
|
27899
42f9a58e0fc4
* viper-cmd.el (viper-envelop-ESC-key): added the option to
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
9 ;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
|
18047
|
10
|
35411
|
11 (defconst viper-version "3.09 of January 19, 2001"
|
14232
|
12 "The current version of Viper")
|
14169
|
13
|
10789
|
14 ;; This file is part of GNU Emacs.
|
|
15
|
|
16 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
17 ;; it under the terms of the GNU General Public License as published by
|
|
18 ;; the Free Software Foundation; either version 2, or (at your option)
|
|
19 ;; any later version.
|
|
20
|
|
21 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
24 ;; GNU General Public License for more details.
|
|
25
|
|
26 ;; You should have received a copy of the GNU General Public License
|
15742
|
27 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
28 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
29 ;; Boston, MA 02111-1307, USA.
|
10789
|
30
|
|
31 ;;; Commentary:
|
|
32
|
26263
|
33 ;; Viper is a full-featured Vi emulator for Emacs and XEmacs. It emulates and
|
10789
|
34 ;; improves upon the standard features of Vi and, at the same time, allows
|
|
35 ;; full access to all Emacs facilities. Viper supports multiple undo,
|
|
36 ;; file name completion, command, file, and search history and it extends
|
26263
|
37 ;; Vi in many other ways. Viper is highly customizable through the various
|
10789
|
38 ;; hooks, user variables, and keymaps. It is implemented as a collection
|
|
39 ;; of minor modes and it is designed to provide full access to all Emacs
|
|
40 ;; major and minor modes.
|
|
41 ;;
|
|
42 ;;; History
|
|
43 ;;
|
|
44 ;; Viper is a new name for a package formerly known as VIP-19,
|
|
45 ;; which was a successor of VIP version 3.5 by Masahiko Sato
|
|
46 ;; <ms@sail.stanford.edu> and VIP version 4.2 by Aamod Sane
|
26263
|
47 ;; <sane@cs.uiuc.edu>. Some ideas from vip 4.4.2 by Aamod Sane
|
10789
|
48 ;; were also shamelessly plagiarized.
|
|
49 ;;
|
|
50 ;; Viper maintains some degree of compatibility with these older
|
26263
|
51 ;; packages. See the documentation for customization.
|
10789
|
52 ;;
|
|
53 ;; The main difference between Viper and these older packages are:
|
|
54 ;;
|
|
55 ;; 1. Viper emulates Vi at several levels, from almost complete conformity
|
|
56 ;; to a rather loose Vi-compliance.
|
|
57 ;;
|
|
58 ;; 2. Viper provides full access to all major and minor modes of Emacs
|
|
59 ;; without the need to type extra keys.
|
|
60 ;; The older versions of VIP (and other Vi emulators) do not work with
|
|
61 ;; some major and minor modes.
|
|
62 ;;
|
|
63 ;; 3. Viper supports vi-style undo.
|
|
64 ;;
|
|
65 ;; 4. Viper fully emulates (and improves upon) vi's replacement mode.
|
|
66 ;;
|
|
67 ;; 5. Viper has a better interface to ex, including command, variable, and
|
|
68 ;; file name completion.
|
|
69 ;;
|
|
70 ;; 6. Viper uses native Emacs history and completion features; it doesn't
|
|
71 ;; rely on other packages (such as gmhist.el and completer.el) to provide
|
|
72 ;; these features.
|
|
73 ;;
|
|
74 ;; 7. Viper supports Vi-style editing in the minibuffer, by allowing the
|
|
75 ;; user to switch from Insert state to Vi state to Replace state, etc.
|
|
76 ;;
|
|
77 ;; 8. Viper keeps history of recently inserted pieces of text and recently
|
|
78 ;; executed Vi-style destructive commands, such as `i', `d', etc.
|
|
79 ;; These pieces of text can be inserted in later insertion commands;
|
|
80 ;; the previous destructive commands can be re-executed.
|
|
81 ;;
|
|
82 ;; 9. Viper has Vi-style keyboard macros, which enhances the similar
|
|
83 ;; facility in the original Vi.
|
|
84 ;; First, one can execute any Emacs command while defining a
|
26263
|
85 ;; macro, not just the Vi commands. Second, macros are defined in a
|
10789
|
86 ;; WYSYWYG mode, using an interface to Emacs' WYSIWYG style of defining
|
26263
|
87 ;; macros. Third, in Viper, one can define macros that are specific to
|
10789
|
88 ;; a given buffer, a given major mode, or macros defined for all buffers.
|
|
89 ;; The same macro name can have several different definitions:
|
|
90 ;; one global, several definitions for various major modes, and
|
|
91 ;; definitions for specific buffers.
|
15739
|
92 ;; Buffer-specific definitions override mode-specific
|
10789
|
93 ;; definitions, which, in turn, override global definitions.
|
|
94 ;;
|
|
95 ;;
|
|
96 ;;; Installation:
|
|
97 ;; -------------
|
|
98 ;;
|
|
99 ;; (require 'viper)
|
|
100 ;;
|
|
101
|
|
102 ;;; Acknowledgements:
|
|
103 ;; -----------------
|
15739
|
104 ;; Bug reports and ideas contributed by many users have helped
|
|
105 ;; improve Viper and the various versions of VIP.
|
12691
|
106 ;; See the on-line manual for a complete list of contributors.
|
10789
|
107 ;;
|
|
108 ;;
|
|
109 ;;; Notes:
|
|
110 ;;
|
|
111 ;; 1. Major modes.
|
|
112 ;; In most cases, Viper handles major modes correctly, i.e., they come up
|
26263
|
113 ;; in the right state (either vi-state or emacs-state). For instance, text
|
10789
|
114 ;; files come up in vi-state, while, say, Dired appears in emacs-state by
|
|
115 ;; default.
|
|
116 ;; However, some modes do not appear in the right mode in the beginning,
|
|
117 ;; usually because they neglect to follow Emacs conventions (e.g., they don't
|
26263
|
118 ;; use kill-all-local-variables when they start). Some major modes
|
10789
|
119 ;; may fail to come up in emacs-state if they call hooks, such as
|
|
120 ;; text-hook, for no good reason.
|
|
121 ;;
|
|
122 ;; As an immediate solution, you can hit C-z to bring about the right mode.
|
|
123 ;; An interim solution is to add an appropriate hook to the mode like this:
|
|
124 ;;
|
|
125 ;; (add-hook 'your-favorite-mode 'viper-mode)
|
|
126 ;; or
|
19079
|
127 ;; (add-hook 'your-favorite-mode 'viper-change-state-to-emacs)
|
10789
|
128 ;;
|
26263
|
129 ;; whichever applies. The right thing to do, however, is to complain to the
|
10789
|
130 ;; author of the respective package. (Sometimes they also neglect to equip
|
|
131 ;; their modes with hooks, which is one more reason for complaining.)
|
|
132 ;;
|
|
133 ;; 2. Keymap handling
|
19079
|
134 ;; Each Viper state (insert, vi, replace) is implemented as a collection of
|
|
135 ;; several minor modes, each with its own keymap.
|
10789
|
136 ;;
|
|
137 ;; Viper's Vi state consists of seven minor modes:
|
|
138 ;;
|
19079
|
139 ;; viper-vi-intercept-minor-mode
|
|
140 ;; viper-vi-local-user-minor-mode
|
|
141 ;; viper-vi-global-user-minor-mode
|
|
142 ;; viper-vi-kbd-minor-mode
|
|
143 ;; viper-vi-state-modifier-minor-mode
|
|
144 ;; viper-vi-diehard-minor-mode
|
|
145 ;; viper-vi-basic-minor-mode
|
10789
|
146 ;;
|
|
147 ;; Bindings done to the keymap of the first mode overshadow those done to
|
|
148 ;; the second, which, in turn, overshadows those done to the third, etc.
|
|
149 ;;
|
19079
|
150 ;; The last viper-vi-basic-minor-mode contains most of the usual Vi bindings
|
26263
|
151 ;; in its edit mode. This mode provides access to all Emacs facilities.
|
18839
|
152 ;; Novice users, however, may want to set their viper-expert-level to 1
|
26263
|
153 ;; in their .viper file. This will enable viper-vi-diehard-minor-mode. This
|
10789
|
154 ;; minor mode's bindings make Viper simulate the usual Vi very closely.
|
|
155 ;; For instance, C-c will not have its standard Emacs binding
|
|
156 ;; and so many of the goodies of Emacs are not available.
|
|
157 ;;
|
26263
|
158 ;; A skilled user should set viper-expert-level to at least 3. This will
|
15739
|
159 ;; enable `C-c' and many Emacs facilities will become available.
|
19079
|
160 ;; In this case, viper-vi-diehard-minor-mode is inactive.
|
10789
|
161 ;;
|
|
162 ;; Viper gurus should have at least
|
18839
|
163 ;; (setq viper-expert-level 4)
|
26263
|
164 ;; in their ~/.viper files. This will unsuppress all Emacs keys that are not
|
10789
|
165 ;; essential for VI-style editing.
|
|
166 ;; Pick-and-choose users may want to put
|
18839
|
167 ;; (setq viper-expert-level 5)
|
26263
|
168 ;; in ~/.viper. Viper will then leave it up to the user to set the variables
|
19079
|
169 ;; viper-want-* See viper-set-expert-level for details.
|
10789
|
170 ;;
|
19079
|
171 ;; The very first minor mode, viper-vi-intercept-minor-mode, is of no
|
26263
|
172 ;; concern for the user. It is needed to bind Viper's vital keys, such as
|
10789
|
173 ;; ESC and C-z.
|
|
174 ;;
|
19079
|
175 ;; The second mode, viper-vi-local-user-minor-mode, usually has an
|
26263
|
176 ;; empty keymap. However, the user can set bindings in this keymap, which
|
10789
|
177 ;; will overshadow the corresponding bindings in the other two minor
|
26263
|
178 ;; modes. This is useful, for example, for setting up ZZ in gnus,
|
10789
|
179 ;; rmail, mh-e, etc., to send message instead of saving it in a file.
|
|
180 ;; Likewise, in Dired mode, you may want to bind ZN and ZP to commands
|
|
181 ;; that would visit the next or the previous file in the Dired buffer.
|
26263
|
182 ;; Setting local keys is tricky, so don't do it directly. Instead, use
|
19079
|
183 ;; viper-add-local-keys function (see its doc).
|
10789
|
184 ;;
|
19079
|
185 ;; The third minor mode, viper-vi-global-user-minor-mode, is also intended
|
|
186 ;; for the users but, unlike viper-vi-local-user-minor-mode, its key
|
26263
|
187 ;; bindings are seen in all Viper buffers. This mode keys can be done
|
10789
|
188 ;; with define-key command.
|
|
189 ;;
|
19079
|
190 ;; The fourth minor mode, viper-vi-kbd-minor-mode, is used by keyboard
|
26263
|
191 ;; macros. Users are NOT supposed to modify this keymap directly.
|
10789
|
192 ;;
|
19079
|
193 ;; The fifth mode, viper-vi-state-modifier-minor-mode, can be used to set
|
10789
|
194 ;; key bindings that are visible in some major modes but not in others.
|
|
195 ;;
|
|
196 ;; Users are allowed to modify keymaps that belong to
|
19079
|
197 ;; viper-vi-local-user-minor-mode, viper-vi-global-user-minor-mode,
|
|
198 ;; and viper-vi-state-modifier-minor-mode only.
|
10789
|
199 ;;
|
|
200 ;; Viper's Insert state also has seven minor modes:
|
|
201 ;;
|
19079
|
202 ;; viper-insert-intercept-minor-mode
|
|
203 ;; viper-insert-local-user-minor-mode
|
|
204 ;; viper-insert-global-user-minor-mode
|
|
205 ;; viper-insert-kbd-minor-mode
|
|
206 ;; viper-insert-state-modifier-minor-mode
|
|
207 ;; viper-insert-diehard-minor-mode
|
|
208 ;; viper-insert-basic-minor-mode
|
10789
|
209 ;;
|
19079
|
210 ;; As with VI's editing modes, the first mode,
|
|
211 ;; viper-insert-intercept-minor-mode is used to bind vital keys that are not
|
|
212 ;; to be changed by the user.
|
10789
|
213 ;;
|
19079
|
214 ;; The next mode, viper-insert-local-user-minor-mode, is used to customize
|
26263
|
215 ;; bindings in the insert state of Viper. The third mode,
|
19079
|
216 ;; viper-insert-global-user-minor-mode is like
|
|
217 ;; viper-insert-local-user-minor-mode, except that its bindings are seen in
|
26263
|
218 ;; all Viper buffers. As with viper-vi-local-user-minor-mode, its bindings
|
|
219 ;; should be done via the function viper-add-local-keys. Bindings for
|
19079
|
220 ;; viper-insert-global-user-minor-mode can be set with the define-key command.
|
10789
|
221 ;;
|
19079
|
222 ;; The next minor mode, viper-insert-kbd-minor-mode,
|
10789
|
223 ;; is used for keyboard VI-style macros defined with :map!.
|
|
224 ;;
|
19079
|
225 ;; The fifth minor mode, viper-insert-state-modifier-minor-mode, is like
|
|
226 ;; viper-vi-state-modifier-minor-mode, except that it is used in the Insert
|
10789
|
227 ;; state; it can be used to modify keys in a mode-specific fashion.
|
|
228 ;;
|
19079
|
229 ;; The minor mode viper-insert-diehard-minor-mode is in effect when
|
10789
|
230 ;; the user wants a high degree of Vi compatibility (a bad idea, really!).
|
19079
|
231 ;; The last minor mode, viper-insert-basic-minor-mode, is always in effect
|
26263
|
232 ;; when Viper is in insert state. It binds a small number of keys needed for
|
10789
|
233 ;; Viper's operation.
|
|
234 ;;
|
|
235 ;; Finally, Viper provides minor modes for overriding bindings set by Emacs
|
|
236 ;; modes when Viper is in Emacs state:
|
|
237 ;;
|
19079
|
238 ;; viper-emacs-local-user-minor-mode
|
|
239 ;; viper-emacs-global-user-minor-mode
|
|
240 ;; viper-emacs-kbd-minor-mode
|
|
241 ;; viper-emacs-state-modifier-minor-mode
|
10789
|
242 ;;
|
26263
|
243 ;; These minor modes are in effect when Viper is in Emacs state. The keymap
|
19079
|
244 ;; associated with viper-emacs-global-user-minor-mode,
|
|
245 ;; viper-emacs-global-user-map, overrides the global and local keymaps as
|
26263
|
246 ;; well as the minor mode keymaps set by other modes. The keymap of
|
19079
|
247 ;; viper-emacs-local-user-minor-mode, viper-emacs-local-user-map, overrides
|
10789
|
248 ;; everything, but it is used on a per buffer basis.
|
19079
|
249 ;; The keymap associated with viper-emacs-state-modifier-minor-mode
|
26263
|
250 ;; overrides keys on a per-major-mode basis. The mode
|
19079
|
251 ;; viper-emacs-kbd-minor-mode is used to define Vi-style macros in Emacs
|
10789
|
252 ;; state.
|
|
253 ;;
|
|
254 ;; 3. There is also one minor mode that is used when Viper is in its
|
26263
|
255 ;; replace-state (used for commands like cw, C, etc.). This mode is
|
10789
|
256 ;; called
|
|
257 ;;
|
19079
|
258 ;; viper-replace-minor-mode
|
10789
|
259 ;;
|
26263
|
260 ;; and its keymap is viper-replace-map. Replace minor mode is always
|
10789
|
261 ;; used in conjunction with the minor modes for insert-state, and its
|
|
262 ;; keymap overshadows the keymaps for insert minor modes.
|
|
263 ;;
|
|
264 ;; 4. Defining buffer-local bindings in Vi and Insert modes.
|
|
265 ;; As mentioned before, sometimes, it is convenient to have
|
|
266 ;; buffer-specific of mode-specific key bindings in Vi and insert modes.
|
19079
|
267 ;; Viper provides a special function, viper-add-local-keys, to do precisely
|
26263
|
268 ;; this. For instance, is you need to add couple of mode-specific bindings
|
10789
|
269 ;; to Insert mode, you can put
|
|
270 ;;
|
19079
|
271 ;; (viper-add-local-keys 'insert-state '((key1 . func1) (key2 .func2)))
|
10789
|
272 ;;
|
26263
|
273 ;; somewhere in a hook of this major mode. If you put something like this
|
10789
|
274 ;; in your own elisp function, this will define bindings specific to the
|
19079
|
275 ;; buffer that was current at the time of the call to viper-add-local-keys.
|
10789
|
276 ;; The only thing to make sure here is that the major mode of this buffer
|
|
277 ;; is written according to Emacs conventions, which includes a call to
|
26263
|
278 ;; (kill-all-local-variables). See viper-add-local-keys for more details.
|
10789
|
279 ;;
|
|
280 ;;
|
|
281 ;; TO DO (volunteers?):
|
|
282 ;;
|
|
283 ;; 1. Some of the code that is inherited from VIP-3.5 is rather
|
26263
|
284 ;; convoluted. Instead of viper-command-argument, keymaps should bind the
|
|
285 ;; actual commands. E.g., "dw" should be bound to a generic command
|
19079
|
286 ;; viper-delete that will delete things based on the value of
|
26263
|
287 ;; last-command-char. This would greatly simplify the logic and the code.
|
10789
|
288 ;;
|
|
289 ;; 2. Somebody should venture to write a customization package a la
|
|
290 ;; options.el that would allow the user to change values of variables
|
|
291 ;; that meet certain specs (e.g., match a regexp) and whose doc string
|
26263
|
292 ;; starts with a '*'. Then, the user should be offered to save
|
|
293 ;; variables that were changed. This will make user's customization job
|
10789
|
294 ;; much easier.
|
|
295 ;;
|
|
296
|
14909
|
297 ;; Code
|
10789
|
298
|
|
299 (require 'advice)
|
|
300 (require 'cl)
|
|
301 (require 'ring)
|
|
302
|
18172
|
303 ;; compiler pacifier
|
|
304 (defvar mark-even-if-inactive)
|
19462
|
305 (defvar quail-mode)
|
18839
|
306 (defvar viper-expert-level)
|
21940
|
307 (defvar viper-mode-string)
|
|
308 (defvar viper-major-mode-modifier-list)
|
18172
|
309
|
|
310 ;; loading happens only in non-interactive compilation
|
|
311 ;; in order to spare non-viperized emacs from being viperized
|
|
312 (if noninteractive
|
|
313 (eval-when-compile
|
|
314 (let ((load-path (cons (expand-file-name ".") load-path)))
|
18907
|
315 (or (featurep 'viper-init)
|
|
316 (load "viper-init.el" nil nil 'nosuffix))
|
18172
|
317 (or (featurep 'viper-cmd)
|
|
318 (load "viper-cmd.el" nil nil 'nosuffix))
|
|
319 )))
|
|
320 ;; end pacifier
|
10789
|
321
|
18896
|
322 (require 'viper-init)
|
|
323
|
18839
|
324 ;; better be defined before Viper custom group.
|
19079
|
325 (defvar viper-custom-file-name (convert-standard-filename "~/.viper")
|
18839
|
326 "Viper customisation file.
|
|
327 If set by the user, this must be done _before_ Viper is loaded in `~/.emacs'.")
|
|
328
|
|
329 (defgroup viper nil
|
|
330 "Vi emulation within Emacs.
|
19079
|
331 NOTE: Viper customization should be saved in `viper-custom-file-name', which
|
18839
|
332 defaults to `~/.viper'."
|
19079
|
333 :prefix "viper-"
|
18839
|
334 :group 'emulations)
|
|
335
|
18129
|
336 (require 'viper-cmd)
|
10789
|
337
|
20003
|
338 (defgroup viper-misc nil
|
|
339 "Miscellaneous Viper customization."
|
|
340 :prefix "viper-"
|
|
341 :group 'viper)
|
|
342
|
|
343
|
19079
|
344 (defcustom viper-always t
|
18289
|
345 "Non-nil means, arrange for vi-state to be a default when appropriate.
|
|
346 This is different from `viper-mode' variable in that `viper-mode' determines
|
|
347 whether to use Viper in the first place, while `viper-always', if nil, lets
|
18839
|
348 user decide when to invoke Viper in a major mode."
|
|
349 :type 'boolean
|
|
350 :tag "Always Invoke Viper"
|
20003
|
351 :group 'viper-misc)
|
10789
|
352
|
18839
|
353 ;; Non-viper variables that need to be saved in case the user decides to
|
|
354 ;; de-viperize emacs.
|
|
355 (defvar viper-saved-non-viper-variables nil)
|
|
356 ;; Contains user settings for vars affected by viper-set-expert-level function.
|
|
357 ;; Not a user option.
|
|
358 (defvar viper-saved-user-settings nil)
|
|
359
|
|
360 (defcustom viper-mode (cond (noninteractive nil)
|
|
361 (t 'ask))
|
|
362 "To Viperize or not to Viperize.
|
26263
|
363 If t, viperize emacs. If nil -- don't. If `ask', ask the user.
|
18289
|
364 This variable is used primatily when Viper is being loaded.
|
|
365
|
|
366 Must be set in `~/.emacs' before Viper is loaded.
|
20003
|
367 DO NOT set this variable interactively, unless you are using the customization
|
|
368 widget."
|
18839
|
369 :type '(choice (const nil) (const t) (const ask))
|
|
370 :tag "Set Viper Mode on Loading"
|
20003
|
371 :group 'viper-misc)
|
18289
|
372
|
21940
|
373 (defcustom viper-vi-state-mode-list
|
|
374 '(fundamental-mode
|
|
375 makefile-mode
|
|
376 help-mode
|
|
377
|
|
378 awk-mode
|
|
379 m4-mode
|
26263
|
380 xrdb-mode
|
|
381 winmgr-mode
|
|
382 autoconf-mode
|
|
383 cvs-edit-mode
|
21940
|
384
|
|
385 html-mode html-helper-mode
|
|
386 emacs-lisp-mode lisp-mode lisp-interaction-mode
|
|
387
|
26263
|
388 jde-mode java-mode
|
|
389 cc-mode c-mode c++-mode objc-mode
|
21940
|
390 fortran-mode f90-mode
|
|
391 basic-mode
|
|
392 bat-mode
|
|
393 asm-mode
|
|
394 prolog-mode
|
26263
|
395 flora-mode
|
27899
42f9a58e0fc4
* viper-cmd.el (viper-envelop-ESC-key): added the option to
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
396 sql-mode
|
21940
|
397
|
|
398 text-mode indented-text-mode
|
|
399 tex-mode latex-mode bibtex-mode
|
27899
42f9a58e0fc4
* viper-cmd.el (viper-envelop-ESC-key): added the option to
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
400 ps-mode
|
21940
|
401
|
|
402 completion-list-mode
|
29412
|
403 diff-mode
|
21940
|
404
|
36607
|
405 perl-mode cperl-mode
|
21940
|
406 javascript-mode
|
|
407 tcl-mode
|
|
408 python-mode
|
|
409
|
|
410 sh-mode ksh-mode csh-mode
|
|
411
|
|
412 gnus-article-mode
|
|
413 mh-show-mode
|
|
414 )
|
|
415 "Major modes that require Vi command state."
|
19909
|
416 :type '(repeat symbol)
|
20003
|
417 :group 'viper-misc)
|
18958
|
418
|
21940
|
419 (defcustom viper-emacs-state-mode-list
|
|
420 '(custom-mode
|
|
421
|
|
422 dired-mode
|
|
423 efs-mode
|
|
424 tar-mode
|
|
425
|
|
426 mh-folder-mode
|
|
427 gnus-group-mode
|
|
428 gnus-summary-mode
|
|
429
|
|
430 Info-mode
|
|
431 Buffer-menu-mode
|
26263
|
432 compilation-mode
|
21940
|
433
|
|
434 view-mode
|
|
435 vm-mode
|
|
436 vm-summary-mode)
|
|
437 "*A list of major modes that should come up in Emacs state.
|
|
438 Normally, Viper would bring buffers up in Emacs state, unless the corresponding
|
|
439 major mode has been placed on `viper-vi-state-mode-list' or
|
26263
|
440 `viper-insert-state-mode-list'. So, don't place a new mode on this list,
|
|
441 unless it is coming up in a wrong Viper state."
|
21940
|
442 :type '(repeat symbol)
|
|
443 :group 'viper-misc)
|
|
444
|
|
445 (defcustom viper-insert-state-mode-list
|
33019
|
446 '(internal-ange-ftp-mode
|
|
447 comint-mode
|
|
448 eshell-mode
|
|
449 shell-mode)
|
21940
|
450 "*A list of major modes that should come up in Vi Insert state."
|
|
451 :type '(repeat symbol)
|
|
452 :group 'viper-misc)
|
|
453
|
|
454
|
|
455 ;; used to set viper-major-mode-modifier-list in defcustom
|
|
456 (defun viper-apply-major-mode-modifiers (&optional symbol value)
|
|
457 (if symbol
|
|
458 (set symbol value))
|
26263
|
459 (mapcar (lambda (triple)
|
|
460 (viper-modify-major-mode
|
|
461 (nth 0 triple) (nth 1 triple) (eval (nth 2 triple))))
|
21940
|
462 viper-major-mode-modifier-list))
|
|
463
|
|
464 (defcustom viper-major-mode-modifier-list
|
|
465 '((help-mode emacs-state viper-slash-and-colon-map)
|
|
466 (comint-mode insert-state viper-comint-mode-modifier-map)
|
|
467 (comint-mode vi-state viper-comint-mode-modifier-map)
|
|
468 (shell-mode insert-state viper-comint-mode-modifier-map)
|
|
469 (shell-mode vi-state viper-comint-mode-modifier-map)
|
|
470 (ange-ftp-shell-mode insert-state viper-comint-mode-modifier-map)
|
|
471 (ange-ftp-shell-mode vi-state viper-comint-mode-modifier-map)
|
|
472 (internal-ange-ftp-mode insert-state viper-comint-mode-modifier-map)
|
|
473 (internal-ange-ftp-mode vi-state viper-comint-mode-modifier-map)
|
|
474 (dired-mode emacs-state viper-dired-modifier-map)
|
|
475 (tar-mode emacs-state viper-slash-and-colon-map)
|
|
476 (mh-folder-mode emacs-state viper-slash-and-colon-map)
|
|
477 (gnus-group-mode emacs-state viper-slash-and-colon-map)
|
|
478 (gnus-summary-mode emacs-state viper-slash-and-colon-map)
|
|
479 (Info-mode emacs-state viper-slash-and-colon-map)
|
|
480 (Buffer-menu-mode emacs-state viper-slash-and-colon-map)
|
|
481 )
|
|
482 "List specifying how to modify the various major modes to enable some Viperisms.
|
|
483 The list has the structure: ((mode viper-state keymap) (mode viper-state
|
26263
|
484 keymap) ...). If `mode' is on the list, the `kemap' will be made active (on
|
|
485 the minor-mode-map-alist) in the specified viper state.
|
21940
|
486 If you change this list, have to restart emacs for the change to take effect.
|
|
487 However, if you did the change through the customization widget, then emacs
|
|
488 needs to be restarted only if you deleted a triple mode-state-keymap from the
|
26263
|
489 list. No need to restart emacs in case of insertion or modification of an
|
21940
|
490 existing triple."
|
|
491 :type '(repeat
|
|
492 (list symbol
|
|
493 (choice (const emacs-state)
|
|
494 (const vi-state)
|
|
495 (const insert-state))
|
|
496 symbol))
|
|
497 :set 'viper-apply-major-mode-modifiers
|
|
498 :group 'viper-misc)
|
|
499
|
|
500
|
18958
|
501
|
18289
|
502
|
|
503
|
|
504 ;;;###autoload
|
19079
|
505 (defun toggle-viper-mode ()
|
20206
|
506 "Toggle Viper on/off.
|
26263
|
507 If Viper is enabled, turn it off. Otherwise, turn it on."
|
19079
|
508 (interactive)
|
|
509 (if (eq viper-mode t)
|
|
510 (viper-go-away)
|
|
511 (setq viper-mode nil)
|
|
512 (viper-mode)))
|
18289
|
513
|
|
514 ;;;###autoload
|
|
515 (defun viper-mode ()
|
|
516 "Turn on Viper emulation of Vi."
|
|
517 (interactive)
|
|
518 (if (not noninteractive)
|
|
519 (progn
|
|
520 ;; if the user requested viper-mode explicitly
|
|
521 (if viper-mode
|
|
522 ()
|
19079
|
523 (setq viper-mode t)
|
18289
|
524 (load-library "viper"))
|
|
525
|
26263
|
526 (if viper-first-time ; Important check. Prevents mix-up of startup
|
|
527 (progn ; and expert-level msgs when viper-mode recurses
|
19079
|
528 (setq viper-first-time nil)
|
26263
|
529 (setq viper-vi-state-cursor-color
|
|
530 (viper-get-cursor-color))
|
19079
|
531 (if (not viper-inhibit-startup-message)
|
18289
|
532 (save-window-excursion
|
19079
|
533 (setq viper-inhibit-startup-message t)
|
18289
|
534 (delete-other-windows)
|
|
535 (switch-to-buffer "Viper Startup Message")
|
|
536 (erase-buffer)
|
|
537 (insert
|
|
538 (substitute-command-keys
|
18839
|
539 "Viper Is a Package for Emacs Rebels,
|
|
540 a VI Plan for Emacs Rescue, and a venomous VI PERil.
|
18289
|
541
|
18839
|
542 Incidentally, Viper emulates Vi under GNU Emacs 20 and XEmacs 20.
|
|
543 It supports all of what is good in Vi and Ex, while extending
|
18289
|
544 and improving upon much of it.
|
|
545
|
26263
|
546 1. Viper supports Vi at several levels. Level 1 is the closest to Vi,
|
18289
|
547 level 5 provides the most flexibility to depart from many Vi conventions.
|
|
548
|
|
549 You will be asked to specify your user level in a following screen.
|
|
550
|
|
551 If you select user level 1 then the keys ^X, ^C, ^Z, and ^G will behave
|
26263
|
552 as in VI, to smooth transition to Viper for the beginners. However, to
|
18289
|
553 use Emacs productively, you are advised to reach user level 3 or higher.
|
|
554
|
18839
|
555 At user level 2 or higher, ^X and ^C have Emacs, not Vi, bindings;
|
|
556 ^Z toggles Vi/Emacs states; ^G is Emacs' keyboard-quit (like ^C in Vi).
|
18289
|
557
|
|
558 2. Vi exit functions (e.g., :wq, ZZ) work on INDIVIDUAL files -- they
|
18839
|
559 do not cause Emacs to quit, except at user level 1 (for a novice).
|
18289
|
560 3. ^X^C EXITS EMACS.
|
26263
|
561 4. Viper supports multiple undo: `u' will undo. Typing `.' will repeat
|
|
562 undo. Another `u' changes direction.
|
18289
|
563
|
18839
|
564 6. Emacs Meta key is `C-\\' (in all modes) or `\\ ESC' (in Vi command mode).
|
|
565 On a window system, the best way is to use the Meta-key on your keyboard.
|
18289
|
566 7. Try \\[keyboard-quit] and \\[abort-recursive-edit] repeatedly,if
|
26263
|
567 something funny happens. This would abort the current editing command.
|
18289
|
568
|
18839
|
569 For more information on Viper:
|
18289
|
570
|
18839
|
571 a. Type `:help' in Vi command mode
|
|
572 b. Print Viper manual, found in ./etc/viper.dvi
|
|
573 c. Print the Quick Reference, found in ./etc/viperCard.dvi
|
|
574
|
|
575 To submit a bug report or to contact the author, type :submitReport in Vi
|
26263
|
576 command mode. To shoo Viper away and return to pure Emacs (horror!), type:
|
18839
|
577
|
|
578 M-x viper-go-away
|
18289
|
579
|
|
580 This startup message appears whenever you load Viper, unless you type `y' now."
|
|
581 ))
|
|
582 (goto-char (point-min))
|
|
583 (if (y-or-n-p "Inhibit Viper startup message? ")
|
19079
|
584 (viper-save-setting
|
|
585 'viper-inhibit-startup-message
|
18289
|
586 "Viper startup message inhibited"
|
19079
|
587 viper-custom-file-name t))
|
18289
|
588 ;;(kill-buffer (current-buffer))
|
|
589 (message
|
|
590 "The last message is in buffer `Viper Startup Message'")
|
|
591 (sit-for 4)
|
|
592 ))
|
18839
|
593 (viper-set-expert-level 'dont-change-unless)))
|
18958
|
594
|
33842
f6a67d77484a
* ediff-diff.el: Moved variables around to have it compile under NT.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
595 (if viper-xemacs-p
|
f6a67d77484a
* ediff-diff.el: Moved variables around to have it compile under NT.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
596 (make-variable-buffer-local 'bar-cursor))
|
f6a67d77484a
* ediff-diff.el: Moved variables around to have it compile under NT.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
597
|
21940
|
598 (or (memq major-mode viper-emacs-state-mode-list) ; don't switch to Vi
|
|
599 (memq major-mode viper-insert-state-mode-list) ; don't switch
|
19079
|
600 (viper-change-state-to-vi)))))
|
10789
|
601
|
18129
|
602
|
12137
|
603 ;; This hook designed to enable Vi-style editing in comint-based modes."
|
19079
|
604 (defun viper-comint-mode-hook ()
|
16135
|
605 (setq require-final-newline nil
|
19462
|
606 viper-ex-style-editing nil
|
19079
|
607 viper-ex-style-motion nil)
|
|
608 (viper-change-state-to-insert))
|
16135
|
609
|
10789
|
610
|
18839
|
611 ;; remove viper hooks from SYMBOL
|
|
612 (defun viper-remove-hooks (symbol)
|
|
613 (cond ((not (boundp symbol)) nil)
|
|
614 ((not (listp (eval symbol))) nil)
|
|
615 ((string-match "-hook" (symbol-name symbol))
|
|
616 (remove-hook symbol 'viper-mode)
|
19079
|
617 (remove-hook symbol 'viper-change-state-to-emacs)
|
|
618 (remove-hook symbol 'viper-change-state-to-insert)
|
|
619 (remove-hook symbol 'viper-change-state-to-vi)
|
18839
|
620 )))
|
|
621
|
|
622 ;; Remove local value in all existing buffers
|
|
623 ;; This doesn't delocalize vars (which would have been desirable)
|
|
624 (defun viper-delocalize-var (symbol)
|
26263
|
625 (mapcar (lambda (buf) (save-excursion
|
|
626 (set-buffer buf)
|
|
627 (kill-local-variable symbol)))
|
18839
|
628 (buffer-list)))
|
|
629
|
|
630
|
|
631 (defun viper-go-away ()
|
|
632 "De-Viperize Emacs.
|
26263
|
633 This function tries to do as good a job as possible. However, it may undo some
|
|
634 user customization, unrelated to Viper. For instance, if the user advised
|
18839
|
635 `read-file-name', `describe-key', and some others, then this advice will be
|
|
636 undone.
|
26263
|
637 It also doesn't undo some Viper settings. For instance, `minor-mode-map-alist'
|
18839
|
638 remains buffer-local."
|
|
639 (interactive)
|
|
640
|
|
641 ;; restore non-viper vars
|
|
642 (setq-default
|
|
643 next-line-add-newlines
|
|
644 (viper-standard-value
|
|
645 'next-line-add-newlines viper-saved-non-viper-variables)
|
|
646 require-final-newline
|
|
647 (viper-standard-value
|
|
648 'require-final-newline viper-saved-non-viper-variables)
|
|
649 scroll-step
|
|
650 (viper-standard-value 'scroll-step viper-saved-non-viper-variables)
|
|
651 mode-line-buffer-identification
|
|
652 (viper-standard-value
|
18855
|
653 'mode-line-buffer-identification viper-saved-non-viper-variables)
|
|
654 global-mode-string
|
20343
|
655 (delq 'viper-mode-string global-mode-string))
|
18855
|
656
|
19079
|
657 (if viper-emacs-p
|
18855
|
658 (setq-default
|
|
659 mark-even-if-inactive
|
|
660 (viper-standard-value
|
|
661 'mark-even-if-inactive viper-saved-non-viper-variables)))
|
18839
|
662
|
|
663 ;; Ideally, we would like to be able to de-localize local variables
|
|
664 (viper-delocalize-var 'minor-mode-map-alist)
|
|
665 (viper-delocalize-var 'require-final-newline)
|
33842
f6a67d77484a
* ediff-diff.el: Moved variables around to have it compile under NT.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
666 (if viper-xemacs-p (viper-delocalize-var 'bar-cursor))
|
18839
|
667
|
|
668
|
|
669 ;; deactivate all advices done by Viper.
|
19079
|
670 (ad-deactivate-regexp "viper-")
|
18839
|
671
|
|
672 (setq viper-mode nil)
|
|
673
|
19079
|
674 (viper-delocalize-var 'viper-vi-minibuffer-minor-mode)
|
|
675 (viper-delocalize-var 'viper-insert-minibuffer-minor-mode)
|
|
676 (viper-delocalize-var 'viper-vi-intercept-minor-mode)
|
|
677 (viper-delocalize-var 'viper-insert-intercept-minor-mode)
|
18839
|
678
|
19079
|
679 (viper-delocalize-var 'viper-vi-local-user-minor-mode)
|
|
680 (viper-delocalize-var 'viper-vi-kbd-minor-mode)
|
|
681 (viper-delocalize-var 'viper-vi-global-user-minor-mode)
|
|
682 (viper-delocalize-var 'viper-vi-state-modifier-minor-mode)
|
|
683 (viper-delocalize-var 'viper-vi-diehard-minor-mode)
|
|
684 (viper-delocalize-var 'viper-vi-basic-minor-mode)
|
18839
|
685
|
19079
|
686 (viper-delocalize-var 'viper-replace-minor-mode)
|
18839
|
687
|
19079
|
688 (viper-delocalize-var 'viper-insert-local-user-minor-mode)
|
|
689 (viper-delocalize-var 'viper-insert-kbd-minor-mode)
|
|
690 (viper-delocalize-var 'viper-insert-global-user-minor-mode)
|
|
691 (viper-delocalize-var 'viper-insert-state-modifier-minor-mode)
|
|
692 (viper-delocalize-var 'viper-insert-diehard-minor-mode)
|
|
693 (viper-delocalize-var 'viper-insert-basic-minor-mode)
|
18839
|
694
|
19079
|
695 (viper-delocalize-var 'viper-emacs-intercept-minor-mode)
|
|
696 (viper-delocalize-var 'viper-emacs-local-user-minor-mode)
|
|
697 (viper-delocalize-var 'viper-emacs-kbd-minor-mode)
|
|
698 (viper-delocalize-var 'viper-emacs-global-user-minor-mode)
|
|
699 (viper-delocalize-var 'viper-emacs-state-modifier-minor-mode)
|
18839
|
700
|
20343
|
701 (viper-delocalize-var 'viper-current-state)
|
|
702 (viper-delocalize-var 'viper-mode-string)
|
|
703
|
19079
|
704 (setq-default viper-vi-minibuffer-minor-mode nil
|
|
705 viper-insert-minibuffer-minor-mode nil
|
|
706 viper-vi-intercept-minor-mode nil
|
|
707 viper-insert-intercept-minor-mode nil
|
18839
|
708
|
19079
|
709 viper-vi-local-user-minor-mode nil
|
|
710 viper-vi-kbd-minor-mode nil
|
|
711 viper-vi-global-user-minor-mode nil
|
|
712 viper-vi-state-modifier-minor-mode nil
|
|
713 viper-vi-diehard-minor-mode nil
|
|
714 viper-vi-basic-minor-mode nil
|
18839
|
715
|
19079
|
716 viper-replace-minor-mode nil
|
18839
|
717
|
19079
|
718 viper-insert-local-user-minor-mode nil
|
|
719 viper-insert-kbd-minor-mode nil
|
|
720 viper-insert-global-user-minor-mode nil
|
|
721 viper-insert-state-modifier-minor-mode nil
|
|
722 viper-insert-diehard-minor-mode nil
|
|
723 viper-insert-basic-minor-mode nil
|
18839
|
724
|
19079
|
725 viper-emacs-intercept-minor-mode nil
|
|
726 viper-emacs-local-user-minor-mode nil
|
|
727 viper-emacs-kbd-minor-mode nil
|
|
728 viper-emacs-global-user-minor-mode nil
|
|
729 viper-emacs-state-modifier-minor-mode nil
|
20343
|
730
|
|
731 viper-current-state 'emacs-state
|
|
732 viper-mode-string viper-emacs-state-id
|
18839
|
733 )
|
|
734
|
|
735 ;; remove all hooks set by viper
|
|
736 (mapatoms 'viper-remove-hooks)
|
19079
|
737 (remove-hook 'comint-mode-hook 'viper-comint-mode-hook)
|
|
738 (remove-hook 'minibuffer-setup-hook 'viper-minibuffer-setup-sentinel)
|
21940
|
739 (remove-hook 'change-major-mode-hook 'viper-major-mode-change-sentinel)
|
19079
|
740
|
|
741 ;; unbind Viper mouse bindings
|
|
742 (viper-unbind-mouse-search-key)
|
|
743 (viper-unbind-mouse-insert-key)
|
19203
|
744 ;; In emacs, we have to advice handle-switch-frame
|
|
745 ;; This advice is undone earlier, when all advices matchine "viper-" are
|
|
746 ;; deactivated.
|
|
747 (if viper-xemacs-p
|
|
748 (remove-hook 'mouse-leave-frame-hook 'viper-remember-current-frame))
|
|
749 ) ; end viper-go-away
|
18839
|
750
|
|
751
|
21940
|
752 ;; list of buffers that just changed their major mode
|
|
753 ;; used in a hack that triggers vi command mode whenever needed
|
|
754 (defvar viper-new-major-mode-buffer-list nil)
|
|
755
|
|
756 ;; set appropriate Viper state in buffers that changed major mode
|
|
757 (defun set-viper-state-in-major-mode ()
|
|
758 (mapcar
|
26263
|
759 (lambda (buf)
|
|
760 (if (viper-buffer-live-p buf)
|
|
761 (with-current-buffer buf
|
|
762 (cond ((and (memq major-mode viper-vi-state-mode-list)
|
|
763 (eq viper-current-state 'emacs-state))
|
|
764 (viper-mode))
|
|
765 ((memq major-mode viper-emacs-state-mode-list)
|
|
766 ;; not checking (eq viper-current-state 'emacs-state)
|
|
767 ;; because viper-current-state could have gotten it by
|
|
768 ;; default. We need viper-change-state-to-emacs here to have
|
|
769 ;; the keymaps take effect.
|
|
770 (viper-change-state-to-emacs))
|
|
771 ((and (memq major-mode viper-insert-state-mode-list)
|
|
772 (not (eq viper-current-state 'insert-state)))
|
|
773 (viper-change-state-to-insert))
|
|
774 )) ; with-current-buffer
|
|
775 )) ; function
|
21940
|
776 viper-new-major-mode-buffer-list)
|
|
777 ;; clear the list of bufs that changed major mode
|
|
778 (setq viper-new-major-mode-buffer-list nil)
|
|
779 ;; change the global value of hook
|
|
780 (remove-hook 'viper-post-command-hooks 'set-viper-state-in-major-mode))
|
|
781
|
|
782 ;; sets up post-command-hook to turn viper-mode, if the current mode is
|
|
783 ;; fundamental
|
|
784 (defun viper-major-mode-change-sentinel ()
|
|
785 (save-match-data
|
|
786 (or (string-match "\*Minibuf-" (buffer-name))
|
|
787 (setq viper-new-major-mode-buffer-list
|
|
788 (cons (current-buffer) viper-new-major-mode-buffer-list))))
|
|
789 ;; change the global value of hook
|
|
790 (add-hook 'viper-post-command-hooks 'set-viper-state-in-major-mode t))
|
|
791
|
18839
|
792
|
|
793
|
13214
|
794 ;; This sets major mode hooks to make them come up in vi-state.
|
19079
|
795 (defun viper-set-hooks ()
|
10789
|
796 ;; It is of course a misnomer to call viper-mode a `major mode'.
|
|
797 ;; However, this has the effect that if the user didn't specify the
|
|
798 ;; default mode, new buffers that fall back on the default will come up
|
|
799 ;; in Fundamental Mode and Vi state.
|
21940
|
800 (if (eq default-major-mode 'fundamental-mode)
|
|
801 (setq default-major-mode 'viper-mode))
|
18839
|
802
|
21940
|
803 (add-hook 'change-major-mode-hook 'viper-major-mode-change-sentinel)
|
|
804 (add-hook 'find-file-hooks 'set-viper-state-in-major-mode)
|
15480
|
805
|
21940
|
806 ;; keep this because many modes we don't know about use this hook
|
15480
|
807 (defvar text-mode-hook)
|
10789
|
808 (add-hook 'text-mode-hook 'viper-mode)
|
|
809
|
15480
|
810 (defvar emerge-startup-hook)
|
19079
|
811 (add-hook 'emerge-startup-hook 'viper-change-state-to-emacs)
|
16135
|
812
|
|
813 ;; Tell vc-diff to put *vc* in Vi mode
|
|
814 (if (featurep 'vc)
|
19079
|
815 (defadvice vc-diff (after viper-vc-ad activate)
|
16135
|
816 "Force Vi state in VC diff buffer."
|
19079
|
817 (viper-change-state-to-vi))
|
|
818 (eval-after-load
|
16135
|
819 "vc"
|
19079
|
820 '(defadvice vc-diff (after viper-vc-ad activate)
|
16135
|
821 "Force Vi state in VC diff buffer."
|
19079
|
822 (viper-change-state-to-vi))))
|
16135
|
823
|
19079
|
824 (eval-after-load
|
12137
|
825 "emerge"
|
19079
|
826 '(defadvice emerge-quit (after viper-emerge-advice activate)
|
|
827 "Run `viper-change-state-to-vi' after quitting emerge."
|
|
828 (viper-change-state-to-vi)))
|
10789
|
829 ;; In case Emerge was loaded before Viper.
|
19079
|
830 (defadvice emerge-quit (after viper-emerge-advice activate)
|
|
831 "Run `viper-change-state-to-vi' after quitting emerge."
|
|
832 (viper-change-state-to-vi))
|
10789
|
833
|
|
834 ;; passwd.el sets up its own buffer, which turns up in Vi mode,
|
26263
|
835 ;; thus overriding the local map. We don't need Vi mode here.
|
19079
|
836 (eval-after-load
|
10789
|
837 "passwd"
|
19079
|
838 '(defadvice read-passwd-1 (before viper-passwd-ad activate)
|
12137
|
839 "Switch to emacs state while reading password."
|
19079
|
840 (viper-change-state-to-emacs)))
|
10789
|
841
|
12137
|
842 ;; Emacs shell, ange-ftp, and comint-based modes
|
21940
|
843 (add-hook 'comint-mode-hook 'viper-comint-mode-hook) ; comint
|
16766
|
844
|
21940
|
845 (viper-set-emacs-state-searchstyle-macros nil 'dired-mode) ; dired
|
|
846 (viper-set-emacs-state-searchstyle-macros nil 'tar-mode) ; tar
|
|
847 (viper-set-emacs-state-searchstyle-macros nil 'mh-folder-mode) ; mhe
|
|
848 (viper-set-emacs-state-searchstyle-macros nil 'gnus-group-mode) ; gnus
|
19079
|
849 (viper-set-emacs-state-searchstyle-macros nil 'gnus-summary-mode)
|
21940
|
850 (viper-set-emacs-state-searchstyle-macros nil 'Info-mode) ; info
|
|
851 (viper-set-emacs-state-searchstyle-macros nil 'Buffer-menu-mode) ;buffer-menu
|
16135
|
852
|
21940
|
853 ;; Modify major modes according to viper-major-mode-modifier-list
|
|
854 (viper-apply-major-mode-modifiers)
|
10789
|
855
|
|
856 ;; For RMAIL users.
|
|
857 ;; Put buf in Emacs state after edit.
|
19079
|
858 (eval-after-load
|
10789
|
859 "rmailedit"
|
19079
|
860 '(defadvice rmail-cease-edit (after viper-rmail-advice activate)
|
12137
|
861 "Switch to emacs state when done editing message."
|
19079
|
862 (viper-change-state-to-emacs)))
|
10789
|
863 ;; In case RMAIL was loaded before Viper.
|
19079
|
864 (defadvice rmail-cease-edit (after viper-rmail-advice activate)
|
12137
|
865 "Switch to emacs state when done editing message."
|
19079
|
866 (viper-change-state-to-emacs))
|
19462
|
867
|
|
868 ;; ISO accents
|
|
869 ;; Need to do it after loading iso-acc, or else this loading will wipe out
|
|
870 ;; the advice.
|
|
871 (eval-after-load
|
|
872 "iso-acc"
|
|
873 (defadvice iso-accents-mode (around viper-iso-accents-advice activate)
|
|
874 "Set viper-automatic-iso-accents to iso-accents-mode."
|
|
875 (let ((arg (ad-get-arg 0)))
|
|
876 ad-do-it
|
|
877 (setq viper-automatic-iso-accents
|
|
878 (if (eq viper-current-state 'vi-state)
|
|
879 (if arg
|
|
880 ;; if iso-accents-mode was called with positive arg, turn
|
|
881 ;; accents on
|
|
882 (> (prefix-numeric-value arg) 0)
|
|
883 ;; else: toggle viper-automatic-iso-accents
|
|
884 (not viper-automatic-iso-accents))
|
|
885 ;; other states: accept what iso-accents-mode has done
|
|
886 iso-accents-mode))
|
|
887 ;; turn off ISO accents in vi-state
|
|
888 (if (eq viper-current-state 'vi-state)
|
|
889 (viper-set-iso-accents-mode nil))
|
|
890 (if (memq viper-current-state '(vi-state insert-state replace-state))
|
|
891 (message "Viper ISO accents mode: %s"
|
|
892 (if viper-automatic-iso-accents "on" "off")))
|
|
893 )))
|
|
894
|
|
895 ;; International input methods
|
|
896 (if viper-emacs-p
|
|
897 (eval-after-load "mule-cmds"
|
|
898 (progn
|
|
899 (defadvice inactivate-input-method (after viper-mule-advice activate)
|
|
900 "Set viper-special-input-method to disable intl. input methods."
|
|
901 (viper-inactivate-input-method-action))
|
|
902 (defadvice activate-input-method (after viper-mule-advice activate)
|
|
903 "Set viper-special-input-method to enable intl. input methods."
|
|
904 (viper-activate-input-method-action))
|
|
905 ))
|
|
906 ;; XEmacs Although these hooks exist in Emacs, they don't seem to be always
|
|
907 ;; called on input-method activation/deactivation, so we the above advise
|
|
908 ;; functions instead.
|
|
909 (eval-after-load "mule-cmds"
|
|
910 (progn
|
|
911 (add-hook 'input-method-activate-hook
|
|
912 'viper-activate-input-method-action t)
|
|
913 (add-hook 'input-method-inactivate-hook
|
|
914 'viper-inactivate-input-method-action t)))
|
|
915 )
|
|
916 (eval-after-load "mule-cmds"
|
|
917 (defadvice toggle-input-method (around viper-mule-advice activate)
|
|
918 "Adjust input-method toggling in vi-state."
|
|
919 (if (and viper-special-input-method (eq viper-current-state 'vi-state))
|
|
920 (viper-inactivate-input-method)
|
|
921 ad-do-it)))
|
|
922
|
19079
|
923 ) ; viper-set-hooks
|
18172
|
924
|
18289
|
925
|
|
926 ;; these are primarily advices and Vi-ish variable settings
|
19079
|
927 (defun viper-non-hook-settings ()
|
18172
|
928
|
19079
|
929 ;; This var is not local in Emacs, so we make it local. It must be local
|
|
930 ;; because although the stack of minor modes can be the same for all buffers,
|
26263
|
931 ;; the associated *keymaps* can be different. In Viper,
|
19079
|
932 ;; viper-vi-local-user-map, viper-insert-local-user-map, and others can have
|
|
933 ;; different keymaps for different buffers. Also, the keymaps associated
|
|
934 ;; with viper-vi/insert-state-modifier-minor-mode can be different.
|
18289
|
935 (make-variable-buffer-local 'minor-mode-map-alist)
|
|
936
|
|
937 ;; Viper changes the default mode-line-buffer-identification
|
|
938 (setq-default mode-line-buffer-identification '(" %b"))
|
|
939
|
|
940 ;; setup emacs-supported vi-style feel
|
|
941 (setq next-line-add-newlines nil
|
|
942 require-final-newline t)
|
|
943
|
|
944 (make-variable-buffer-local 'require-final-newline)
|
|
945
|
|
946 ;; don't bark when mark is inactive
|
19079
|
947 (if viper-emacs-p
|
18855
|
948 (setq mark-even-if-inactive t))
|
18289
|
949
|
|
950 (setq scroll-step 1)
|
|
951
|
|
952 ;; Variable displaying the current Viper state in the mode line.
|
19079
|
953 (viper-deflocalvar viper-mode-string viper-emacs-state-id)
|
|
954 (or (memq 'viper-mode-string global-mode-string)
|
18289
|
955 (setq global-mode-string
|
19079
|
956 (append '("" viper-mode-string) (cdr global-mode-string))))
|
18172
|
957
|
19079
|
958 (defadvice read-key-sequence (around viper-read-keyseq-ad activate)
|
26263
|
959 "Harness to work for Viper. This advice is harmless---don't worry!"
|
18289
|
960 (let (inhibit-quit event keyseq)
|
|
961 (setq keyseq ad-do-it)
|
19079
|
962 (setq event (if viper-xemacs-p
|
18289
|
963 (elt keyseq 0) ; XEmacs returns vector of events
|
|
964 (elt (listify-key-sequence keyseq) 0)))
|
19079
|
965 (if (viper-ESC-event-p event)
|
18289
|
966 (let (unread-command-events)
|
19079
|
967 (viper-set-unread-command-events keyseq)
|
|
968 (if (viper-fast-keysequence-p)
|
|
969 (let ((viper-vi-global-user-minor-mode nil)
|
|
970 (viper-vi-local-user-minor-mode nil)
|
|
971 (viper-replace-minor-mode nil) ; actually unnecessary
|
|
972 (viper-insert-global-user-minor-mode nil)
|
|
973 (viper-insert-local-user-minor-mode nil))
|
18289
|
974 (setq keyseq ad-do-it))
|
|
975 (setq keyseq ad-do-it))))
|
|
976 keyseq))
|
|
977
|
19079
|
978 (defadvice describe-key (before viper-read-keyseq-ad protect activate)
|
18289
|
979 "Force to read key via `read-key-sequence'."
|
19079
|
980 (interactive (list (viper-events-to-keys
|
18289
|
981 (read-key-sequence "Describe key: ")))))
|
|
982
|
19079
|
983 (defadvice describe-key-briefly
|
|
984 (before viper-read-keyseq-ad protect activate)
|
18289
|
985 "Force to read key via `read-key-sequence'."
|
19079
|
986 (interactive (list (viper-events-to-keys
|
18289
|
987 (read-key-sequence "Describe key briefly: ")))))
|
|
988
|
|
989
|
19079
|
990 (defadvice find-file (before viper-add-suffix-advice activate)
|
18289
|
991 "Use `read-file-name' for reading arguments."
|
|
992 (interactive (cons (read-file-name "Find file: " nil default-directory)
|
29412
|
993 ;; XEmacs: if Mule & prefix arg, ask for coding system
|
|
994 (cond ((and viper-xemacs-p (featurep 'mule))
|
18839
|
995 (list
|
|
996 (and current-prefix-arg
|
29412
|
997 (read-coding-system "Coding-system: "))))
|
|
998 ;; Emacs: do wildcards
|
|
999 ((and viper-emacs-p (boundp 'find-file-wildcards))
|
|
1000 (list find-file-wildcards))))
|
|
1001 ))
|
18289
|
1002
|
19079
|
1003 (defadvice find-file-other-window (before viper-add-suffix-advice activate)
|
18289
|
1004 "Use `read-file-name' for reading arguments."
|
|
1005 (interactive (cons (read-file-name "Find file in other window: "
|
|
1006 nil default-directory)
|
29412
|
1007 ;; XEmacs: if Mule & prefix arg, ask for coding system
|
|
1008 (cond ((and viper-xemacs-p (featurep 'mule))
|
18839
|
1009 (list
|
|
1010 (and current-prefix-arg
|
29412
|
1011 (read-coding-system "Coding-system: "))))
|
|
1012 ;; Emacs: do wildcards
|
|
1013 ((and viper-emacs-p (boundp 'find-file-wildcards))
|
|
1014 (list find-file-wildcards))))
|
|
1015 ))
|
18289
|
1016
|
18839
|
1017
|
19079
|
1018 (defadvice find-file-other-frame (before viper-add-suffix-advice activate)
|
18289
|
1019 "Use `read-file-name' for reading arguments."
|
|
1020 (interactive (cons (read-file-name "Find file in other frame: "
|
|
1021 nil default-directory)
|
29412
|
1022 ;; XEmacs: if Mule & prefix arg, ask for coding system
|
|
1023 (cond ((and viper-xemacs-p (featurep 'mule))
|
18839
|
1024 (list
|
|
1025 (and current-prefix-arg
|
29412
|
1026 (read-coding-system "Coding-system: "))))
|
|
1027 ;; Emacs: do wildcards
|
|
1028 ((and viper-emacs-p (boundp 'find-file-wildcards))
|
|
1029 (list find-file-wildcards))))
|
|
1030 ))
|
18839
|
1031
|
18289
|
1032
|
19079
|
1033 (defadvice read-file-name (around viper-suffix-advice activate)
|
|
1034 "Tell `exit-minibuffer' to run `viper-file-add-suffix' as a hook."
|
19756
|
1035 (let ((viper-minibuffer-exit-hook
|
21940
|
1036 (append viper-minibuffer-exit-hook
|
|
1037 '(viper-minibuffer-trim-tail viper-file-add-suffix))))
|
18289
|
1038 ad-do-it))
|
|
1039
|
19079
|
1040 (defadvice start-kbd-macro (after viper-kbd-advice activate)
|
18289
|
1041 "Remove Viper's intercepting bindings for C-x ).
|
|
1042 This may be needed if the previous `:map' command terminated abnormally."
|
19079
|
1043 (define-key viper-vi-intercept-map "\C-x)" nil)
|
|
1044 (define-key viper-insert-intercept-map "\C-x)" nil)
|
|
1045 (define-key viper-emacs-intercept-map "\C-x)" nil))
|
19203
|
1046
|
|
1047 ;; catch frame switching event
|
|
1048 (if (viper-window-display-p)
|
|
1049 (if viper-xemacs-p
|
|
1050 (add-hook 'mouse-leave-frame-hook
|
|
1051 'viper-remember-current-frame)
|
|
1052 (defadvice handle-switch-frame (before viper-frame-advice activate)
|
|
1053 "Remember the selected frame before the switch-frame event."
|
|
1054 (viper-remember-current-frame (selected-frame)))) )
|
|
1055
|
19079
|
1056 ) ; end viper-non-hook-settings
|
18172
|
1057
|
18289
|
1058
|
19203
|
1059 ;; Ask only if this-command/last-command are nil, i.e., when loading
|
|
1060 (cond ((and (eq viper-mode 'ask) (null this-command) (null last-command))
|
|
1061 (save-window-excursion
|
|
1062 (with-output-to-temp-buffer " *viper-info*"
|
|
1063 (princ "
|
18289
|
1064 You have loaded Viper, and are about to Viperize your emacs!
|
|
1065
|
19079
|
1066 Viper is a Package for Emacs Rebels and a venomous VI PERil,
|
18289
|
1067
|
|
1068 It's time to decide: to Viperize or not to Viperize...
|
18172
|
1069
|
18289
|
1070 If you wish to Viperize AND make this your way of life, please put
|
|
1071
|
|
1072 (setq viper-mode t)
|
|
1073 (require 'viper)
|
|
1074
|
|
1075 in your .emacs file (preferably, close to the top).
|
|
1076 These two lines must come in the order given.
|
|
1077
|
19079
|
1078 ** Viper users:
|
|
1079 **** The startup file name has been changed from .vip to .viper
|
|
1080 **** All vip-* style names have been converted to viper-* style."))
|
19203
|
1081 (if (y-or-n-p "Viperize? ")
|
|
1082 (setq viper-mode t)
|
|
1083 (setq viper-mode nil))
|
|
1084 (message "")
|
|
1085 (kill-buffer " *viper-info*")))
|
|
1086
|
26263
|
1087 ;; If viper-mode is t, then just continue. Viper will kick in.
|
19203
|
1088 ((eq viper-mode t))
|
21940
|
1089 ;; Otherwise, it was asking Viper was not loaded through .emacs
|
19203
|
1090 ;; In this case, it was either through M-x viper-mode or via something
|
26263
|
1091 ;; else, like the custom widget. If Viper was loaded through
|
19203
|
1092 ;; M-x viper-mode, then viper will kick in anyway.
|
|
1093 (t (setq viper-mode nil)))
|
19079
|
1094
|
|
1095 (defun viper-load-custom-file ()
|
|
1096 (if (and (file-exists-p viper-custom-file-name)
|
|
1097 (not noninteractive))
|
|
1098 (load viper-custom-file-name)))
|
18289
|
1099
|
18172
|
1100
|
|
1101
|
|
1102
|
26263
|
1103 ;; Get viper standard value of SYMBOL. If symbol is customized, get its
|
|
1104 ;; standard value. Otherwise, get the value saved in the alist STORAGE. If
|
18839
|
1105 ;; STORAGE is nil, use viper-saved-user-settings.
|
|
1106 (defun viper-standard-value (symbol &optional storage)
|
|
1107 (or (eval (car (get symbol 'customized-value)))
|
|
1108 (eval (car (get symbol 'saved-value)))
|
|
1109 (nth 1 (assoc symbol (or storage viper-saved-user-settings)))))
|
|
1110
|
|
1111
|
|
1112
|
|
1113 ;; save non-viper vars that Viper might change
|
|
1114 (if (null viper-saved-non-viper-variables)
|
|
1115 (setq viper-saved-non-viper-variables
|
|
1116 (list
|
|
1117 (cons 'next-line-add-newlines (list next-line-add-newlines))
|
|
1118 (cons 'require-final-newline (list require-final-newline))
|
|
1119 (cons 'scroll-step (list scroll-step))
|
|
1120 (cons 'mode-line-buffer-identification
|
|
1121 (list (default-value 'mode-line-buffer-identification)))
|
|
1122 (cons 'global-mode-string (list global-mode-string))
|
19079
|
1123 (if viper-emacs-p
|
18855
|
1124 (cons 'mark-even-if-inactive (list mark-even-if-inactive)))
|
18839
|
1125 )))
|
|
1126
|
10789
|
1127
|
18289
|
1128 ;; Set some useful macros, advices
|
18839
|
1129 ;; These must be BEFORE ~/.viper is loaded,
|
|
1130 ;; so the user can unrecord them in ~/.viper.
|
18289
|
1131 (if viper-mode
|
|
1132 (progn
|
|
1133 ;; set advices and some variables that give emacs Vi look.
|
19079
|
1134 (viper-non-hook-settings)
|
12900
7a7b8d42bdec
* viper.el (vip-set-hooks): Use view-mode-hook in emacs and view hook in xemacs.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
1135
|
18289
|
1136 ;; repeat the 2nd previous command without rotating the command history
|
19079
|
1137 (viper-record-kbd-macro
|
|
1138 (vector viper-repeat-from-history-key '\1) 'vi-state
|
|
1139 [(meta x) v i p e r - r e p e a t - f r o m - h i s t o r y return] 't)
|
18289
|
1140 ;; repeat the 3d previous command without rotating the command history
|
19079
|
1141 (viper-record-kbd-macro
|
|
1142 (vector viper-repeat-from-history-key '\2) 'vi-state
|
|
1143 [(meta x) v i p e r - r e p e a t - f r o m - h i s t o r y return] 't)
|
18289
|
1144
|
18839
|
1145 ;; set macros for toggling case sensitivity and regexp search
|
19079
|
1146 (viper-set-searchstyle-toggling-macros nil)
|
18289
|
1147 ;; Make %%% toggle parsing comments for matching parentheses
|
19079
|
1148 (viper-set-parsing-style-toggling-macro nil)
|
|
1149
|
|
1150 ;; ~/.viper is loaded if exists
|
|
1151 (viper-load-custom-file)
|
|
1152
|
|
1153 ;; should be after loading custom file to avoid the pesky msg that
|
|
1154 ;; mouse-search/insert keys are already bound
|
|
1155 (viper-bind-mouse-search-key)
|
|
1156 (viper-bind-mouse-insert-key)
|
18289
|
1157 ))
|
12900
7a7b8d42bdec
* viper.el (vip-set-hooks): Use view-mode-hook in emacs and view hook in xemacs.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
1158
|
10789
|
1159
|
|
1160
|
19079
|
1161 ;; Applying Viper customization -- runs after (load .viper)
|
10789
|
1162
|
18839
|
1163 ;; Save user settings or Viper defaults for vars controled by
|
|
1164 ;; viper-expert-level
|
|
1165 (if (null viper-saved-user-settings)
|
|
1166 (setq viper-saved-user-settings
|
19079
|
1167 (list (cons 'viper-want-ctl-h-help (list viper-want-ctl-h-help))
|
18839
|
1168 (cons 'viper-always (list viper-always))
|
19079
|
1169 (cons 'viper-no-multiple-ESC (list viper-no-multiple-ESC))
|
|
1170 (cons 'viper-ex-style-motion (list viper-ex-style-motion))
|
19462
|
1171 (cons 'viper-ex-style-editing
|
|
1172 (list viper-ex-style-editing))
|
19079
|
1173 (cons 'viper-want-emacs-keys-in-vi
|
|
1174 (list viper-want-emacs-keys-in-vi))
|
|
1175 (cons 'viper-electric-mode (list viper-electric-mode))
|
|
1176 (cons 'viper-want-emacs-keys-in-insert
|
|
1177 (list viper-want-emacs-keys-in-insert))
|
|
1178 (cons 'viper-re-search (list viper-re-search)))))
|
10789
|
1179
|
|
1180
|
18289
|
1181 (if viper-mode
|
|
1182 (progn
|
19079
|
1183 (viper-set-minibuffer-style)
|
|
1184 (if viper-buffer-search-char
|
|
1185 (viper-buffer-search-enable))
|
19462
|
1186 (viper-update-syntax-classes 'set-default)
|
18289
|
1187 ))
|
10789
|
1188
|
18129
|
1189
|
10789
|
1190 ;;; Familiarize Viper with some minor modes that have their own keymaps
|
18289
|
1191 (if viper-mode
|
|
1192 (progn
|
19079
|
1193 (viper-harness-minor-mode "compile")
|
|
1194 (viper-harness-minor-mode "outline")
|
|
1195 (viper-harness-minor-mode "allout")
|
|
1196 (viper-harness-minor-mode "xref")
|
|
1197 (viper-harness-minor-mode "lmenu")
|
|
1198 (viper-harness-minor-mode "vc")
|
|
1199 (viper-harness-minor-mode "ltx-math") ; LaTeX-math-mode in AUC-TeX, which
|
|
1200 (viper-harness-minor-mode "latex") ; sits in one of these two files
|
|
1201 (viper-harness-minor-mode "cyrillic")
|
|
1202 (viper-harness-minor-mode "russian")
|
|
1203 (viper-harness-minor-mode "view-less")
|
|
1204 (viper-harness-minor-mode "view")
|
21940
|
1205 (viper-harness-minor-mode "reftex")
|
26263
|
1206 (viper-harness-minor-mode "flyspell")
|
18289
|
1207 ))
|
10789
|
1208
|
|
1209
|
|
1210 ;; Intercept maps could go in viper-keym.el
|
18839
|
1211 ;; We keep them here in case someone redefines them in ~/.viper
|
10789
|
1212
|
19079
|
1213 (define-key viper-vi-intercept-map viper-ESC-key 'viper-intercept-ESC-key)
|
|
1214 (define-key viper-insert-intercept-map viper-ESC-key 'viper-intercept-ESC-key)
|
10789
|
1215
|
19079
|
1216 ;; This is taken care of by viper-insert-global-user-map.
|
|
1217 ;;(define-key viper-replace-map viper-ESC-key 'viper-intercept-ESC-key)
|
10789
|
1218
|
16135
|
1219
|
19079
|
1220 ;; The default viper-toggle-key is \C-z; for the novice, it suspends or
|
10789
|
1221 ;; iconifies Emacs
|
19079
|
1222 (define-key viper-vi-intercept-map viper-toggle-key 'viper-toggle-key-action)
|
|
1223 (define-key
|
|
1224 viper-emacs-intercept-map viper-toggle-key 'viper-change-state-to-vi)
|
20206
|
1225
|
|
1226 ;;; Escape from Emacs and Insert modes to Vi for one command
|
|
1227 (define-key
|
|
1228 viper-emacs-intercept-map "\C-c\\" 'viper-escape-to-vi)
|
|
1229 (define-key
|
|
1230 viper-insert-intercept-map "\C-c\\" 'viper-escape-to-vi)
|
|
1231
|
|
1232 (if viper-mode
|
20343
|
1233 (setq-default viper-emacs-intercept-minor-mode t
|
|
1234 viper-emacs-local-user-minor-mode t
|
|
1235 viper-emacs-global-user-minor-mode t
|
|
1236 viper-emacs-kbd-minor-mode t
|
|
1237 viper-emacs-state-modifier-minor-mode t))
|
|
1238 (if (and viper-mode (eq viper-current-state 'emacs-state))
|
|
1239 (setq viper-emacs-intercept-minor-mode t
|
|
1240 viper-emacs-local-user-minor-mode t
|
|
1241 viper-emacs-global-user-minor-mode t
|
|
1242 viper-emacs-kbd-minor-mode t
|
|
1243 viper-emacs-state-modifier-minor-mode t))
|
10789
|
1244
|
|
1245
|
18289
|
1246 (if (and viper-mode
|
|
1247 (or viper-always
|
18839
|
1248 (and (< viper-expert-level 5) (> viper-expert-level 0))))
|
19079
|
1249 (viper-set-hooks))
|
10789
|
1250
|
35411
|
1251 ;; Let all minor modes take effect after loading.
|
|
1252 ;; This may not be enough, so we also set default minor-mode-alist.
|
10789
|
1253 ;; Without setting the default, new buffers that come up in emacs mode have
|
19079
|
1254 ;; minor-mode-map-alist = nil, unless we call viper-change-state-*
|
20206
|
1255 (if (and viper-mode (eq viper-current-state 'emacs-state))
|
10789
|
1256 (progn
|
19079
|
1257 (viper-change-state-to-emacs)
|
10789
|
1258 (setq-default minor-mode-map-alist minor-mode-map-alist)
|
|
1259 ))
|
21940
|
1260
|
|
1261 (if (and viper-mode (memq major-mode viper-vi-state-mode-list))
|
|
1262 (viper-mode))
|
12900
7a7b8d42bdec
* viper.el (vip-set-hooks): Use view-mode-hook in emacs and view hook in xemacs.
Michael Kifer <kifer@cs.stonybrook.edu>
diff
changeset
|
1263
|
35411
|
1264 (if viper-mode
|
|
1265 (setq initial-major-mode
|
|
1266 `(lambda ()
|
|
1267 (funcall (quote ,initial-major-mode))
|
|
1268 (set-viper-state-in-major-mode))
|
|
1269 ))
|
|
1270
|
|
1271
|
18129
|
1272
|
19079
|
1273 (run-hooks 'viper-load-hook) ; the last chance to change something
|
10789
|
1274
|
18129
|
1275 (provide 'viper)
|
10789
|
1276
|
18839
|
1277
|
|
1278 ;;; Local Variables:
|
19079
|
1279 ;;; eval: (put 'viper-deflocalvar 'lisp-indent-hook 'defun)
|
18839
|
1280 ;;; End:
|
|
1281
|
10789
|
1282 ;;; viper.el ends here
|