diff options
Diffstat (limited to 'lisp/emulation')
-rw-r--r-- | lisp/emulation/viper-cmd.el | 183 | ||||
-rw-r--r-- | lisp/emulation/viper-ex.el | 40 | ||||
-rw-r--r-- | lisp/emulation/viper-keym.el | 4 | ||||
-rw-r--r-- | lisp/emulation/viper-util.el | 29 | ||||
-rw-r--r-- | lisp/emulation/viper.el | 76 |
5 files changed, 194 insertions, 138 deletions
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index 9033ac7ce02..d4574779412 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el @@ -74,18 +74,15 @@ ;; given symbol foo, foo-p is the test function, foos is the set of ;; Viper command keys ;; (macroexpand '(viper-test-com-defun foo)) -;; (defun foo-p (com) (consp (memq (if (< com 0) (- com) com) foos))) +;; (defun foo-p (com) (consp (memq com foos))) (defmacro viper-test-com-defun (name) (let* ((snm (symbol-name name)) (nm-p (intern (concat snm "-p"))) (nms (intern (concat snm "s")))) `(defun ,nm-p (com) - (consp (viper-memq-char - (if (and (viper-characterp com) (< com 0)) - (- com) com) - ,nms) - )))) + (consp (viper-memq-char com ,nms) + )))) ;; Variables for defining VI commands @@ -725,10 +722,8 @@ Vi's prefix argument will be used. Otherwise, the prefix argument passed to viper-emacs-kbd-minor-mode) (unwind-protect (progn - (setq com (key-binding (setq key - (if viper-xemacs-p - (read-key-sequence nil) - (read-key-sequence nil t))))) + (setq com + (key-binding (setq key (viper-read-key-sequence nil)))) ;; In case of binding indirection--chase definitions. ;; Have to do it here because we execute this command under ;; different keymaps, so command-execute may not do the @@ -797,6 +792,12 @@ Similar to viper-escape-to-emacs, but accepts forms rather than keystrokes." (viper-set-mode-vars-for viper-current-state) result)) +;; This executes the last kbd event in emacs mode. Is used when we want to +;; interpret certain keys directly in emacs (as, for example, in comint mode). +(defun viper-exec-key-in-emacs (arg) + (interactive "P") + (viper-escape-to-emacs arg last-command-event)) + ;; This is needed because minor modes sometimes override essential Viper ;; bindings. By letting Viper know which files these modes are in, it will @@ -878,9 +879,7 @@ as a Meta key and any number of multiple escapes is allowed." (progn (let (minor-mode-map-alist) (viper-set-unread-command-events event) - (setq keyseq - (funcall - (ad-get-orig-definition 'read-key-sequence) nil)) + (setq keyseq (read-key-sequence nil 'continue-echo)) ) ; let ;; If keyseq translates into something that still has ESC ;; at the beginning, separate ESC from the rest of the seq. @@ -933,8 +932,7 @@ as a Meta key and any number of multiple escapes is allowed." ;; this is escape event with nothing after it ;; put in unread-command-event and then re-read (viper-set-unread-command-events event) - (setq keyseq - (funcall (ad-get-orig-definition 'read-key-sequence) nil)) + (setq keyseq (read-key-sequence nil)) )) ;; not an escape event (setq keyseq (vector event))) @@ -1121,7 +1119,8 @@ as a Meta key and any number of multiple escapes is allowed." ;; execute apropriate region command. (let ((char (car com)) (com (cdr com))) (setq prefix-arg (cons value com)) - (if (viper= char ?r) (viper-region prefix-arg) + (if (viper= char ?r) + (viper-region prefix-arg) (viper-Region prefix-arg)) ;; reset prefix-arg (setq prefix-arg nil)) @@ -1249,9 +1248,10 @@ as a Meta key and any number of multiple escapes is allowed." (exchange-point-and-mark)) (if (eq (preceding-char) ?\n) (viper-backward-char-carefully)) ; give back the newline - (if (viper= com ?c) - (viper-change (mark t) (point)) - (viper-change-subr (mark t) (point)))) + (if (eq viper-intermediate-command 'viper-repeat) + (viper-change-subr (mark t) (point)) + (viper-change (mark t) (point)) + )) ;; this is invoked by viper-substitute-line (defun viper-exec-Change (m-com com) @@ -1271,9 +1271,10 @@ as a Meta key and any number of multiple escapes is allowed." (setq viper-use-register nil))) (delete-region (mark t) (point))) (open-line 1) - (if (viper= com ?C) - (viper-change-state-to-insert) - (viper-yank-last-insertion))) + (if (eq viper-intermediate-command 'viper-repeat) + (viper-yank-last-insertion) + (viper-change-state-to-insert) + )) (defun viper-exec-delete (m-com com) (or (and (markerp viper-com-point) (marker-position viper-com-point)) @@ -1455,15 +1456,13 @@ as a Meta key and any number of multiple escapes is allowed." ;; this is the special command `#' (if (> com 128) (viper-special-prefix-com (- com 128)) - (let ((fn (aref viper-exec-array (if (< com 0) (- com) com)))) + (let ((fn (aref viper-exec-array com))) (if (null fn) (error "%c: %s" com viper-InvalidViCommand) (funcall fn m-com com)))) (if (viper-dotable-command-p com) (viper-set-destructive-command - (list m-com val - (if (viper-memq-char com (list ?c ?C ?!)) (- com) com) - reg nil nil))) + (list m-com val com reg nil nil))) )) @@ -1889,8 +1888,7 @@ Undo previous insertion and inserts new." (if (fboundp 'minibuffer-prompt-end) (delete-region (minibuffer-prompt-end) (point-max)) (erase-buffer)) - (insert initial))) - (viper-minibuffer-setup-sentinel)) + (insert initial)))) (defsubst viper-minibuffer-real-start () (if (fboundp 'minibuffer-prompt-end) @@ -1994,7 +1992,16 @@ problems." ;; KEYMAP is used, if given, instead of minibuffer-local-map. ;; INIT-MESSAGE is the message temporarily displayed after entering the ;; minibuffer. - (let ((minibuffer-setup-hook 'viper-minibuffer-standard-hook) + (let ((minibuffer-setup-hook + ;; stolen from add-hook + (let ((old + (if (boundp 'minibuffer-setup-hook) + minibuffer-setup-hook + nil))) + (cons + 'viper-minibuffer-standard-hook + (if (or (not (listp old)) (eq (car old) 'lambda)) + (list old) old)))) (val "") (padding "") temp-msg) @@ -2059,7 +2066,7 @@ problems." (let ((val (viper-p-val arg)) (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-insert val ?r nil nil nil)) - (if com + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (viper-yank-last-insertion)) (viper-change-state-to-insert)))) @@ -2071,7 +2078,7 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-append val ?r nil nil nil)) (if (not (eolp)) (forward-char)) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (viper-yank-last-insertion)) (viper-change-state-to-insert)))) @@ -2083,7 +2090,7 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-Append val ?r nil nil nil)) (end-of-line) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (viper-yank-last-insertion)) (viper-change-state-to-insert)))) @@ -2095,7 +2102,7 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-Insert val ?r nil nil nil)) (back-to-indentation) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (viper-yank-last-insertion)) (viper-change-state-to-insert)))) @@ -2107,26 +2114,15 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-open-line val ?r nil nil nil)) (let ((col (current-indentation))) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (end-of-line) (newline 1) - (if viper-auto-indent - (progn - (setq viper-cted t) - (if viper-electric-mode - (indent-according-to-mode) - (indent-to col)) - )) + (viper-indent-line col) (viper-yank-last-insertion)) (end-of-line) (newline 1) - (if viper-auto-indent - (progn - (setq viper-cted t) - (if viper-electric-mode - (indent-according-to-mode) - (indent-to col)))) + (viper-indent-line col) (viper-change-state-to-insert))))) (defun viper-Open-line (arg) @@ -2137,27 +2133,15 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-Open-line val ?r nil nil nil)) (let ((col (current-indentation))) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (beginning-of-line) (open-line 1) - (if viper-auto-indent - (progn - (setq viper-cted t) - (if viper-electric-mode - (indent-according-to-mode) - (indent-to col)) - )) + (viper-indent-line col) (viper-yank-last-insertion)) (beginning-of-line) (open-line 1) - (if viper-auto-indent - (progn - (setq viper-cted t) - (if viper-electric-mode - (indent-according-to-mode) - (indent-to col)) - )) + (viper-indent-line col) (viper-change-state-to-insert))))) (defun viper-open-line-at-point (arg) @@ -2168,13 +2152,14 @@ problems." (com (viper-getcom arg))) (viper-set-destructive-command (list 'viper-open-line-at-point val ?r nil nil nil)) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-loop val (open-line 1) (viper-yank-last-insertion)) (open-line 1) (viper-change-state-to-insert)))) +;; bound to s (defun viper-substitute (arg) "Substitute characters." (interactive "P") @@ -2182,9 +2167,10 @@ problems." (com (viper-getcom arg))) (push-mark nil t) (forward-char val) - (if (viper= com ?r) + (if (eq viper-intermediate-command 'viper-repeat) (viper-change-subr (mark t) (point)) (viper-change (mark t) (point))) + ;; com is set to ?r when we repeat this comand with dot (viper-set-destructive-command (list 'viper-substitute val ?r nil nil nil)) )) @@ -2356,7 +2342,7 @@ These keys are ESC, RET, and LineFeed" (if (eq this-command 'viper-intercept-ESC-key) (setq com 'viper-exit-insert-state) (viper-set-unread-command-events last-input-char) - (setq com (key-binding (read-key-sequence nil)))) + (setq com (key-binding (viper-read-key-sequence nil)))) (condition-case conds (command-execute com) @@ -2405,11 +2391,11 @@ These keys are ESC, RET, and LineFeed" (let ((val (viper-p-val arg)) (com (viper-getcom arg)) (len)) (viper-set-destructive-command (list 'viper-overwrite val ?r nil nil nil)) - (if com + (if (eq viper-intermediate-command 'viper-repeat) (progn ;; Viper saves inserted text in viper-last-insertion (setq len (length viper-last-insertion)) - (delete-char len) + (delete-char (min len (- (point-max) (point) 1))) (viper-loop val (viper-yank-last-insertion))) (setq last-command 'viper-overwrite) (viper-set-complex-command-for-undo) @@ -2476,7 +2462,7 @@ These keys are ESC, RET, and LineFeed" (defun viper-replace-char-subr (com arg) (let (char) - (setq char (if (viper= com ?r) + (setq char (if (eq viper-intermediate-command 'viper-repeat) viper-d-char (read-char))) (let (inhibit-quit) ; preserve consistency of undo-list and iso-accents @@ -2694,15 +2680,17 @@ On reaching beginning of line, stop and signal error." (com (viper-getcom arg))) (if com (viper-move-marker-locally 'viper-com-point (point))) (viper-forward-word-kernel val) - (if com (progn - (cond ((viper-memq-char com (list ?c (- ?c))) - (viper-separator-skipback-special 'twice viper-com-point)) - ;; Yank words including the whitespace, but not newline - ((viper-memq-char com (list ?y (- ?y))) - (viper-separator-skipback-special nil viper-com-point)) - ((viper-dotable-command-p com) - (viper-separator-skipback-special nil viper-com-point))) - (viper-execute-com 'viper-forward-word val com))))) + (if com + (progn + (cond ((viper-char-equal com ?c) + (viper-separator-skipback-special 'twice viper-com-point)) + ;; Yank words including the whitespace, but not newline + ((viper-char-equal com ?y) + (viper-separator-skipback-special nil viper-com-point)) + ((viper-dotable-command-p com) + (viper-separator-skipback-special nil viper-com-point))) + (viper-execute-com 'viper-forward-word val com))) + )) (defun viper-forward-Word (arg) @@ -2716,10 +2704,10 @@ On reaching beginning of line, stop and signal error." (viper-skip-nonseparators 'forward) (viper-skip-separators t)) (if com (progn - (cond ((viper-memq-char com (list ?c (- ?c))) + (cond ((viper-char-equal com ?c) (viper-separator-skipback-special 'twice viper-com-point)) ;; Yank words including the whitespace, but not newline - ((viper-memq-char com (list ?y (- ?y))) + ((viper-char-equal com ?y) (viper-separator-skipback-special nil viper-com-point)) ((viper-dotable-command-p com) (viper-separator-skipback-special nil viper-com-point))) @@ -4234,7 +4222,7 @@ and regexp replace." (interactive) (let ((char (read-char))) (cond ((and (<= ?a char) (<= char ?z)) - (point-to-register (1+ (- char ?a)))) + (point-to-register (viper-int-to-char (1+ (- char ?a))))) ((viper= char ?<) (viper-mark-beginning-of-buffer)) ((viper= char ?>) (viper-mark-end-of-buffer)) ((viper= char ?.) (viper-set-mark-if-necessary)) @@ -4304,7 +4292,7 @@ One can use `` and '' to temporarily jump 1 step back." (backward-char 1))) (cond ((viper-valid-register char '(letter)) (let* ((buff (current-buffer)) - (reg (1+ (- char ?a))) + (reg (viper-int-to-char (1+ (- char ?a)))) (text-marker (get-register reg))) ;; If marker points to file that had markers set (and those markers ;; were saved (as e.g., in session.el), then restore those markers @@ -4410,6 +4398,19 @@ One can use `` and '' to temporarily jump 1 step back." (if (or (bolp) (viper-looking-back "[^ \t]")) (setq viper-cted nil))))) +;; do smart indent +(defun viper-indent-line (col) + (if viper-auto-indent + (progn + (setq viper-cted t) + (if (and viper-electric-mode + (not (memq major-mode '(fundamental-mode + text-mode + paragraph-indent-text-mode)))) + (indent-according-to-mode) + (indent-to col))))) + + (defun viper-autoindent () "Auto Indentation, Vi-style." (interactive) @@ -4427,17 +4428,7 @@ One can use `` and '' to temporarily jump 1 step back." ;; use \n instead of newline, or else <Return> will move the insert point ;;(newline 1) (insert "\n") - (if viper-auto-indent - (progn - (setq viper-cted t) - (if (and viper-electric-mode - (not - (memq major-mode '(fundamental-mode - text-mode - paragraph-indent-text-mode )))) - (indent-according-to-mode) - (indent-to viper-current-indent)) - )) + (viper-indent-line viper-current-indent) )) @@ -4469,7 +4460,7 @@ One can use `` and '' to temporarily jump 1 step back." ((viper= ?\] reg) (viper-heading-end arg)) ((viper-valid-register reg '(letter)) - (let* ((val (get-register (1+ (- reg ?a)))) + (let* ((val (get-register (viper-int-to-char (1+ (- reg ?a))))) (buf (if (not (markerp val)) (error viper-EmptyTextmarker reg) (marker-buffer val))) @@ -4699,17 +4690,17 @@ Please, specify your level now: ") (if (and enforce-buffer (not (equal (current-buffer) (marker-buffer val)))) (error (concat viper-EmptyTextmarker " in this buffer") - (1- (+ char ?a)))) + (viper-int-to-char (1- (+ char ?a))))) (pop-to-buffer (marker-buffer val)) (goto-char val)) ((and (consp val) (eq (car val) 'file)) (find-file (cdr val))) (t - (error viper-EmptyTextmarker (1- (+ char ?a))))))) + (error viper-EmptyTextmarker (viper-int-to-char (1- (+ char ?a)))))))) (defun viper-save-kill-buffer () - "Save then kill current buffer. " + "Save then kill current buffer." (interactive) (if (< viper-expert-level 2) (save-buffers-kill-emacs) diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el index 3b01dd05241..398e5a937c6 100644 --- a/lisp/emulation/viper-ex.el +++ b/lisp/emulation/viper-ex.el @@ -122,6 +122,7 @@ ("k" (ex-mark) one-letter) ("kmark" (ex-mark)) ("m" "move") + ("make" (ex-compile)) ; old viper doesn't specify a default for "ma" so leave it undefined ("map" (ex-map)) ("mark" (ex-mark)) @@ -215,7 +216,7 @@ ;; If there is no appropriate key (no match or duplicate matches) return nil (defun ex-cmd-assoc (key list) (let ((entry (try-completion key list)) - result onelet) + result) (setq result (cond ((eq entry t) (assoc key list)) ((stringp entry) (or (ex-splice-args-in-1-letr-cmd key list) @@ -320,6 +321,11 @@ Don't put `-c' here, as it is added automatically." :type '(choice (const nil) string) :group 'viper-ex) +(defcustom ex-compile-command "make" + "The comand to run when the user types :make." + :type 'string + :group 'viper-ex) + (defcustom viper-glob-function (cond (ex-unix-type-shell 'viper-glob-unix-files) ((eq system-type 'emx) 'viper-glob-mswindows-files) ; OS/2 @@ -643,7 +649,7 @@ reversed." 'viper-ex-history ;; no default when working on region (if initial-str - "none" + nil (car viper-ex-history)) map (if initial-str @@ -855,8 +861,9 @@ reversed." (save-excursion (if (null ex-token) (exchange-point-and-mark) - (goto-char (viper-register-to-point - (1+ (- ex-token ?a)) 'enforce-buffer))) + (goto-char + (viper-register-to-point + (viper-int-to-char (1+ (- ex-token ?a))) 'enforce-buffer))) (setq address (point-marker))))) address)) @@ -1454,7 +1461,7 @@ reversed." (error "`%s' requires a following letter" ex-token)))) (save-excursion (goto-char (car ex-addresses)) - (point-to-register (1+ (- char ?a)))))) + (point-to-register (viper-int-to-char (1+ (- char ?a))))))) @@ -2159,6 +2166,29 @@ Please contact your system administrator. " (shell-command-on-region (point) (mark t) command t)) (goto-char beg))))) +(defun ex-compile () + "Reads args from the command line, then runs make with the args. +If no args are given, then it runs the last compile command. +Type 'mak ' (including the space) to run make with no args." + (let (args) + (save-window-excursion + (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name)) + (set-buffer viper-ex-work-buf) + (setq args (buffer-substring (point) (point-max))) + (end-of-line)) + ;; Remove the newline that may (will?) be at the end of the args + (if (string= "\n" (substring args (1- (length args)))) + (setq args (substring args 0 (1- (length args))))) + ;; Run last command if no args given, else construct a new command. + (setq args + (if (string= "" args) + (if (boundp 'compile-command) + compile-command + ex-compile-command) + (concat ex-compile-command " " args))) + (compile args) + )) + ;; Print line number (defun ex-line-no () (message "%d" diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el index 2df1b388755..73155a05798 100644 --- a/lisp/emulation/viper-keym.el +++ b/lisp/emulation/viper-keym.el @@ -445,8 +445,8 @@ Useful in some modes, such as Gnus, MH, etc.") (defvar viper-comint-mode-modifier-map (make-sparse-keymap) "This map modifies comint mode.") -(define-key viper-comint-mode-modifier-map "\C-m" 'comint-send-input) -(define-key viper-comint-mode-modifier-map "\C-d" 'comint-delchar-or-maybe-eof) +(define-key viper-comint-mode-modifier-map "\C-m" 'viper-exec-key-in-emacs) +(define-key viper-comint-mode-modifier-map "\C-d" 'viper-exec-key-in-emacs) (defvar viper-dired-modifier-map (make-sparse-keymap) "This map modifies Dired behavior.") diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el index a27f20b626f..cacd8debd46 100644 --- a/lisp/emulation/viper-util.el +++ b/lisp/emulation/viper-util.el @@ -1,4 +1,4 @@ -;;; viper-util.el --- utilities used by viper.el +;;; viper-util.el --- Utilities used by viper.el ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. @@ -103,16 +103,26 @@ (symbol-function (if viper-xemacs-p 'characterp 'integerp))) +(fset 'viper-int-to-char + (symbol-function + (if viper-xemacs-p 'int-to-char 'identity))) + ;; CHAR is supposed to be a char or an integer (positive or negative) ;; LIST is a list of chars, nil, and negative numbers -;; Check if CHAR is a member by trying to convert into integers, if necessary. +;; Check if CHAR is a member by trying to convert in characters, if necessary. ;; Introduced for compatibility with XEmacs, where integers are not the same as ;; chars. (defun viper-memq-char (char list) - (cond (viper-emacs-p (memq char list)) - ((and (integerp char) (>= char 0)) (memq (int-to-char char) list)) + (cond ((and (integerp char) (>= char 0)) + (memq (viper-int-to-char char) list)) ((memq char list)))) +;; Check if char-or-int and char are the same as characters +(defun viper-char-equal (char-or-int char) + (cond ((and (integerp char-or-int) (>= char-or-int 0)) + (= (viper-int-to-char char-or-int) char)) + ((eq char-or-int char)))) + ;; Like =, but accommodates null and also is t for eq-objects (defun viper= (char char1) (cond ((eq char char1) t) @@ -683,8 +693,13 @@ (and (featurep 'vc-hooks) ;; CVS files are considered not checked in (not (memq (vc-backend file) '(nil CVS))) - (not (memq (vc-state file) '(edited needs-merge))) - (not (stringp (vc-state file))))) + (if (fboundp 'vc-state) + (progn + (not (memq (vc-state file) '(edited needs-merge))) + (not (stringp (vc-state file)))) + ;; XEmacs has no vc-state + (not (vc-locking-user file))) + )) ;; checkout if visited file is checked in (defun viper-maybe-checkout (buf) @@ -926,7 +941,7 @@ help-char key) (use-global-map viper-overriding-map) (unwind-protect - (setq key (elt (read-key-sequence nil) 0)) + (setq key (elt (viper-read-key-sequence nil) 0)) (use-global-map global-map)) key)) diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index 792bb1578b0..277ae0c408e 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el @@ -1,4 +1,4 @@ -;;; viper.el --- a full-featured Vi emulator for GNU Emacs and XEmacs, +;;; viper.el --- A full-featured Vi emulator for GNU Emacs and XEmacs, ;; a VI Plan for Emacs Rescue, ;; and a venomous VI PERil. ;; Viper Is also a Package for Emacs Rebels. @@ -8,7 +8,7 @@ ;; Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01 Free Software Foundation, Inc. -(defconst viper-version "3.10 of March 3, 2001" +(defconst viper-version "3.11 of July 18, 2001" "The current version of Viper") ;; This file is part of GNU Emacs. @@ -401,6 +401,7 @@ widget." completion-list-mode diff-mode + idl-mode perl-mode cperl-mode @@ -446,6 +447,7 @@ unless it is coming up in a wrong Viper state." (defcustom viper-insert-state-mode-list '(internal-ange-ftp-mode comint-mode + inferior-emacs-lisp-mode eshell-mode shell-mode) "*A list of major modes that should come up in Vi Insert state." @@ -462,11 +464,14 @@ unless it is coming up in a wrong Viper state." (nth 0 triple) (nth 1 triple) (eval (nth 2 triple)))) viper-major-mode-modifier-list)) +;; We change standard bindings in some major mode, making them slightly +;; different than in "normal" vi/insert/emacs states (defcustom viper-major-mode-modifier-list '((help-mode emacs-state viper-slash-and-colon-map) (comint-mode insert-state viper-comint-mode-modifier-map) (comint-mode vi-state viper-comint-mode-modifier-map) (shell-mode insert-state viper-comint-mode-modifier-map) + (inferior-emacs-lisp-mode insert-state viper-comint-mode-modifier-map) (shell-mode vi-state viper-comint-mode-modifier-map) (ange-ftp-shell-mode insert-state viper-comint-mode-modifier-map) (ange-ftp-shell-mode vi-state viper-comint-mode-modifier-map) @@ -595,11 +600,23 @@ This startup message appears whenever you load Viper, unless you type `y' now." (if viper-xemacs-p (make-variable-buffer-local 'bar-cursor)) + (if (eq major-mode 'viper-mode) + (setq major-mode 'fundamental-mode)) (or (memq major-mode viper-emacs-state-mode-list) ; don't switch to Vi (memq major-mode viper-insert-state-mode-list) ; don't switch (viper-change-state-to-vi))))) + +;; Apply a little heuristic to invoke vi state on major-modes +;; that are not listed in viper-vi-state-mode-list +(defun this-major-mode-requires-vi-state (mode) + (cond ((memq mode viper-vi-state-mode-list) t) + ((memq mode viper-emacs-state-mode-list) nil) + ((memq mode viper-insert-state-mode-list) nil) + (t (and (eq (key-binding "a") 'self-insert-command) + (eq (key-binding " ") 'self-insert-command))))) + ;; This hook designed to enable Vi-style editing in comint-based modes." (defun viper-comint-mode-hook () @@ -760,7 +777,7 @@ remains buffer-local." (lambda (buf) (if (viper-buffer-live-p buf) (with-current-buffer buf - (cond ((and (memq major-mode viper-vi-state-mode-list) + (cond ((and (this-major-mode-requires-vi-state major-mode) (eq viper-current-state 'emacs-state)) (viper-mode)) ((memq major-mode viper-emacs-state-mode-list) @@ -798,6 +815,8 @@ remains buffer-local." ;; However, this has the effect that if the user didn't specify the ;; default mode, new buffers that fall back on the default will come up ;; in Fundamental Mode and Vi state. + ;; When viper-mode is executed in such a case, it will set the major mode + ;; back to fundamental-mode. (if (eq default-major-mode 'fundamental-mode) (setq default-major-mode 'viper-mode)) @@ -956,36 +975,16 @@ remains buffer-local." (setq global-mode-string (append '("" viper-mode-string) (cdr global-mode-string)))) - (defadvice read-key-sequence (around viper-read-keyseq-ad activate) - "Harness to work for Viper. This advice is harmless---don't worry!" - (let (inhibit-quit event keyseq) - (setq keyseq ad-do-it) - (setq event (if viper-xemacs-p - (elt keyseq 0) ; XEmacs returns vector of events - (elt (listify-key-sequence keyseq) 0))) - (if (viper-ESC-event-p event) - (let (unread-command-events) - (viper-set-unread-command-events keyseq) - (if (viper-fast-keysequence-p) - (let ((viper-vi-global-user-minor-mode nil) - (viper-vi-local-user-minor-mode nil) - (viper-replace-minor-mode nil) ; actually unnecessary - (viper-insert-global-user-minor-mode nil) - (viper-insert-local-user-minor-mode nil)) - (setq keyseq ad-do-it)) - (setq keyseq ad-do-it)))) - keyseq)) - (defadvice describe-key (before viper-read-keyseq-ad protect activate) - "Force to read key via `read-key-sequence'." + "Force to read key via `viper-read-key-sequence'." (interactive (list (viper-events-to-keys - (read-key-sequence "Describe key: "))))) + (viper-read-key-sequence "Describe key: "))))) (defadvice describe-key-briefly (before viper-read-keyseq-ad protect activate) - "Force to read key via `read-key-sequence'." + "Force to read key via `viper-read-key-sequence'." (interactive (list (viper-events-to-keys - (read-key-sequence "Describe key briefly: "))))) + (viper-read-key-sequence "Describe key briefly: "))))) (defadvice find-file (before viper-add-suffix-advice activate) @@ -1056,6 +1055,27 @@ remains buffer-local." ) ; end viper-non-hook-settings +;; Viperized read-key-sequence +(defun viper-read-key-sequence (prompt &optional continue-echo) + (let (inhibit-quit event keyseq) + (setq keyseq (read-key-sequence prompt continue-echo)) + (setq event (if viper-xemacs-p + (elt keyseq 0) ; XEmacs returns vector of events + (elt (listify-key-sequence keyseq) 0))) + (if (viper-ESC-event-p event) + (let (unread-command-events) + (viper-set-unread-command-events keyseq) + (if (viper-fast-keysequence-p) + (let ((viper-vi-global-user-minor-mode nil) + (viper-vi-local-user-minor-mode nil) + (viper-replace-minor-mode nil) ; actually unnecessary + (viper-insert-global-user-minor-mode nil) + (viper-insert-local-user-minor-mode nil)) + (setq keyseq (read-key-sequence prompt continue-echo))) + (setq keyseq (read-key-sequence prompt continue-echo))))) + keyseq)) + + ;; 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)) @@ -1259,7 +1279,7 @@ These two lines must come in the order given. (setq-default minor-mode-map-alist minor-mode-map-alist) )) -(if (and viper-mode (memq major-mode viper-vi-state-mode-list)) +(if (and viper-mode (this-major-mode-requires-vi-state major-mode)) (viper-mode)) (if viper-mode |