diff lisp/viper/viper.el @ 175:2d532a89d707 r20-3b14

Import from CVS: tag r20-3b14
author cvs
date Mon, 13 Aug 2007 09:50:14 +0200
parents 0132846995bd
children 6075d714658b
line wrap: on
line diff
--- a/lisp/viper/viper.el	Mon Aug 13 09:49:11 2007 +0200
+++ b/lisp/viper/viper.el	Mon Aug 13 09:50:14 2007 +0200
@@ -8,7 +8,7 @@
 
 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
 
-(defconst viper-version "2.94 of June 12, 1997"
+(defconst viper-version "2.95 of July 9, 1997"
   "The current version of Viper")
 
 ;; This file is part of GNU Emacs.
@@ -150,24 +150,24 @@
 ;;
 ;;  The last vip-vi-basic-minor-mode contains most of the usual Vi bindings
 ;;  in its edit mode. This mode provides access to all Emacs facilities.
-;;  Novice users, however, may want to set their vip-expert-level to 1
+;;  Novice users, however, may want to set their viper-expert-level to 1
 ;;  in their .vip file. This will enable vip-vi-diehard-minor-mode. This
 ;;  minor mode's bindings make Viper simulate the usual Vi very closely.
 ;;  For instance,  C-c will not have its standard Emacs binding
 ;;  and so many of the goodies of Emacs are not available.
 ;;
-;;  A skilled user should set vip-expert-level to at least 3. This will
+;;  A skilled user should set viper-expert-level to at least 3. This will
 ;;  enable `C-c' and many Emacs facilities will become available.
 ;;  In this case, vip-vi-diehard-minor-mode is inactive.
 ;;
 ;;  Viper gurus should have at least
-;;      (setq vip-expert-level 4)
-;;  in their ~/.vip files. This will unsuppress all Emacs keys that are not
+;;      (setq viper-expert-level 4)
+;;  in their ~/.viper files. This will unsuppress all Emacs keys that are not
 ;;  essential for VI-style editing.
 ;;  Pick-and-choose users may want to put
-;;      (setq vip-expert-level 5)
-;;  in ~/.vip. Viper will then leave it up to the user to set the variables
-;;  vip-want-*  See vip-set-expert-level for details.
+;;      (setq viper-expert-level 5)
+;;  in ~/.viper. Viper will then leave it up to the user to set the variables
+;;  vip-want-*  See viper-set-expert-level for details.
 ;;
 ;;  The very first minor mode, vip-vi-intercept-minor-mode, is of no
 ;;  concern for the user. It is needed to bind Viper's vital keys, such as
@@ -302,6 +302,8 @@
 
 ;; compiler pacifier
 (defvar mark-even-if-inactive)
+(defvar viper-expert-level)
+(defvar vip-expert-level)
 
 ;; loading happens only in non-interactive compilation
 ;; in order to spare non-viperized emacs from being viperized
@@ -313,24 +315,49 @@
 	)))
 ;; end pacifier
 
+;; better be defined before Viper custom group.
+(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.viper")
+  "Viper customisation file.
+If set by the user, this must be done _before_ Viper is loaded in `~/.emacs'.")
+
+(defgroup viper nil
+  "Vi emulation within Emacs.
+NOTE: Viper customization should be saved in `vip-custom-file-name', which
+defaults to `~/.viper'."
+  :prefix "vip-"
+  :group 'emulations)
+
 (require 'viper-cmd)
 
 (defvar vip-always t
   "See `viper-always'. This variable is for compatibility with older Vipers.")
-(defvar viper-always vip-always
+(defcustom viper-always vip-always
   "Non-nil means, arrange for vi-state to be a default when appropriate.
 This is different from `viper-mode' variable in that `viper-mode' determines
 whether to use Viper in the first place, while `viper-always', if nil, lets
-user decide when to invoke Viper in a major mode.")
+user decide when to invoke Viper in a major mode."
+  :type 'boolean
+  :tag "Always Invoke Viper"
+  :group 'viper)
 
-(defvar viper-mode (cond (noninteractive nil)
-			 (t 'ask))
-  "Viperize or not Viperize.
+;; Non-viper variables that need to be saved in case the user decides to
+;; de-viperize emacs.
+(defvar viper-saved-non-viper-variables nil)
+;; Contains user settings for vars affected by viper-set-expert-level function.
+;; Not a user option.
+(defvar viper-saved-user-settings nil)
+	       
+(defcustom viper-mode (cond (noninteractive nil)
+			    (t 'ask))
+  "To Viperize or not to Viperize.
 If t, viperize emacs. If nil -- don't. If `ask', ask the user.
 This variable is used primatily when Viper is being loaded.
 
 Must be set in `~/.emacs' before Viper is loaded.
-DO NOT set this variable interactively.")
+DO NOT set this variable interactively."
+  :type '(choice (const nil) (const t) (const ask))
+  :tag "Set Viper Mode on Loading"
+  :group 'viper)
 
 
 ;; The following are provided for compatibility with older VIP's
@@ -342,6 +369,7 @@
 (defalias 'vip-change-mode-to-insert 'vip-change-state-to-insert)
 (defalias 'vip-change-mode-to-emacs 'vip-change-state-to-emacs)
 
+
 
 
 ;;;###autoload
@@ -367,11 +395,11 @@
 		    (erase-buffer)
 		    (insert
 		     (substitute-command-keys
-		      "Viper Is a Package for Emacs Rebels.
-It is also a VI Plan for Emacs Rescue and a venomous VI PERil.
+		      "Viper Is a Package for Emacs Rebels,
+a VI Plan for Emacs Rescue, and a venomous VI PERil.
 
-Technically speaking, Viper is a Vi emulation package for GNU Emacs 19 and
-XEmacs 19.  It supports virtually all of Vi and Ex functionality, extending
+Incidentally, Viper emulates Vi under GNU Emacs 20 and XEmacs 20.
+It supports all of what is good in Vi and Ex, while extending
 and improving upon much of it.
 
    1. Viper supports Vi at several levels. Level 1 is the closest to Vi,
@@ -383,26 +411,30 @@
       as in VI, to smooth transition to Viper for the beginners. However, to
       use Emacs productively, you are advised to reach user level 3 or higher. 
       
-      If your user level is 2 or higher, ^X and ^C will invoke Emacs
-      functions,as usual in Emacs; ^Z will toggle vi/emacs modes, and 
-      ^G will be the usual Emacs's keyboard-quit (something like ^C in VI).
+      At user level 2 or higher, ^X and ^C have Emacs, not Vi, bindings;
+      ^Z toggles Vi/Emacs states; ^G is Emacs' keyboard-quit (like ^C in Vi).
    
    2. Vi exit functions (e.g., :wq, ZZ) work on INDIVIDUAL files -- they
-      do not cause Emacs to quit, except at user level 1 (a novice).
+      do not cause Emacs to quit, except at user level 1 (for a novice).
    3. ^X^C EXITS EMACS.
    4. Viper supports multiple undo: `u' will undo. Typing `.' will repeat
       undo. Another `u' changes direction.
    
-   6. Emacs Meta functions are invoked by typing `C-\\' or `\\ ESC'.
-      On a window system, the best way is to use the Meta-key.
+   6. Emacs Meta key is `C-\\' (in all modes) or `\\ ESC' (in Vi command mode).
+      On a window system, the best way is to use the Meta-key on your keyboard.
    7. Try \\[keyboard-quit] and \\[abort-recursive-edit] repeatedly,if
       something funny happens. This would abort the current editing command. 
       
-You can get more information on Viper by:
+For more information on Viper:
 
-   a. Typing `:help' in Vi state
-   b. Printing Viper manual, found in ./etc/viper.dvi
-   c. Printing ViperCard, the Quick Reference, found in ./etc/viperCard.dvi
+   a. Type `:help' in Vi command mode
+   b. Print Viper manual, found in ./etc/viper.dvi
+   c. Print the Quick Reference, found in ./etc/viperCard.dvi
+
+To submit a bug report or to contact the author, type :submitReport in Vi
+command mode. To shoo Viper away and return to pure Emacs (horror!), type:
+
+   M-x viper-go-away
     
 This startup message appears whenever you load Viper, unless you type `y' now."
 		      ))
@@ -417,7 +449,7 @@
 		     "The last message is in buffer `Viper Startup Message'")
 		    (sit-for 4)
 		    ))
-	      (vip-set-expert-level 'dont-change-unless)))
+	      (viper-set-expert-level 'dont-change-unless)))
 	(vip-change-state-to-vi))))
    
 
@@ -429,6 +461,135 @@
   (vip-change-state-to-insert))
 
 
+;; remove viper hooks from SYMBOL
+(defun viper-remove-hooks (symbol)
+  (cond ((not (boundp symbol)) nil)
+	((not (listp (eval symbol))) nil)
+	((string-match "-hook" (symbol-name symbol))
+	 (remove-hook symbol 'viper-mode)
+	 (remove-hook symbol 'vip-change-state-to-emacs)
+	 (remove-hook symbol 'vip-change-state-to-insert)
+	 (remove-hook symbol 'vip-change-state-to-vi)
+	 )))
+
+;; Remove local value in all existing buffers
+;; This doesn't delocalize vars (which would have been desirable)
+(defun viper-delocalize-var (symbol)
+  (mapcar (function (lambda (buf)
+		      (save-excursion
+			(set-buffer buf)
+			(kill-local-variable symbol))))
+	  (buffer-list)))
+
+
+(defun viper-go-away ()
+  "De-Viperize Emacs.
+This function tries to do as good a job as possible. However, it may undo some
+user customization, unrelated to Viper. For instance, if the user advised
+`read-file-name', `describe-key', and some others, then this advice will be
+undone.
+It also doesn't undo some Viper settings. For instance, `minor-mode-map-alist'
+remains buffer-local."
+  (interactive)
+
+  ;; restore non-viper vars
+  (setq-default
+   default-major-mode
+   (viper-standard-value 'default-major-mode viper-saved-non-viper-variables) 
+   next-line-add-newlines
+   (viper-standard-value 
+    'next-line-add-newlines viper-saved-non-viper-variables) 
+   require-final-newline
+   (viper-standard-value 
+    'require-final-newline viper-saved-non-viper-variables) 
+   scroll-step
+   (viper-standard-value 'scroll-step viper-saved-non-viper-variables) 
+   mode-line-buffer-identification
+   (viper-standard-value
+    'mode-line-buffer-identification viper-saved-non-viper-variables)
+   global-mode-string
+   (viper-standard-value 'global-mode-string viper-saved-non-viper-variables))
+
+  (if vip-emacs-p
+      (setq-default
+       mark-even-if-inactive
+       (viper-standard-value
+	'mark-even-if-inactive viper-saved-non-viper-variables)))
+
+  ;; Ideally, we would like to be able to de-localize local variables 
+  (viper-delocalize-var 'minor-mode-map-alist)
+  (viper-delocalize-var 'require-final-newline)
+
+  
+  ;; deactivate all advices done by Viper.
+  (ad-deactivate-regexp "vip-")
+
+  (setq viper-mode nil)
+
+  (viper-delocalize-var 'vip-vi-minibuffer-minor-mode)
+  (viper-delocalize-var 'vip-insert-minibuffer-minor-mode)
+  (viper-delocalize-var 'vip-vi-intercept-minor-mode)
+  (viper-delocalize-var 'vip-insert-intercept-minor-mode)
+  
+  (viper-delocalize-var 'vip-vi-local-user-minor-mode)
+  (viper-delocalize-var 'vip-vi-kbd-minor-mode)
+  (viper-delocalize-var 'vip-vi-global-user-minor-mode)
+  (viper-delocalize-var 'vip-vi-state-modifier-minor-mode)
+  (viper-delocalize-var 'vip-vi-diehard-minor-mode)
+  (viper-delocalize-var 'vip-vi-basic-minor-mode)
+	
+  (viper-delocalize-var 'vip-replace-minor-mode)
+	
+  (viper-delocalize-var 'vip-insert-local-user-minor-mode)
+  (viper-delocalize-var 'vip-insert-kbd-minor-mode)
+  (viper-delocalize-var 'vip-insert-global-user-minor-mode)
+  (viper-delocalize-var 'vip-insert-state-modifier-minor-mode)
+  (viper-delocalize-var 'vip-insert-diehard-minor-mode)
+  (viper-delocalize-var 'vip-insert-basic-minor-mode)
+  
+  (viper-delocalize-var 'vip-emacs-intercept-minor-mode)
+  (viper-delocalize-var 'vip-emacs-local-user-minor-mode)
+  (viper-delocalize-var 'vip-emacs-kbd-minor-mode)
+  (viper-delocalize-var 'vip-emacs-global-user-minor-mode)
+  (viper-delocalize-var 'vip-emacs-state-modifier-minor-mode)
+
+  (setq-default vip-vi-minibuffer-minor-mode	   nil
+		vip-insert-minibuffer-minor-mode   nil
+		vip-vi-intercept-minor-mode	   nil
+		vip-insert-intercept-minor-mode	   nil
+		
+		vip-vi-local-user-minor-mode       nil
+		vip-vi-kbd-minor-mode        	   nil
+		vip-vi-global-user-minor-mode      nil
+		vip-vi-state-modifier-minor-mode   nil
+		vip-vi-diehard-minor-mode     	   nil
+		vip-vi-basic-minor-mode       	   nil
+		
+		vip-replace-minor-mode 	      	   nil
+		
+		vip-insert-local-user-minor-mode     nil
+		vip-insert-kbd-minor-mode     	     nil
+		vip-insert-global-user-minor-mode    nil
+		vip-insert-state-modifier-minor-mode nil
+		vip-insert-diehard-minor-mode 	     nil
+		vip-insert-basic-minor-mode   	     nil
+
+		vip-emacs-intercept-minor-mode       nil
+		vip-emacs-local-user-minor-mode      nil
+		vip-emacs-kbd-minor-mode             nil
+		vip-emacs-global-user-minor-mode     nil
+		vip-emacs-state-modifier-minor-mode  nil
+		)
+
+  ;; remove all hooks set by viper
+  (mapatoms 'viper-remove-hooks)
+  (remove-hook 'comint-mode-hook 'vip-comint-mode-hook)
+  (remove-hook 'minibuffer-setup-hook 'vip-minibuffer-setup-sentinel)
+  )
+
+
+
+
 ;; This sets major mode hooks to make them come up in vi-state.
 (defun vip-set-hooks ()
   
@@ -461,6 +622,9 @@
   (defvar java-mode-hook)
   (add-hook 'java-mode-hook 'viper-mode)
   
+  (defvar javascript-mode-hook)
+  (add-hook 'javascript-mode-hook 'viper-mode)
+  
   (defvar emacs-lisp-mode-hook)
   (add-hook 'emacs-lisp-mode-hook 'viper-mode)
   (defvar lisp-mode-hook)
@@ -502,8 +666,14 @@
   (add-hook 'completion-list-mode-hook 'viper-mode)  
   (add-hook 'compilation-mode-hook     'viper-mode)  
 
-  (add-hook 'perl-mode-hook    'viper-mode)  
-  (add-hook 'tcl-mode-hook     'viper-mode)  
+  (defvar perl-mode-hook)
+  (add-hook 'perl-mode-hook 'viper-mode)  
+
+  (defvar tcl-mode-hook)
+  (add-hook 'tcl-mode-hook 'viper-mode)  
+  
+  (defvar python-mode-hook)
+  (add-hook 'python-mode-hook 'viper-mode)  
   
   (defvar emerge-startup-hook)
   (add-hook 'emerge-startup-hook 'vip-change-state-to-emacs)
@@ -568,26 +738,26 @@
   
   ;; Dired
   (vip-modify-major-mode 'dired-mode 'emacs-state vip-dired-modifier-map)
-  (vip-set-emacs-search-style-macros nil 'dired-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'dired-mode)
   (add-hook 'dired-mode-hook 'vip-change-state-to-emacs)
 
   ;; Tar
   (vip-modify-major-mode 'tar-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'tar-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'tar-mode)
 
   ;; MH-E
   (vip-modify-major-mode 'mh-folder-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'mh-folder-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'mh-folder-mode)
   ;; changing state to emacs is needed so the preceding will take hold
   (add-hook 'mh-folder-mode-hook 'vip-change-state-to-emacs)
   (add-hook 'mh-show-mode-hook 'viper-mode)
 
   ;; Gnus
   (vip-modify-major-mode 'gnus-group-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'gnus-group-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'gnus-group-mode)
   (vip-modify-major-mode 
    'gnus-summary-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'gnus-summary-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'gnus-summary-mode)
   ;; changing state to emacs is needed so the preceding will take hold
   (add-hook 'gnus-group-mode-hook 'vip-change-state-to-emacs)
   (add-hook 'gnus-summary-mode-hook 'vip-change-state-to-emacs)
@@ -595,7 +765,7 @@
 
   ;; Info
   (vip-modify-major-mode 'Info-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'Info-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'Info-mode)
   ;; Switching to emacs is needed  so the above will take hold
   (defadvice Info-mode (after vip-Info-ad activate)
     "Switch to emacs mode."
@@ -604,7 +774,7 @@
   ;; Buffer menu
   (vip-modify-major-mode 
    'Buffer-menu-mode 'emacs-state vip-slash-and-colon-map)
-  (vip-set-emacs-search-style-macros nil 'Buffer-menu-mode)
+  (vip-set-emacs-state-searchstyle-macros nil 'Buffer-menu-mode)
   ;; Switching to emacs is needed  so the above will take hold
   (defadvice Buffer-menu-mode (after vip-Buffer-menu-ad activate)
     "Switch to emacs mode."
@@ -659,7 +829,8 @@
   (make-variable-buffer-local 'require-final-newline)
   
   ;; don't bark when mark is inactive
-  (setq mark-even-if-inactive t)
+  (if vip-emacs-p
+      (setq mark-even-if-inactive t))
   
   (setq scroll-step 1)
   
@@ -709,11 +880,16 @@
     "Use `read-file-name' for reading arguments."
     (interactive (cons (read-file-name "Find file: " nil default-directory)
 		       ;; if Mule and prefix argument, ask for coding system
-		       (if (or (boundp 'MULE)    ; mule integrated Emacs 19
-			       (featurep 'mule)) ; mule integrated XEmacs 20
-			   (list
-			    (and current-prefix-arg
-				 (read-coding-system "Coding-system: "))))
+		       (cond ((and vip-emacs-p 
+				   (boundp 'MULE))   ; Emacs 20 with MULE
+			      nil)
+			     ((and vip-xemacs-p
+				   (featurep 'mule)) ; XEmacs 20 with MULE
+			      (list
+			       (and current-prefix-arg
+				    (read-coding-system 
+				     "Coding-system: "))))
+			     )
 		       )))
   
   (defadvice find-file-other-window (before vip-add-suffix-advice activate)
@@ -721,24 +897,36 @@
     (interactive (cons (read-file-name "Find file in other window: "
 				       nil default-directory)
 		       ;; if Mule and prefix argument, ask for coding system
-		       (if (or (boundp 'MULE)    ; mule integrated Emacs 19
-			       (featurep 'mule)) ; mule integrated XEmacs 20
-			   (list
-			    (and current-prefix-arg
-				 (read-coding-system "Coding-system: "))))
+		       (cond ((and vip-emacs-p 
+				   (boundp 'MULE)) ; Emacs 20 with MULE
+			      nil)
+			     ((and vip-xemacs-p
+				   (featurep 'mule))   ; XEmacs 20 with MULE
+			      (list
+			       (and current-prefix-arg
+				    (read-coding-system 
+				     "Coding-system: "))))
+			     )
 		       )))
   
+
   (defadvice find-file-other-frame (before vip-add-suffix-advice activate)
     "Use `read-file-name' for reading arguments."
     (interactive (cons (read-file-name "Find file in other frame: "
 				       nil default-directory)
 		       ;; if Mule and prefix argument, ask for coding system
-		       (if (or (boundp 'MULE)    ; mule integrated Emacs 19
-			       (featurep 'mule)) ; mule integrated XEmacs 20
-			   (list
-			    (and current-prefix-arg
-				 (read-coding-system "Coding-system: "))))
+		       (cond ((and vip-emacs-p 
+				   (boundp 'MULE))   ; Emacs 20 with MULE
+			      nil)
+			     ((and vip-xemacs-p
+				   (featurep 'mule)) ; XEmacs 20 with MULE
+			      (list
+			       (and current-prefix-arg
+				    (read-coding-system 
+				     "Coding-system: "))))
+			     )
 		       )))
+
   
   (defadvice read-file-name (around vip-suffix-advice activate)
     "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook."
@@ -815,7 +1003,7 @@
 in your .emacs file (preferably, close to the top).
 These two lines must come in the order given.
 
-Also, the startup file name has changed from .vip to .viper"))
+Also, the startup file name has been changed from .vip to .viper"))
 	(if (y-or-n-p "Viperize? ")
 	    (setq viper-mode t)
 	  (setq viper-mode nil))
@@ -825,10 +1013,35 @@
 
 
 
+;; Get viper standard value of SYMBOL. If symbol is customized, get its
+;; standard value. Otherwise, get the value saved in the alist STORAGE.  If
+;; STORAGE is nil, use viper-saved-user-settings. 
+(defun viper-standard-value (symbol &optional storage)
+  (or (eval (car (get symbol 'customized-value)))
+      (eval (car (get symbol 'saved-value)))
+      (nth 1 (assoc symbol (or storage viper-saved-user-settings)))))
+
+
+
+;; save non-viper vars that Viper might change
+(if (null viper-saved-non-viper-variables)
+    (setq viper-saved-non-viper-variables
+	  (list
+	   (cons 'default-major-mode (list default-major-mode))
+	   (cons 'next-line-add-newlines (list next-line-add-newlines))
+	   (cons 'require-final-newline (list require-final-newline))
+	   (cons 'scroll-step (list scroll-step))
+	   (cons 'mode-line-buffer-identification
+		 (list (default-value 'mode-line-buffer-identification)))
+	   (cons 'global-mode-string (list global-mode-string))
+	   (if vip-emacs-p
+	       (cons 'mark-even-if-inactive (list mark-even-if-inactive)))
+	   )))
+       
       
 ;; Set some useful macros, advices
-;; These must be BEFORE we ~/.vip is loaded, 
-;; so the user can unrecord them in ~/.vip.
+;; These must be BEFORE ~/.viper is loaded, 
+;; so the user can unrecord them in ~/.viper.
 (if viper-mode
     (progn
       ;; set advices and some variables that give emacs Vi look.
@@ -843,18 +1056,14 @@
        (vector vip-repeat-from-history-key '\2) 'vi-state
        [(meta x) v i p - r e p e a t - f r o m - h i s t o r y return] 't)
       
-      ;; set the toggle case sensitivity and regexp search macros
-      (vip-set-vi-search-style-macros nil)
-      
+      ;; set macros for toggling case sensitivity and regexp search 
+      (vip-set-searchstyle-toggling-macros nil)
       ;; Make %%% toggle parsing comments for matching parentheses
-      (vip-record-kbd-macro
-       "%%%" 'vi-state
-       [(meta x) v i p - t o g g l e - p a r s e - s e x p - i g n o r e - c o m m e n t s return]
-       't)
+      (vip-set-parsing-style-toggling-macro nil)
       ))
  
 
-;; ~/.vip is loaded if it exists
+;; ~/.viper is loaded if it exists
 (if (and (file-exists-p vip-custom-file-name)
 	 viper-mode
 	 (not noninteractive))
@@ -864,21 +1073,29 @@
 ;; Viper's basic map.
 (vip-add-keymap vip-mode-map vip-vi-global-user-map)
 
+(if (boundp 'vip-expert-level)
+    (setq viper-expert-level vip-expert-level))
+
+
 
 ;; Applying Viper customization -- runs after (load .vip)
 
-;; Save user settings or Viper defaults for vars controled by vip-expert-level
-(setq vip-saved-user-settings 
-      (list (cons 'vip-want-ctl-h-help vip-want-ctl-h-help)
-	    (cons 'viper-always viper-always)
-	    (cons 'vip-no-multiple-ESC vip-no-multiple-ESC)
-	    (cons 'vip-ex-style-motion vip-ex-style-motion)
-	    (cons 'vip-ex-style-editing-in-insert
-		    	    	    	    vip-ex-style-editing-in-insert) 
-	    (cons 'vip-want-emacs-keys-in-vi vip-want-emacs-keys-in-vi)
-	    (cons 'vip-electric-mode vip-electric-mode)
-	    (cons 'vip-want-emacs-keys-in-insert vip-want-emacs-keys-in-insert)
-	    (cons 'vip-re-search vip-re-search)))
+;; Save user settings or Viper defaults for vars controled by
+;; viper-expert-level 
+(if (null viper-saved-user-settings)
+    (setq viper-saved-user-settings 
+	  (list (cons 'vip-want-ctl-h-help (list vip-want-ctl-h-help))
+		(cons 'viper-always (list viper-always))
+		(cons 'vip-no-multiple-ESC (list vip-no-multiple-ESC))
+		(cons 'vip-ex-style-motion (list vip-ex-style-motion))
+		(cons 'vip-ex-style-editing-in-insert
+		      (list vip-ex-style-editing-in-insert))
+		(cons 'vip-want-emacs-keys-in-vi 
+		      (list vip-want-emacs-keys-in-vi))
+		(cons 'vip-electric-mode (list vip-electric-mode))
+		(cons 'vip-want-emacs-keys-in-insert
+		      (list vip-want-emacs-keys-in-insert))
+		(cons 'vip-re-search (list vip-re-search)))))
 	      
 
 (if viper-mode
@@ -909,7 +1126,7 @@
 
 
 ;; Intercept maps could go in viper-keym.el
-;; We keep them here in case someone redefines them in ~/.vip
+;; We keep them here in case someone redefines them in ~/.viper
 
 (define-key vip-vi-intercept-map vip-ESC-key 'vip-intercept-ESC-key)
 (define-key vip-insert-intercept-map vip-ESC-key 'vip-intercept-ESC-key)
@@ -926,7 +1143,7 @@
 
 (if (and viper-mode
 	 (or viper-always 
-	     (and (< vip-expert-level 5) (> vip-expert-level 0))))
+	     (and (< viper-expert-level 5) (> viper-expert-level 0))))
     (vip-set-hooks))
     
 ;; Let all minor modes take effect after loading
@@ -946,4 +1163,9 @@
 (provide 'vip)
 (provide 'viper)
 
+
+;;; Local Variables:
+;;; eval: (put 'vip-deflocalvar 'lisp-indent-hook 'defun)
+;;; End:
+
 ;;;  viper.el ends here