comparison lisp/viper/viper.el @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents e04119814345
children c7528f8e288d
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
4 ;; Viper Is also a Package for Emacs Rebels. 4 ;; Viper Is also a Package for Emacs Rebels.
5 ;; 5 ;;
6 ;; Keywords: emulations 6 ;; Keywords: emulations
7 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> 7 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
8 8
9 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 9 ;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
10 10
11 (defconst viper-version "2.93 of March 9, 1997" 11 (defconst viper-version "2.90 of June 19, 1996"
12 "The current version of Viper") 12 "The current version of Viper")
13 13
14 ;; This file is part of GNU Emacs. 14 ;; This file is part of GNU Emacs.
15 15
16 ;; GNU Emacs is free software; you can redistribute it and/or modify 16 ;; GNU Emacs is free software; you can redistribute it and/or modify
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details. 24 ;; GNU General Public License for more details.
25 25
26 ;; You should have received a copy of the GNU General Public License 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 27 ;; along with GNU Emacs; see the file COPYING. If not, write to
28 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 28 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
29 ;; Boston, MA 02111-1307, USA.
30 29
31 ;;; Commentary: 30 ;;; Commentary:
32 31
33 ;; Viper is a full-featured Vi emulator for Emacs 19. It emulates and 32 ;; 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 33 ;; improves upon the standard features of Vi and, at the same time, allows
87 ;; macros. Third, in Viper, one can define macros that are specific to 86 ;; 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. 87 ;; a given buffer, a given major mode, or macros defined for all buffers.
89 ;; The same macro name can have several different definitions: 88 ;; The same macro name can have several different definitions:
90 ;; one global, several definitions for various major modes, and 89 ;; one global, several definitions for various major modes, and
91 ;; definitions for specific buffers. 90 ;; definitions for specific buffers.
92 ;; Buffer-specific definitions override mode-specific 91 ;; Bffer-specific definitions override mode-specific
93 ;; definitions, which, in turn, override global definitions. 92 ;; definitions, which, in turn, override global definitions.
94 ;; 93 ;;
95 ;; 94 ;;
96 ;;; Installation: 95 ;;; Installation:
97 ;; ------------- 96 ;; -------------
99 ;; (require 'viper) 98 ;; (require 'viper)
100 ;; 99 ;;
101 100
102 ;;; Acknowledgements: 101 ;;; Acknowledgements:
103 ;; ----------------- 102 ;; -----------------
104 ;; Bug reports and ideas contributed by many users have helped 103 ;; Bug reports and ideas contributed by the following users
105 ;; improve Viper and the various versions of VIP. 104 ;; have helped improve Viper and the various versions of VIP.
106 ;; See the on-line manual for a complete list of contributors. 105 ;; See the on-line manual for a complete list of contributors.
107 ;; 106 ;;
108 ;; 107 ;;
109 ;;; Notes: 108 ;;; Notes:
110 ;; 109 ;;
154 ;; in their .vip file. This will enable vip-vi-diehard-minor-mode. This 153 ;; 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. 154 ;; minor mode's bindings make Viper simulate the usual Vi very closely.
156 ;; For instance, C-c will not have its standard Emacs binding 155 ;; For instance, C-c will not have its standard Emacs binding
157 ;; and so many of the goodies of Emacs are not available. 156 ;; and so many of the goodies of Emacs are not available.
158 ;; 157 ;;
159 ;; A skilled user should set vip-expert-level to at least 3. This will 158 ;; An skilled user, should set vip-expert-level to at least 3. This will
160 ;; enable `C-c' and many Emacs facilities will become available. 159 ;; enable ;; C-c and many Emacs facilities will become available.
161 ;; In this case, vip-vi-diehard-minor-mode is inactive. 160 ;; In this case, vip-vi-diehard-minor-mode is inactive.
162 ;; 161 ;;
163 ;; Viper gurus should have at least 162 ;; Viper gurus should have at least
164 ;; (setq vip-expert-level 4) 163 ;; (setq vip-expert-level 4)
165 ;; in their ~/.vip files. This will unsuppress all Emacs keys that are not 164 ;; in their ~/.vip files. This will unsuppress all Emacs keys that are not
298 297
299 (require 'advice) 298 (require 'advice)
300 (require 'cl) 299 (require 'cl)
301 (require 'ring) 300 (require 'ring)
302 301
303 (provide 'viper) 302 (require 'viper-util)
304 303
305 ;; Compiler pacifier 304 ;; Compiler pacifier
306 (defvar vip-minibuffer-current-face) 305 (defvar vip-minibuffer-current-face)
307 (defvar vip-minibuffer-insert-face) 306 (defvar vip-minibuffer-insert-face)
308 (defvar vip-minibuffer-vi-face) 307 (defvar vip-minibuffer-vi-face)
309 (defvar vip-minibuffer-emacs-face) 308 (defvar vip-minibuffer-emacs-face)
310 (defvar iso-accents-mode) 309 (defvar iso-accents-mode)
311 (defvar zmacs-region-stays) 310 (defvar zmacs-region-stays)
312 (defvar mark-even-if-inactive)
313
314 (eval-when-compile
315 (let ((load-path (cons (expand-file-name ".") load-path)))
316 (or (featurep 'viper-util)
317 (load "viper-util.el" nil nil 'nosuffix))
318 (or (featurep 'viper-keym)
319 (load "viper-keym.el" nil nil 'nosuffix))
320 (or (featurep 'viper-mous)
321 (load "viper-mous.el" nil nil 'nosuffix))
322 (or (featurep 'viper-macs)
323 (load "viper-macs.el" nil nil 'nosuffix))
324 (or (featurep 'viper-ex)
325 (load "viper-ex.el" nil nil 'nosuffix))
326 ))
327 ;; end pacifier 311 ;; end pacifier
328 312
329
330 (require 'viper-util)
331 (require 'viper-keym)
332 (require 'viper-mous)
333 (require 'viper-macs)
334 (require 'viper-ex)
335
336
337 313
314 ;;; Variables
315
316 ;; Is t until viper-mode executes for the very first time.
317 ;; Prevents recursive descend into startup messages.
318 (defvar vip-first-time t)
319
320 (defvar vip-expert-level 0
321 "User's expert level.
322 The minor mode vip-vi-diehard-minor-mode is in effect when
323 vip-expert-level is 1 or 2 or when vip-want-emacs-keys-in-vi is t.
324 The minor mode vip-insert-diehard-minor-mode is in effect when
325 vip-expert-level is 1 or 2 or if vip-want-emacs-keys-in-insert is t.
326 Use `M-x vip-set-expert-level' to change this.")
327
328 ;; Max expert level supported by Viper. This is NOT a user option.
329 ;; It is here to make it hard for the user from resetting it.
330 (defconst vip-max-expert-level 5)
331
332 ;; Contains user settings for vars affected by vip-set-expert-level function.
333 ;; Not a user option.
334 (defvar vip-saved-user-settings nil)
335
336
337 ;;; Viper minor modes
338
339 ;; This is not local in Emacs, so we make it local.
340 (make-variable-buffer-local 'minor-mode-map-alist)
341
342 ;; Mode for vital things like \e, C-z.
343 (vip-deflocalvar vip-vi-intercept-minor-mode nil)
344
345 (vip-deflocalvar vip-vi-basic-minor-mode nil
346 "Viper's minor mode for Vi bindings.")
347
348 (vip-deflocalvar vip-vi-local-user-minor-mode nil
349 "Auxiliary minor mode for user-defined local bindings in Vi state.")
350
351 (vip-deflocalvar vip-vi-global-user-minor-mode nil
352 "Auxiliary minor mode for user-defined global bindings in Vi state.")
353
354 (vip-deflocalvar vip-vi-state-modifier-minor-mode nil
355 "Minor mode used to make major-mode-specific modification to Vi state.")
356
357 (vip-deflocalvar vip-vi-diehard-minor-mode nil
358 "This minor mode is in effect when the user wants Viper to be Vi.")
359
360 (vip-deflocalvar vip-vi-kbd-minor-mode nil
361 "Minor mode for Ex command macros in Vi state.
362 The corresponding keymap stores key bindings of Vi macros defined with
363 the Ex command :map.")
364
365 ;; Mode for vital things like \e, C-z.
366 (vip-deflocalvar vip-insert-intercept-minor-mode nil)
367
368 (vip-deflocalvar vip-insert-basic-minor-mode nil
369 "Viper's minor mode for bindings in Insert mode.")
370
371 (vip-deflocalvar vip-insert-local-user-minor-mode nil
372 "Auxiliary minor mode for buffer-local user-defined bindings in Insert state.
373 This is a way to overshadow normal Insert mode bindings locally to certain
374 designated buffers.")
375
376 (vip-deflocalvar vip-insert-global-user-minor-mode nil
377 "Auxiliary minor mode for global user-defined bindings in Insert state.")
378
379 (vip-deflocalvar vip-insert-state-modifier-minor-mode nil
380 "Minor mode used to make major-mode-specific modification to Insert state.")
381
382 (vip-deflocalvar vip-insert-diehard-minor-mode nil
383 "Minor mode that simulates Vi very closely.
384 Not recommened, except for the novice user.")
385
386 (vip-deflocalvar vip-insert-kbd-minor-mode nil
387 "Minor mode for Ex command macros Insert state.
388 The corresponding keymap stores key bindings of Vi macros defined with
389 the Ex command :map!.")
390
391 (vip-deflocalvar vip-replace-minor-mode nil
392 "Minor mode in effect in replace state (cw, C, and the like commands).")
393
394 ;; Mode for vital things like \C-z and \C-x)
395 ;; This is t, by default. So, any new buffer will have C-z defined as
396 ;; switch to Vi, unless we switched states in this buffer
397 (vip-deflocalvar vip-emacs-intercept-minor-mode t)
398
399 (vip-deflocalvar vip-emacs-local-user-minor-mode t
400 "Minor mode for local user bindings effective in Emacs state.
401 Users can use it to override Emacs bindings when Viper is in its Emacs
402 state.")
403
404 (vip-deflocalvar vip-emacs-global-user-minor-mode t
405 "Minor mode for global user bindings in effect in Emacs state.
406 Users can use it to override Emacs bindings when Viper is in its Emacs
407 state.")
408
409 (vip-deflocalvar vip-emacs-kbd-minor-mode t
410 "Minor mode for Vi style macros in Emacs state.
411 The corresponding keymap stores key bindings of Vi macros defined with
412 `vip-record-kbd-macro' command. There is no Ex-level command to do this
413 interactively.")
414
415 (vip-deflocalvar vip-emacs-state-modifier-minor-mode t
416 "Minor mode used to make major-mode-specific modification to Emacs state.
417 For instance, a Vi purist may want to bind `dd' in Dired mode to a function
418 that deletes a file.")
419
420
421
422 ;;; ISO characters
423
424 (vip-deflocalvar vip-automatic-iso-accents nil
425 "*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state.
426 For some users, this behavior may be too primitive. In this case, use
427 insert/emacs/vi state hooks.")
428
429
430 ;;; Emacs keys in other states.
431
432 (defvar vip-want-emacs-keys-in-insert t
433 "*Set to nil if you want complete Vi compatibility in insert mode.
434 Complete compatibility with Vi is not recommended for power use of Viper.")
435
436 (defvar vip-want-emacs-keys-in-vi t
437 "*Set to nil if you want complete Vi compatibility in Vi mode.
438 Full Vi compatibility is not recommended for power use of Viper.")
439
440
441
442 ;; VI-style Undo
443
444 ;; Used to 'undo' complex commands, such as replace and insert commands.
445 (vip-deflocalvar vip-undo-needs-adjustment nil)
446 (put 'vip-undo-needs-adjustment 'permanent-local t)
447
448 ;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a
449 ;; complex command that must be undone atomically. If inserted, it is
450 ;; erased by vip-change-state-to-vi and vip-repeat.
451 (defconst vip-buffer-undo-list-mark 'viper)
452
453 (defvar vip-keep-point-on-undo nil
454 "*Non-nil means not to move point while undoing commands.
455 This style is different from Emacs and Vi. Try it to see if
456 it better fits your working style.")
457
458 ;; Replace mode and changing text
459
460 ;; Viper's own after/before change functions, which get vip-add-hook'ed to
461 ;; Emacs's
462 (vip-deflocalvar vip-after-change-functions nil "")
463 (vip-deflocalvar vip-before-change-functions nil "")
464 (vip-deflocalvar vip-post-command-hooks nil "")
465 (vip-deflocalvar vip-pre-command-hooks nil "")
466
467 ;; Can be used to pass global states around for short period of time
468 (vip-deflocalvar vip-intermediate-command nil "")
469
470 ;; Indicates that the current destructive command has started in replace mode.
471 (vip-deflocalvar vip-began-as-replace nil "")
472
473 (defvar vip-replace-overlay-cursor-color "Red"
474 "*Cursor color to use in Replace state")
475
476
477 (vip-deflocalvar vip-replace-overlay nil "")
478 (put 'vip-replace-overlay 'permanent-local t)
479
480 (if (vip-has-face-support-p)
481 (progn
482 (make-face 'vip-replace-overlay-face)
483 (vip-hide-face 'vip-replace-overlay-face)
484 (or (face-differs-from-default-p 'vip-replace-overlay-face)
485 (progn
486 (if (vip-can-use-colors "darkseagreen2" "Black")
487 (progn
488 (set-face-background
489 'vip-replace-overlay-face "darkseagreen2")
490 (set-face-foreground 'vip-replace-overlay-face "Black")))
491 (set-face-underline-p 'vip-replace-overlay-face t))
492 )))
493
494 (defvar vip-replace-overlay-face 'vip-replace-overlay-face
495 "*Face for highlighting replace regions on a window display.")
496
497 (defvar vip-replace-region-end-delimiter "$"
498 "A string marking the end of replacement regions.
499 It is used only with TTYs or if `vip-use-replace-region-delimiters'
500 is non-nil.")
501 (defvar vip-replace-region-start-delimiter ""
502 "A string marking the beginning of replacement regions.
503 It is used only with TTYs or if `vip-use-replace-region-delimiters'
504 is non-nil.")
505 (defvar vip-use-replace-region-delimiters
506 (or (not (vip-has-face-support-p)) (not (vip-color-display-p)))
507 "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and
508 `vip-replace-region-start-delimiter' to delimit replacement regions, even on
509 color displays. By default, the delimiters are used only on TTYs or
510 monochrome displays.")
511
512 ;; XEmacs requires glyphs
513 (if vip-xemacs-p
514 (progn
515 (or (glyphp vip-replace-region-end-delimiter)
516 (setq vip-replace-region-end-delimiter
517 (make-glyph vip-replace-region-end-delimiter)))
518 (or (glyphp vip-replace-region-start-delimiter)
519 (setq vip-replace-region-start-delimiter
520 (make-glyph vip-replace-region-start-delimiter)))
521 ))
522
523
524 ;; These are local marker that must be initialized to nil and moved with
525 ;; `vip-move-marker-locally'
526 ;;
527 ;; Remember the last position inside the replace region.
528 (vip-deflocalvar vip-last-posn-in-replace-region nil)
529 ;; Remember the last position while inserting
530 (vip-deflocalvar vip-last-posn-while-in-insert-state nil)
531 (put 'vip-last-posn-in-replace-region 'permanent-local t)
532 (put 'vip-last-posn-while-in-insert-state 'permanent-local t)
533
534 (vip-deflocalvar vip-sitting-in-replace nil "")
535 (put 'vip-sitting-in-replace 'permanent-local t)
536
537 ;; Remember the number of characters that have to be deleted in replace
538 ;; mode to compensate for the inserted characters.
539 (vip-deflocalvar vip-replace-chars-to-delete 0 "")
540 (vip-deflocalvar vip-replace-chars-deleted 0 "")
541
542 ;; Insertion ring and command ring
543 (defvar vip-insertion-ring-size 14
544 "The size of the insertion ring.")
545 ;; The insertion ring.
546 (defvar vip-insertion-ring nil)
547 ;; This is temp insertion ring. Used to do rotation for display purposes.
548 ;; When rotation just started, it is initialized to vip-insertion-ring.
549 (defvar vip-temp-insertion-ring nil)
550 (defvar vip-last-inserted-string-from-insertion-ring "")
551
552 (defvar vip-command-ring-size 14
553 "The size of the command ring.")
554 ;; The command ring.
555 (defvar vip-command-ring nil)
556 ;; This is temp command ring. Used to do rotation for display purposes.
557 ;; When rotation just started, it is initialized to vip-command-ring.
558 (defvar vip-temp-command-ring nil)
559
560 ;; Modes and related variables
561
562 ;; Current mode. One of: `emacs-state', `vi-state', `insert-state'
563 (vip-deflocalvar vip-current-state 'emacs-state)
564
565
566 (defvar vip-toggle-key "\C-z"
567 "The key used to change states from emacs to Vi and back.
568 In insert mode, this key also functions as Meta.
569 Must be set in .vip file or prior to loading Viper.
570 This setting cannot be changed interactively.")
571
572 (defvar vip-ESC-key "\e"
573 "Key used to ESC.
574 Must be set in .vip file or prior to loading Viper.
575 This setting cannot be changed interactively.")
576
577 (defvar vip-no-multiple-ESC t
578 "*If true, multiple ESC in Vi mode will cause bell to ring.
579 \_ is then mapped to Meta.
580 This is set to t on a windowing terminal and to 'twice on a dumb
581 terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this
582 enables cursor keys and is generally more convenient, as terminals usually
583 don't have a convenient Meta key.
584 Setting vip-no-multiple-ESC to nil will allow as many multiple ESC,
585 as is allowed by the major mode in effect.")
586
587
588 (defvar vip-want-ctl-h-help nil
589 "*If t then C-h is bound to help-command in insert mode, if nil then it is
590 bound to delete-backward-char.")
591
592 ;; Autoindent in insert
593
594 ;; Variable that keeps track of whether C-t has been pressed.
595 (vip-deflocalvar vip-cted nil "")
596
597 ;; Preserve the indent value, used by C-d in insert mode.
598 (vip-deflocalvar vip-current-indent 0)
599
600 ;; Whether to preserve the indent, used by C-d in insert mode.
601 (vip-deflocalvar vip-preserve-indent nil)
602
603 (vip-deflocalvar vip-auto-indent nil
604 "*Autoindent if t.")
605 (vip-deflocalvar vip-electric-mode t
606 "*If t, enable electric behavior.
607 Currently only enables auto-indentation `according to mode'.")
608
609 (defconst vip-shift-width 8
610 "*The shiftwidth variable.")
611
612 ;; Variables for repeating destructive commands
613
614 (defconst vip-keep-point-on-repeat t
615 "*If t, don't move point when repeating previous command.
616 This is useful for doing repeated changes with the '.' key.
617 The user can change this to nil, if she likes when the cursor moves
618 to a new place after repeating previous Vi command.")
619
620 ;; Remember insert point as a marker. This is a local marker that must be
621 ;; initialized to nil and moved with `vip-move-marker-locally'.
622 (vip-deflocalvar vip-insert-point nil)
623 (put 'vip-insert-point 'permanent-local t)
624
625 ;; This remembers the point before dabbrev-expand was called.
626 ;; If vip-insert-point turns out to be bigger than that, it is reset
627 ;; back to vip-pre-command-point.
628 ;; The reason this is needed is because dabbrev-expand (and possibly
629 ;; others) may jump to before the insertion point, delete something and
630 ;; then reinsert a bigger piece. For instance: bla^blo
631 ;; If dabbrev-expand is called after `blo' and ^ undicates vip-insert-point,
632 ;; then point jumps to the beginning of `blo'. If expansion is found, `blablo'
633 ;; is deleted, and we have |^, where | denotes point. Next, dabbrev-expand
634 ;; will insert the expansion, and we get: blablo^
635 ;; Whatever we insert next goes before the ^, i.e., before the
636 ;; vip-insert-point marker. So, Viper will think that nothing was
637 ;; inserted. Remembering the orig position of the marker circumvents the
638 ;; problem.
639 ;; We don't know of any command, except dabbrev-expand, that has the same
640 ;; problem. However, the same trick can be used if such a command is
641 ;; discovered later.
642 ;;
643 (vip-deflocalvar vip-pre-command-point nil)
644 (put 'vip-pre-command-point 'permanent-local t) ; this is probably an overkill
645
646 ;; This is used for saving inserted text.
647 (defvar vip-last-insertion nil)
648
649 ;; Remembers the last replaced region.
650 (defvar vip-last-replace-region "")
651
652 ;; Remember com point as a marker.
653 ;; This is a local marker. Should be moved with `vip-move-marker-locally'
654 (vip-deflocalvar vip-com-point nil)
655
656 ;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys)
657 ;; It is used to re-execute last destructive command.
658 ;; M-COM is a Lisp symbol representing the function to be executed.
659 ;; VAL is the prefix argument that was used with that command.
660 ;; COM is an internal descriptor, such as ?r, ?c, ?C, which contains
661 ;; additional information on how the function in M-COM is to be handled.
662 ;; REG is the register used by command
663 ;; INSERTED-TEXT is text inserted by that command (in case of o, c, C, i, r
664 ;; commands).
665 ;; COMMAND-KEYS are the keys that were typed to invoke the command.
666 (defvar vip-d-com nil)
667
668 ;; The character remembered by the Vi `r' command.
669 (defvar vip-d-char nil)
670
671 ;; Name of register to store deleted or yanked strings
672 (defvar vip-use-register nil)
673
674
675
676 ;; Variables for Moves and Searches
677
678 ;; For use by `;' command.
679 (defvar vip-f-char nil)
680
681 ;; For use by `.' command.
682 (defvar vip-F-char nil)
683
684 ;; For use by `;' command.
685 (defvar vip-f-forward nil)
686
687 ;; For use by `;' command.
688 (defvar vip-f-offset nil)
689
690 ;; Last search string
691 (defvar vip-s-string "")
692
693 (defvar vip-quote-string "> "
694 "String inserted at the beginning of quoted region.")
695
696 ;; If t, search is forward.
697 (defvar vip-s-forward nil)
698
699 (defconst vip-case-fold-search nil
700 "*If t, search ignores cases.")
701
702 (defconst vip-re-search t
703 "*If t, search is reg-exp search, otherwise vanilla search.")
704
705 (defconst vip-re-query-replace t
706 "*If t then do regexp replace, if nil then do string replace.")
707
708 (defconst vip-re-replace t
709 "*If t, do regexp replace. nil means do string replace.")
710
711 (vip-deflocalvar vip-ex-style-motion t
712 "*Ex-style: the commands l,h do not cross lines, etc.")
713
714 (vip-deflocalvar vip-ex-style-editing-in-insert t
715 "*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc.
716 Note: this doesn't preclude ^H and ^? from deleting characters by moving
717 past the insertion point. This is a feature, not a bug. ")
718
719 (vip-deflocalvar vip-delete-backwards-in-replace nil
720 "*If t, DEL key will delete characters while moving the cursor backwards.
721 If nil, the cursor will move backwards without deleting anything.")
722
723 (defconst vip-buffer-search-char nil
724 "*Key bound for buffer-searching.")
725
726 (defconst vip-search-wrap-around-t t
727 "*If t, search wraps around.")
728
729 (vip-deflocalvar vip-related-files-and-buffers-ring nil
730 "*Ring of file and buffer names that are considered to be related to the
731 current buffer.
732 These buffers can be cycled through via :R and :P commands.")
733 (put 'vip-related-files-and-buffers-ring 'permanent-local t)
734
735 ;; Used to find out if we are done with searching the current buffer.
736 (vip-deflocalvar vip-local-search-start-marker nil)
737 ;; As above, but global
738 (defvar vip-search-start-marker (make-marker))
739
740 ;; the search overlay
741 (vip-deflocalvar vip-search-overlay nil)
742
743
744 (defvar vip-heading-start
745 (concat "^\\s-*(\\s-*defun\\s-\\|" ; lisp
746 "^{\\s-*$\\|^[_a-zA-Z][^()]*[()].*{\\s-*$\\|" ; C/C++
747 "^\\s-*class.*{\\|^\\s-*struct.*{\\|^\\s-*enum.*{\\|"
748 "^\\\\[sb][a-z]*{.*}\\s-*$\\|" ; latex
749 "^@node\\|@table\\|^@m?enu\\|^@itemize\\|^@if\\|" ; texinfo
750 "^.+:-") ; prolog
751 "*Regexps for Headings. Used by \[\[ and \]\].")
752
753 (defvar vip-heading-end
754 (concat "^}\\|" ; C/C++
755 "^\\\\end{\\|" ; latex
756 "^@end \\|" ; texinfo
757 ")\n\n[ \t\n]*\\|" ; lisp
758 "\\.\\s-*$") ; prolog
759 "*Regexps to end Headings/Sections. Used by \[\].")
760
761
762 ;; These two vars control the interaction of jumps performed by ' and `.
763 ;; In this new version, '' doesn't erase the marks set by ``, so one can
764 ;; use both kinds of jumps interchangeably and without loosing positions
765 ;; inside the lines.
766
767 ;; Remembers position of the last jump done using ``'.
768 (vip-deflocalvar vip-last-jump nil)
769 ;; Remembers position of the last jump done using `''.
770 (vip-deflocalvar vip-last-jump-ignore 0)
771
772 ;; Some common error messages
773
774 (defconst vip-SpuriousText "Spurious text after command" "")
775 (defconst vip-BadExCommand "Not an editor command" "")
776 (defconst vip-InvalidCommandArgument "Invalid command argument" "")
777 (defconst vip-NoPrevSearch "No previous search string" "")
778 (defconst vip-EmptyRegister "`%c': Nothing in this register" "")
779 (defconst vip-InvalidRegister "`%c': Invalid register" "")
780 (defconst vip-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "")
781 (defconst vip-InvalidTextmarker "`%c': Invalid text marker" "")
782 (defconst vip-InvalidViCommand "Invalid command" "")
783 (defconst vip-BadAddress "Ill-formed address" "")
784 (defconst vip-FirstAddrExceedsSecond "First address exceeds second" "")
785 (defconst vip-NoFileSpecified "No file specified" "")
786
787
788 ;; History variables
789
790 ;; History of search strings.
791 (defvar vip-search-history (list ""))
792 ;; History of query-replace strings used as a source.
793 (defvar vip-replace1-history nil)
794 ;; History of query-replace strings used as replacement.
795 (defvar vip-replace2-history nil)
796 ;; History of region quoting strings.
797 (defvar vip-quote-region-history (list vip-quote-string))
798 ;; History of Ex-style commands.
799 (defvar vip-ex-history nil)
800 ;; History of shell commands.
801 (defvar vip-shell-history nil)
802
803
804 ;; Last shell command. There are two of these, one for Ex (in viper-ex)
805 ;; and one for Vi.
806
807 ;; Last shell command executed with ! command.
808 (defvar vip-last-shell-com nil)
809
810
811
812 ;;; Miscellaneous
813
814 ;; don't bark when mark is inactive
815 (setq mark-even-if-inactive t)
816
817 (defvar vip-inhibit-startup-message nil
818 "Whether Viper startup message should be inhibited.")
819
820 (defvar vip-always t
821 "t means, arrange that vi-state will be a default.")
822
823 (defvar vip-ms-style-os-p (memq system-type '(ms-dos windows-nt windows-95))
824 "Tells is Emacs is running under an MS-style OS: ms-dos, window-nt, W95.")
825 (defvar vip-vms-os-p (memq system-type '(vax-vms axp-vms))
826 "Tells if Emacs is running under VMS.")
827
828 (defvar vip-custom-file-name (cond (vip-vms-os-p "sys$login:.vip")
829 ((memq system-type '(emx ms-dos))
830 "/_vip")
831 ((memq system-type '(windows-nt windows-95))
832 "~/_vip")
833 (t ; Unix
834 "~/.vip"))
835 "Viper customisation file.
836 This variable must be set _before_ loading Viper.")
837
838
839 (defvar vip-spell-function 'ispell-region
840 "Spell function used by #s<move> command to spell.")
841
842 (defvar vip-tags-file-name "TAGS"
843 "The tags file used by Viper.")
844
845 ;; Minibuffer
846
847 (defvar vip-vi-style-in-minibuffer t
848 "If t, use vi-style editing in minibuffer.
849 Should be set in `~/.vip' file.")
850
851 ;; overlay used in the minibuffer to indicate which state it is in
852 (vip-deflocalvar vip-minibuffer-overlay nil)
853
854 ;; Hook, specific to Viper, which is run just *before* exiting the minibuffer.
855 ;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run
856 ;; *after* exiting the minibuffer
857 (defvar vip-minibuffer-exit-hook nil)
858
859 (vip-deflocalvar vip-vi-minibuffer-minor-mode nil
860 "Minor mode that forces Vi-style when the Minibuffer is in Vi state.")
861 (vip-deflocalvar vip-insert-minibuffer-minor-mode nil
862 "Minor mode that forces Vi-style when the Minibuffer is in Insert state.")
863
864 ;; setup emacs-supported vi-style feel
865 (setq next-line-add-newlines nil
866 require-final-newline t)
867
868 (make-variable-buffer-local 'require-final-newline)
869
870
871 ;; Mode line
872 (defconst vip-vi-state-id "<V> "
873 "Mode line tag identifying the Vi mode of Viper.")
874 (defconst vip-emacs-state-id "<E> "
875 "Mode line tag identifying the Emacs mode of Viper.")
876 (defconst vip-insert-state-id "<I> "
877 "Mode line tag identifying the Insert mode of Viper.")
878 (defconst vip-replace-state-id "<R> "
879 "Mode line tag identifying the Replace mode of Viper.")
880
881 ;; Viper changes the default mode-line-buffer-identification
882 (setq-default mode-line-buffer-identification '(" %b"))
883
884 ;; Variable displaying the current Viper state in the mode line.
885 (vip-deflocalvar vip-mode-string vip-emacs-state-id)
886 (or (memq 'vip-mode-string global-mode-string)
887 (setq global-mode-string
888 (append '("" vip-mode-string) (cdr global-mode-string))))
889
890
891 (defvar vip-vi-state-hook nil
892 "*Hooks run just before the switch to Vi mode is completed.")
893 (defvar vip-insert-state-hook nil
894 "*Hooks run just before the switch to Insert mode is completed.")
895 (defvar vip-replace-state-hook nil
896 "*Hooks run just before the switch to Replace mode is completed.")
897 (defvar vip-emacs-state-hook nil
898 "*Hooks run just before the switch to Emacs mode is completed.")
899
900 (defvar vip-load-hook nil
901 "Hooks run just after loading Viper.")
902
903
338 ;; Generic predicates 904 ;; Generic predicates
339 905
340 ;; These test functions are shamelessly lifted from vip 4.4.2 by Aamod Sane 906 ;; These test functions are shamelessly lifted from vip 4.4.2 by Aamod Sane
341 907
342 ;; generate test functions 908 ;; generate test functions
354 920
355 ;; Variables for defining VI commands 921 ;; Variables for defining VI commands
356 922
357 ;; Modifying commands that can be prefixes to movement commands 923 ;; Modifying commands that can be prefixes to movement commands
358 (defconst vip-prefix-commands '(?c ?d ?y ?! ?= ?# ?< ?> ?\")) 924 (defconst vip-prefix-commands '(?c ?d ?y ?! ?= ?# ?< ?> ?\"))
359 ;; define vip-prefix-command-p
360 (vip-test-com-defun vip-prefix-command) 925 (vip-test-com-defun vip-prefix-command)
361 926
362 ;; Commands that are pairs eg. dd. r and R here are a hack 927 ;; Commands that are pairs eg. dd. r and R here are a hack
363 (defconst vip-charpair-commands '(?c ?d ?y ?! ?= ?< ?> ?r ?R)) 928 (defconst vip-charpair-commands '(?c ?d ?y ?! ?= ?< ?> ?r ?R))
364 ;; define vip-charpair-command-p
365 (vip-test-com-defun vip-charpair-command) 929 (vip-test-com-defun vip-charpair-command)
366 930
367 (defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l 931 (defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l
368 ?H ?M ?L ?n ?t ?T ?w ?W ?$ ?% 932 ?H ?M ?n ?t ?T ?w ?W ?$ ?%
369 ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?` 933 ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?`
370 ?; ?, ?0 ?? ?/ 934 ?; ?, ?0 ?? ?/
371 ) 935 )
372 "Movement commands") 936 "Movement commands")
373 ;; define vip-movement-command-p
374 (vip-test-com-defun vip-movement-command) 937 (vip-test-com-defun vip-movement-command)
375 938
376 (defconst vip-digit-commands '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9) 939 ;; Commands that can be repeated by .(dotted)
377 "Digit commands") 940 (defconst vip-dotable-commands '(?c ?d ?C ?D ?> ?<))
378 ;; define vip-digit-command-p
379 (vip-test-com-defun vip-digit-command)
380
381 ;; Commands that can be repeated by . (dotted)
382 (defconst vip-dotable-commands '(?c ?d ?C ?s ?S ?D ?> ?<))
383 ;; define vip-dotable-command-p
384 (vip-test-com-defun vip-dotable-command) 941 (vip-test-com-defun vip-dotable-command)
385 942
386 ;; Commands that can follow a # 943 ;; Commands that can follow a #
387 (defconst vip-hash-commands '(?c ?C ?g ?q ?s)) 944 (defconst vip-hash-cmds '(?c ?C ?g ?q ?S))
388 ;; define vip-hash-command-p 945 (vip-test-com-defun vip-hash-cmd)
389 (vip-test-com-defun vip-hash-command)
390 946
391 ;; Commands that may have registers as prefix 947 ;; Commands that may have registers as prefix
392 (defconst vip-regsuffix-commands '(?d ?y ?Y ?D ?p ?P ?x ?X)) 948 (defconst vip-regsuffix-commands '(?d ?y ?Y ?D ?p ?P ?x ?X))
393 ;; define vip-regsuffix-command-p
394 (vip-test-com-defun vip-regsuffix-command) 949 (vip-test-com-defun vip-regsuffix-command)
395 950
396 (defconst vip-vi-commands (append vip-movement-commands 951
397 vip-digit-commands 952
398 vip-dotable-commands 953 ;;; Arrange the keymaps
399 vip-charpair-commands 954 (require 'viper-keym)
400 vip-hash-commands
401 vip-prefix-commands
402 vip-regsuffix-commands)
403 "The list of all commands in Vi-state.")
404 ;; define vip-vi-command-p
405 (vip-test-com-defun vip-vi-command)
406 955
407 956
408 ;;; CODE 957 ;;; CODE
409 958
410 ;; sentinels 959 ;; sentinels
434 (defsubst vip-insert-state-post-command-sentinel () 983 (defsubst vip-insert-state-post-command-sentinel ()
435 (if (and (memq vip-current-state '(insert-state replace-state)) 984 (if (and (memq vip-current-state '(insert-state replace-state))
436 vip-insert-point 985 vip-insert-point
437 (>= (point) vip-insert-point)) 986 (>= (point) vip-insert-point))
438 (setq vip-last-posn-while-in-insert-state (point-marker))) 987 (setq vip-last-posn-while-in-insert-state (point-marker)))
439 (if (eq vip-current-state 'insert-state)
440 (progn
441 (or (stringp vip-saved-cursor-color)
442 (string= (vip-get-cursor-color) vip-insert-state-cursor-color)
443 (setq vip-saved-cursor-color (vip-get-cursor-color)))
444 (if (stringp vip-saved-cursor-color)
445 (vip-change-cursor-color vip-insert-state-cursor-color))
446 ))
447 (if (and (eq this-command 'dabbrev-expand) 988 (if (and (eq this-command 'dabbrev-expand)
448 (integerp vip-pre-command-point) 989 (integerp vip-pre-command-point)
449 (> vip-insert-point vip-pre-command-point)) 990 (> vip-insert-point vip-pre-command-point))
450 (move-marker vip-insert-point vip-pre-command-point)) 991 (move-marker vip-insert-point vip-pre-command-point))
451 ) 992 )
452 993
453 (defsubst vip-insert-state-pre-command-sentinel () 994 (defsubst vip-insert-state-pre-command-sentinel ()
454 (or (memq this-command '(self-insert-command))
455 (memq (vip-event-key last-command-event)
456 '(up down left right (meta f) (meta b)
457 (control n) (control p) (control f) (control b)))
458 (vip-restore-cursor-color-after-insert))
459 (if (and (eq this-command 'dabbrev-expand) 995 (if (and (eq this-command 'dabbrev-expand)
460 (markerp vip-insert-point) 996 (markerp vip-insert-point)
461 (marker-position vip-insert-point)) 997 (marker-position vip-insert-point))
462 (setq vip-pre-command-point (marker-position vip-insert-point)))) 998 (setq vip-pre-command-point (marker-position vip-insert-point))))
463 999
469 ;; the point outside the replacement region, then the cursor color will 1005 ;; the point outside the replacement region, then the cursor color will
470 ;; remain red. Restoring the default, below, prevents this. 1006 ;; remain red. Restoring the default, below, prevents this.
471 (if (and (<= (vip-replace-start) (point)) 1007 (if (and (<= (vip-replace-start) (point))
472 (<= (point) (vip-replace-end))) 1008 (<= (point) (vip-replace-end)))
473 (vip-change-cursor-color vip-replace-overlay-cursor-color) 1009 (vip-change-cursor-color vip-replace-overlay-cursor-color)
474 (vip-restore-cursor-color-after-replace) 1010 (vip-restore-cursor-color)
475 )) 1011 ))
476 1012
477 ;; to speed up, don't change cursor color before self-insert 1013 ;; to speed up, don't change cursor color before self-insert
478 ;; and common move commands 1014 ;; and common move commands
479 (defsubst vip-replace-state-pre-command-sentinel () 1015 (defsubst vip-replace-state-pre-command-sentinel ()
480 (or (memq this-command '(self-insert-command)) 1016 (or (memq this-command '(self-insert-command))
481 (memq (vip-event-key last-command-event) 1017 (memq (vip-event-key last-command-event)
482 '(up down left right (meta f) (meta b) 1018 '(up down left right (meta f) (meta b)
483 (control n) (control p) (control f) (control b))) 1019 (control n) (control p) (control f) (control b)))
484 (vip-restore-cursor-color-after-replace))) 1020 (vip-restore-cursor-color)))
485 1021
486 (defun vip-replace-state-post-command-sentinel () 1022 (defun vip-replace-state-post-command-sentinel ()
487 ;; Restoring cursor color is needed despite 1023 ;; Restoring cursor color is needed despite
488 ;; vip-replace-state-pre-command-sentinel: When one jumps to another buffer 1024 ;; vip-replace-state-pre-command-sentinel: When one jumps to another buffer
489 ;; in another frame, the pre-command hook won't change cursor color to 1025 ;; in another frame, the pre-command hook won't change cursor color to
493 ;; 1029 ;;
494 ;; We optimize for self-insert-command's here, since they either don't change 1030 ;; We optimize for self-insert-command's here, since they either don't change
495 ;; cursor color or, if they terminate replace mode, the color will be changed 1031 ;; cursor color or, if they terminate replace mode, the color will be changed
496 ;; in vip-finish-change 1032 ;; in vip-finish-change
497 (or (memq this-command '(self-insert-command)) 1033 (or (memq this-command '(self-insert-command))
498 (vip-restore-cursor-color-after-replace)) 1034 (vip-restore-cursor-color))
499 (cond 1035 (cond
500 ((eq vip-current-state 'replace-state) 1036 ((eq vip-current-state 'replace-state)
501 ;; delete characters to compensate for inserted chars. 1037 ;; delete characters to compensate for inserted chars.
502 (let ((replace-boundary (vip-replace-end))) 1038 (let ((replace-boundary (vip-replace-end)))
503 (save-excursion 1039 (save-excursion
605 (define-key vip-insert-basic-map "\C-m" 'vip-autoindent) 1141 (define-key vip-insert-basic-map "\C-m" 'vip-autoindent)
606 (if vip-want-emacs-keys-in-insert 1142 (if vip-want-emacs-keys-in-insert
607 ;; expert 1143 ;; expert
608 (define-key vip-insert-basic-map "\C-j" nil) 1144 (define-key vip-insert-basic-map "\C-j" nil)
609 ;; novice 1145 ;; novice
610 (define-key vip-insert-basic-map "\C-j" 'vip-autoindent))) 1146 (define-key vip-insert-basic-map "\C-j" 'vip-autoindent))))
611 (define-key vip-insert-basic-map "\C-m" nil)
612 (define-key vip-insert-basic-map "\C-j" nil))
613 1147
614 (setq vip-insert-diehard-minor-mode 1148 (setq vip-insert-diehard-minor-mode
615 (not vip-want-emacs-keys-in-insert)) 1149 (not vip-want-emacs-keys-in-insert))
616 1150
617 (if vip-want-ctl-h-help 1151 (if vip-want-ctl-h-help
618 (progn 1152 (progn
619 (define-key vip-insert-basic-map [(control h)] 'help-command) 1153 (define-key vip-insert-basic-map "\C-h" 'help-command)
620 (define-key vip-replace-map [(control h)] 'help-command)) 1154 (define-key vip-replace-map "\C-h" 'help-command))
621 (define-key vip-insert-basic-map 1155 (define-key vip-insert-basic-map
622 [(control h)] 'vip-del-backward-char-in-insert) 1156 "\C-h" 'vip-del-backward-char-in-insert)
623 (define-key vip-replace-map 1157 (define-key vip-replace-map
624 [(control h)] 'vip-del-backward-char-in-replace))) 1158 "\C-h" 'vip-del-backward-char-in-replace)))
625 1159
626 (t ; Vi state 1160 (t
627 (setq vip-vi-diehard-minor-mode (not vip-want-emacs-keys-in-vi)) 1161 (setq vip-vi-diehard-minor-mode (not vip-want-emacs-keys-in-vi))
628 (if vip-want-ctl-h-help 1162 (if vip-want-ctl-h-help
629 (define-key vip-vi-basic-map [(control h)] 'help-command) 1163 (define-key vip-vi-basic-map "\C-h" 'help-command)
630 (define-key vip-vi-basic-map [(control h)] 'vip-backward-char))) 1164 (define-key vip-vi-basic-map "\C-h" 'vip-backward-char)))
631 )) 1165 ))
632 1166
633 1167
634 ;; Normalizes minor-mode-map-alist by putting Viper keymaps first. 1168 ;; Normalizes minor-mode-map-alist by putting Viper keymaps first.
635 ;; This ensures that Viper bindings are in effect, regardless of which minor 1169 ;; This ensures that Viper bindings are in effect, regardless of which minor
745 do not cause Emacs to quit, except at user level 1 (a novice). 1279 do not cause Emacs to quit, except at user level 1 (a novice).
746 3. ^X^C EXITS EMACS. 1280 3. ^X^C EXITS EMACS.
747 4. Viper supports multiple undo: `u' will undo. Typing `.' will repeat 1281 4. Viper supports multiple undo: `u' will undo. Typing `.' will repeat
748 undo. Another `u' changes direction. 1282 undo. Another `u' changes direction.
749 1283
750 6. Emacs Meta functions are invoked by typing `C-\\' or `\\ ESC'. 1284 6. Emacs Meta functions are invoked by typing `_' or `\\ ESC'.
751 On a window system, the best way is to use the Meta-key. 1285 On a window system, the best way is to use the Meta-key.
752 7. Try \\[keyboard-quit] and \\[abort-recursive-edit] repeatedly,if 1286 7. Try \\[keyboard-quit] and \\[abort-recursive-edit] repeatedly,if
753 something funny happens. This would abort the current editing command. 1287 something funny happens. This would abort the current editing command.
754 1288
755 You can get more information on Viper by: 1289 You can get more information on Viper by:
895 1429
896 ;; always turn off iso-accents-mode, or else we won't be able to use the 1430 ;; always turn off iso-accents-mode, or else we won't be able to use the
897 ;; keys `,',^ in Vi state, as they will do accents instead of Vi actions. 1431 ;; keys `,',^ in Vi state, as they will do accents instead of Vi actions.
898 (if (and (boundp 'iso-accents-mode) iso-accents-mode) 1432 (if (and (boundp 'iso-accents-mode) iso-accents-mode)
899 (iso-accents-mode -1)) 1433 (iso-accents-mode -1))
900
901 (vip-restore-cursor-color-after-insert)
902 1434
903 ;; Protection against user errors in hooks 1435 ;; Protection against user errors in hooks
904 (condition-case conds 1436 (condition-case conds
905 (run-hooks 'vip-vi-state-hook) 1437 (run-hooks 'vip-vi-state-hook)
906 (error 1438 (error
911 (interactive) 1443 (interactive)
912 (vip-change-state 'insert-state) 1444 (vip-change-state 'insert-state)
913 (if (and vip-automatic-iso-accents (fboundp 'iso-accents-mode)) 1445 (if (and vip-automatic-iso-accents (fboundp 'iso-accents-mode))
914 (iso-accents-mode 1)) ; turn iso accents on 1446 (iso-accents-mode 1)) ; turn iso accents on
915 1447
916 (or (stringp vip-saved-cursor-color)
917 (string= (vip-get-cursor-color) vip-insert-state-cursor-color)
918 (setq vip-saved-cursor-color (vip-get-cursor-color)))
919 ;; Commented out, because if vip-change-state-to-insert is executed
920 ;; non-interactively then the old cursor color may get lost. Same old Emacs
921 ;; bug related to local variables?
922 ;;;(if (stringp vip-saved-cursor-color)
923 ;;; (vip-change-cursor-color vip-insert-state-cursor-color))
924 ;; Protection against user errors in hooks 1448 ;; Protection against user errors in hooks
925 (condition-case conds 1449 (condition-case conds
926 (run-hooks 'vip-insert-state-hook) 1450 (run-hooks 'vip-insert-state-hook)
927 (error 1451 (error
928 (vip-message-conditions conds)))) 1452 (vip-message-conditions conds))))
970 (defun vip-escape-to-emacs (arg &optional events) 1494 (defun vip-escape-to-emacs (arg &optional events)
971 "Escape to Emacs state from Vi state for one Emacs command. 1495 "Escape to Emacs state from Vi state for one Emacs command.
972 ARG is used as the prefix value for the executed command. If 1496 ARG is used as the prefix value for the executed command. If
973 EVENTS is a list of events, which become the beginning of the command." 1497 EVENTS is a list of events, which become the beginning of the command."
974 (interactive "P") 1498 (interactive "P")
975 (if (= last-command-char ?\\)
976 (message "Switched to EMACS state for the next command..."))
977 (vip-escape-to-state arg events 'emacs-state)) 1499 (vip-escape-to-state arg events 'emacs-state))
978 1500
979 ;; escape to Vi mode termporarily 1501 ;; escape to Vi mode termporarily
980 (defun vip-escape-to-vi (arg) 1502 (defun vip-escape-to-vi ()
981 "Escape from Emacs state to Vi state for one Vi 1-character command. 1503 "Escape from Emacs state to Vi state for one Vi 1-character command.
982 If the Vi command that the user types has a prefix argument, e.g., `d2w', then 1504 This doesn't work with prefix arguments or most complex commands like
983 Vi's prefix argument will be used. Otherwise, the prefix argument passed to 1505 cw, dw, etc. But it does work with some 2-character commands,
984 `vip-escape-to-vi' is used." 1506 like dd or dr."
985 (interactive "P") 1507 (interactive)
986 (message "Switched to VI state for the next command...") 1508 (vip-escape-to-state nil nil 'vi-state))
987 (vip-escape-to-state arg nil 'vi-state))
988 1509
989 ;; Escape to STATE mode for one Emacs command. 1510 ;; Escape to STATE mode for one Emacs command.
990 (defun vip-escape-to-state (arg events state) 1511 (defun vip-escape-to-state (arg events state)
991 ;;(let (com key prefix-arg) 1512 (let (com key prefix-arg)
992 (let (com key)
993 ;; this temporarily turns off Viper's minor mode keymaps 1513 ;; this temporarily turns off Viper's minor mode keymaps
994 (vip-set-mode-vars-for state) 1514 (vip-set-mode-vars-for state)
995 (vip-normalize-minor-mode-map-alist) 1515 (vip-normalize-minor-mode-map-alist)
996 (if events (vip-set-unread-command-events events)) 1516 (if events (vip-set-unread-command-events events))
997 1517
998 ;; protect against keyboard quit and other errors 1518 ;; protect against keyboard quit and other errors
999 (condition-case nil 1519 (condition-case nil
1000 (let (vip-vi-kbd-minor-mode 1520 (progn
1001 vip-insert-kbd-minor-mode
1002 vip-emacs-kbd-minor-mode)
1003 (unwind-protect 1521 (unwind-protect
1004 (progn 1522 (progn
1005 (setq com (key-binding (setq key 1523 (setq com (key-binding (setq key
1006 (if vip-xemacs-p 1524 (if vip-xemacs-p
1007 (read-key-sequence nil) 1525 (read-key-sequence nil)
1008 (read-key-sequence nil t))))) 1526 (read-key-sequence nil t)))))
1009 ;; In case of binding indirection--chase definitions. 1527 ;; In case of indirection--chase definitions.
1010 ;; Have to do it here because we execute this command under 1528 ;; Have to do it here because we execute this command under
1011 ;; different keymaps, so command-execute may not do the 1529 ;; different keymaps, so command-execute may not do the
1012 ;; right thing there 1530 ;; right thing there
1013 (while (vectorp com) (setq com (key-binding com)))) 1531 (while (vectorp com) (setq com (key-binding com))))
1014 nil) 1532 nil)
1015 ;; Execute command com in the original Viper state, not in state 1533 ;; exec command in the right Viper state
1016 ;; `state'. Otherwise, if we switch buffers while executing the 1534 ;; otherwise, if we switch buffers in the escaped command,
1017 ;; escaped to command, Viper's mode vars will remain those of 1535 ;; Viper's mode vars will remain those of `state'. When we return
1018 ;; `state'. When we return to the orig buffer, the bindings will be 1536 ;; to the orig buffer, the bindings will be screwed up.
1019 ;; screwed up.
1020 (vip-set-mode-vars-for vip-current-state) 1537 (vip-set-mode-vars-for vip-current-state)
1021 1538
1022 ;; this-command, last-command-char, last-command-event 1539 ;; this-command, last-command-char, last-command-event
1023 (setq this-command com) 1540 (setq this-command com)
1024 (if vip-xemacs-p ; XEmacs represents key sequences as vectors 1541 (if vip-xemacs-p ; XEmacs represents key sequences as vectors
1025 (setq last-command-event (vip-copy-event (vip-seq-last-elt key)) 1542 (setq last-command-event (vip-seq-last-elt key)
1026 last-command-char (event-to-character last-command-event)) 1543 last-command-char (event-to-character last-command-event))
1027 ;; Emacs represents them as sequences (str or vec) 1544 ;; Emacs represents them as sequences (str or vec)
1028 (setq last-command-event (vip-copy-event (vip-seq-last-elt key)) 1545 (setq last-command-event (vip-seq-last-elt key)
1029 last-command-char last-command-event)) 1546 last-command-char last-command-event))
1030 1547
1031 (if (commandp com) 1548 (if (commandp com)
1032 (progn 1549 (progn
1033 (setq prefix-arg (or prefix-arg arg)) 1550 (setq prefix-arg arg)
1034 (command-execute com))) 1551 (command-execute com)))
1035 ) 1552 )
1036 (quit (ding)) 1553 (quit (ding))
1037 (error (beep 1)))) 1554 (error (beep 1))))
1038 ;; set state in the new buffer 1555 (vip-set-mode-vars-for vip-current-state)) ; set state in new buffer
1039 (vip-set-mode-vars-for vip-current-state))
1040 1556
1041 (defun vip-exec-form-in-vi (form)
1042 "Execute FORM in Vi state, regardless of the Ccurrent Vi state."
1043 (let ((buff (current-buffer))
1044 result)
1045 (vip-set-mode-vars-for 'vi-state)
1046
1047 (condition-case nil
1048 (setq result (eval form))
1049 (error
1050 (signal 'quit nil)))
1051
1052 (if (not (equal buff (current-buffer))) ; cmd switched buffer
1053 (save-excursion
1054 (set-buffer buff)
1055 (vip-set-mode-vars-for vip-current-state)))
1056 (vip-set-mode-vars-for vip-current-state)
1057 result))
1058
1059 (defun vip-exec-form-in-emacs (form) 1557 (defun vip-exec-form-in-emacs (form)
1060 "Execute FORM in Emacs, temporarily disabling Viper's minor modes. 1558 "Execute FORM in Emacs, temporarily disabling Viper's minor modes.
1061 Similar to vip-escape-to-emacs, but accepts forms rather than keystrokes." 1559 Similar to vip-escape-to-emacs, but accepts forms rather than keystrokes."
1062 (let ((buff (current-buffer)) 1560 (let ((buff (current-buffer))
1063 result) 1561 result)
1096 ) 1594 )
1097 1595
1098 1596
1099 (defun vip-ESC (arg) 1597 (defun vip-ESC (arg)
1100 "Emulate ESC key in Emacs. 1598 "Emulate ESC key in Emacs.
1101 Prevents multiple escape keystrokes if vip-no-multiple-ESC is true. 1599 Prevents multiple escape keystrokes if vip-no-multiple-ESC is true. In that
1102 If vip-no-multiple-ESC is 'twice double ESC would ding in vi-state. 1600 case \@ will be bound to ESC. If vip-no-multiple-ESC is 'twice double ESC
1103 Other ESC sequences are emulated via the current Emacs's major mode 1601 would dings in vi-state. Other ESC sequences are emulated via the current
1104 keymap. This is more convenient on TTYs, since this won't block 1602 Emacs's major mode keymap. This is more convenient on dumb terminals and in
1105 function keys such as up,down, etc. ESC will also will also work as 1603 Emacs -nw, since this won't block functional keys such as up,down,
1106 a Meta key in this case. When vip-no-multiple-ESC is nil, ESC functions 1604 etc. Meta key also will work. When vip-no-multiple-ESC is nil, ESC key
1107 as a Meta key and any number of multiple escapes is allowed." 1605 behaves as in Emacs, any number of multiple escapes is allowed."
1108 (interactive "P") 1606 (interactive "P")
1109 (let (char) 1607 (let (char)
1110 (cond ((and (not vip-no-multiple-ESC) (eq vip-current-state 'vi-state)) 1608 (cond ((and (not vip-no-multiple-ESC) (eq vip-current-state 'vi-state))
1111 (setq char (vip-read-char-exclusive)) 1609 (setq char (vip-read-char-exclusive))
1112 (vip-escape-to-emacs arg (list ?\e char) )) 1610 (vip-escape-to-emacs arg (list ?\e char) ))
1117 (ding) 1615 (ding)
1118 (vip-escape-to-emacs arg (list ?\e char) ))) 1616 (vip-escape-to-emacs arg (list ?\e char) )))
1119 (t (ding))) 1617 (t (ding)))
1120 )) 1618 ))
1121 1619
1122 (defun vip-alternate-Meta-key (arg) 1620 (defun vip-alternate-ESC (arg)
1123 "Simulate Emacs Meta key." 1621 "ESC key without checking for multiple keystrokes."
1124 (interactive "P") 1622 (interactive "P")
1125 (sit-for 1) (message "ESC-")
1126 (vip-escape-to-emacs arg '(?\e))) 1623 (vip-escape-to-emacs arg '(?\e)))
1127 1624
1128 (defun vip-toggle-key-action ()
1129 "Action bound to `vip-toggle-key'."
1130 (interactive)
1131 (if (and (< vip-expert-level 2) (equal vip-toggle-key "\C-z"))
1132 (if (vip-window-display-p)
1133 (vip-iconify)
1134 (suspend-emacs))
1135 (vip-change-state-to-emacs)))
1136
1137 1625
1138 ;; Intercept ESC sequences on dumb terminals. 1626 ;; Intercept ESC sequences on dumb terminals.
1139 ;; Based on the idea contributed by Marcelino Veiga Tuimil <mveiga@dit.upm.es> 1627 ;; Based on the idea contributed by Marcelino Veiga Tuimil <mveiga@dit.upm.es>
1140 1628
1141 ;; Check if last key was ESC and if so try to reread it as a function key. 1629 ;; Check if last key was ESC and if so try to reread it as a function key.
1195 (character-to-event (event-key first-key))) 1683 (character-to-event (event-key first-key)))
1196 (subseq keyseq 1))) 1684 (subseq keyseq 1)))
1197 (setq last-input-event event 1685 (setq last-input-event event
1198 keyseq (vector (character-to-event ?\e)))) 1686 keyseq (vector (character-to-event ?\e))))
1199 ((eventp first-key) 1687 ((eventp first-key)
1200 (setq last-command-event (vip-copy-event first-key))) 1688 (setq last-command-event first-key))
1201 )) 1689 ))
1202 ) ; end progn 1690 ) ; end progn
1203 1691
1204 ;; this is escape event with nothing after it 1692 ;; this is escape event with nothing after it
1205 ;; put in unread-command-event and then re-read 1693 ;; put in unread-command-event and then re-read
1264 ((eq vip-current-state 'replace-state) 1752 ((eq vip-current-state 'replace-state)
1265 'vip-replace-state-exit-cmd) 1753 'vip-replace-state-exit-cmd)
1266 (t 'vip-change-state-to-vi) 1754 (t 'vip-change-state-to-vi)
1267 ))) 1755 )))
1268 (call-interactively cmd))) 1756 (call-interactively cmd)))
1269
1270 1757
1271 1758
1272 1759
1273 ;; prefix argument for Vi mode 1760 ;; prefix argument for Vi mode
1274 1761
1303 ((equal com ?y) ?Y) 1790 ((equal com ?y) ?Y)
1304 (t com)))) 1791 (t com))))
1305 1792
1306 1793
1307 ;; Compute numeric prefix arg value. 1794 ;; Compute numeric prefix arg value.
1308 ;; Invoked by EVENT. COM is the command part obtained so far. 1795 ;; Invoked by CHAR. COM is the command part obtained so far.
1309 (defun vip-prefix-arg-value (event com) 1796 (defun vip-prefix-arg-value (event com)
1310 (let (value func) 1797 (let (value)
1311 ;; read while number 1798 ;; read while number
1312 (while (and (vip-characterp event) (>= event ?0) (<= event ?9)) 1799 (while (and (vip-characterp event) (>= event ?0) (<= event ?9))
1313 (setq value (+ (* (if (integerp value) value 0) 10) (- event ?0))) 1800 (setq value (+ (* (if (vip-characterp value) value 0) 10) (- event ?0)))
1314 (setq event (vip-read-event-convert-to-char))) 1801 (setq event (vip-read-event-convert-to-char)))
1315 1802
1316 (setq prefix-arg value) 1803 (setq prefix-arg value)
1317 (if com (setq prefix-arg (cons prefix-arg com))) 1804 (if com (setq prefix-arg (cons prefix-arg com)))
1318 (while (eq event ?U) 1805 (while (eq event ?U)
1319 (vip-describe-arg prefix-arg) 1806 (vip-describe-arg prefix-arg)
1320 (setq event (vip-read-event-convert-to-char))) 1807 (setq event (vip-read-event-convert-to-char)))
1321 1808 (vip-set-unread-command-events event)))
1322 (if (or com (and (not (eq vip-current-state 'vi-state))
1323 ;; make sure it is a Vi command
1324 (vip-characterp event) (vip-vi-command-p event)
1325 ))
1326 ;; If appears to be one of the vi commands,
1327 ;; then execute it with funcall and clear prefix-arg in order to not
1328 ;; confuse subsequent commands
1329 (progn
1330 ;; last-command-char is the char we want emacs to think was typed
1331 ;; last. If com is not nil, the vip-digit-argument command was called
1332 ;; from within vip-prefix-arg command, such as `d', `w', etc., i.e.,
1333 ;; the user typed, say, d2. In this case, `com' would be `d', `w',
1334 ;; etc.
1335 ;; If vip-digit-argument was invoked by vip-escape-to-vi (which is
1336 ;; indicated by the fact that the current state is not vi-state),
1337 ;; then `event' represents the vi command to be executed (e.g., `d',
1338 ;; `w', etc). Again, last-command-char must make emacs believe that
1339 ;; this is the command we typed.
1340 (setq last-command-char (or com event))
1341 (setq func (vip-exec-form-in-vi
1342 (` (key-binding (char-to-string (, event))))))
1343 (funcall func prefix-arg)
1344 (setq prefix-arg nil))
1345 ;; some other command -- let emacs do it in its own way
1346 (vip-set-unread-command-events event))
1347 ))
1348
1349 1809
1350 ;; Vi operator as prefix argument." 1810 ;; Vi operator as prefix argument."
1351 (defun vip-prefix-arg-com (char value com) 1811 (defun vip-prefix-arg-com (char value com)
1352 (let ((cont t) 1812 (let ((cont t))
1353 cmd-info mv-or-digit-cmd)
1354 (while (and cont 1813 (while (and cont
1355 (memq char 1814 (memq char
1356 (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\" 1815 (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"
1357 vip-buffer-search-char))) 1816 vip-buffer-search-char)))
1358 (if com 1817 (if com
1382 (setq vip-use-register reg) 1841 (setq vip-use-register reg)
1383 (error "")) 1842 (error ""))
1384 (setq char (read-char)))) 1843 (setq char (read-char))))
1385 (t 1844 (t
1386 (setq com char) 1845 (setq com char)
1387 (setq char (read-char)))))) 1846 (setq char (vip-read-char-exclusive)))))))
1388
1389 (if (atom com) 1847 (if (atom com)
1390 ;; `com' is a single char, so we construct the command argument 1848 ;; com is a single char, so we construct prefix-arg
1391 ;; and if `char' is `?', we describe the arg; otherwise 1849 ;; and if char is ?, describe prefix arg, otherwise exit by
1392 ;; we prepare the command that will be executed at the end. 1850 ;; pushing the char back into vip-set-unread-command-events
1851 ;; Since char is a command, the command will execute with the prefix
1852 ;; argument that we just constructed.
1393 (progn 1853 (progn
1394 (setq cmd-info (cons value com)) 1854 (setq prefix-arg (cons value com))
1395 (while (= char ?U) 1855 (while (= char ?U)
1396 (vip-describe-arg cmd-info) 1856 (vip-describe-arg prefix-arg)
1397 (setq char (read-char))) 1857 (setq char (read-char)))
1398 ;; `char' is a movement cmd, a digit arg cmd, or a register cmd---so we 1858 (vip-set-unread-command-events char)
1399 ;; execute it at the very end 1859 )
1400 (or (vip-movement-command-p char)
1401 (vip-digit-command-p char)
1402 (vip-regsuffix-command-p char)
1403 (error ""))
1404 (setq mv-or-digit-cmd
1405 (vip-exec-form-in-vi
1406 (` (key-binding (char-to-string (, char)))))))
1407
1408 ;; as com is non-nil, this means that we have a command to execute 1860 ;; as com is non-nil, this means that we have a command to execute
1409 (if (memq (car com) '(?r ?R)) 1861 (if (memq (car com) '(?r ?R))
1410 ;; execute apropriate region command. 1862 ;; execute apropriate region command.
1411 (let ((char (car com)) (com (cdr com))) 1863 (let ((char (car com)) (com (cdr com)))
1412 (setq prefix-arg (cons value com)) 1864 (setq prefix-arg (cons value com))
1423 ((equal com '(?y . ?y)) (vip-line (cons value ?Y))) 1875 ((equal com '(?y . ?y)) (vip-line (cons value ?Y)))
1424 ((equal com '(?< . ?<)) (vip-line (cons value ?<))) 1876 ((equal com '(?< . ?<)) (vip-line (cons value ?<)))
1425 ((equal com '(?> . ?>)) (vip-line (cons value ?>))) 1877 ((equal com '(?> . ?>)) (vip-line (cons value ?>)))
1426 ((equal com '(?! . ?!)) (vip-line (cons value ?!))) 1878 ((equal com '(?! . ?!)) (vip-line (cons value ?!)))
1427 ((equal com '(?= . ?=)) (vip-line (cons value ?=))) 1879 ((equal com '(?= . ?=)) (vip-line (cons value ?=)))
1428 (t (error ""))))) 1880 (t (error ""))))))
1429
1430 (if mv-or-digit-cmd
1431 (progn
1432 (setq last-command-char char)
1433 (setq last-command-event
1434 (vip-copy-event
1435 (if vip-xemacs-p (character-to-event char) char)))
1436 (condition-case nil
1437 (funcall mv-or-digit-cmd cmd-info)
1438 (error
1439 (error "")))))
1440 ))
1441 1881
1442 (defun vip-describe-arg (arg) 1882 (defun vip-describe-arg (arg)
1443 (let (val com) 1883 (let (val com)
1444 (setq val (vip-P-val arg) 1884 (setq val (vip-P-val arg)
1445 com (vip-getcom arg)) 1885 com (vip-getcom arg))
1453 1893
1454 (defun vip-digit-argument (arg) 1894 (defun vip-digit-argument (arg)
1455 "Begin numeric argument for the next command." 1895 "Begin numeric argument for the next command."
1456 (interactive "P") 1896 (interactive "P")
1457 (vip-leave-region-active) 1897 (vip-leave-region-active)
1458 (vip-prefix-arg-value 1898 (vip-prefix-arg-value last-command-char
1459 last-command-char (if (consp arg) (cdr arg) nil))) 1899 (if (consp arg) (cdr arg) nil)))
1460 1900
1461 (defun vip-command-argument (arg) 1901 (defun vip-command-argument (arg)
1462 "Accept a motion command as an argument." 1902 "Accept a motion command as an argument."
1463 (interactive "P") 1903 (interactive "P")
1464 (let ((vip-inside-command-argument-action t)) 1904 (condition-case nil
1465 (condition-case nil 1905 (vip-prefix-arg-com
1466 (vip-prefix-arg-com 1906 last-command-char
1467 last-command-char 1907 (cond ((null arg) nil)
1468 (cond ((null arg) nil) 1908 ((consp arg) (car arg))
1469 ((consp arg) (car arg)) 1909 ((integerp arg) arg)
1470 ((integerp arg) arg) 1910 (t (error vip-InvalidCommandArgument)))
1471 (t (error vip-InvalidCommandArgument))) 1911 (cond ((null arg) nil)
1472 (cond ((null arg) nil) 1912 ((consp arg) (cdr arg))
1473 ((consp arg) (cdr arg)) 1913 ((integerp arg) nil)
1474 ((integerp arg) nil) 1914 (t (error vip-InvalidCommandArgument))))
1475 (t (error vip-InvalidCommandArgument)))) 1915 (quit (setq vip-use-register nil)
1476 (quit (setq vip-use-register nil) 1916 (signal 'quit nil)))
1477 (signal 'quit nil))) 1917 (vip-deactivate-mark))
1478 (vip-deactivate-mark)))
1479 1918
1480 1919
1481 ;; repeat last destructive command 1920 ;; repeat last destructive command
1482 1921
1483 ;; Append region to text in register REG. 1922 ;; Append region to text in register REG.
1510 1949
1511 ;; define functions to be executed 1950 ;; define functions to be executed
1512 1951
1513 ;; invoked by the `C' command 1952 ;; invoked by the `C' command
1514 (defun vip-exec-change (m-com com) 1953 (defun vip-exec-change (m-com com)
1515 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1516 (set-marker vip-com-point (point) (current-buffer)))
1517 ;; handle C cmd at the eol and at eob. 1954 ;; handle C cmd at the eol and at eob.
1518 (if (or (and (eolp) (= vip-com-point (point))) 1955 (if (or (and (eolp) (= vip-com-point (point)))
1519 (= vip-com-point (point-max))) 1956 (= vip-com-point (point-max)))
1520 (progn 1957 (progn
1521 (insert " ")(backward-char 1))) 1958 (insert " ")(backward-char 1)))
1545 (delete-region (mark t) (point))) 1982 (delete-region (mark t) (point)))
1546 (open-line 1) 1983 (open-line 1)
1547 (if (= com ?C) (vip-change-mode-to-insert) (vip-yank-last-insertion))) 1984 (if (= com ?C) (vip-change-mode-to-insert) (vip-yank-last-insertion)))
1548 1985
1549 (defun vip-exec-delete (m-com com) 1986 (defun vip-exec-delete (m-com com)
1550 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1551 (set-marker vip-com-point (point) (current-buffer)))
1552 (if vip-use-register 1987 (if vip-use-register
1553 (progn 1988 (progn
1554 (cond ((vip-valid-register vip-use-register '(letter digit)) 1989 (cond ((vip-valid-register vip-use-register '(letter digit))
1555 ;;(vip-valid-register vip-use-register '(letter)) 1990 ;;(vip-valid-register vip-use-register '(letter))
1556 (copy-to-register 1991 (copy-to-register
1589 (kill-region (mark t) (point)) 2024 (kill-region (mark t) (point))
1590 (if (eq m-com 'vip-line) (setq this-command 'D-command))) 2025 (if (eq m-com 'vip-line) (setq this-command 'D-command)))
1591 (back-to-indentation)) 2026 (back-to-indentation))
1592 2027
1593 (defun vip-exec-yank (m-com com) 2028 (defun vip-exec-yank (m-com com)
1594 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1595 (set-marker vip-com-point (point) (current-buffer)))
1596 (if vip-use-register 2029 (if vip-use-register
1597 (progn 2030 (progn
1598 (cond ((vip-valid-register vip-use-register '(letter digit)) 2031 (cond ((vip-valid-register vip-use-register '(letter digit))
1599 ;; (vip-valid-register vip-use-register '(letter)) 2032 ;; (vip-valid-register vip-use-register '(letter))
1600 (copy-to-register 2033 (copy-to-register
1799 (vip-special-ring-rotate1 vip-command-ring 1) 2232 (vip-special-ring-rotate1 vip-command-ring 1)
1800 (setq num (1+ num))) 2233 (setq num (1+ num)))
1801 )) 2234 ))
1802 2235
1803 2236
1804 ;; The hash-command. It is invoked interactively by the key sequence #<char>. 2237 ;; This command is invoked interactively by the key sequence #<char>
1805 ;; The chars that can follow `#' are determined by vip-hash-command-p
1806 (defun vip-special-prefix-com (char) 2238 (defun vip-special-prefix-com (char)
1807 (cond ((= char ?c) 2239 (cond ((= char ?c)
1808 (downcase-region (min vip-com-point (point)) 2240 (downcase-region (min vip-com-point (point))
1809 (max vip-com-point (point)))) 2241 (max vip-com-point (point))))
1810 ((= char ?C) 2242 ((= char ?C)
2046 (forward-line 1))) 2478 (forward-line 1)))
2047 2479
2048 ;; Tells whether BEG is on the same line as END. 2480 ;; Tells whether BEG is on the same line as END.
2049 ;; If one of the args is nil, it'll return nil. 2481 ;; If one of the args is nil, it'll return nil.
2050 (defun vip-same-line (beg end) 2482 (defun vip-same-line (beg end)
2051 (let ((selective-display nil) 2483 (let ((selective-display nil))
2052 (incr 0) 2484 (cond ((and beg end)
2053 temp) 2485 ;; This 'if' is needed because Emacs treats the next empty line
2054 (if (and beg end (> beg end)) 2486 ;; as part of the previous line.
2055 (setq temp beg 2487 (if (or (> beg (point-max)) (> end (point-max))) ; out of range
2056 beg end 2488 ()
2057 end temp)) 2489 (if (and (> end beg) (= (vip-line-pos 'start) end))
2058 (if (and beg end) 2490 (setq end (min (1+ end) (point-max))))
2059 (cond ((or (> beg (point-max)) (> end (point-max))) ; out of range 2491 (if (and (> beg end) (= (vip-line-pos 'start) beg))
2060 nil) 2492 (setq beg (min (1+ beg) (point-max))))
2061 (t 2493 (<= (count-lines beg end) 1) ))
2062 ;; This 'if' is needed because Emacs treats the next empty line 2494
2063 ;; as part of the previous line. 2495 (t nil))
2064 (if (= (vip-line-pos 'start) end) 2496 ))
2065 (setq incr 1))
2066 (<= (+ incr (count-lines beg end)) 1))))
2067 ))
2068 2497
2069 2498
2070 ;; Check if the string ends with a newline. 2499 ;; Check if the string ends with a newline.
2071 (defun vip-end-with-a-newline-p (string) 2500 (defun vip-end-with-a-newline-p (string)
2072 (or (string= string "") 2501 (or (string= string "")
2101 (let (command) 2530 (let (command)
2102 (setq command (local-key-binding (char-to-string last-command-char))) 2531 (setq command (local-key-binding (char-to-string last-command-char)))
2103 (if command 2532 (if command
2104 (command-execute command) 2533 (command-execute command)
2105 (exit-minibuffer)))) 2534 (exit-minibuffer))))
2535
2536
2537 (defun vip-set-search-face ()
2538 (if (vip-has-face-support-p)
2539 (defvar vip-search-face
2540 (progn
2541 (make-face 'vip-search-face)
2542 (vip-hide-face 'vip-search-face)
2543 (or (face-differs-from-default-p 'vip-search-face)
2544 ;; face wasn't set in .vip or .Xdefaults
2545 (if (vip-can-use-colors "Black" "khaki")
2546 (progn
2547 (set-face-background 'vip-search-face "khaki")
2548 (set-face-foreground 'vip-search-face "Black"))
2549 (copy-face 'italic 'vip-search-face)
2550 (set-face-underline-p 'vip-search-face t)))
2551 'vip-search-face)
2552 "*Face used to flash out the search pattern.")
2553 ))
2554
2555
2556 (defun vip-set-minibuffer-faces ()
2557 (if (not (vip-has-face-support-p))
2558 ()
2559 (defvar vip-minibuffer-emacs-face
2560 (progn
2561 (make-face 'vip-minibuffer-emacs-face)
2562 (vip-hide-face 'vip-minibuffer-emacs-face)
2563 (or (face-differs-from-default-p 'vip-minibuffer-emacs-face)
2564 ;; face wasn't set in .vip or .Xdefaults
2565 (if vip-vi-style-in-minibuffer
2566 ;; emacs state is an exception in the minibuffer
2567 (if (vip-can-use-colors "darkseagreen2" "Black")
2568 (progn
2569 (set-face-background
2570 'vip-minibuffer-emacs-face "darkseagreen2")
2571 (set-face-foreground
2572 'vip-minibuffer-emacs-face "Black"))
2573 (copy-face 'modeline 'vip-minibuffer-emacs-face))
2574 ;; emacs state is the main state in the minibuffer
2575 (if (vip-can-use-colors "Black" "pink")
2576 (progn
2577 (set-face-background 'vip-minibuffer-emacs-face "pink")
2578 (set-face-foreground
2579 'vip-minibuffer-emacs-face "Black"))
2580 (copy-face 'italic 'vip-minibuffer-emacs-face))
2581 ))
2582 'vip-minibuffer-emacs-face)
2583 "Face used in the Minibuffer when it is in Emacs state.")
2584
2585 (defvar vip-minibuffer-insert-face
2586 (progn
2587 (make-face 'vip-minibuffer-insert-face)
2588 (vip-hide-face 'vip-minibuffer-insert-face)
2589 (or (face-differs-from-default-p 'vip-minibuffer-insert-face)
2590 (if vip-vi-style-in-minibuffer
2591 (if (vip-can-use-colors "Black" "pink")
2592 (progn
2593 (set-face-background 'vip-minibuffer-insert-face "pink")
2594 (set-face-foreground
2595 'vip-minibuffer-insert-face "Black"))
2596 (copy-face 'italic 'vip-minibuffer-insert-face))
2597 ;; If Insert state is an exception
2598 (if (vip-can-use-colors "darkseagreen2" "Black")
2599 (progn
2600 (set-face-background
2601 'vip-minibuffer-insert-face "darkseagreen2")
2602 (set-face-foreground
2603 'vip-minibuffer-insert-face "Black"))
2604 (copy-face 'modeline 'vip-minibuffer-insert-face))
2605 (vip-italicize-face 'vip-minibuffer-insert-face)))
2606 'vip-minibuffer-insert-face)
2607 "Face used in the Minibuffer when it is in Insert state.")
2608
2609 (defvar vip-minibuffer-vi-face
2610 (progn
2611 (make-face 'vip-minibuffer-vi-face)
2612 (vip-hide-face 'vip-minibuffer-vi-face)
2613 (or (face-differs-from-default-p 'vip-minibuffer-vi-face)
2614 (if vip-vi-style-in-minibuffer
2615 (if (vip-can-use-colors "Black" "grey")
2616 (progn
2617 (set-face-background 'vip-minibuffer-vi-face "grey")
2618 (set-face-foreground 'vip-minibuffer-vi-face "Black"))
2619 (copy-face 'bold 'vip-minibuffer-vi-face))
2620 (copy-face 'bold 'vip-minibuffer-vi-face)
2621 (invert-face 'vip-minibuffer-vi-face)))
2622 'vip-minibuffer-vi-face)
2623 "Face used in the Minibuffer when it is in Vi state.")
2624
2625 ;; the current face used in the minibuffer
2626 (vip-deflocalvar vip-minibuffer-current-face vip-minibuffer-emacs-face "")
2627 ))
2628
2106 2629
2107 2630
2108 ;;; Reading string with history 2631 ;;; Reading string with history
2109 2632
2110 (defun vip-read-string-with-history (prompt &optional initial 2633 (defun vip-read-string-with-history (prompt &optional initial
2256 (if vip-auto-indent 2779 (if vip-auto-indent
2257 (progn 2780 (progn
2258 (setq vip-cted t) 2781 (setq vip-cted t)
2259 (if vip-electric-mode 2782 (if vip-electric-mode
2260 (indent-according-to-mode) 2783 (indent-according-to-mode)
2261 (indent-to col)))) 2784 (indent-to col))
2262 (vip-change-state-to-insert))))) 2785 ))
2786 (vip-change-state-to-insert)
2787 ))))
2263 2788
2264 (defun vip-Open-line (arg) 2789 (defun vip-Open-line (arg)
2265 "Open line above." 2790 "Open line above."
2266 (interactive "P") 2791 (interactive "P")
2267 (vip-set-complex-command-for-undo) 2792 (vip-set-complex-command-for-undo)
2343 (vip-replace-start)) 2868 (vip-replace-start))
2344 (vip-add-hook 2869 (vip-add-hook
2345 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel t) 2870 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel t)
2346 (vip-add-hook 2871 (vip-add-hook
2347 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) 2872 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t)
2348 ;; guard against a smartie who switched from R-replace to normal replace
2349 (vip-remove-hook
2350 'vip-post-command-hooks 'vip-R-state-post-command-sentinel)
2351 (if overwrite-mode (overwrite-mode nil))
2352 ) 2873 )
2353 2874
2354 2875
2355 ;; checks how many chars were deleted by the last change 2876 ;; checks how many chars were deleted by the last change
2356 (defun vip-replace-mode-spy-before (beg end) 2877 (defun vip-replace-mode-spy-before (beg end)
2422 (or (marker-position vip-last-posn-in-replace-region) 2943 (or (marker-position vip-last-posn-in-replace-region)
2423 (vip-replace-start)) 2944 (vip-replace-start))
2424 )) 2945 ))
2425 2946
2426 (setq vip-replace-chars-to-delete 2947 (setq vip-replace-chars-to-delete
2427 (max 0 2948 (max 0 (min vip-replace-chars-to-delete
2428 (min vip-replace-chars-to-delete 2949 (- (vip-replace-end)
2429 (- (vip-replace-end) vip-last-posn-in-replace-region) 2950 vip-last-posn-in-replace-region))))
2430 (- (vip-line-pos 'end) vip-last-posn-in-replace-region)
2431 )))
2432 ))) 2951 )))
2433 2952
2434 2953
2435 ;; Delete stuff between posn and the end of vip-replace-overlay-marker, if 2954 ;; Delete stuff between posn and the end of vip-replace-overlay-marker, if
2436 ;; posn is within the overlay. 2955 ;; posn is within the overlay.
2439 (vip-remove-hook 'vip-before-change-functions 'vip-replace-mode-spy-before) 2958 (vip-remove-hook 'vip-before-change-functions 'vip-replace-mode-spy-before)
2440 (vip-remove-hook 'vip-post-command-hooks 2959 (vip-remove-hook 'vip-post-command-hooks
2441 'vip-replace-state-post-command-sentinel) 2960 'vip-replace-state-post-command-sentinel)
2442 (vip-remove-hook 2961 (vip-remove-hook
2443 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel) 2962 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel)
2444 (vip-restore-cursor-color-after-replace) 2963 (vip-restore-cursor-color)
2445 (setq vip-sitting-in-replace nil) ; just in case we'll need to know it 2964 (setq vip-sitting-in-replace nil) ; just in case we'll need to know it
2446 (save-excursion 2965 (save-excursion
2447 (if (and 2966 (if (and
2448 vip-replace-overlay 2967 vip-replace-overlay
2449 (>= posn (vip-replace-start)) 2968 (>= posn (vip-replace-start))
2478 (overwrite-mode 1) 2997 (overwrite-mode 1)
2479 (vip-add-hook 2998 (vip-add-hook
2480 'vip-post-command-hooks 'vip-R-state-post-command-sentinel t) 2999 'vip-post-command-hooks 'vip-R-state-post-command-sentinel t)
2481 (vip-add-hook 3000 (vip-add-hook
2482 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) 3001 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t)
2483 ;; guard against a smartie who switched from R-replace to normal replace
2484 (vip-remove-hook
2485 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel)
2486 ) 3002 )
2487 3003
2488 3004
2489 3005
2490 (defun vip-replace-state-exit-cmd () 3006 (defun vip-replace-state-exit-cmd ()
2504 (command-execute com) 3020 (command-execute com)
2505 (error 3021 (error
2506 (vip-message-conditions conds))) 3022 (vip-message-conditions conds)))
2507 ) 3023 )
2508 (vip-hide-replace-overlay)) 3024 (vip-hide-replace-overlay))
2509
2510 (defun vip-replace-state-carriage-return ()
2511 "Implements carriage return in Viper replace state."
2512 (interactive)
2513 ;; If Emacs start supporting overlay maps, as it currently supports
2514 ;; text-property maps, we could do away with vip-replace-minor-mode and
2515 ;; just have keymap attached to replace overlay. Then the "if part" of this
2516 ;; statement can be deleted.
2517 (if (or (< (point) (vip-replace-start))
2518 (> (point) (vip-replace-end)))
2519 (let (vip-replace-minor-mode com)
2520 (vip-set-unread-command-events last-input-char)
2521 (setq com (key-binding (read-key-sequence nil)))
2522 (condition-case conds
2523 (command-execute com)
2524 (error
2525 (vip-message-conditions conds))))
2526 (if (not vip-allow-multiline-replace-regions)
2527 (vip-replace-state-exit-cmd)
2528 (if (vip-same-line (point) (vip-replace-end))
2529 (vip-replace-state-exit-cmd)
2530 (vip-kill-line nil)
2531 (vip-next-line-at-bol nil)))))
2532 3025
2533 3026
2534 ;; This is the function bound to 'R'---unlimited replace. 3027 ;; This is the function bound to 'R'---unlimited replace.
2535 ;; Similar to Emacs's own overwrite-mode. 3028 ;; Similar to Emacs's own overwrite-mode.
2536 (defun vip-overwrite (arg) 3029 (defun vip-overwrite (arg)
3281 (defun vip-line-to-bottom (arg) 3774 (defun vip-line-to-bottom (arg)
3282 "Put current line on the last line." 3775 "Put current line on the last line."
3283 (interactive "p") 3776 (interactive "p")
3284 (recenter (- (window-height) (1+ arg)))) 3777 (recenter (- (window-height) (1+ arg))))
3285 3778
3286 ;; If point is within vip-search-scroll-threshold of window top or bottom,
3287 ;; scroll up or down 1/7 of window height, depending on whether we are at the
3288 ;; bottom or at the top of the window. This function is called by vip-search
3289 ;; (which is called from vip-search-forward/backward/next). If the value of
3290 ;; vip-search-scroll-threshold is negative - don't scroll.
3291 (defun vip-adjust-window ()
3292 (let ((win-height (if vip-emacs-p
3293 (1- (window-height)) ; adjust for modeline
3294 (window-displayed-height)))
3295 (pt (point))
3296 at-top-p at-bottom-p
3297 min-scroll direction)
3298 (save-excursion
3299 (move-to-window-line 0) ; top
3300 (setq at-top-p
3301 (<= (count-lines pt (point))
3302 vip-search-scroll-threshold))
3303 (move-to-window-line -1) ; bottom
3304 (setq at-bottom-p
3305 (<= (count-lines pt (point)) vip-search-scroll-threshold))
3306 )
3307 (cond (at-top-p (setq min-scroll (1- vip-search-scroll-threshold)
3308 direction 1))
3309 (at-bottom-p (setq min-scroll (1+ vip-search-scroll-threshold)
3310 direction -1)))
3311 (if min-scroll
3312 (recenter
3313 (* (max min-scroll (/ win-height 7)) direction)))
3314 ))
3315
3316 3779
3317 ;; paren match 3780 ;; paren match
3318 ;; must correct this to only match ( to ) etc. On the other hand 3781 ;; must correct this to only match ( to ) etc. On the other hand
3319 ;; it is good that paren match gets confused, because that way you 3782 ;; it is good that paren match gets confused, because that way you
3320 ;; catch _all_ imbalances. 3783 ;; catch _all_ imbalances.
3321 3784
3322 (defun vip-paren-match (arg) 3785 (defun vip-paren-match (arg)
3323 "Go to the matching parenthesis." 3786 "Go to the matching parenthesis."
3324 (interactive "P") 3787 (interactive "P")
3325 (vip-leave-region-active)
3326 (let ((com (vip-getcom arg)) 3788 (let ((com (vip-getcom arg))
3327 parse-sexp-ignore-comments anchor-point) 3789 anchor-point)
3328 (if (integerp arg) 3790 (if (integerp arg)
3329 (if (or (> arg 99) (< arg 1)) 3791 (if (or (> arg 99) (< arg 1))
3330 (error "Prefix must be between 1 and 99") 3792 (error "Prefix must be between 1 and 99")
3331 (goto-char 3793 (goto-char
3332 (if (> (point-max) 80000) 3794 (if (> (point-max) 80000)
3450 3912
3451 ;; scrolling 3913 ;; scrolling
3452 3914
3453 (setq scroll-step 1) 3915 (setq scroll-step 1)
3454 3916
3455 (defun vip-scroll-screen (arg) 3917 (defun vip-scroll (arg)
3456 "Scroll to next screen." 3918 "Scroll to next screen."
3457 (interactive "p") 3919 (interactive "p")
3458 (condition-case nil 3920 (if (> arg 0)
3459 (if (> arg 0) 3921 (while (> arg 0)
3460 (while (> arg 0) 3922 (scroll-up)
3461 (scroll-up) 3923 (setq arg (1- arg)))
3462 (setq arg (1- arg))) 3924 (while (> 0 arg)
3463 (while (> 0 arg) 3925 (scroll-down)
3464 (scroll-down) 3926 (setq arg (1+ arg)))))
3465 (setq arg (1+ arg)))) 3927
3466 (error (beep 1) 3928 (defun vip-scroll-back (arg)
3467 (if (> arg 0)
3468 (progn
3469 (message "End of buffer")
3470 (goto-char (point-max)))
3471 (message "Beginning of buffer")
3472 (goto-char (point-min))))
3473 ))
3474
3475 (defun vip-scroll-screen-back (arg)
3476 "Scroll to previous screen." 3929 "Scroll to previous screen."
3477 (interactive "p") 3930 (interactive "p")
3478 (vip-scroll-screen (- arg))) 3931 (vip-scroll (- arg)))
3479 3932
3480 (defun vip-scroll-down (arg) 3933 (defun vip-scroll-down (arg)
3481 "Pull down half screen." 3934 "Pull down half screen."
3482 (interactive "P") 3935 (interactive "P")
3483 (condition-case nil 3936 (condition-case nil
3562 (setq msg "Search becomes vanilla-style"))) 4015 (setq msg "Search becomes vanilla-style")))
3563 (t 4016 (t
3564 (setq msg "Search style remains unchanged"))) 4017 (setq msg "Search style remains unchanged")))
3565 (prin1 msg t))) 4018 (prin1 msg t)))
3566 4019
3567 (defun vip-set-vi-search-style-macros (unset)
3568 "Set the macros for toggling the search style in Viper's vi-state.
3569 The macro that toggles case sensitivity is bound to `//', and the one that
3570 toggles regexp search is bound to `///'.
3571 With a prefix argument, this function unsets the macros. "
3572 (interactive "P")
3573 (or noninteractive
3574 (if (not unset)
3575 (progn
3576 ;; toggle case sensitivity in search
3577 (vip-record-kbd-macro
3578 "//" 'vi-state
3579 [1 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return]
3580 't)
3581 ;; toggle regexp/vanila search
3582 (vip-record-kbd-macro
3583 "///" 'vi-state
3584 [2 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return]
3585 't)
3586 (if (interactive-p)
3587 (message
3588 "// and /// now toggle case-sensitivity and regexp search.")))
3589 (vip-unrecord-kbd-macro "//" 'vi-state)
3590 (sit-for 2)
3591 (vip-unrecord-kbd-macro "///" 'vi-state))))
3592
3593 (defun vip-set-emacs-search-style-macros (unset &optional arg-majormode)
3594 "Set the macros for toggling the search style in Viper's emacs-state.
3595 The macro that toggles case sensitivity is bound to `//', and the one that
3596 toggles regexp search is bound to `///'.
3597 With a prefix argument, this function unsets the macros.
3598 If the optional prefix argument is non-nil and specifies a valid major mode,
3599 this sets the macros only in the macros in that major mode. Otherwise,
3600 the macros are set in the current major mode.
3601 \(When unsetting the macros, the second argument has no effect.\)"
3602 (interactive "P")
3603 (or noninteractive
3604 (if (not unset)
3605 (progn
3606 ;; toggle case sensitivity in search
3607 (vip-record-kbd-macro
3608 "//" 'emacs-state
3609 [1 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return]
3610 (or arg-majormode major-mode))
3611 ;; toggle regexp/vanila search
3612 (vip-record-kbd-macro
3613 "///" 'emacs-state
3614 [2 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return]
3615 (or arg-majormode major-mode))
3616 (if (interactive-p)
3617 (message
3618 "// and /// now toggle case-sensitivity and regexp search.")))
3619 (vip-unrecord-kbd-macro "//" 'emacs-state)
3620 (sit-for 2)
3621 (vip-unrecord-kbd-macro "///" 'emacs-state))))
3622
3623 4020
3624 (defun vip-search-forward (arg) 4021 (defun vip-search-forward (arg)
3625 "Search a string forward. 4022 "Search a string forward.
3626 ARG is used to find the ARG's occurrence of the string. 4023 ARG is used to find the ARG's occurrence of the string.
3627 Null string will repeat previous search." 4024 Null string will repeat previous search."
3686 (progn 4083 (progn
3687 (re-search-forward string nil nil val) 4084 (re-search-forward string nil nil val)
3688 (re-search-backward string)) 4085 (re-search-backward string))
3689 (search-forward string nil nil val) 4086 (search-forward string nil nil val)
3690 (search-backward string)) 4087 (search-backward string))
4088 ;; don't wait and don't flash in macros
4089 (or executing-kbd-macro
4090 (vip-flash-search-pattern))
3691 (if (not (equal start-point (point))) 4091 (if (not (equal start-point (point)))
3692 (push-mark start-point t))) 4092 (push-mark start-point t)))
3693 (search-failed 4093 (search-failed
3694 (if (and (not fail-if-not-found) vip-search-wrap-around-t) 4094 (if (and (not fail-if-not-found) vip-search-wrap-around-t)
3695 (progn 4095 (progn
3696 (message "Search wrapped around BOTTOM of buffer") 4096 (message "Search wrapped around end of buffer")
3697 (goto-char (point-min)) 4097 (goto-char (point-min))
3698 (vip-search string forward (cons 1 com) t start-point 'fail) 4098 (vip-search string forward (cons 1 com) t start-point 'fail)
3699 ;; don't wait in macros 4099 ;; don't wait in macros
3700 (or executing-kbd-macro (sit-for 2)) 4100 (or executing-kbd-macro (sit-for 2))
3701 ;; delete the wrap-around message 4101 ;; delete the wrap-around message
3710 (condition-case nil 4110 (condition-case nil
3711 (progn 4111 (progn
3712 (if vip-re-search 4112 (if vip-re-search
3713 (re-search-backward string nil nil val) 4113 (re-search-backward string nil nil val)
3714 (search-backward string nil nil val)) 4114 (search-backward string nil nil val))
4115 ;; don't wait and don't flash in macros
4116 (or executing-kbd-macro
4117 (vip-flash-search-pattern))
3715 (if (not (equal start-point (point))) 4118 (if (not (equal start-point (point)))
3716 (push-mark start-point t))) 4119 (push-mark start-point t)))
3717 (search-failed 4120 (search-failed
3718 (if (and (not fail-if-not-found) vip-search-wrap-around-t) 4121 (if (and (not fail-if-not-found) vip-search-wrap-around-t)
3719 (progn 4122 (progn
3720 (message "Search wrapped around TOP of buffer") 4123 (message "Search wrapped around beginning of buffer")
3721 (goto-char (point-max)) 4124 (goto-char (point-max))
3722 (vip-search string forward (cons 1 com) t start-point 'fail) 4125 (vip-search string forward (cons 1 com) t start-point 'fail)
3723 ;; don't wait in macros 4126 ;; don't wait in macros
3724 (or executing-kbd-macro (sit-for 2)) 4127 (or executing-kbd-macro (sit-for 2))
3725 ;; delete the wrap-around message 4128 ;; delete the wrap-around message
3727 ) 4130 )
3728 (goto-char start-point) 4131 (goto-char start-point)
3729 (error "`%s': %s not found" 4132 (error "`%s': %s not found"
3730 string 4133 string
3731 (if vip-re-search "Pattern" "String")) 4134 (if vip-re-search "Pattern" "String"))
3732 )))) 4135 )))))))
3733 ;; pull up or down if at top/bottom of window
3734 (vip-adjust-window)
3735 ;; highlight the result of search
3736 ;; don't wait and don't highlight in macros
3737 (or executing-kbd-macro
3738 vip-inside-command-argument-action
3739 (vip-flash-search-pattern))
3740 )))
3741 4136
3742 (defun vip-search-next (arg) 4137 (defun vip-search-next (arg)
3743 "Repeat previous search." 4138 "Repeat previous search."
3744 (interactive "P") 4139 (interactive "P")
3745 (let ((val (vip-p-val arg)) 4140 (let ((val (vip-p-val arg))
3836 buffer-name))) 4231 buffer-name)))
3837 (kill-buffer buffer) 4232 (kill-buffer buffer)
3838 (error "Buffer not killed")))) 4233 (error "Buffer not killed"))))
3839 4234
3840 4235
3841 (defvar vip-smart-suffix-list 4236 (defvar vip-smart-suffix-list '("" "tex" "c" "cc" "el" "p")
3842 '("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p")
3843 "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'. 4237 "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'.
3844 This is useful when you the current directory contains files with the same 4238 This is useful when you the current directory contains files with the same
3845 prefix and many different suffixes. Usually, only one of the suffixes 4239 prefix and many different suffixes. Usually, only one of the suffixes
3846 represents an editable file. However, file completion will stop at the `.' 4240 represents an editable file. However, file completion will stop at the `.'
3847 The smart suffix feature lets you hit RET in such a case, and Viper will 4241 The smart suffix feature lets you hit RET in such a case, and Viper will
3895 "Run `vip-minibuffer-exit-hook' just before exiting the minibuffer." 4289 "Run `vip-minibuffer-exit-hook' just before exiting the minibuffer."
3896 (run-hooks 'vip-minibuffer-exit-hook)) 4290 (run-hooks 'vip-minibuffer-exit-hook))
3897 4291
3898 (defadvice find-file (before vip-add-suffix-advice activate) 4292 (defadvice find-file (before vip-add-suffix-advice activate)
3899 "Use `read-file-name' for reading arguments." 4293 "Use `read-file-name' for reading arguments."
3900 (interactive (cons (read-file-name "Find file: " nil default-directory) 4294 (interactive (list (read-file-name "Find file: "
3901 ;; if Mule and prefix argument, ask for coding system 4295 nil default-directory))))
3902 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3903 (featurep 'mule)) ; mule integrated XEmacs 20
3904 (list
3905 (and current-prefix-arg
3906 (read-coding-system "Coding-system: "))))
3907 )))
3908 4296
3909 (defadvice find-file-other-window (before vip-add-suffix-advice activate) 4297 (defadvice find-file-other-window (before vip-add-suffix-advice activate)
3910 "Use `read-file-name' for reading arguments." 4298 "Use `read-file-name' for reading arguments."
3911 (interactive (cons (read-file-name "Find file in other window: " 4299 (interactive (list (read-file-name "Find file in other window: "
3912 nil default-directory) 4300 nil default-directory))))
3913 ;; if Mule and prefix argument, ask for coding system
3914 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3915 (featurep 'mule)) ; mule integrated XEmacs 20
3916 (list
3917 (and current-prefix-arg
3918 (read-coding-system "Coding-system: "))))
3919 )))
3920 4301
3921 (defadvice find-file-other-frame (before vip-add-suffix-advice activate) 4302 (defadvice find-file-other-frame (before vip-add-suffix-advice activate)
3922 "Use `read-file-name' for reading arguments." 4303 "Use `read-file-name' for reading arguments."
3923 (interactive (cons (read-file-name "Find file in other frame: " 4304 (interactive (list (read-file-name "Find file in other frame: "
3924 nil default-directory) 4305 nil default-directory))))
3925 ;; if Mule and prefix argument, ask for coding system
3926 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3927 (featurep 'mule)) ; mule integrated XEmacs 20
3928 (list
3929 (and current-prefix-arg
3930 (read-coding-system "Coding-system: "))))
3931 )))
3932 4306
3933 (defadvice read-file-name (around vip-suffix-advice activate) 4307 (defadvice read-file-name (around vip-suffix-advice activate)
3934 "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook." 4308 "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook."
3935 (let ((vip-minibuffer-exit-hook 'vip-file-add-suffix)) 4309 (let ((vip-minibuffer-exit-hook 'vip-file-add-suffix))
3936 ad-do-it)) 4310 ad-do-it))
3962 (error vip-EmptyRegister reg)) 4336 (error vip-EmptyRegister reg))
3963 (error ""))) 4337 (error "")))
3964 (setq vip-use-register nil) 4338 (setq vip-use-register nil)
3965 (if (vip-end-with-a-newline-p text) 4339 (if (vip-end-with-a-newline-p text)
3966 (progn 4340 (progn
3967 (end-of-line)
3968 (if (eobp) 4341 (if (eobp)
3969 (insert "\n") 4342 (insert "\n")
3970 (forward-line 1)) 4343 (forward-line 1))
3971 (beginning-of-line)) 4344 (beginning-of-line))
3972 (if (not (eolp)) (vip-forward-char-carefully))) 4345 (if (not (eolp)) (vip-forward-char-carefully)))
4156 (vip-replace-end))) 4529 (vip-replace-end)))
4157 4530
4158 ;; protect against error while inserting "@" and other disasters 4531 ;; protect against error while inserting "@" and other disasters
4159 ;; (e.g., read-only buff) 4532 ;; (e.g., read-only buff)
4160 (condition-case conds 4533 (condition-case conds
4161 (if (or vip-allow-multiline-replace-regions 4534 (if (vip-same-line (vip-replace-start)
4162 (vip-same-line (vip-replace-start) 4535 (vip-replace-end))
4163 (vip-replace-end)))
4164 (progn 4536 (progn
4165 ;; tabs cause problems in replace, so untabify 4537 ;; tabs cause problems in replace, so untabify
4166 (goto-char (vip-replace-end)) 4538 (goto-char (vip-replace-end))
4167 (insert-before-markers "@") ; put placeholder after the TAB 4539 (insert-before-markers "@") ; put placeholder after the TAB
4168 (untabify (vip-replace-start) (point)) 4540 (untabify (vip-replace-start) (point))
4278 (message "Mark set at the end of buffer")) 4650 (message "Mark set at the end of buffer"))
4279 4651
4280 (defun vip-mark-point () 4652 (defun vip-mark-point ()
4281 "Set mark at point of buffer." 4653 "Set mark at point of buffer."
4282 (interactive) 4654 (interactive)
4283 (let ((char (read-char))) 4655 (let ((char (vip-read-char-exclusive)))
4284 (cond ((and (<= ?a char) (<= char ?z)) 4656 (cond ((and (<= ?a char) (<= char ?z))
4285 (point-to-register (1+ (- char ?a)))) 4657 (point-to-register (1+ (- char ?a))))
4286 ((= char ?<) (vip-mark-beginning-of-buffer)) 4658 ((= char ?<) (vip-mark-beginning-of-buffer))
4287 ((= char ?>) (vip-mark-end-of-buffer)) 4659 ((= char ?>) (vip-mark-end-of-buffer))
4288 ((= char ?.) (vip-set-mark-if-necessary)) 4660 ((= char ?.) (vip-set-mark-if-necessary))
4289 ((= char ?,) (vip-cycle-through-mark-ring)) 4661 ((= char ?,) (vip-cycle-through-mark-ring))
4290 ((= char ?D) (mark-defun)) 4662 ((= char ?D) (mark-defun))
4291 (t (error "")) 4663 (t (error ""))
4292 ))) 4664 )))
4293 4665
4294 ;; Algorithm: If first invocation of this command save mark on ring, goto 4666 ;; Algorithm: If first invocation of this command save mark on ring, goto
4295 ;; mark, M0, and pop the most recent elt from the mark ring into mark, 4667 ;; mark, M0, and pop the most recent elt from the mark ring into mark,
4296 ;; making it into the new mark, M1. 4668 ;; making it into the new mark, M1.
4297 ;; Push this mark back and set mark to the original point position, p1. 4669 ;; Push this mark back and set mark to the original point position, p1.
4378 ((and (not skip-white) (= char ?`)) 4750 ((and (not skip-white) (= char ?`))
4379 (if com (vip-move-marker-locally 'vip-com-point (point))) 4751 (if com (vip-move-marker-locally 'vip-com-point (point)))
4380 (if (and (vip-same-line (point) vip-last-jump) 4752 (if (and (vip-same-line (point) vip-last-jump)
4381 (= (point) vip-last-jump-ignore)) 4753 (= (point) vip-last-jump-ignore))
4382 (goto-char vip-last-jump)) 4754 (goto-char vip-last-jump))
4383 (if (null (mark t)) (error "Mark is not set in this buffer"))
4384 (if (= (point) (mark t)) (pop-mark)) 4755 (if (= (point) (mark t)) (pop-mark))
4385 (exchange-point-and-mark) 4756 (exchange-point-and-mark)
4386 (setq vip-last-jump (point-marker) 4757 (setq vip-last-jump (point-marker)
4387 vip-last-jump-ignore 0) 4758 vip-last-jump-ignore 0)
4388 (if com (vip-execute-com 'vip-goto-mark nil com))) 4759 (if com (vip-execute-com 'vip-goto-mark nil com)))
4446 4817
4447 (defun vip-autoindent () 4818 (defun vip-autoindent ()
4448 "Auto Indentation, Vi-style." 4819 "Auto Indentation, Vi-style."
4449 (interactive) 4820 (interactive)
4450 (let ((col (current-indentation))) 4821 (let ((col (current-indentation)))
4451 (if abbrev-mode (expand-abbrev))
4452 (if vip-preserve-indent 4822 (if vip-preserve-indent
4453 (setq vip-preserve-indent nil) 4823 (setq vip-preserve-indent nil)
4454 (setq vip-current-indent col)) 4824 (setq vip-current-indent col))
4455 ;; don't leave whitespace lines around 4825 ;; don't leave whitespace lines around
4456 (if (memq last-command 4826 (if (memq last-command
4457 '(vip-autoindent 4827 '(vip-autoindent
4458 vip-open-line vip-Open-line 4828 vip-open-line vip-Open-line
4459 vip-replace-state-exit-cmd)) 4829 vip-replace-state-exit-cmd))
4460 (indent-to-left-margin)) 4830 (indent-to-left-margin))
4461 ;; use \n instead of newline, or else <Return> will move the insert point 4831 (newline 1)
4462 ;;(newline 1)
4463 (insert "\n")
4464 (if vip-auto-indent 4832 (if vip-auto-indent
4465 (progn 4833 (progn
4466 (setq vip-cted t) 4834 (setq vip-cted t)
4467 (if vip-electric-mode 4835 (if vip-electric-mode
4468 (indent-according-to-mode) 4836 (indent-according-to-mode)
4582 (setq vip-always t 4950 (setq vip-always t
4583 vip-ex-style-motion t 4951 vip-ex-style-motion t
4584 vip-ex-style-editing-in-insert t 4952 vip-ex-style-editing-in-insert t
4585 vip-want-ctl-h-help nil) 4953 vip-want-ctl-h-help nil)
4586 4954
4587 (cond ((eq vip-expert-level 1) ; novice or beginner 4955 (cond
4588 (global-set-key ; in emacs-state 4956 ;; a novice or a beginner
4589 vip-toggle-key 4957 ((eq vip-expert-level 1)
4590 (if (vip-window-display-p) 'vip-iconify 'suspend-emacs)) 4958 (global-set-key vip-toggle-key ;; in emacs-state
4959 (if (vip-window-display-p)
4960 'vip-iconify
4961 'suspend-emacs))
4591 (setq vip-no-multiple-ESC t 4962 (setq vip-no-multiple-ESC t
4592 vip-re-search t 4963 vip-re-search t
4593 vip-vi-style-in-minibuffer t 4964 vip-vi-style-in-minibuffer t
4594 vip-search-wrap-around-t t 4965 vip-search-wrap-around-t t
4595 vip-want-emacs-keys-in-vi nil 4966 vip-want-emacs-keys-in-vi nil
4596 vip-want-emacs-keys-in-insert nil)) 4967 vip-want-emacs-keys-in-insert nil))
4597 4968
4969 ;; an intermediate to guru
4598 ((and (> vip-expert-level 1) (< vip-expert-level 5)) 4970 ((and (> vip-expert-level 1) (< vip-expert-level 5))
4599 ;; intermediate to guru
4600 (setq vip-no-multiple-ESC (if (vip-window-display-p) t 'twice) 4971 (setq vip-no-multiple-ESC (if (vip-window-display-p) t 'twice)
4601 vip-want-emacs-keys-in-vi t 4972 vip-want-emacs-keys-in-vi t
4602 vip-want-emacs-keys-in-insert (> vip-expert-level 2)) 4973 vip-want-emacs-keys-in-insert (> vip-expert-level 2))
4603 4974
4604 (if (eq vip-expert-level 4) ; respect user's ex-style motions 4975 (if (eq vip-expert-level 4) ; respect user's ex-style motions
4619 (cdr (assoc 'vip-re-search vip-saved-user-settings)) 4990 (cdr (assoc 'vip-re-search vip-saved-user-settings))
4620 vip-no-multiple-ESC 4991 vip-no-multiple-ESC
4621 (cdr (assoc 'vip-no-multiple-ESC 4992 (cdr (assoc 'vip-no-multiple-ESC
4622 vip-saved-user-settings)))))) 4993 vip-saved-user-settings))))))
4623 4994
4624 ;; A wizard!! 4995 ;; A wizard
4625 ;; Ideally, if 5 is selected, a buffer should pop up to let the 4996 ;; Ideally, if 5 is selected, a buffer should pop up to let the
4626 ;; user toggle the values of variables. 4997 ;; user toggle variable values.
4627 (t (setq-default vip-ex-style-editing-in-insert 4998 (t (setq-default vip-ex-style-editing-in-insert
4628 (cdr (assoc 'vip-ex-style-editing-in-insert 4999 (cdr (assoc 'vip-ex-style-editing-in-insert
4629 vip-saved-user-settings)) 5000 vip-saved-user-settings))
4630 vip-ex-style-motion 5001 vip-ex-style-motion
4631 (cdr (assoc 'vip-ex-style-motion 5002 (cdr (assoc 'vip-ex-style-motion
4982 elt))))) 5353 elt)))))
4983 lis)) 5354 lis))
4984 5355
4985 5356
4986 5357
5358 ;;; Bring in the rest of the files
5359 (require 'viper-mous)
5360 (require 'viper-macs)
5361 (require 'viper-ex)
5362
5363
5364
4987 ;; The following is provided for compatibility with older VIP's 5365 ;; The following is provided for compatibility with older VIP's
4988 5366
4989 (defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi) 5367 (defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi)
4990 (defalias 'vip-change-mode-to-insert 'vip-change-state-to-insert) 5368 (defalias 'vip-change-mode-to-insert 'vip-change-state-to-insert)
4991 (defalias 'vip-change-mode-to-emacs 'vip-change-state-to-emacs) 5369 (defalias 'vip-change-mode-to-emacs 'vip-change-state-to-emacs)
4994 5372
4995 ;;; Load .vip and set up hooks 5373 ;;; Load .vip and set up hooks
4996 5374
4997 ;; This hook designed to enable Vi-style editing in comint-based modes." 5375 ;; This hook designed to enable Vi-style editing in comint-based modes."
4998 (defun vip-comint-mode-hook () 5376 (defun vip-comint-mode-hook ()
4999 (setq require-final-newline nil 5377 (setq require-final-newline nil)
5000 vip-ex-style-editing-in-insert nil 5378 (setq vip-ex-style-editing-in-insert nil
5001 vip-ex-style-motion nil) 5379 vip-ex-style-motion nil)
5002 (vip-change-state-to-insert)) 5380 (vip-add-local-keys 'vi-state
5003 5381 '(("\C-m" . comint-send-input) ; return
5382 ("\C-d" . comint-delchar-or-maybe-eof))) ; \C-d
5383 (vip-add-local-keys 'insert-state
5384 '(("\C-m" . comint-send-input) ; return
5385 ("\C-d" . comint-delchar-or-maybe-eof))) ; \C-d
5386 )
5387
5004 5388
5005 ;; This sets major mode hooks to make them come up in vi-state. 5389 ;; This sets major mode hooks to make them come up in vi-state.
5006 (defun vip-set-hooks () 5390 (defun vip-set-hooks ()
5007 5391
5008 ;; It is of course a misnomer to call viper-mode a `major mode'. 5392 ;; It is of course a misnomer to call viper-mode a `major mode'.
5019 (defvar makefile-mode-hook) 5403 (defvar makefile-mode-hook)
5020 (add-hook 'makefile-mode-hook 'viper-mode) 5404 (add-hook 'makefile-mode-hook 'viper-mode)
5021 5405
5022 (defvar help-mode-hook) 5406 (defvar help-mode-hook)
5023 (add-hook 'help-mode-hook 'viper-mode) 5407 (add-hook 'help-mode-hook 'viper-mode)
5024 (vip-modify-major-mode 'help-mode 'vi-state vip-help-modifier-map)
5025 5408
5026 (defvar awk-mode-hook) 5409 (defvar awk-mode-hook)
5027 (add-hook 'awk-mode-hook 'viper-mode) 5410 (add-hook 'awk-mode-hook 'viper-mode)
5028 5411
5029 (defvar html-mode-hook) 5412 (defvar html-mode-hook)
5030 (add-hook 'html-mode-hook 'viper-mode) 5413 (add-hook 'html-mode-hook 'viper-mode)
5031 (defvar html-helper-mode-hook) 5414 (defvar html-helper-mode-hook)
5032 (add-hook 'html-helper-mode-hook 'viper-mode) 5415 (add-hook 'html-helper-mode-hook 'viper-mode)
5033 (defvar java-mode-hook)
5034 (add-hook 'java-mode-hook 'viper-mode)
5035 5416
5036 (defvar emacs-lisp-mode-hook) 5417 (defvar emacs-lisp-mode-hook)
5037 (add-hook 'emacs-lisp-mode-hook 'viper-mode) 5418 (add-hook 'emacs-lisp-mode-hook 'viper-mode)
5038 5419
5039 (defvar lisp-mode-hook) 5420 (defvar lisp-mode-hook)
5054 (defvar lisp-interaction-mode-hook) 5435 (defvar lisp-interaction-mode-hook)
5055 (add-hook 'lisp-interaction-mode-hook 'viper-mode) 5436 (add-hook 'lisp-interaction-mode-hook 'viper-mode)
5056 5437
5057 (defvar fortran-mode-hook) 5438 (defvar fortran-mode-hook)
5058 (add-hook 'fortran-mode-hook 'vip-mode) 5439 (add-hook 'fortran-mode-hook 'vip-mode)
5059
5060 (defvar basic-mode-hook)
5061 (add-hook 'basic-mode-hook 'vip-mode)
5062 (defvar bat-mode-hook)
5063 (add-hook 'bat-mode-hook 'vip-mode)
5064 5440
5065 (defvar text-mode-hook) 5441 (defvar text-mode-hook)
5066 (add-hook 'text-mode-hook 'viper-mode) 5442 (add-hook 'text-mode-hook 'viper-mode)
5067 5443
5068 (add-hook 'completion-list-mode-hook 'viper-mode) 5444 (add-hook 'completion-list-mode-hook 'viper-mode)
5071 (add-hook 'perl-mode-hook 'viper-mode) 5447 (add-hook 'perl-mode-hook 'viper-mode)
5072 (add-hook 'tcl-mode-hook 'viper-mode) 5448 (add-hook 'tcl-mode-hook 'viper-mode)
5073 5449
5074 (defvar emerge-startup-hook) 5450 (defvar emerge-startup-hook)
5075 (add-hook 'emerge-startup-hook 'vip-change-state-to-emacs) 5451 (add-hook 'emerge-startup-hook 'vip-change-state-to-emacs)
5076 5452 ;; Run vip-change-state-to-vi after quitting emerge.
5077 ;; Tell vc-diff to put *vc* in Vi mode
5078 (if (featurep 'vc)
5079 (defadvice vc-diff (after vip-vc-ad activate)
5080 "Force Vi state in VC diff buffer."
5081 (vip-change-state-to-vi))
5082 (vip-eval-after-load
5083 "vc"
5084 '(defadvice vc-diff (after vip-vc-ad activate)
5085 "Force Vi state in VC diff buffer."
5086 (vip-change-state-to-vi))))
5087
5088 (vip-eval-after-load 5453 (vip-eval-after-load
5089 "emerge" 5454 "emerge"
5090 '(defadvice emerge-quit (after vip-emerge-advice activate) 5455 '(defadvice emerge-quit (after vip-emerge-advice activate)
5091 "Run `vip-change-state-to-vi' after quitting emerge." 5456 "Run `vip-change-state-to-vi' after quitting emerge."
5092 (vip-change-state-to-vi))) 5457 (vip-change-state-to-vi)))
5115 "Switch to Vi state in Prolog mode." 5480 "Switch to Vi state in Prolog mode."
5116 (vip-change-state-to-vi))) 5481 (vip-change-state-to-vi)))
5117 5482
5118 ;; Emacs shell, ange-ftp, and comint-based modes 5483 ;; Emacs shell, ange-ftp, and comint-based modes
5119 (defvar comint-mode-hook) 5484 (defvar comint-mode-hook)
5120 (vip-modify-major-mode 5485 (add-hook 'comint-mode-hook 'vip-change-state-to-insert)
5121 'comint-mode 'insert-state vip-comint-mode-modifier-map)
5122 (vip-modify-major-mode
5123 'comint-mode 'vi-state vip-comint-mode-modifier-map)
5124 (vip-modify-major-mode
5125 'shell-mode 'insert-state vip-comint-mode-modifier-map)
5126 (vip-modify-major-mode
5127 'shell-mode 'vi-state vip-comint-mode-modifier-map)
5128 ;; ange-ftp in XEmacs
5129 (vip-modify-major-mode
5130 'ange-ftp-shell-mode 'insert-state vip-comint-mode-modifier-map)
5131 (vip-modify-major-mode
5132 'ange-ftp-shell-mode 'vi-state vip-comint-mode-modifier-map)
5133 ;; ange-ftp in Emacs
5134 (vip-modify-major-mode
5135 'internal-ange-ftp-mode 'insert-state vip-comint-mode-modifier-map)
5136 (vip-modify-major-mode
5137 'internal-ange-ftp-mode 'vi-state vip-comint-mode-modifier-map)
5138 ;; set hook
5139 (add-hook 'comint-mode-hook 'vip-comint-mode-hook) 5486 (add-hook 'comint-mode-hook 'vip-comint-mode-hook)
5140 5487
5141 ;; Shell scripts 5488 ;; Shell scripts
5142 (defvar sh-mode-hook) 5489 (defvar sh-mode-hook)
5143 (add-hook 'sh-mode-hook 'viper-mode) 5490 (add-hook 'sh-mode-hook 'viper-mode)
5144 (defvar ksh-mode-hook) 5491 (defvar ksh-mode-hook)
5145 (add-hook 'ksh-mode-hook 'viper-mode) 5492 (add-hook 'ksh-mode-hook 'viper-mode)
5146 5493
5147 ;; Dired 5494 ;; Dired
5148 (vip-modify-major-mode 'dired-mode 'emacs-state vip-dired-modifier-map) 5495 ;; This is only necessary when the user uses vip-modify-major-mode
5149 (vip-set-emacs-search-style-macros nil 'dired-mode)
5150 (add-hook 'dired-mode-hook 'vip-change-state-to-emacs) 5496 (add-hook 'dired-mode-hook 'vip-change-state-to-emacs)
5151 5497
5152 ;; Tar
5153 (vip-modify-major-mode 'tar-mode 'emacs-state vip-slash-and-colon-map)
5154 (vip-set-emacs-search-style-macros nil 'tar-mode)
5155
5156 ;; MH-E
5157 (vip-modify-major-mode 'mh-folder-mode 'emacs-state vip-slash-and-colon-map)
5158 (vip-set-emacs-search-style-macros nil 'mh-folder-mode)
5159 ;; changing state to emacs is needed so the preceding will take hold
5160 (add-hook 'mh-folder-mode-hook 'vip-change-state-to-emacs)
5161 (add-hook 'mh-show-mode-hook 'viper-mode)
5162
5163 ;; Gnus
5164 (vip-modify-major-mode 'gnus-group-mode 'emacs-state vip-slash-and-colon-map)
5165 (vip-set-emacs-search-style-macros nil 'gnus-group-mode)
5166 (vip-modify-major-mode
5167 'gnus-summary-mode 'emacs-state vip-slash-and-colon-map)
5168 (vip-set-emacs-search-style-macros nil 'gnus-summary-mode)
5169 ;; changing state to emacs is needed so the preceding will take hold
5170 (add-hook 'gnus-group-mode-hook 'vip-change-state-to-emacs)
5171 (add-hook 'gnus-summary-mode-hook 'vip-change-state-to-emacs)
5172 (add-hook 'gnus-article-mode-hook 'viper-mode)
5173
5174 ;; Info
5175 (vip-modify-major-mode 'Info-mode 'emacs-state vip-slash-and-colon-map)
5176 (vip-set-emacs-search-style-macros nil 'Info-mode)
5177 ;; Switching to emacs is needed so the above will take hold
5178 (defadvice Info-mode (after vip-Info-ad activate)
5179 "Switch to emacs mode."
5180 (vip-change-state-to-emacs))
5181
5182 ;; Buffer menu
5183 (vip-modify-major-mode
5184 'Buffer-menu-mode 'emacs-state vip-slash-and-colon-map)
5185 (vip-set-emacs-search-style-macros nil 'Buffer-menu-mode)
5186 ;; Switching to emacs is needed so the above will take hold
5187 (defadvice Buffer-menu-mode (after vip-Buffer-menu-ad activate)
5188 "Switch to emacs mode."
5189 (vip-change-state-to-emacs))
5190
5191 ;; View mode
5192 (if vip-emacs-p 5498 (if vip-emacs-p
5193 (progn 5499 (progn
5194 (defvar view-mode-hook) 5500 (defvar view-mode-hook)
5195 (add-hook 'view-mode-hook 'vip-change-state-to-emacs)) 5501 (add-hook 'view-mode-hook 'vip-change-state-to-emacs))
5196 (defadvice view-minor-mode (after vip-view-ad activate) 5502 (defadvice view-minor-mode (after vip-view-ad activate)
5229 ;; repeat the 3d previous command without rotating the command history 5535 ;; repeat the 3d previous command without rotating the command history
5230 (vip-record-kbd-macro 5536 (vip-record-kbd-macro
5231 (vector vip-repeat-from-history-key '\2) 'vi-state 5537 (vector vip-repeat-from-history-key '\2) 'vi-state
5232 [(meta x) v i p - r e p e a t - f r o m - h i s t o r y return] 't) 5538 [(meta x) v i p - r e p e a t - f r o m - h i s t o r y return] 't)
5233 5539
5234 ;; set the toggle case sensitivity and regexp search macros 5540 ;; toggle case sensitivity in search
5235 (vip-set-vi-search-style-macros nil) 5541 (vip-record-kbd-macro
5542 "//" 'vi-state
5543 [1 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return] 't)
5544 ;; toggle regexp/vanila search
5545 (vip-record-kbd-macro
5546 "///" 'vi-state
5547 [2 (meta x) v i p - t o g g l e - s e a r c h - s t y l e return] 't)
5236 5548
5237 5549
5238 ;; ~/.vip is loaded if it exists 5550 ;; ~/.vip is loaded if it exists
5239 (if (and (file-exists-p vip-custom-file-name) 5551 (if (and (file-exists-p vip-custom-file-name)
5240 (not noninteractive)) 5552 (not noninteractive))
5259 (cons 'vip-want-emacs-keys-in-insert vip-want-emacs-keys-in-insert) 5571 (cons 'vip-want-emacs-keys-in-insert vip-want-emacs-keys-in-insert)
5260 (cons 'vip-re-search vip-re-search))) 5572 (cons 'vip-re-search vip-re-search)))
5261 5573
5262 5574
5263 (vip-set-minibuffer-style) 5575 (vip-set-minibuffer-style)
5576 (vip-set-minibuffer-faces)
5577 (vip-set-search-face)
5264 (if vip-buffer-search-char 5578 (if vip-buffer-search-char
5265 (vip-buffer-search-enable)) 5579 (vip-buffer-search-enable))
5266 (vip-update-alphanumeric-class) 5580 (vip-update-alphanumeric-class)
5267 5581
5268 ;;; Familiarize Viper with some minor modes that have their own keymaps 5582 ;;; Familiarize Viper with some minor modes that have their own keymaps
5287 (define-key vip-insert-intercept-map vip-ESC-key 'vip-intercept-ESC-key) 5601 (define-key vip-insert-intercept-map vip-ESC-key 'vip-intercept-ESC-key)
5288 5602
5289 ;; This is taken care of by vip-insert-global-user-map. 5603 ;; This is taken care of by vip-insert-global-user-map.
5290 ;;(define-key vip-replace-map vip-ESC-key 'vip-intercept-ESC-key) 5604 ;;(define-key vip-replace-map vip-ESC-key 'vip-intercept-ESC-key)
5291 5605
5292 5606 (define-key vip-insert-intercept-map vip-toggle-key 'vip-alternate-ESC)
5293 ;; The default vip-toggle-key is \C-z; for the novice, it suspends or 5607 ;; The default vip-toggle-key is \C-z; for the novice, it suspends or
5294 ;; iconifies Emacs 5608 ;; iconifies Emacs
5295 (define-key vip-vi-intercept-map vip-toggle-key 'vip-toggle-key-action) 5609 (define-key vip-vi-intercept-map vip-toggle-key
5610 '(lambda () (interactive)
5611 (if (and (< vip-expert-level 2) (equal vip-toggle-key "\C-z"))
5612 (if (vip-window-display-p) (vip-iconify) (suspend-emacs))
5613 (vip-change-state-to-emacs))))
5614
5296 (define-key vip-emacs-intercept-map vip-toggle-key 'vip-change-state-to-vi) 5615 (define-key vip-emacs-intercept-map vip-toggle-key 'vip-change-state-to-vi)
5297 5616
5298 5617
5299 (if (or vip-always 5618 (if (or vip-always
5300 (and (< vip-expert-level 5) (> vip-expert-level 0))) 5619 (and (< vip-expert-level 5) (> vip-expert-level 0)))
5311 )) 5630 ))
5312 5631
5313 5632
5314 (run-hooks 'vip-load-hook) ; the last chance to change something 5633 (run-hooks 'vip-load-hook) ; the last chance to change something
5315 5634
5635 (provide 'viper)
5316 (provide 'vip19) 5636 (provide 'vip19)
5317 (provide 'vip) 5637 (provide 'vip)
5318 5638
5319 ;;; viper.el ends here 5639 ;;; viper.el ends here