new version
authorMichael Kifer <kifer@cs.stonybrook.edu>
Thu, 7 Aug 1997 04:48:48 +0000 (04:48 +0000)
committerMichael Kifer <kifer@cs.stonybrook.edu>
Thu, 7 Aug 1997 04:48:48 +0000 (04:48 +0000)
lisp/emulation/viper-cmd.el
lisp/emulation/viper-init.el
lisp/emulation/viper-mous.el
lisp/emulation/viper-util.el
lisp/emulation/viper.el

index 9702af8..be02683 100644 (file)
               (cons 'viper-vi-global-user-minor-mode viper-vi-global-user-map)
               (cons 'viper-vi-state-modifier-minor-mode
                     (if (keymapp
-                         (cdr (assoc major-mode viper-vi-state-modifier-alist)))
+                         (cdr (assoc major-mode
+                                     viper-vi-state-modifier-alist))) 
                         (cdr (assoc major-mode viper-vi-state-modifier-alist))
                       viper-empty-keymap))
               (cons 'viper-vi-diehard-minor-mode  viper-vi-diehard-map)
               (cons 'viper-vi-basic-minor-mode     viper-vi-basic-map)
-              (cons 'viper-insert-intercept-minor-mode viper-insert-intercept-map)
+              (cons 'viper-insert-intercept-minor-mode
+                    viper-insert-intercept-map) 
               (cons 'viper-replace-minor-mode  viper-replace-map)
               ;; viper-insert-minibuffer-minor-mode must come after
               ;; viper-replace-minor-mode 
                     viper-insert-global-user-map)
               (cons 'viper-insert-state-modifier-minor-mode
                     (if (keymapp
-                         (cdr
-                          (assoc major-mode viper-insert-state-modifier-alist)))
-                        (cdr
-                         (assoc major-mode viper-insert-state-modifier-alist))
+                         (cdr (assoc major-mode
+                                     viper-insert-state-modifier-alist))) 
+                        (cdr (assoc major-mode
+                                    viper-insert-state-modifier-alist))
                       viper-empty-keymap))
               (cons 'viper-insert-diehard-minor-mode viper-insert-diehard-map)
               (cons 'viper-insert-basic-minor-mode viper-insert-basic-map)
      
 (defsubst viper-downgrade-to-insert ()
  (setq viper-current-state 'insert-state
-       viper-replace-minor-mode nil)
- )
+       viper-replace-minor-mode nil))
 
     
   
@@ -3576,7 +3577,8 @@ To turn this feature off, set this variable to nil."
          (while (and (not found) (< count len))
            (setq suff (nth count viper-smart-suffix-list)
                  count (1+ count))
-           (if (file-exists-p (format "%s%s" file suff))
+           (if (file-exists-p
+                (format "%s%s" (substitute-in-file-name file) suff))
                (progn
                  (setq found t)
                  (insert suff))))
@@ -3835,7 +3837,7 @@ cursor move past the beginning of line."
   (condition-case conds
       (if (or viper-allow-multiline-replace-regions
              (viper-same-line (viper-replace-start)
-                            (viper-replace-end)))
+                              (viper-replace-end)))
          (progn
            ;; tabs cause problems in replace, so untabify
            (goto-char (viper-replace-end))
index 4c14949..47360ed 100644 (file)
@@ -325,16 +325,6 @@ delete the text being replaced, as in standard Vi."
 (viper-deflocalvar viper-replace-overlay nil "")
 (put 'viper-replace-overlay 'permanent-local t)
 
-(defcustom viper-replace-overlay-pixmap "gray3"
-  "Pixmap to use for search face on non-color displays."
-  :type 'string
-  :group 'viper)
-(defcustom viper-search-face-pixmap "gray3"
-  "Pixmap to use for search face on non-color displays."
-  :type 'string
-  :group 'viper)
-
-
 (defcustom viper-replace-region-end-delimiter "$"
   "A string marking the end of replacement regions.
 It is used only with TTYs or if `viper-use-replace-region-delimiters'
@@ -699,6 +689,174 @@ Related buffers can be cycled through via :R and :P commands."
 ;; Last shell command executed with ! command.
 (defvar viper-last-shell-com nil)
 
+\f
+;;; Face-saving tricks
+
+(defcustom viper-replace-overlay-pixmap "gray3"
+  "Pixmap to use for search face on non-color displays."
+  :type 'string
+  :group 'viper)
+(defcustom viper-search-face-pixmap "gray3"
+  "Pixmap to use for search face on non-color displays."
+  :type 'string
+  :group 'viper)
+
+(defun viper-hide-face (face)
+  (if (and (viper-has-face-support-p) viper-emacs-p)
+      (add-to-list 'facemenu-unlisted-faces face)))
+
+
+(defgroup viper-highlighting nil
+  "Hilighting of replace region, search pattern, minibuffer, etc."
+  :prefix "viper-"
+  :group 'viper)
+
+;;(defvar viper-search-face
+;;  (if (viper-has-face-support-p)
+;;      (progn
+;;     (make-face 'viper-search-face)
+;;     (or (face-differs-from-default-p 'viper-search-face)
+;;         ;; face wasn't set in .viper or .Xdefaults
+;;         (if (viper-can-use-colors "Black" "khaki")
+;;             (progn
+;;               (set-face-background 'viper-search-face "khaki")
+;;               (set-face-foreground 'viper-search-face "Black"))
+;;           (set-face-underline-p 'viper-search-face t)
+;;           (viper-set-face-pixmap 'viper-search-face
+;;                                  viper-search-face-pixmap))) 
+;;     'viper-search-face))
+;;  "*Face used to flash out the search pattern.")
+
+(defface viper-search-face
+  '((((class color)) (:foreground "Black" :background "khaki"))
+    (t (:underline t :stipple viper-search-face-pixmap)))
+  "*Face used to flash out the search pattern."
+  :group 'viper-highlighting)
+;; An internal variable. Viper takes the face from here.
+(defvar viper-search-face 'viper-search-face)
+(viper-hide-face 'viper-search-face)
+  
+;;(defvar viper-replace-overlay-face
+;;  (if (viper-has-face-support-p)
+;;      (progn
+;;     (make-face 'viper-replace-overlay-face)
+;;     (or (face-differs-from-default-p 'viper-replace-overlay-face)
+;;         (progn
+;;           (if (viper-can-use-colors "darkseagreen2" "Black")
+;;               (progn
+;;                 (set-face-background
+;;                  'viper-replace-overlay-face "darkseagreen2")
+;;                 (set-face-foreground 'viper-replace-overlay-face "Black")))
+;;           (set-face-underline-p 'viper-replace-overlay-face t)
+;;           (viper-set-face-pixmap
+;;            'viper-replace-overlay-face viper-replace-overlay-pixmap)))
+;;     'viper-replace-overlay-face))
+;;  "*Face for highlighting replace regions on a window display.")
+
+(defface viper-replace-overlay-face
+  '((((class color)) (:foreground "Black" :background "darkseagreen2"))
+    (t (:underline t :stipple viper-replace-overlay-face-pixmap)))
+  "*Face for highlighting replace regions on a window display."
+  :group 'viper-highlighting)
+;; An internal variable. Viper takes the face from here.
+(defvar viper-replace-overlay-face 'viper-replace-overlay-face)
+(viper-hide-face 'viper-replace-overlay-face)
+
+;;(defvar viper-minibuffer-emacs-face
+;;  (if (viper-has-face-support-p)
+;;      (progn
+;;     (make-face 'viper-minibuffer-emacs-face)
+;;     (or (face-differs-from-default-p 'viper-minibuffer-emacs-face)
+;;         ;; face wasn't set in .viper or .Xdefaults
+;;         (if viper-vi-style-in-minibuffer
+;;             ;; emacs state is an exception in the minibuffer
+;;             (if (viper-can-use-colors "darkseagreen2" "Black")
+;;                 (progn
+;;                   (set-face-background
+;;                    'viper-minibuffer-emacs-face "darkseagreen2")
+;;                   (set-face-foreground
+;;                    'viper-minibuffer-emacs-face "Black"))
+;;               (copy-face 'modeline 'viper-minibuffer-emacs-face))
+;;           ;; emacs state is the main state in the minibuffer
+;;           (if (viper-can-use-colors "Black" "pink")
+;;               (progn
+;;                 (set-face-background 'viper-minibuffer-emacs-face "pink") 
+;;                 (set-face-foreground
+;;                  'viper-minibuffer-emacs-face "Black"))
+;;             (copy-face 'italic 'viper-minibuffer-emacs-face))
+;;           ))
+;;     'viper-minibuffer-emacs-face))
+;;  "Face used in the Minibuffer when it is in Emacs state.")
+
+(defface viper-minibuffer-emacs-face
+  '((((class color)) (:foreground "Black" :background "darkseagreen2"))
+    (t (:bold t)))
+  "Face used in the Minibuffer when it is in Emacs state."
+  :group 'viper-highlighting)
+;; An internal variable. Viper takes the face from here.
+(defvar viper-minibuffer-emacs-face 'viper-minibuffer-emacs-face)
+(viper-hide-face 'viper-minibuffer-emacs-face)
+    
+;;(defvar viper-minibuffer-insert-face
+;;  (if (viper-has-face-support-p)
+;;      (progn
+;;     (make-face 'viper-minibuffer-insert-face)
+;;     (or (face-differs-from-default-p 'viper-minibuffer-insert-face)
+;;         (if viper-vi-style-in-minibuffer
+;;             (if (viper-can-use-colors "Black" "pink")
+;;                 (progn
+;;                   (set-face-background 'viper-minibuffer-insert-face "pink") 
+;;                   (set-face-foreground
+;;                    'viper-minibuffer-insert-face "Black"))
+;;               (copy-face 'italic 'viper-minibuffer-insert-face))
+;;           ;; If Insert state is an exception
+;;           (if (viper-can-use-colors "darkseagreen2" "Black")
+;;               (progn
+;;                 (set-face-background
+;;                  'viper-minibuffer-insert-face "darkseagreen2")
+;;                 (set-face-foreground
+;;                  'viper-minibuffer-insert-face "Black"))
+;;             (copy-face 'modeline 'viper-minibuffer-insert-face))
+;;           (viper-italicize-face 'viper-minibuffer-insert-face)))
+;;     'viper-minibuffer-insert-face))
+;;  "Face used in the Minibuffer when it is in Insert state.")
+
+(defface viper-minibuffer-insert-face
+  '((((class color)) (:foreground "Black" :background "pink"))
+    (t (:italic t)))
+  "Face used in the Minibuffer when it is in Insert state."
+  :group 'viper-highlighting)
+;; An internal variable. Viper takes the face from here.
+(defvar viper-minibuffer-insert-face 'viper-minibuffer-insert-face)
+(viper-hide-face 'viper-minibuffer-insert-face)
+    
+;;(defvar viper-minibuffer-vi-face
+;;  (if (viper-has-face-support-p)
+;;      (progn
+;;     (make-face 'viper-minibuffer-vi-face)
+;;     (or (face-differs-from-default-p 'viper-minibuffer-vi-face)
+;;         (if viper-vi-style-in-minibuffer
+;;             (if (viper-can-use-colors "Black" "grey")
+;;                 (progn
+;;                   (set-face-background 'viper-minibuffer-vi-face "grey")
+;;                   (set-face-foreground 'viper-minibuffer-vi-face "Black"))
+;;               (copy-face 'bold 'viper-minibuffer-vi-face))
+;;           (copy-face 'bold 'viper-minibuffer-vi-face)
+;;           (invert-face 'viper-minibuffer-vi-face)))
+;;     'viper-minibuffer-vi-face))
+;;  "Face used in the Minibuffer when it is in Vi state.")
+
+(defface viper-minibuffer-vi-face
+  '((((class color)) (:foreground "DarkGreen" :background "grey"))
+    (t (:inverse-video t)))
+  "Face used in the Minibuffer when it is in Vi state."
+  :group 'viper-highlighting)
+;; An internal variable. Viper takes the face from here.
+(defvar viper-minibuffer-vi-face 'viper-minibuffer-vi-face)
+(viper-hide-face 'viper-minibuffer-vi-face)
+    
+;; the current face to be used in the minibuffer
+(viper-deflocalvar viper-minibuffer-current-face viper-minibuffer-emacs-face "")
 
 \f
 ;;; Miscellaneous
index 828b468..d630a64 100644 (file)
@@ -424,7 +424,7 @@ this command."
   
 (defun viper-mouse-catch-frame-switch (event arg)
   "Catch the event of switching frame.
-Usually is bound to a 'down-mouse' event to work properly. See sample
+Usually is bound to a `down-mouse' event to work properly. See sample
 bindings in the Viper manual."
   (interactive "e\nP")
   (setq viper-frame-of-focus nil)
index 28584aa..d9e3928 100644 (file)
 (require 'viper-init)
 
 
+;; A fix for NeXT Step
+;; Should go away, when NS people fix the design flaw, which leaves the
+;; two x-* functions undefined.
+(if (and (not (fboundp 'x-display-color-p)) (fboundp 'ns-display-color-p))
+    (fset 'x-display-color-p (symbol-function 'ns-display-color-p)))
+(if (and (not (fboundp 'x-color-defined-p)) (fboundp 'ns-color-defined-p))
+      (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p)))
+
 \f
 ;;; XEmacs support
 
-;; A fix for NeXT Step
-;; Should probably be eliminated in later versions.
-(if (and (viper-window-display-p) (eq (viper-device-type) 'ns))
-    (progn
-      (fset 'x-display-color-p (symbol-function 'ns-display-color-p))
-      (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p))
-      ))
 
 (if viper-xemacs-p
     (progn
       (cdr (assoc 'cursor-color (frame-parameters)))
     (color-instance-name (frame-property (selected-frame) 'cursor-color))))
   
-(defun viper-set-face-pixmap (face pixmap)
-  "Set face pixmap on a monochrome display."
-  (if (and (viper-window-display-p) (not (viper-color-display-p)))
-      (condition-case nil
-         (set-face-background-pixmap face pixmap)
-       (error
-        (message "Pixmap not found for %S: %s" (face-name face) pixmap)
-        (sit-for 1)))))
+;;(defun viper-set-face-pixmap (face pixmap)
+;;  "Set face pixmap on a monochrome display."
+;;  (if (and (viper-window-display-p) (not (viper-color-display-p)))
+;;      (condition-case nil
+;;       (set-face-background-pixmap face pixmap)
+;;     (error
+;;      (message "Pixmap not found for %S: %s" (face-name face) pixmap)
+;;      (sit-for 1)))))
 
   
 ;; OS/2
             (function (lambda (color) (assoc color pm-color-alist))))))
     
 ;; needed to smooth out the difference between Emacs and XEmacs
-(defsubst viper-italicize-face (face)
-  (if viper-xemacs-p
-      (make-face-italic face)
-    (make-face-italic face nil 'noerror)))
+;;(defsubst viper-italicize-face (face)
+;;  (if viper-xemacs-p
+;;      (make-face-italic face)
+;;    (make-face-italic face nil 'noerror)))
     
 ;; test if display is color and the colors are defined
-(defsubst viper-can-use-colors (&rest colors)
-  (if (viper-color-display-p)
-      (not (memq nil (mapcar 'viper-color-defined-p colors)))
-    ))
-
-(defun viper-hide-face (face)
-  (if (and (viper-has-face-support-p) viper-emacs-p)
-      (add-to-list 'facemenu-unlisted-faces face)))
+;;(defsubst viper-can-use-colors (&rest colors)
+;;  (if (viper-color-display-p)
+;;      (not (memq nil (mapcar 'viper-color-defined-p colors)))
+;;    ))
 
 ;; cursor colors
 (defun viper-change-cursor-color (new-color)
 (defsubst viper-restore-cursor-color-after-insert ()
   (viper-change-cursor-color viper-saved-cursor-color))
         
-\f
-;; Face-saving tricks
-
-(defvar viper-search-face
-  (if (viper-has-face-support-p)
-      (progn
-       (make-face 'viper-search-face)
-       (viper-hide-face 'viper-search-face)
-       (or (face-differs-from-default-p 'viper-search-face)
-           ;; face wasn't set in .viper or .Xdefaults
-           (if (viper-can-use-colors "Black" "khaki")
-               (progn
-                 (set-face-background 'viper-search-face "khaki")
-                 (set-face-foreground 'viper-search-face "Black"))
-             (set-face-underline-p 'viper-search-face t)
-             (viper-set-face-pixmap 'viper-search-face viper-search-face-pixmap)))
-       'viper-search-face))
-  "*Face used to flash out the search pattern.")
-  
-(defvar viper-replace-overlay-face
-  (if (viper-has-face-support-p)
-      (progn
-       (make-face 'viper-replace-overlay-face)
-       (viper-hide-face 'viper-replace-overlay-face)
-       (or (face-differs-from-default-p 'viper-replace-overlay-face)
-           (progn
-             (if (viper-can-use-colors "darkseagreen2" "Black")
-                 (progn
-                   (set-face-background
-                    'viper-replace-overlay-face "darkseagreen2")
-                   (set-face-foreground 'viper-replace-overlay-face "Black")))
-             (set-face-underline-p 'viper-replace-overlay-face t)
-             (viper-set-face-pixmap
-              'viper-replace-overlay-face viper-replace-overlay-pixmap)))
-       'viper-replace-overlay-face))
-  "*Face for highlighting replace regions on a window display.")
-
-(defvar viper-minibuffer-emacs-face
-  (if (viper-has-face-support-p)
-      (progn
-       (make-face 'viper-minibuffer-emacs-face)
-       (viper-hide-face 'viper-minibuffer-emacs-face)
-       (or (face-differs-from-default-p 'viper-minibuffer-emacs-face)
-           ;; face wasn't set in .viper or .Xdefaults
-           (if viper-vi-style-in-minibuffer
-               ;; emacs state is an exception in the minibuffer
-               (if (viper-can-use-colors "darkseagreen2" "Black")
-                   (progn
-                     (set-face-background
-                      'viper-minibuffer-emacs-face "darkseagreen2")
-                     (set-face-foreground
-                      'viper-minibuffer-emacs-face "Black"))
-                 (copy-face 'modeline 'viper-minibuffer-emacs-face))
-             ;; emacs state is the main state in the minibuffer
-             (if (viper-can-use-colors "Black" "pink")
-                 (progn
-                   (set-face-background 'viper-minibuffer-emacs-face "pink") 
-                   (set-face-foreground
-                    'viper-minibuffer-emacs-face "Black"))
-               (copy-face 'italic 'viper-minibuffer-emacs-face))
-             ))
-       'viper-minibuffer-emacs-face))
-  "Face used in the Minibuffer when it is in Emacs state.")
-    
-(defvar viper-minibuffer-insert-face
-  (if (viper-has-face-support-p)
-      (progn
-       (make-face 'viper-minibuffer-insert-face)
-       (viper-hide-face 'viper-minibuffer-insert-face)
-       (or (face-differs-from-default-p 'viper-minibuffer-insert-face)
-           (if viper-vi-style-in-minibuffer
-               (if (viper-can-use-colors "Black" "pink")
-                   (progn
-                     (set-face-background 'viper-minibuffer-insert-face "pink") 
-                     (set-face-foreground
-                      'viper-minibuffer-insert-face "Black"))
-                 (copy-face 'italic 'viper-minibuffer-insert-face))
-             ;; If Insert state is an exception
-             (if (viper-can-use-colors "darkseagreen2" "Black")
-                 (progn
-                   (set-face-background
-                    'viper-minibuffer-insert-face "darkseagreen2")
-                   (set-face-foreground
-                    'viper-minibuffer-insert-face "Black"))
-               (copy-face 'modeline 'viper-minibuffer-insert-face))
-             (viper-italicize-face 'viper-minibuffer-insert-face)))
-       'viper-minibuffer-insert-face))
-  "Face used in the Minibuffer when it is in Insert state.")
-    
-(defvar viper-minibuffer-vi-face
-  (if (viper-has-face-support-p)
-      (progn
-       (make-face 'viper-minibuffer-vi-face)
-       (viper-hide-face 'viper-minibuffer-vi-face)
-       (or (face-differs-from-default-p 'viper-minibuffer-vi-face)
-           (if viper-vi-style-in-minibuffer
-               (if (viper-can-use-colors "Black" "grey")
-                   (progn
-                     (set-face-background 'viper-minibuffer-vi-face "grey")
-                     (set-face-foreground 'viper-minibuffer-vi-face "Black"))
-                 (copy-face 'bold 'viper-minibuffer-vi-face))
-             (copy-face 'bold 'viper-minibuffer-vi-face)
-             (invert-face 'viper-minibuffer-vi-face)))
-       'viper-minibuffer-vi-face))
-  "Face used in the Minibuffer when it is in Vi state.")
-    
-;; the current face to be used in the minibuffer
-(viper-deflocalvar viper-minibuffer-current-face viper-minibuffer-emacs-face "")
    
 \f
 ;; Check the current version against the major and minor version numbers
@@ -979,10 +868,11 @@ to write a custom function, similar to `viper-ex-nontrivial-find-file-unix'."
 (defun viper-read-key () 
   (let ((overriding-local-map viper-overriding-map) 
        (inhibit-quit t)
-        key) 
+       help-char key) 
     (use-global-map viper-overriding-map) 
-    (setq key (elt (read-key-sequence nil) 0)) 
-    (use-global-map global-map) 
+    (unwind-protect
+       (setq key (elt (read-key-sequence nil) 0)) 
+      (use-global-map global-map))
     key))
 
 
index d09fddb..84fac50 100644 (file)
@@ -361,8 +361,11 @@ DO NOT set this variable interactively."
   :tag "Set Viper Mode on Loading"
   :group 'viper)
 
-(defcustom viper-non-vi-major-modes nil
-  "*A list of major modes that should never come up in vi command mode.
+(defcustom viper-non-vi-major-modes
+  '(custom-mode dired-mode efs-mode internal-ange-ftp-mode tar-mode
+               mh-folder-mode gnus-group-mode gnus-summary-mode Info-mode
+               Buffer-menu-mode view-mode vm-mode vm-summary-mode)
+  "*A list of major modes that should never come up in Vi command mode.
 Viper automatically augments this list with some obvious modes, such as
 `dired-mode', `tar-mode', etc. So, don't put modes on this list, unless 
 it comes up in a wrong Viper state."
@@ -599,7 +602,12 @@ remains buffer-local."
   ;; unbind Viper mouse bindings
   (viper-unbind-mouse-search-key)
   (viper-unbind-mouse-insert-key)
-  )
+  ;; In emacs, we have to advice handle-switch-frame
+  ;; This advice is undone earlier, when all advices matchine "viper-" are
+  ;; deactivated.
+  (if viper-xemacs-p
+      (remove-hook 'mouse-leave-frame-hook 'viper-remember-current-frame))
+  ) ; end viper-go-away
 
 
 
@@ -754,14 +762,10 @@ remains buffer-local."
   (viper-modify-major-mode 'dired-mode 'emacs-state viper-dired-modifier-map)
   (viper-set-emacs-state-searchstyle-macros nil 'dired-mode)
   (add-hook 'dired-mode-hook 'viper-change-state-to-emacs)
-  (setq viper-non-vi-major-modes
-       (append '(dired-mode efs-mode internal-ange-ftp-mode)
-               viper-non-vi-major-modes))
 
   ;; Tar
   (viper-modify-major-mode 'tar-mode 'emacs-state viper-slash-and-colon-map)
   (viper-set-emacs-state-searchstyle-macros nil 'tar-mode)
-  (setq viper-non-vi-major-modes (cons 'tar-mode viper-non-vi-major-modes))
 
   ;; MH-E
   (viper-modify-major-mode 
@@ -770,8 +774,6 @@ remains buffer-local."
   ;; changing state to emacs is needed so the preceding will take hold
   (add-hook 'mh-folder-mode-hook 'viper-change-state-to-emacs)
   (add-hook 'mh-show-mode-hook 'viper-mode)
-  (setq viper-non-vi-major-modes
-       (cons 'mh-folder-mode viper-non-vi-major-modes))
 
   ;; Gnus
   (viper-modify-major-mode
@@ -784,9 +786,6 @@ remains buffer-local."
   (add-hook 'gnus-group-mode-hook 'viper-change-state-to-emacs)
   (add-hook 'gnus-summary-mode-hook 'viper-change-state-to-emacs)
   (add-hook 'gnus-article-mode-hook 'viper-mode)
-  (setq viper-non-vi-major-modes
-       (append '(gnus-group-mode gnus-summary-mode)
-               viper-non-vi-major-modes))
 
   ;; Info
   (viper-modify-major-mode 'Info-mode 'emacs-state viper-slash-and-colon-map)
@@ -795,7 +794,6 @@ remains buffer-local."
   (defadvice Info-mode (after viper-Info-ad activate)
     "Switch to emacs mode."
     (viper-change-state-to-emacs))
-  (setq viper-non-vi-major-modes (cons 'Info-mode viper-non-vi-major-modes))
 
   ;; Buffer menu
   (viper-modify-major-mode 
@@ -805,15 +803,12 @@ remains buffer-local."
   (defadvice Buffer-menu-mode (after viper-Buffer-menu-ad activate)
     "Switch to emacs mode."
     (viper-change-state-to-emacs))
-  (setq viper-non-vi-major-modes
-       (cons 'Buffer-menu-mode viper-non-vi-major-modes))
 
   ;; View mode
   (defvar view-mode-hook)
   (defvar view-hook)
   (add-hook 'view-hook 'viper-change-state-to-emacs)
   (add-hook 'view-mode-hook 'viper-change-state-to-emacs)
-  (setq viper-non-vi-major-modes (cons 'view-mode viper-non-vi-major-modes))
   
   ;; For VM users.
   ;; Put summary and other VM buffers in Emacs state.
@@ -821,8 +816,6 @@ remains buffer-local."
   (defvar vm-summary-mode-hooks)
   (add-hook 'vm-mode-hooks   'viper-change-state-to-emacs)
   (add-hook 'vm-summary-mode-hooks   'viper-change-state-to-emacs)
-  (setq viper-non-vi-major-modes
-       (append '(vm-mode vm-summary-mode) viper-non-vi-major-modes))
   
   ;; For RMAIL users.
   ;; Put buf in Emacs state after edit.
@@ -970,14 +963,24 @@ remains buffer-local."
     (define-key viper-vi-intercept-map "\C-x)" nil)
     (define-key viper-insert-intercept-map "\C-x)" nil)
     (define-key viper-emacs-intercept-map "\C-x)" nil))
+
+  ;; catch frame switching event
+  (if (viper-window-display-p)
+      (if viper-xemacs-p
+            (add-hook 'mouse-leave-frame-hook
+                      'viper-remember-current-frame)
+          (defadvice handle-switch-frame (before viper-frame-advice activate)
+            "Remember the selected frame before the switch-frame event." 
+            (viper-remember-current-frame (selected-frame)))) )
+
   ) ; end viper-non-hook-settings
 
 \f
-(if (eq viper-mode 'ask)
-    (progn
-      (save-window-excursion
-       (with-output-to-temp-buffer " *viper-info*"
-         (princ "
+;; Ask only if this-command/last-command are nil, i.e., when loading
+(cond ((and (eq viper-mode 'ask) (null this-command) (null last-command))
+       (save-window-excursion
+        (with-output-to-temp-buffer " *viper-info*"
+          (princ "
 You have loaded Viper, and are about to Viperize your emacs!
 
 Viper is a Package for Emacs Rebels and a venomous VI PERil,
@@ -995,11 +998,19 @@ These two lines must come in the order given.
 ** Viper users:
        **** The startup file name has been changed from .vip to .viper
        **** All vip-* style names have been converted to viper-* style."))
-       (if (y-or-n-p "Viperize? ")
-           (setq viper-mode t)
-         (setq viper-mode nil))
-       (message "")
-       (kill-buffer " *viper-info*"))))
+        (if (y-or-n-p "Viperize? ")
+            (setq viper-mode t)
+          (setq viper-mode nil))
+        (message "")
+        (kill-buffer " *viper-info*")))
+
+      ;; If viper-mode is t, then just continue. Viper will kick in.
+      ((eq viper-mode t))
+      ;; Otherwise, it was asking mode and Viper was not loaded through .emacs
+      ;; In this case, it was either through M-x viper-mode or via something
+      ;; else, like the custom widget. If Viper was loaded through 
+      ;; M-x viper-mode, then viper will kick in anyway.
+      (t (setq viper-mode nil)))
 
 (defun viper-load-custom-file ()
   (if (and (file-exists-p viper-custom-file-name)