| 1 | ;;; viper.el --- A full-featured Vi emulator for GNU Emacs 19 and XEmacs 19, |
| 2 | ;; a VI Plan for Emacs Rescue, |
| 3 | ;; and a venomous VI PERil. |
| 4 | ;; Viper Is also a Package for Emacs Rebels. |
| 5 | ;; |
| 6 | ;; Keywords: emulations |
| 7 | ;; Author: Michael Kifer <kifer@cs.sunysb.edu> |
| 8 | |
| 9 | ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. |
| 10 | |
| 11 | (defconst viper-version "2.94 of June 12, 1997" |
| 12 | "The current version of Viper") |
| 13 | |
| 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 |
| 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. |
| 30 | |
| 31 | ;;; Commentary: |
| 32 | |
| 33 | ;; Viper is a full-featured Vi emulator for Emacs 19. It emulates and |
| 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 |
| 37 | ;; Vi in many other ways. Viper is highly customizable through the various |
| 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 |
| 47 | ;; <sane@cs.uiuc.edu>. Some ideas from vip 4.4.2 by Aamod Sane |
| 48 | ;; were also shamelessly plagiarized. |
| 49 | ;; |
| 50 | ;; Viper maintains some degree of compatibility with these older |
| 51 | ;; packages. See the documentation for customization. |
| 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 |
| 85 | ;; macro, not just the Vi commands. Second, macros are defined in a |
| 86 | ;; WYSYWYG mode, using an interface to Emacs' WYSIWYG style of defining |
| 87 | ;; macros. Third, in Viper, one can define macros that are specific to |
| 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. |
| 92 | ;; Buffer-specific definitions override mode-specific |
| 93 | ;; definitions, which, in turn, override global definitions. |
| 94 | ;; |
| 95 | ;; |
| 96 | ;;; Installation: |
| 97 | ;; ------------- |
| 98 | ;; |
| 99 | ;; (require 'viper) |
| 100 | ;; |
| 101 | |
| 102 | ;;; Acknowledgements: |
| 103 | ;; ----------------- |
| 104 | ;; Bug reports and ideas contributed by many users have helped |
| 105 | ;; improve Viper and the various versions of VIP. |
| 106 | ;; See the on-line manual for a complete list of contributors. |
| 107 | ;; |
| 108 | ;; |
| 109 | ;;; Notes: |
| 110 | ;; |
| 111 | ;; 1. Major modes. |
| 112 | ;; In most cases, Viper handles major modes correctly, i.e., they come up |
| 113 | ;; in the right state (either vi-state or emacs-state). For instance, text |
| 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 |
| 118 | ;; use kill-all-local-variables when they start). Some major modes |
| 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 |
| 127 | ;; (add-hook 'your-favorite-mode 'vip-change-state-to-emacs) |
| 128 | ;; |
| 129 | ;; whichever applies. The right thing to do, however, is to complain to the |
| 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 |
| 134 | ;; Because Emacs 19 has an elegant mechanism for turning minor mode keymaps |
| 135 | ;; on and off, implementation of Viper has been greatly simplified. Viper |
| 136 | ;; has several minor modes. |
| 137 | ;; |
| 138 | ;; Viper's Vi state consists of seven minor modes: |
| 139 | ;; |
| 140 | ;; vip-vi-intercept-minor-mode |
| 141 | ;; vip-vi-local-user-minor-mode |
| 142 | ;; vip-vi-global-user-minor-mode |
| 143 | ;; vip-vi-kbd-minor-mode |
| 144 | ;; vip-vi-state-modifier-minor-mode |
| 145 | ;; vip-vi-diehard-minor-mode |
| 146 | ;; vip-vi-basic-minor-mode |
| 147 | ;; |
| 148 | ;; Bindings done to the keymap of the first mode overshadow those done to |
| 149 | ;; the second, which, in turn, overshadows those done to the third, etc. |
| 150 | ;; |
| 151 | ;; The last vip-vi-basic-minor-mode contains most of the usual Vi bindings |
| 152 | ;; in its edit mode. This mode provides access to all Emacs facilities. |
| 153 | ;; Novice users, however, may want to set their vip-expert-level to 1 |
| 154 | ;; in their .vip file. This will enable vip-vi-diehard-minor-mode. This |
| 155 | ;; minor mode's bindings make Viper simulate the usual Vi very closely. |
| 156 | ;; For instance, C-c will not have its standard Emacs binding |
| 157 | ;; and so many of the goodies of Emacs are not available. |
| 158 | ;; |
| 159 | ;; A skilled user should set vip-expert-level to at least 3. This will |
| 160 | ;; enable `C-c' and many Emacs facilities will become available. |
| 161 | ;; In this case, vip-vi-diehard-minor-mode is inactive. |
| 162 | ;; |
| 163 | ;; Viper gurus should have at least |
| 164 | ;; (setq vip-expert-level 4) |
| 165 | ;; in their ~/.vip files. This will unsuppress all Emacs keys that are not |
| 166 | ;; essential for VI-style editing. |
| 167 | ;; Pick-and-choose users may want to put |
| 168 | ;; (setq vip-expert-level 5) |
| 169 | ;; in ~/.vip. Viper will then leave it up to the user to set the variables |
| 170 | ;; vip-want-* See vip-set-expert-level for details. |
| 171 | ;; |
| 172 | ;; The very first minor mode, vip-vi-intercept-minor-mode, is of no |
| 173 | ;; concern for the user. It is needed to bind Viper's vital keys, such as |
| 174 | ;; ESC and C-z. |
| 175 | ;; |
| 176 | ;; The second mode, vip-vi-local-user-minor-mode, usually has an |
| 177 | ;; empty keymap. However, the user can set bindings in this keymap, which |
| 178 | ;; will overshadow the corresponding bindings in the other two minor |
| 179 | ;; modes. This is useful, for example, for setting up ZZ in gnus, |
| 180 | ;; rmail, mh-e, etc., to send message instead of saving it in a file. |
| 181 | ;; Likewise, in Dired mode, you may want to bind ZN and ZP to commands |
| 182 | ;; that would visit the next or the previous file in the Dired buffer. |
| 183 | ;; Setting local keys is tricky, so don't do it directly. Instead, use |
| 184 | ;; vip-add-local-keys function (see its doc). |
| 185 | ;; |
| 186 | ;; The third minor mode, vip-vi-global-user-minor-mode, is also intended |
| 187 | ;; for the users but, unlike vip-vi-local-user-minor-mode, its key |
| 188 | ;; bindings are seen in all Viper buffers. This mode keys can be done |
| 189 | ;; with define-key command. |
| 190 | ;; |
| 191 | ;; The fourth minor mode, vip-vi-kbd-minor-mode, is used by keyboard |
| 192 | ;; macros. Users are NOT supposed to modify this keymap directly. |
| 193 | ;; |
| 194 | ;; The fifth mode, vip-vi-state-modifier-minor-mode, can be used to set |
| 195 | ;; key bindings that are visible in some major modes but not in others. |
| 196 | ;; |
| 197 | ;; Users are allowed to modify keymaps that belong to |
| 198 | ;; vip-vi-local-user-minor-mode, vip-vi-global-user-minor-mode, |
| 199 | ;; and vip-vi-state-modifier-minor-mode only. |
| 200 | ;; |
| 201 | ;; Viper's Insert state also has seven minor modes: |
| 202 | ;; |
| 203 | ;; vip-insert-intercept-minor-mode |
| 204 | ;; vip-insert-local-user-minor-mode |
| 205 | ;; vip-insert-global-user-minor-mode |
| 206 | ;; vip-insert-kbd-minor-mode |
| 207 | ;; vip-insert-state-modifier-minor-mode |
| 208 | ;; vip-insert-diehard-minor-mode |
| 209 | ;; vip-insert-basic-minor-mode |
| 210 | ;; |
| 211 | ;; As with VI's editing modes, the first mode, vip-insert-intercept-minor-mode |
| 212 | ;; is used to bind vital keys that are not to be changed by the user. |
| 213 | ;; |
| 214 | ;; The next mode, vip-insert-local-user-minor-mode, is used to customize |
| 215 | ;; bindings in the insert state of Viper. The third mode, |
| 216 | ;; vip-insert-global-user-minor-mode is like |
| 217 | ;; vip-insert-local-user-minor-mode, except that its bindings are seen in |
| 218 | ;; all Viper buffers. As with vip-vi-local-user-minor-mode, its bindings |
| 219 | ;; should be done via the function vip-add-local-keys. Bindings for |
| 220 | ;; vip-insert-global-user-minor-mode can be set with the define-key command. |
| 221 | ;; |
| 222 | ;; The next minor mode, vip-insert-kbd-minor-mode, |
| 223 | ;; is used for keyboard VI-style macros defined with :map!. |
| 224 | ;; |
| 225 | ;; The fifth minor mode, vip-insert-state-modifier-minor-mode, is like |
| 226 | ;; vip-vi-state-modifier-minor-mode, except that it is used in the Insert |
| 227 | ;; state; it can be used to modify keys in a mode-specific fashion. |
| 228 | ;; |
| 229 | ;; The minor mode vip-insert-diehard-minor-mode is in effect when |
| 230 | ;; the user wants a high degree of Vi compatibility (a bad idea, really!). |
| 231 | ;; The last minor mode, vip-insert-basic-minor-mode, is always in effect |
| 232 | ;; when Viper is in insert state. It binds a small number of keys needed for |
| 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 | ;; |
| 238 | ;; vip-emacs-local-user-minor-mode |
| 239 | ;; vip-emacs-global-user-minor-mode |
| 240 | ;; vip-emacs-kbd-minor-mode |
| 241 | ;; vip-emacs-state-modifier-minor-mode |
| 242 | ;; |
| 243 | ;; These minor modes are in effect when Viper is in Emacs state. The keymap |
| 244 | ;; associated with vip-emacs-global-user-minor-mode, |
| 245 | ;; vip-emacs-global-user-map, overrides the global and local keymaps as |
| 246 | ;; well as the minor mode keymaps set by other modes. The keymap of |
| 247 | ;; vip-emacs-local-user-minor-mode, vip-emacs-local-user-map, overrides |
| 248 | ;; everything, but it is used on a per buffer basis. |
| 249 | ;; The keymap associated with vip-emacs-state-modifier-minor-mode |
| 250 | ;; overrides keys on a per-major-mode basis. The mode |
| 251 | ;; vip-emacs-kbd-minor-mode is used to define Vi-style macros in Emacs |
| 252 | ;; state. |
| 253 | ;; |
| 254 | ;; 3. There is also one minor mode that is used when Viper is in its |
| 255 | ;; replace-state (used for commands like cw, C, etc.). This mode is |
| 256 | ;; called |
| 257 | ;; |
| 258 | ;; vip-replace-minor-mode |
| 259 | ;; |
| 260 | ;; and its keymap is vip-replace-map. Replace minor mode is always |
| 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. |
| 267 | ;; Viper provides a special function, vip-add-local-keys, to do precisely |
| 268 | ;; this. For instance, is you need to add couple of mode-specific bindings |
| 269 | ;; to Insert mode, you can put |
| 270 | ;; |
| 271 | ;; (vip-add-local-keys 'insert-state '((key1 . func1) (key2 .func2))) |
| 272 | ;; |
| 273 | ;; somewhere in a hook of this major mode. If you put something like this |
| 274 | ;; in your own elisp function, this will define bindings specific to the |
| 275 | ;; buffer that was current at the time of the call to vip-add-local-keys. |
| 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 |
| 278 | ;; (kill-all-local-variables). See vip-add-local-keys for more details. |
| 279 | ;; |
| 280 | ;; |
| 281 | ;; TO DO (volunteers?): |
| 282 | ;; |
| 283 | ;; 1. Some of the code that is inherited from VIP-3.5 is rather |
| 284 | ;; convoluted. Instead of vip-command-argument, keymaps should bind the |
| 285 | ;; actual commands. E.g., "dw" should be bound to a generic command |
| 286 | ;; vip-delete that will delete things based on the value of |
| 287 | ;; last-command-char. This would greatly simplify the logic and the code. |
| 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 |
| 292 | ;; starts with a '*'. Then, the user should be offered to save |
| 293 | ;; variables that were changed. This will make user's customization job |
| 294 | ;; much easier. |
| 295 | ;; |
| 296 | |
| 297 | ;; Code |
| 298 | |
| 299 | (require 'advice) |
| 300 | (require 'cl) |
| 301 | (require 'ring) |
| 302 | |
| 303 | ;; compiler pacifier |
| 304 | (defvar mark-even-if-inactive) |
| 305 | |
| 306 | ;; loading happens only in non-interactive compilation |
| 307 | ;; in order to spare non-viperized emacs from being viperized |
| 308 | (if noninteractive |
| 309 | (eval-when-compile |
| 310 | (let ((load-path (cons (expand-file-name ".") load-path))) |
| 311 | (or (featurep 'viper-cmd) |
| 312 | (load "viper-cmd.el" nil nil 'nosuffix)) |
| 313 | ))) |
| 314 | ;; end pacifier |
| 315 | |
| 316 | (require 'viper-cmd) |
| 317 | |
| 318 | (defvar vip-always t |
| 319 | "See `viper-always'. This variable is for compatibility with older Vipers.") |
| 320 | (defvar viper-always vip-always |
| 321 | "Non-nil means, arrange for vi-state to be a default when appropriate. |
| 322 | This is different from `viper-mode' variable in that `viper-mode' determines |
| 323 | whether to use Viper in the first place, while `viper-always', if nil, lets |
| 324 | user decide when to invoke Viper in a major mode.") |
| 325 | |
| 326 | (defvar viper-mode (cond (noninteractive nil) |
| 327 | (t 'ask)) |
| 328 | "Viperize or not Viperize. |
| 329 | If t, viperize emacs. If nil -- don't. If `ask', ask the user. |
| 330 | This variable is used primatily when Viper is being loaded. |
| 331 | |
| 332 | Must be set in `~/.emacs' before Viper is loaded. |
| 333 | DO NOT set this variable interactively.") |
| 334 | |
| 335 | \f |
| 336 | ;; The following are provided for compatibility with older VIP's |
| 337 | |
| 338 | ;;;###autoload |
| 339 | (defalias 'vip-mode 'viper-mode) |
| 340 | |
| 341 | (defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi) |
| 342 | (defalias 'vip-change-mode-to-insert 'vip-change-state-to-insert) |
| 343 | (defalias 'vip-change-mode-to-emacs 'vip-change-state-to-emacs) |
| 344 | |
| 345 | \f |
| 346 | |
| 347 | ;;;###autoload |
| 348 | (defun viper-mode () |
| 349 | "Turn on Viper emulation of Vi." |
| 350 | (interactive) |
| 351 | (if (not noninteractive) |
| 352 | (progn |
| 353 | ;; if the user requested viper-mode explicitly |
| 354 | (if viper-mode |
| 355 | () |
| 356 | (setq viper-mode 1) |
| 357 | (load-library "viper")) |
| 358 | |
| 359 | (if vip-first-time ; This check is important. Without it, startup and |
| 360 | (progn ; expert-level msgs mix up when viper-mode recurses |
| 361 | (setq vip-first-time nil) |
| 362 | (if (not vip-inhibit-startup-message) |
| 363 | (save-window-excursion |
| 364 | (setq vip-inhibit-startup-message t) |
| 365 | (delete-other-windows) |
| 366 | (switch-to-buffer "Viper Startup Message") |
| 367 | (erase-buffer) |
| 368 | (insert |
| 369 | (substitute-command-keys |
| 370 | "Viper Is a Package for Emacs Rebels. |
| 371 | It is also a VI Plan for Emacs Rescue and a venomous VI PERil. |
| 372 | |
| 373 | Technically speaking, Viper is a Vi emulation package for GNU Emacs 19 and |
| 374 | XEmacs 19. It supports virtually all of Vi and Ex functionality, extending |
| 375 | and improving upon much of it. |
| 376 | |
| 377 | 1. Viper supports Vi at several levels. Level 1 is the closest to Vi, |
| 378 | level 5 provides the most flexibility to depart from many Vi conventions. |
| 379 | |
| 380 | You will be asked to specify your user level in a following screen. |
| 381 | |
| 382 | If you select user level 1 then the keys ^X, ^C, ^Z, and ^G will behave |
| 383 | as in VI, to smooth transition to Viper for the beginners. However, to |
| 384 | use Emacs productively, you are advised to reach user level 3 or higher. |
| 385 | |
| 386 | If your user level is 2 or higher, ^X and ^C will invoke Emacs |
| 387 | functions,as usual in Emacs; ^Z will toggle vi/emacs modes, and |
| 388 | ^G will be the usual Emacs's keyboard-quit (something like ^C in VI). |
| 389 | |
| 390 | 2. Vi exit functions (e.g., :wq, ZZ) work on INDIVIDUAL files -- they |
| 391 | do not cause Emacs to quit, except at user level 1 (a novice). |
| 392 | 3. ^X^C EXITS EMACS. |
| 393 | 4. Viper supports multiple undo: `u' will undo. Typing `.' will repeat |
| 394 | undo. Another `u' changes direction. |
| 395 | |
| 396 | 6. Emacs Meta functions are invoked by typing `C-\\' or `\\ ESC'. |
| 397 | On a window system, the best way is to use the Meta-key. |
| 398 | 7. Try \\[keyboard-quit] and \\[abort-recursive-edit] repeatedly,if |
| 399 | something funny happens. This would abort the current editing command. |
| 400 | |
| 401 | You can get more information on Viper by: |
| 402 | |
| 403 | a. Typing `:help' in Vi state |
| 404 | b. Printing Viper manual, found in ./etc/viper.dvi |
| 405 | c. Printing ViperCard, the Quick Reference, found in ./etc/viperCard.dvi |
| 406 | |
| 407 | This startup message appears whenever you load Viper, unless you type `y' now." |
| 408 | )) |
| 409 | (goto-char (point-min)) |
| 410 | (if (y-or-n-p "Inhibit Viper startup message? ") |
| 411 | (vip-save-setting |
| 412 | 'vip-inhibit-startup-message |
| 413 | "Viper startup message inhibited" |
| 414 | vip-custom-file-name t)) |
| 415 | ;;(kill-buffer (current-buffer)) |
| 416 | (message |
| 417 | "The last message is in buffer `Viper Startup Message'") |
| 418 | (sit-for 4) |
| 419 | )) |
| 420 | (vip-set-expert-level 'dont-change-unless))) |
| 421 | (vip-change-state-to-vi)))) |
| 422 | |
| 423 | \f |
| 424 | ;; This hook designed to enable Vi-style editing in comint-based modes." |
| 425 | (defun vip-comint-mode-hook () |
| 426 | (setq require-final-newline nil |
| 427 | vip-ex-style-editing-in-insert nil |
| 428 | vip-ex-style-motion nil) |
| 429 | (vip-change-state-to-insert)) |
| 430 | |
| 431 | |
| 432 | ;; This sets major mode hooks to make them come up in vi-state. |
| 433 | (defun vip-set-hooks () |
| 434 | |
| 435 | ;; It is of course a misnomer to call viper-mode a `major mode'. |
| 436 | ;; However, this has the effect that if the user didn't specify the |
| 437 | ;; default mode, new buffers that fall back on the default will come up |
| 438 | ;; in Fundamental Mode and Vi state. |
| 439 | (setq default-major-mode 'viper-mode) |
| 440 | |
| 441 | ;; The following major modes should come up in vi-state |
| 442 | (defadvice fundamental-mode (after vip-fundamental-mode-ad activate) |
| 443 | "Run `vip-change-state-to-vi' on entry." |
| 444 | (vip-change-state-to-vi)) |
| 445 | |
| 446 | (defvar makefile-mode-hook) |
| 447 | (add-hook 'makefile-mode-hook 'viper-mode) |
| 448 | |
| 449 | (defvar help-mode-hook) |
| 450 | (add-hook 'help-mode-hook 'viper-mode) |
| 451 | (vip-modify-major-mode 'help-mode 'vi-state vip-help-modifier-map) |
| 452 | |
| 453 | (defvar awk-mode-hook) |
| 454 | (add-hook 'awk-mode-hook 'viper-mode) |
| 455 | |
| 456 | (defvar html-mode-hook) |
| 457 | (add-hook 'html-mode-hook 'viper-mode) |
| 458 | (defvar html-helper-mode-hook) |
| 459 | (add-hook 'html-helper-mode-hook 'viper-mode) |
| 460 | |
| 461 | (defvar java-mode-hook) |
| 462 | (add-hook 'java-mode-hook 'viper-mode) |
| 463 | |
| 464 | (defvar emacs-lisp-mode-hook) |
| 465 | (add-hook 'emacs-lisp-mode-hook 'viper-mode) |
| 466 | (defvar lisp-mode-hook) |
| 467 | (add-hook 'lisp-mode-hook 'viper-mode) |
| 468 | (defvar lisp-interaction-mode-hook) |
| 469 | (add-hook 'lisp-interaction-mode-hook 'viper-mode) |
| 470 | |
| 471 | (defvar bibtex-mode-hook) |
| 472 | (add-hook 'bibtex-mode-hook 'viper-mode) |
| 473 | |
| 474 | (defvar cc-mode-hook) |
| 475 | (add-hook 'cc-mode-hook 'viper-mode) |
| 476 | |
| 477 | (defvar c-mode-hook) |
| 478 | (add-hook 'c-mode-hook 'viper-mode) |
| 479 | |
| 480 | (defvar c++-mode-hook) |
| 481 | (add-hook 'c++-mode-hook 'viper-mode) |
| 482 | |
| 483 | (defvar fortran-mode-hook) |
| 484 | (add-hook 'fortran-mode-hook 'viper-mode) |
| 485 | (defvar f90-mode-hook) |
| 486 | (add-hook 'f90-mode-hook 'viper-mode) |
| 487 | |
| 488 | (defvar basic-mode-hook) |
| 489 | (add-hook 'basic-mode-hook 'viper-mode) |
| 490 | (defvar bat-mode-hook) |
| 491 | (add-hook 'bat-mode-hook 'viper-mode) |
| 492 | |
| 493 | (defvar asm-mode-hook) |
| 494 | (add-hook 'asm-mode-hook 'viper-mode) |
| 495 | |
| 496 | (defvar prolog-mode-hook) |
| 497 | (add-hook 'prolog-mode-hook 'viper-mode) |
| 498 | |
| 499 | (defvar text-mode-hook) |
| 500 | (add-hook 'text-mode-hook 'viper-mode) |
| 501 | |
| 502 | (add-hook 'completion-list-mode-hook 'viper-mode) |
| 503 | (add-hook 'compilation-mode-hook 'viper-mode) |
| 504 | |
| 505 | (add-hook 'perl-mode-hook 'viper-mode) |
| 506 | (add-hook 'tcl-mode-hook 'viper-mode) |
| 507 | |
| 508 | (defvar emerge-startup-hook) |
| 509 | (add-hook 'emerge-startup-hook 'vip-change-state-to-emacs) |
| 510 | |
| 511 | ;; Tell vc-diff to put *vc* in Vi mode |
| 512 | (if (featurep 'vc) |
| 513 | (defadvice vc-diff (after vip-vc-ad activate) |
| 514 | "Force Vi state in VC diff buffer." |
| 515 | (vip-change-state-to-vi)) |
| 516 | (vip-eval-after-load |
| 517 | "vc" |
| 518 | '(defadvice vc-diff (after vip-vc-ad activate) |
| 519 | "Force Vi state in VC diff buffer." |
| 520 | (vip-change-state-to-vi)))) |
| 521 | |
| 522 | (vip-eval-after-load |
| 523 | "emerge" |
| 524 | '(defadvice emerge-quit (after vip-emerge-advice activate) |
| 525 | "Run `vip-change-state-to-vi' after quitting emerge." |
| 526 | (vip-change-state-to-vi))) |
| 527 | ;; In case Emerge was loaded before Viper. |
| 528 | (defadvice emerge-quit (after vip-emerge-advice activate) |
| 529 | "Run `vip-change-state-to-vi' after quitting emerge." |
| 530 | (vip-change-state-to-vi)) |
| 531 | |
| 532 | ;; passwd.el sets up its own buffer, which turns up in Vi mode, |
| 533 | ;; thus overriding the local map. We don't need Vi mode here. |
| 534 | (vip-eval-after-load |
| 535 | "passwd" |
| 536 | '(defadvice read-passwd-1 (before vip-passwd-ad activate) |
| 537 | "Switch to emacs state while reading password." |
| 538 | (vip-change-state-to-emacs))) |
| 539 | |
| 540 | ;; Emacs shell, ange-ftp, and comint-based modes |
| 541 | (defvar comint-mode-hook) |
| 542 | (vip-modify-major-mode |
| 543 | 'comint-mode 'insert-state vip-comint-mode-modifier-map) |
| 544 | (vip-modify-major-mode |
| 545 | 'comint-mode 'vi-state vip-comint-mode-modifier-map) |
| 546 | (vip-modify-major-mode |
| 547 | 'shell-mode 'insert-state vip-comint-mode-modifier-map) |
| 548 | (vip-modify-major-mode |
| 549 | 'shell-mode 'vi-state vip-comint-mode-modifier-map) |
| 550 | ;; ange-ftp in XEmacs |
| 551 | (vip-modify-major-mode |
| 552 | 'ange-ftp-shell-mode 'insert-state vip-comint-mode-modifier-map) |
| 553 | (vip-modify-major-mode |
| 554 | 'ange-ftp-shell-mode 'vi-state vip-comint-mode-modifier-map) |
| 555 | ;; ange-ftp in Emacs |
| 556 | (vip-modify-major-mode |
| 557 | 'internal-ange-ftp-mode 'insert-state vip-comint-mode-modifier-map) |
| 558 | (vip-modify-major-mode |
| 559 | 'internal-ange-ftp-mode 'vi-state vip-comint-mode-modifier-map) |
| 560 | ;; set hook |
| 561 | (add-hook 'comint-mode-hook 'vip-comint-mode-hook) |
| 562 | |
| 563 | ;; Shell scripts |
| 564 | (defvar sh-mode-hook) |
| 565 | (add-hook 'sh-mode-hook 'viper-mode) |
| 566 | (defvar ksh-mode-hook) |
| 567 | (add-hook 'ksh-mode-hook 'viper-mode) |
| 568 | |
| 569 | ;; Dired |
| 570 | (vip-modify-major-mode 'dired-mode 'emacs-state vip-dired-modifier-map) |
| 571 | (vip-set-emacs-search-style-macros nil 'dired-mode) |
| 572 | (add-hook 'dired-mode-hook 'vip-change-state-to-emacs) |
| 573 | |
| 574 | ;; Tar |
| 575 | (vip-modify-major-mode 'tar-mode 'emacs-state vip-slash-and-colon-map) |
| 576 | (vip-set-emacs-search-style-macros nil 'tar-mode) |
| 577 | |
| 578 | ;; MH-E |
| 579 | (vip-modify-major-mode 'mh-folder-mode 'emacs-state vip-slash-and-colon-map) |
| 580 | (vip-set-emacs-search-style-macros nil 'mh-folder-mode) |
| 581 | ;; changing state to emacs is needed so the preceding will take hold |
| 582 | (add-hook 'mh-folder-mode-hook 'vip-change-state-to-emacs) |
| 583 | (add-hook 'mh-show-mode-hook 'viper-mode) |
| 584 | |
| 585 | ;; Gnus |
| 586 | (vip-modify-major-mode 'gnus-group-mode 'emacs-state vip-slash-and-colon-map) |
| 587 | (vip-set-emacs-search-style-macros nil 'gnus-group-mode) |
| 588 | (vip-modify-major-mode |
| 589 | 'gnus-summary-mode 'emacs-state vip-slash-and-colon-map) |
| 590 | (vip-set-emacs-search-style-macros nil 'gnus-summary-mode) |
| 591 | ;; changing state to emacs is needed so the preceding will take hold |
| 592 | (add-hook 'gnus-group-mode-hook 'vip-change-state-to-emacs) |
| 593 | (add-hook 'gnus-summary-mode-hook 'vip-change-state-to-emacs) |
| 594 | (add-hook 'gnus-article-mode-hook 'viper-mode) |
| 595 | |
| 596 | ;; Info |
| 597 | (vip-modify-major-mode 'Info-mode 'emacs-state vip-slash-and-colon-map) |
| 598 | (vip-set-emacs-search-style-macros nil 'Info-mode) |
| 599 | ;; Switching to emacs is needed so the above will take hold |
| 600 | (defadvice Info-mode (after vip-Info-ad activate) |
| 601 | "Switch to emacs mode." |
| 602 | (vip-change-state-to-emacs)) |
| 603 | |
| 604 | ;; Buffer menu |
| 605 | (vip-modify-major-mode |
| 606 | 'Buffer-menu-mode 'emacs-state vip-slash-and-colon-map) |
| 607 | (vip-set-emacs-search-style-macros nil 'Buffer-menu-mode) |
| 608 | ;; Switching to emacs is needed so the above will take hold |
| 609 | (defadvice Buffer-menu-mode (after vip-Buffer-menu-ad activate) |
| 610 | "Switch to emacs mode." |
| 611 | (vip-change-state-to-emacs)) |
| 612 | |
| 613 | ;; View mode |
| 614 | (defvar view-mode-hook) |
| 615 | (defvar view-hook) |
| 616 | (add-hook 'view-hook 'vip-change-state-to-emacs) |
| 617 | (add-hook 'view-mode-hook 'vip-change-state-to-emacs) |
| 618 | |
| 619 | ;; For VM users. |
| 620 | ;; Put summary and other VM buffers in Emacs state. |
| 621 | (defvar vm-mode-hooks) |
| 622 | (defvar vm-summary-mode-hooks) |
| 623 | (add-hook 'vm-mode-hooks 'vip-change-state-to-emacs) |
| 624 | (add-hook 'vm-summary-mode-hooks 'vip-change-state-to-emacs) |
| 625 | |
| 626 | ;; For RMAIL users. |
| 627 | ;; Put buf in Emacs state after edit. |
| 628 | (vip-eval-after-load |
| 629 | "rmailedit" |
| 630 | '(defadvice rmail-cease-edit (after vip-rmail-advice activate) |
| 631 | "Switch to emacs state when done editing message." |
| 632 | (vip-change-state-to-emacs))) |
| 633 | ;; In case RMAIL was loaded before Viper. |
| 634 | (defadvice rmail-cease-edit (after vip-rmail-advice activate) |
| 635 | "Switch to emacs state when done editing message." |
| 636 | (vip-change-state-to-emacs)) |
| 637 | ) ; vip-set-hooks |
| 638 | |
| 639 | |
| 640 | ;; these are primarily advices and Vi-ish variable settings |
| 641 | (defun vip-non-hook-settings () |
| 642 | |
| 643 | ;; This var is not local in Emacs, so we make it local. |
| 644 | ;; It must be local because although the stack of minor modes can be the same |
| 645 | ;; for all buffers, the associated *keymaps* can be different. In Viper, |
| 646 | ;; vip-vi-local-user-map, vip-insert-local-user-map, and others can have |
| 647 | ;; different keymaps for different buffers. |
| 648 | ;; Also, the keymaps associated with vip-vi/insert-state-modifier-minor-mode |
| 649 | ;; can be different. |
| 650 | (make-variable-buffer-local 'minor-mode-map-alist) |
| 651 | |
| 652 | ;; Viper changes the default mode-line-buffer-identification |
| 653 | (setq-default mode-line-buffer-identification '(" %b")) |
| 654 | |
| 655 | ;; setup emacs-supported vi-style feel |
| 656 | (setq next-line-add-newlines nil |
| 657 | require-final-newline t) |
| 658 | |
| 659 | (make-variable-buffer-local 'require-final-newline) |
| 660 | |
| 661 | ;; don't bark when mark is inactive |
| 662 | (setq mark-even-if-inactive t) |
| 663 | |
| 664 | (setq scroll-step 1) |
| 665 | |
| 666 | ;; Variable displaying the current Viper state in the mode line. |
| 667 | (vip-deflocalvar vip-mode-string vip-emacs-state-id) |
| 668 | (or (memq 'vip-mode-string global-mode-string) |
| 669 | (setq global-mode-string |
| 670 | (append '("" vip-mode-string) (cdr global-mode-string)))) |
| 671 | |
| 672 | (defadvice read-key-sequence (around vip-read-keyseq-ad activate) |
| 673 | "Harness to work for Viper. This advice is harmless---don't worry!" |
| 674 | (let (inhibit-quit event keyseq) |
| 675 | (setq keyseq ad-do-it) |
| 676 | (setq event (if vip-xemacs-p |
| 677 | (elt keyseq 0) ; XEmacs returns vector of events |
| 678 | (elt (listify-key-sequence keyseq) 0))) |
| 679 | (if (vip-ESC-event-p event) |
| 680 | (let (unread-command-events) |
| 681 | (vip-set-unread-command-events keyseq) |
| 682 | (if (vip-fast-keysequence-p) |
| 683 | (let ((vip-vi-global-user-minor-mode nil) |
| 684 | (vip-vi-local-user-minor-mode nil) |
| 685 | (vip-replace-minor-mode nil) ; actually unnecessary |
| 686 | (vip-insert-global-user-minor-mode nil) |
| 687 | (vip-insert-local-user-minor-mode nil)) |
| 688 | (setq keyseq ad-do-it)) |
| 689 | (setq keyseq ad-do-it)))) |
| 690 | keyseq)) |
| 691 | |
| 692 | (defadvice describe-key (before vip-read-keyseq-ad protect activate) |
| 693 | "Force to read key via `read-key-sequence'." |
| 694 | (interactive (list (vip-events-to-keys |
| 695 | (read-key-sequence "Describe key: "))))) |
| 696 | |
| 697 | (defadvice describe-key-briefly (before vip-read-keyseq-ad protect activate) |
| 698 | "Force to read key via `read-key-sequence'." |
| 699 | (interactive (list (vip-events-to-keys |
| 700 | (read-key-sequence "Describe key briefly: "))))) |
| 701 | |
| 702 | |
| 703 | ;; Advice for use in find-file and read-file-name commands. |
| 704 | (defadvice exit-minibuffer (before vip-exit-minibuffer-advice activate) |
| 705 | "Run `vip-minibuffer-exit-hook' just before exiting the minibuffer." |
| 706 | (run-hooks 'vip-minibuffer-exit-hook)) |
| 707 | |
| 708 | (defadvice find-file (before vip-add-suffix-advice activate) |
| 709 | "Use `read-file-name' for reading arguments." |
| 710 | (interactive (cons (read-file-name "Find file: " nil default-directory) |
| 711 | ;; if Mule and prefix argument, ask for coding system |
| 712 | (if (or (boundp 'MULE) ; mule integrated Emacs 19 |
| 713 | (featurep 'mule)) ; mule integrated XEmacs 20 |
| 714 | (list |
| 715 | (and current-prefix-arg |
| 716 | (read-coding-system "Coding-system: ")))) |
| 717 | ))) |
| 718 | |
| 719 | (defadvice find-file-other-window (before vip-add-suffix-advice activate) |
| 720 | "Use `read-file-name' for reading arguments." |
| 721 | (interactive (cons (read-file-name "Find file in other window: " |
| 722 | nil default-directory) |
| 723 | ;; if Mule and prefix argument, ask for coding system |
| 724 | (if (or (boundp 'MULE) ; mule integrated Emacs 19 |
| 725 | (featurep 'mule)) ; mule integrated XEmacs 20 |
| 726 | (list |
| 727 | (and current-prefix-arg |
| 728 | (read-coding-system "Coding-system: ")))) |
| 729 | ))) |
| 730 | |
| 731 | (defadvice find-file-other-frame (before vip-add-suffix-advice activate) |
| 732 | "Use `read-file-name' for reading arguments." |
| 733 | (interactive (cons (read-file-name "Find file in other frame: " |
| 734 | nil default-directory) |
| 735 | ;; if Mule and prefix argument, ask for coding system |
| 736 | (if (or (boundp 'MULE) ; mule integrated Emacs 19 |
| 737 | (featurep 'mule)) ; mule integrated XEmacs 20 |
| 738 | (list |
| 739 | (and current-prefix-arg |
| 740 | (read-coding-system "Coding-system: ")))) |
| 741 | ))) |
| 742 | |
| 743 | (defadvice read-file-name (around vip-suffix-advice activate) |
| 744 | "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook." |
| 745 | (let ((vip-minibuffer-exit-hook 'vip-file-add-suffix)) |
| 746 | ad-do-it)) |
| 747 | |
| 748 | (defadvice start-kbd-macro (after vip-kbd-advice activate) |
| 749 | "Remove Viper's intercepting bindings for C-x ). |
| 750 | This may be needed if the previous `:map' command terminated abnormally." |
| 751 | (define-key vip-vi-intercept-map "\C-x)" nil) |
| 752 | (define-key vip-insert-intercept-map "\C-x)" nil) |
| 753 | (define-key vip-emacs-intercept-map "\C-x)" nil)) |
| 754 | |
| 755 | (cond ((vip-window-display-p) |
| 756 | (let* ((search-key (if vip-xemacs-p |
| 757 | [(meta shift button1up)] [M-S-mouse-1])) |
| 758 | (search-key-catch |
| 759 | (if vip-xemacs-p [(meta shift button1)] [M-S-down-mouse-1])) |
| 760 | (insert-key (if vip-xemacs-p |
| 761 | [(meta shift button2up)] [M-S-mouse-2])) |
| 762 | (insert-key-catch |
| 763 | (if vip-xemacs-p [(meta shift button2)] [M-S-down-mouse-2])) |
| 764 | (search-key-unbound (and (not (key-binding search-key)) |
| 765 | (not (key-binding search-key-catch)))) |
| 766 | (insert-key-unbound (and (not (key-binding insert-key)) |
| 767 | (not (key-binding insert-key-catch)))) |
| 768 | ) |
| 769 | |
| 770 | (if search-key-unbound |
| 771 | (global-set-key search-key 'vip-mouse-click-search-word)) |
| 772 | (if insert-key-unbound |
| 773 | (global-set-key insert-key 'vip-mouse-click-insert-word)) |
| 774 | |
| 775 | ;; The following would be needed if you want to use the above two |
| 776 | ;; while clicking in another frame. If you only want to use them |
| 777 | ;; by clicking in another window, not frame, the bindings below |
| 778 | ;; aren't necessary. |
| 779 | |
| 780 | ;; These must be bound to mouse-down event for the same mouse |
| 781 | ;; buttons as 'vip-mouse-click-search-word and |
| 782 | ;; 'vip-mouse-click-insert-word |
| 783 | (if search-key-unbound |
| 784 | (global-set-key search-key-catch 'vip-mouse-catch-frame-switch)) |
| 785 | (if insert-key-unbound |
| 786 | (global-set-key insert-key-catch 'vip-mouse-catch-frame-switch)) |
| 787 | |
| 788 | (if vip-xemacs-p |
| 789 | (add-hook 'mouse-leave-frame-hook |
| 790 | 'vip-remember-current-frame) |
| 791 | (defadvice handle-switch-frame (before vip-frame-advice activate) |
| 792 | "Remember the selected frame before the switch-frame event." |
| 793 | (vip-remember-current-frame (selected-frame)))) |
| 794 | ))) |
| 795 | ) ; end vip-non-hook-settings |
| 796 | |
| 797 | \f |
| 798 | (if (eq viper-mode 'ask) |
| 799 | (progn |
| 800 | (save-window-excursion |
| 801 | (with-output-to-temp-buffer " *vip-info*" |
| 802 | (princ " |
| 803 | You have loaded Viper, and are about to Viperize your emacs! |
| 804 | |
| 805 | Viper is a Package for Emacs Rebels |
| 806 | and a venomous VI PERil, |
| 807 | |
| 808 | It's time to decide: to Viperize or not to Viperize... |
| 809 | |
| 810 | If you wish to Viperize AND make this your way of life, please put |
| 811 | |
| 812 | (setq viper-mode t) |
| 813 | (require 'viper) |
| 814 | |
| 815 | in your .emacs file (preferably, close to the top). |
| 816 | These two lines must come in the order given. |
| 817 | |
| 818 | Also, the startup file name has changed from .vip to .viper")) |
| 819 | (if (y-or-n-p "Viperize? ") |
| 820 | (setq viper-mode t) |
| 821 | (setq viper-mode nil)) |
| 822 | (message "") |
| 823 | (kill-buffer " *vip-info*")))) |
| 824 | |
| 825 | |
| 826 | |
| 827 | \f |
| 828 | |
| 829 | ;; Set some useful macros, advices |
| 830 | ;; These must be BEFORE we ~/.vip is loaded, |
| 831 | ;; so the user can unrecord them in ~/.vip. |
| 832 | (if viper-mode |
| 833 | (progn |
| 834 | ;; set advices and some variables that give emacs Vi look. |
| 835 | (vip-non-hook-settings) |
| 836 | |
| 837 | ;; repeat the 2nd previous command without rotating the command history |
| 838 | (vip-record-kbd-macro |
| 839 | (vector vip-repeat-from-history-key '\1) 'vi-state |
| 840 | [(meta x) v i p - r e p e a t - f r o m - h i s t o r y return] 't) |
| 841 | ;; repeat the 3d previous command without rotating the command history |
| 842 | (vip-record-kbd-macro |
| 843 | (vector vip-repeat-from-history-key '\2) 'vi-state |
| 844 | [(meta x) v i p - r e p e a t - f r o m - h i s t o r y return] 't) |
| 845 | |
| 846 | ;; set the toggle case sensitivity and regexp search macros |
| 847 | (vip-set-vi-search-style-macros nil) |
| 848 | |
| 849 | ;; Make %%% toggle parsing comments for matching parentheses |
| 850 | (vip-record-kbd-macro |
| 851 | "%%%" 'vi-state |
| 852 | [(meta x) v i p - t o g g l e - p a r s e - s e x p - i g n o r e - c o m m e n t s return] |
| 853 | 't) |
| 854 | )) |
| 855 | |
| 856 | |
| 857 | ;; ~/.vip is loaded if it exists |
| 858 | (if (and (file-exists-p vip-custom-file-name) |
| 859 | viper-mode |
| 860 | (not noninteractive)) |
| 861 | (load vip-custom-file-name)) |
| 862 | |
| 863 | ;; VIP compatibility: merge whatever the user has in vip-mode-map into |
| 864 | ;; Viper's basic map. |
| 865 | (vip-add-keymap vip-mode-map vip-vi-global-user-map) |
| 866 | |
| 867 | \f |
| 868 | ;; Applying Viper customization -- runs after (load .vip) |
| 869 | |
| 870 | ;; Save user settings or Viper defaults for vars controled by vip-expert-level |
| 871 | (setq vip-saved-user-settings |
| 872 | (list (cons 'vip-want-ctl-h-help vip-want-ctl-h-help) |
| 873 | (cons 'viper-always viper-always) |
| 874 | (cons 'vip-no-multiple-ESC vip-no-multiple-ESC) |
| 875 | (cons 'vip-ex-style-motion vip-ex-style-motion) |
| 876 | (cons 'vip-ex-style-editing-in-insert |
| 877 | vip-ex-style-editing-in-insert) |
| 878 | (cons 'vip-want-emacs-keys-in-vi vip-want-emacs-keys-in-vi) |
| 879 | (cons 'vip-electric-mode vip-electric-mode) |
| 880 | (cons 'vip-want-emacs-keys-in-insert vip-want-emacs-keys-in-insert) |
| 881 | (cons 'vip-re-search vip-re-search))) |
| 882 | |
| 883 | |
| 884 | (if viper-mode |
| 885 | (progn |
| 886 | (vip-set-minibuffer-style) |
| 887 | (if vip-buffer-search-char |
| 888 | (vip-buffer-search-enable)) |
| 889 | (vip-update-alphanumeric-class) |
| 890 | )) |
| 891 | |
| 892 | \f |
| 893 | ;;; Familiarize Viper with some minor modes that have their own keymaps |
| 894 | (if viper-mode |
| 895 | (progn |
| 896 | (vip-harness-minor-mode "compile") |
| 897 | (vip-harness-minor-mode "outline") |
| 898 | (vip-harness-minor-mode "allout") |
| 899 | (vip-harness-minor-mode "xref") |
| 900 | (vip-harness-minor-mode "lmenu") |
| 901 | (vip-harness-minor-mode "vc") |
| 902 | (vip-harness-minor-mode "ltx-math") ; LaTeX-math-mode in AUC-TeX |
| 903 | (vip-harness-minor-mode "latex") ; which is in one of these two files |
| 904 | (vip-harness-minor-mode "cyrillic") |
| 905 | (vip-harness-minor-mode "russian") |
| 906 | (vip-harness-minor-mode "view-less") |
| 907 | (vip-harness-minor-mode "view") |
| 908 | )) |
| 909 | |
| 910 | |
| 911 | ;; Intercept maps could go in viper-keym.el |
| 912 | ;; We keep them here in case someone redefines them in ~/.vip |
| 913 | |
| 914 | (define-key vip-vi-intercept-map vip-ESC-key 'vip-intercept-ESC-key) |
| 915 | (define-key vip-insert-intercept-map vip-ESC-key 'vip-intercept-ESC-key) |
| 916 | |
| 917 | ;; This is taken care of by vip-insert-global-user-map. |
| 918 | ;;(define-key vip-replace-map vip-ESC-key 'vip-intercept-ESC-key) |
| 919 | |
| 920 | |
| 921 | ;; The default vip-toggle-key is \C-z; for the novice, it suspends or |
| 922 | ;; iconifies Emacs |
| 923 | (define-key vip-vi-intercept-map vip-toggle-key 'vip-toggle-key-action) |
| 924 | (define-key vip-emacs-intercept-map vip-toggle-key 'vip-change-state-to-vi) |
| 925 | |
| 926 | |
| 927 | (if (and viper-mode |
| 928 | (or viper-always |
| 929 | (and (< vip-expert-level 5) (> vip-expert-level 0)))) |
| 930 | (vip-set-hooks)) |
| 931 | |
| 932 | ;; Let all minor modes take effect after loading |
| 933 | ;; this may not be enough, so we also set default minor-mode-alist. |
| 934 | ;; Without setting the default, new buffers that come up in emacs mode have |
| 935 | ;; minor-mode-map-alist = nil, unless we call vip-change-state-* |
| 936 | (if (eq vip-current-state 'emacs-state) |
| 937 | (progn |
| 938 | (vip-change-state-to-emacs) |
| 939 | (setq-default minor-mode-map-alist minor-mode-map-alist) |
| 940 | )) |
| 941 | |
| 942 | |
| 943 | |
| 944 | (run-hooks 'vip-load-hook) ; the last chance to change something |
| 945 | |
| 946 | (provide 'vip) |
| 947 | (provide 'viper) |
| 948 | |
| 949 | ;;; viper.el ends here |