# HG changeset patch # User Michael Kifer # Date 865036973 0 # Node ID 1b06411ccc04e837ff445344742d634c62b43e61 # Parent 5c0bcd2a17160abde5a5505ee990e8d1e173f9d9 new version diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-ex.el --- a/lisp/emulation/viper-ex.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-ex.el Sat May 31 00:02:53 1997 +0000 @@ -1,6 +1,6 @@ ;;; viper-ex.el --- functions implementing the Ex commands for Viper -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -19,14 +19,35 @@ ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. +;; Code -;; Code +(provide 'viper-ex) + +;; Compiler pacifier +(defvar read-file-name-map) +(defvar vip-use-register) +(defvar vip-s-string) +(defvar vip-shift-width) +(defvar vip-ex-history) +(defvar vip-related-files-and-buffers-ring) +(defvar vip-local-search-start-marker) +(defvar vip-expert-level) +(defvar vip-custom-file-name) +(defvar vip-case-fold-search) + +(eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + (or (featurep 'viper-keym) + (load "viper-keym.el" nil nil 'nosuffix)) + (or (featurep 'viper) + (load "viper.el" nil nil 'nosuffix)) + )) +;; end pacifier (require 'viper-util) -;; Compiler pacifier -(defvar read-file-name-map) -;; end compiler pacifier ;;; Variables @@ -637,7 +658,8 @@ ;; Get an ex-address as a marker and set ex-flag if a flag is found (defun vip-get-ex-address () - (let ((address (point-marker)) (cont t)) + (let ((address (point-marker)) + (cont t)) (setq ex-token "") (setq ex-flag nil) (while cont @@ -1852,7 +1874,12 @@ (defun ex-write (q-flag) (vip-default-ex-addresses t) (vip-get-ex-file) - (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) + (let ((end (car ex-addresses)) + (beg (car (cdr ex-addresses))) + (orig-buf (current-buffer)) + (orig-buf-file-name (buffer-file-name)) + (orig-buf-name (buffer-name)) + (buff-changed-p (buffer-modified-p)) temp-buf writing-same-file region file-exists writing-whole-file) (if (> beg end) (error vip-FirstAddrExceedsSecond)) @@ -1875,8 +1902,9 @@ buffer-file-name (not (file-directory-p buffer-file-name))) (setq ex-file - (concat ex-file (file-name-nondirectory buffer-file-name)))) - + (concat (file-name-as-directory ex-file) + (file-name-nondirectory buffer-file-name)))) + (setq file-exists (file-exists-p ex-file) writing-same-file (string= ex-file (buffer-file-name))) @@ -1884,35 +1912,58 @@ (if (not (buffer-modified-p)) (message "(No changes need to be saved)") (save-buffer) - (ex-write-info file-exists ex-file beg end)) - ;; writing some other file or portion of the currents - ;; file---create temp buffer for it - ;; disable undo in that buffer, for efficiency - (buffer-disable-undo (setq temp-buf (create-file-buffer ex-file))) - (unwind-protect - (save-excursion - (if (and file-exists - (not writing-same-file) - (not (yes-or-no-p - (format "File %s exists. Overwrite? " ex-file)))) - (error "Quit") - (vip-enlarge-region beg end) - (setq region (buffer-substring (point) (mark t))) - (set-buffer temp-buf) - (set-visited-file-name ex-file) - (erase-buffer) - (if (and file-exists ex-append) - (insert-file-contents ex-file)) - (goto-char (point-max)) - (insert region) - (save-buffer) - (ex-write-info file-exists ex-file (point-min) (point-max)) - ) - (set-buffer temp-buf) - (set-buffer-modified-p nil) - (kill-buffer temp-buf) + (save-restriction + (widen) + (ex-write-info file-exists ex-file (point-min) (point-max)) + )) + ;; writing some other file or portion of the current file + (cond ((and file-exists + (not writing-same-file) + (not (yes-or-no-p + (format "File %s exists. Overwrite? " ex-file)))) + (error "Quit")) + ((and writing-whole-file (not ex-append)) + (unwind-protect + (progn + (set-visited-file-name ex-file) + (set-buffer-modified-p t) + (save-buffer)) + ;; restore the buffer file name + (set-visited-file-name orig-buf-file-name) + (set-buffer-modified-p buff-changed-p) + ;; If the buffer wasn't visiting a file, restore buffer name. + ;; Name could've been changed by packages such as uniquify. + (or orig-buf-file-name + (progn + (unlock-buffer) + (rename-buffer orig-buf-name)))) + (save-restriction + (widen) + (ex-write-info + file-exists ex-file (point-min) (point-max)))) + (t ; writing a region + (unwind-protect + (save-excursion + (vip-enlarge-region beg end) + (setq region (buffer-substring (point) (mark t))) + ;; create temp buffer for the region + (setq temp-buf (get-buffer-create " *ex-write*")) + (set-buffer temp-buf) + (set-visited-file-name ex-file 'noquerry) + (erase-buffer) + (if (and file-exists ex-append) + (insert-file-contents ex-file)) + (goto-char (point-max)) + (insert region) + (save-buffer) + (ex-write-info + file-exists ex-file (point-min) (point-max)) + )) + (set-buffer temp-buf) + (set-buffer-modified-p nil) + (kill-buffer temp-buf)) )) - ) + (set-buffer orig-buf) ;; this prevents the loss of data if writing part of the buffer (if (and (buffer-file-name) writing-same-file) (set-visited-file-modtime)) @@ -2024,6 +2075,4 @@ )) -(provide 'viper-ex) - ;;; viper-ex.el ends here diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-init.el --- a/lisp/emulation/viper-init.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-init.el Sat May 31 00:02:53 1997 +0000 @@ -0,0 +1,677 @@ +;;; viper-init.el --- some common definitions for Viper + +;; Copyright (C) 1997 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;; Code + +(provide 'viper-init) + +;; compiler pacifier +(defvar mark-even-if-inactive) +;; end pacifier + +;; Is it XEmacs? +(defconst vip-xemacs-p (string-match "\\(Lucid\\|XEmacs\\)" emacs-version)) +;; Is it Emacs? +(defconst vip-emacs-p (not vip-xemacs-p)) +;; Tell whether we are running as a window application or on a TTY +(defsubst vip-device-type () + (if vip-emacs-p + window-system + (device-type (selected-device)))) +;; in XEmacs: device-type is tty on tty and stream in batch. +(defun vip-window-display-p () + (and (vip-device-type) (not (memq (vip-device-type) '(tty stream pc))))) + +(defvar vip-ms-style-os-p (memq system-type '(ms-dos windows-nt windows-95)) + "Tells if Emacs is running under an MS-style OS: ms-dos, windows-nt, W95.") +(defvar vip-vms-os-p (memq system-type '(vax-vms axp-vms)) + "Tells if Emacs is running under VMS.") + +(defvar vip-force-faces nil + "If t, Viper will think that it is running on a display that supports faces. +This is provided as a temporary relief for users of face-capable displays +that Viper doesn't know about.") + +(defun vip-has-face-support-p () + (cond ((vip-window-display-p)) + (vip-force-faces) + (vip-emacs-p (memq (vip-device-type) '(pc))) + (vip-xemacs-p (memq (vip-device-type) '(tty pc))))) + +(defun vip-convert-standard-file-name (fname) + (if vip-emacs-p + (convert-standard-filename fname) + ;; hopefully, XEmacs adds this functionality + fname)) + + +;;; Macros + +(defmacro vip-deflocalvar (var default-value &optional documentation) + (` (progn + (defvar (, var) (, default-value) + (, (format "%s\n\(buffer local\)" documentation))) + (make-variable-buffer-local '(, var)) + ))) + +(defmacro vip-loop (count body) + "(vip-loop COUNT BODY) Execute BODY COUNT times." + (list 'let (list (list 'count count)) + (list 'while '(> count 0) + body + '(setq count (1- count)) + ))) + +(defmacro vip-buffer-live-p (buf) + (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf)))))) + +;; return buffer-specific macro definition, given a full macro definition +(defmacro vip-kbd-buf-alist (macro-elt) + (` (nth 1 (, macro-elt)))) +;; get a pair: (curr-buffer . macro-definition) +(defmacro vip-kbd-buf-pair (macro-elt) + (` (assoc (buffer-name) (vip-kbd-buf-alist (, macro-elt))))) +;; get macro definition for current buffer +(defmacro vip-kbd-buf-definition (macro-elt) + (` (cdr (vip-kbd-buf-pair (, macro-elt))))) + +;; return mode-specific macro definitions, given a full macro definition +(defmacro vip-kbd-mode-alist (macro-elt) + (` (nth 2 (, macro-elt)))) +;; get a pair: (major-mode . macro-definition) +(defmacro vip-kbd-mode-pair (macro-elt) + (` (assoc major-mode (vip-kbd-mode-alist (, macro-elt))))) +;; get macro definition for the current major mode +(defmacro vip-kbd-mode-definition (macro-elt) + (` (cdr (vip-kbd-mode-pair (, macro-elt))))) + +;; return global macro definition, given a full macro definition +(defmacro vip-kbd-global-pair (macro-elt) + (` (nth 3 (, macro-elt)))) +;; get global macro definition from an elt of macro-alist +(defmacro vip-kbd-global-definition (macro-elt) + (` (cdr (vip-kbd-global-pair (, macro-elt))))) + +;; last elt of a sequence +(defsubst vip-seq-last-elt (seq) + (elt seq (1- (length seq)))) + + +(defvar vip-minibuffer-overlay-priority 300) +(defvar vip-replace-overlay-priority 400) +(defvar vip-search-overlay-priority 500) + + +;;; Viper minor modes + +;; This is not local in Emacs, so we make it local. +;; This must be local because although the stack of minor modes can be the same +;; for all buffers, the associated *keymaps* can be different. In Viper, +;; vip-vi-local-user-map, vip-insert-local-user-map, and others can have +;; different keymaps for different buffers. +;; Also, the keymaps associated with vip-vi/insert-state-modifier-minor-mode +;; can be different. +(make-variable-buffer-local 'minor-mode-map-alist) + +;; Mode for vital things like \e, C-z. +(vip-deflocalvar vip-vi-intercept-minor-mode nil) + +(vip-deflocalvar vip-vi-basic-minor-mode nil + "Viper's minor mode for Vi bindings.") + +(vip-deflocalvar vip-vi-local-user-minor-mode nil + "Auxiliary minor mode for user-defined local bindings in Vi state.") + +(vip-deflocalvar vip-vi-global-user-minor-mode nil + "Auxiliary minor mode for user-defined global bindings in Vi state.") + +(vip-deflocalvar vip-vi-state-modifier-minor-mode nil + "Minor mode used to make major-mode-specific modification to Vi state.") + +(vip-deflocalvar vip-vi-diehard-minor-mode nil + "This minor mode is in effect when the user wants Viper to be Vi.") + +(vip-deflocalvar vip-vi-kbd-minor-mode nil + "Minor mode for Ex command macros in Vi state. +The corresponding keymap stores key bindings of Vi macros defined with +the Ex command :map.") + +;; Mode for vital things like \e, C-z. +(vip-deflocalvar vip-insert-intercept-minor-mode nil) + +(vip-deflocalvar vip-insert-basic-minor-mode nil + "Viper's minor mode for bindings in Insert mode.") + +(vip-deflocalvar vip-insert-local-user-minor-mode nil + "Auxiliary minor mode for buffer-local user-defined bindings in Insert state. +This is a way to overshadow normal Insert mode bindings locally to certain +designated buffers.") + +(vip-deflocalvar vip-insert-global-user-minor-mode nil + "Auxiliary minor mode for global user-defined bindings in Insert state.") + +(vip-deflocalvar vip-insert-state-modifier-minor-mode nil + "Minor mode used to make major-mode-specific modification to Insert state.") + +(vip-deflocalvar vip-insert-diehard-minor-mode nil + "Minor mode that simulates Vi very closely. +Not recommened, except for the novice user.") + +(vip-deflocalvar vip-insert-kbd-minor-mode nil +"Minor mode for Ex command macros Insert state. +The corresponding keymap stores key bindings of Vi macros defined with +the Ex command :map!.") + +(vip-deflocalvar vip-replace-minor-mode nil + "Minor mode in effect in replace state (cw, C, and the like commands).") + +;; Mode for vital things like \C-z and \C-x) +;; This is t, by default. So, any new buffer will have C-z defined as +;; switch to Vi, unless we switched states in this buffer +(vip-deflocalvar vip-emacs-intercept-minor-mode t) + +(vip-deflocalvar vip-emacs-local-user-minor-mode t + "Minor mode for local user bindings effective in Emacs state. +Users can use it to override Emacs bindings when Viper is in its Emacs +state.") + +(vip-deflocalvar vip-emacs-global-user-minor-mode t + "Minor mode for global user bindings in effect in Emacs state. +Users can use it to override Emacs bindings when Viper is in its Emacs +state.") + +(vip-deflocalvar vip-emacs-kbd-minor-mode t + "Minor mode for Vi style macros in Emacs state. +The corresponding keymap stores key bindings of Vi macros defined with +`vip-record-kbd-macro' command. There is no Ex-level command to do this +interactively.") + +(vip-deflocalvar vip-emacs-state-modifier-minor-mode t + "Minor mode used to make major-mode-specific modification to Emacs state. +For instance, a Vi purist may want to bind `dd' in Dired mode to a function +that deletes a file.") + +(vip-deflocalvar vip-vi-minibuffer-minor-mode nil + "Minor mode that forces Vi-style when the Minibuffer is in Vi state.") + +(vip-deflocalvar vip-insert-minibuffer-minor-mode nil + "Minor mode that forces Vi-style when the Minibuffer is in Insert state.") + + + +;; Some common error messages + +(defconst vip-SpuriousText "Spurious text after command" "") +(defconst vip-BadExCommand "Not an editor command" "") +(defconst vip-InvalidCommandArgument "Invalid command argument" "") +(defconst vip-NoPrevSearch "No previous search string" "") +(defconst vip-EmptyRegister "`%c': Nothing in this register" "") +(defconst vip-InvalidRegister "`%c': Invalid register" "") +(defconst vip-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "") +(defconst vip-InvalidTextmarker "`%c': Invalid text marker" "") +(defconst vip-InvalidViCommand "Invalid command" "") +(defconst vip-BadAddress "Ill-formed address" "") +(defconst vip-FirstAddrExceedsSecond "First address exceeds second" "") +(defconst vip-NoFileSpecified "No file specified" "") + +;; Is t until viper-mode executes for the very first time. +;; Prevents recursive descend into startup messages. +(defvar vip-first-time t) + +(defvar vip-expert-level 0 + "User's expert level. +The minor mode vip-vi-diehard-minor-mode is in effect when +vip-expert-level is 1 or 2 or when vip-want-emacs-keys-in-vi is t. +The minor mode vip-insert-diehard-minor-mode is in effect when +vip-expert-level is 1 or 2 or if vip-want-emacs-keys-in-insert is t. +Use `M-x vip-set-expert-level' to change this.") + +;; Max expert level supported by Viper. This is NOT a user option. +;; It is here to make it hard for the user from resetting it. +(defconst vip-max-expert-level 5) + +;; Contains user settings for vars affected by vip-set-expert-level function. +;; Not a user option. +(defvar vip-saved-user-settings nil) + + +;;; ISO characters + +(vip-deflocalvar vip-automatic-iso-accents nil + "*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state. +For some users, this behavior may be too primitive. In this case, use +insert/emacs/vi state hooks.") + + +;; VI-style Undo + +;; Used to 'undo' complex commands, such as replace and insert commands. +(vip-deflocalvar vip-undo-needs-adjustment nil) +(put 'vip-undo-needs-adjustment 'permanent-local t) + +;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a +;; complex command that must be undone atomically. If inserted, it is +;; erased by vip-change-state-to-vi and vip-repeat. +(defconst vip-buffer-undo-list-mark 'viper) + +(defvar vip-keep-point-on-undo nil + "*Non-nil means not to move point while undoing commands. +This style is different from Emacs and Vi. Try it to see if +it better fits your working style.") + +;; Replace mode and changing text + +;; Viper's own after/before change functions, which get vip-add-hook'ed to +;; Emacs's +(vip-deflocalvar vip-after-change-functions nil "") +(vip-deflocalvar vip-before-change-functions nil "") +(vip-deflocalvar vip-post-command-hooks nil "") +(vip-deflocalvar vip-pre-command-hooks nil "") + +;; Can be used to pass global states around for short period of time +(vip-deflocalvar vip-intermediate-command nil "") + +;; Indicates that the current destructive command has started in replace mode. +(vip-deflocalvar vip-began-as-replace nil "") + +(defvar vip-allow-multiline-replace-regions t + "If non-nil, Viper will allow multi-line replace regions. +This is an extension to standard Vi. +If nil, commands that attempt to replace text spanning multiple lines first +delete the text being replaced, as in standard Vi.") + +(defvar vip-replace-overlay-cursor-color "Red" + "*Cursor color to use in Replace state") +(defvar vip-insert-state-cursor-color nil + "Cursor color for Viper insert state.") +(put 'vip-insert-state-cursor-color 'permanent-local t) +;; place to save cursor colow when switching to insert mode +(vip-deflocalvar vip-saved-cursor-color nil "") + +(vip-deflocalvar vip-replace-overlay nil "") +(put 'vip-replace-overlay 'permanent-local t) + +(defvar vip-replace-overlay-pixmap "gray3" + "Pixmap to use for search face on non-color displays.") +(defvar vip-search-face-pixmap "gray3" + "Pixmap to use for search face on non-color displays.") + + +(defvar vip-replace-region-end-delimiter "$" + "A string marking the end of replacement regions. +It is used only with TTYs or if `vip-use-replace-region-delimiters' +is non-nil.") +(defvar vip-replace-region-start-delimiter "" + "A string marking the beginning of replacement regions. +It is used only with TTYs or if `vip-use-replace-region-delimiters' +is non-nil.") +(defvar vip-use-replace-region-delimiters (not (vip-has-face-support-p)) + "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and +`vip-replace-region-start-delimiter' to delimit replacement regions, even on +color displays. By default, the delimiters are used only on TTYs.") + +;; XEmacs requires glyphs +(if vip-xemacs-p + (progn + (or (glyphp vip-replace-region-end-delimiter) + (setq vip-replace-region-end-delimiter + (make-glyph vip-replace-region-end-delimiter))) + (or (glyphp vip-replace-region-start-delimiter) + (setq vip-replace-region-start-delimiter + (make-glyph vip-replace-region-start-delimiter))) + )) + + +;; These are local marker that must be initialized to nil and moved with +;; `vip-move-marker-locally' +;; +;; Remember the last position inside the replace region. +(vip-deflocalvar vip-last-posn-in-replace-region nil) +;; Remember the last position while inserting +(vip-deflocalvar vip-last-posn-while-in-insert-state nil) +(put 'vip-last-posn-in-replace-region 'permanent-local t) +(put 'vip-last-posn-while-in-insert-state 'permanent-local t) + +(vip-deflocalvar vip-sitting-in-replace nil "") +(put 'vip-sitting-in-replace 'permanent-local t) + +;; Remember the number of characters that have to be deleted in replace +;; mode to compensate for the inserted characters. +(vip-deflocalvar vip-replace-chars-to-delete 0 "") +(vip-deflocalvar vip-replace-chars-deleted 0 "") + +;; Insertion ring and command ring +(defvar vip-insertion-ring-size 14 + "The size of the insertion ring.") +;; The insertion ring. +(defvar vip-insertion-ring nil) +;; This is temp insertion ring. Used to do rotation for display purposes. +;; When rotation just started, it is initialized to vip-insertion-ring. +(defvar vip-temp-insertion-ring nil) +(defvar vip-last-inserted-string-from-insertion-ring "") + +(defvar vip-command-ring-size 14 + "The size of the command ring.") +;; The command ring. +(defvar vip-command-ring nil) +;; This is temp command ring. Used to do rotation for display purposes. +;; When rotation just started, it is initialized to vip-command-ring. +(defvar vip-temp-command-ring nil) + +;; Modes and related variables + +;; Current mode. One of: `emacs-state', `vi-state', `insert-state' +(vip-deflocalvar vip-current-state 'emacs-state) + + +;; Autoindent in insert + +;; Variable that keeps track of whether C-t has been pressed. +(vip-deflocalvar vip-cted nil "") + +;; Preserve the indent value, used by C-d in insert mode. +(vip-deflocalvar vip-current-indent 0) + +;; Whether to preserve the indent, used by C-d in insert mode. +(vip-deflocalvar vip-preserve-indent nil) + +(vip-deflocalvar vip-auto-indent nil + "*Autoindent if t.") +(vip-deflocalvar vip-electric-mode t + "*If t, enable electric behavior. +Currently only enables auto-indentation `according to mode'.") + +(defconst vip-shift-width 8 + "*The shiftwidth variable.") + +;; Variables for repeating destructive commands + +(defconst vip-keep-point-on-repeat t + "*If t, don't move point when repeating previous command. +This is useful for doing repeated changes with the '.' key. +The user can change this to nil, if she likes when the cursor moves +to a new place after repeating previous Vi command.") + +;; Remember insert point as a marker. This is a local marker that must be +;; initialized to nil and moved with `vip-move-marker-locally'. +(vip-deflocalvar vip-insert-point nil) +(put 'vip-insert-point 'permanent-local t) + +;; This remembers the point before dabbrev-expand was called. +;; If vip-insert-point turns out to be bigger than that, it is reset +;; back to vip-pre-command-point. +;; The reason this is needed is because dabbrev-expand (and possibly +;; others) may jump to before the insertion point, delete something and +;; then reinsert a bigger piece. For instance: bla^blo +;; If dabbrev-expand is called after `blo' and ^ undicates vip-insert-point, +;; then point jumps to the beginning of `blo'. If expansion is found, `blablo' +;; is deleted, and we have |^, where | denotes point. Next, dabbrev-expand +;; will insert the expansion, and we get: blablo^ +;; Whatever we insert next goes before the ^, i.e., before the +;; vip-insert-point marker. So, Viper will think that nothing was +;; inserted. Remembering the orig position of the marker circumvents the +;; problem. +;; We don't know of any command, except dabbrev-expand, that has the same +;; problem. However, the same trick can be used if such a command is +;; discovered later. +;; +(vip-deflocalvar vip-pre-command-point nil) +(put 'vip-pre-command-point 'permanent-local t) ; this is probably an overkill + +;; This is used for saving inserted text. +(defvar vip-last-insertion nil) + +;; Remembers the last replaced region. +(defvar vip-last-replace-region "") + +;; Remember com point as a marker. +;; This is a local marker. Should be moved with `vip-move-marker-locally' +(vip-deflocalvar vip-com-point nil) + +;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys) +;; It is used to re-execute last destructive command. +;; M-COM is a Lisp symbol representing the function to be executed. +;; VAL is the prefix argument that was used with that command. +;; COM is an internal descriptor, such as ?r, ?c, ?C, which contains +;; additional information on how the function in M-COM is to be handled. +;; REG is the register used by command +;; INSERTED-TEXT is text inserted by that command (in case of o, c, C, i, r +;; commands). +;; COMMAND-KEYS are the keys that were typed to invoke the command. +(defvar vip-d-com nil) + +;; The character remembered by the Vi `r' command. +(defvar vip-d-char nil) + +;; Name of register to store deleted or yanked strings +(defvar vip-use-register nil) + + + +;; Variables for Moves and Searches + +;; For use by `;' command. +(defvar vip-f-char nil) + +;; For use by `.' command. +(defvar vip-F-char nil) + +;; For use by `;' command. +(defvar vip-f-forward nil) + +;; For use by `;' command. +(defvar vip-f-offset nil) + +;; Last search string +(defvar vip-s-string "") + +(defvar vip-quote-string "> " + "String inserted at the beginning of quoted region.") + +;; If t, search is forward. +(defvar vip-s-forward nil) + +(defconst vip-case-fold-search nil + "*If not nil, search ignores cases.") + +(defconst vip-re-search t + "*If not nil, search is reg-exp search, otherwise vanilla search.") + +(defvar vip-search-scroll-threshold 2 + "*If search lands within this threshnold from the window top/bottom, +the window will be scrolled up or down appropriately, to reveal context. +If you want Viper search to behave as usual in Vi, set this variable to a +negative number.") + +(defconst vip-re-query-replace t + "*If t then do regexp replace, if nil then do string replace.") + +(defconst vip-re-replace t + "*If t, do regexp replace. nil means do string replace.") + +(defvar vip-parse-sexp-ignore-comments t + "*If t, `%' ignores the parentheses that occur inside comments.") + +(vip-deflocalvar vip-ex-style-motion t + "*Ex-style: the commands l,h do not cross lines, etc.") + +(vip-deflocalvar vip-ex-style-editing-in-insert t + "*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc. +Note: this doesn't preclude ^H and ^? from deleting characters by moving +past the insertion point. This is a feature, not a bug. ") + +(vip-deflocalvar vip-delete-backwards-in-replace nil + "*If t, DEL key will delete characters while moving the cursor backwards. +If nil, the cursor will move backwards without deleting anything.") + +(defconst vip-buffer-search-char nil + "*Key bound for buffer-searching.") + +(defconst vip-search-wrap-around-t t + "*If t, search wraps around.") + +(vip-deflocalvar vip-related-files-and-buffers-ring nil + "*Ring of file and buffer names that are considered to be related to the +current buffer. +These buffers can be cycled through via :R and :P commands.") +(put 'vip-related-files-and-buffers-ring 'permanent-local t) + +;; Used to find out if we are done with searching the current buffer. +(vip-deflocalvar vip-local-search-start-marker nil) +;; As above, but global +(defvar vip-search-start-marker (make-marker)) + +;; the search overlay +(vip-deflocalvar vip-search-overlay nil) + + +(defvar vip-heading-start + (concat "^\\s-*(\\s-*defun\\s-\\|" ; lisp + "^{\\s-*$\\|^[_a-zA-Z][^()]*[()].*{\\s-*$\\|" ; C/C++ + "^\\s-*class.*{\\|^\\s-*struct.*{\\|^\\s-*enum.*{\\|" + "^\\\\[sb][a-z]*{.*}\\s-*$\\|" ; latex + "^@node\\|@table\\|^@m?enu\\|^@itemize\\|^@if\\|" ; texinfo + "^.+:-") ; prolog + "*Regexps for Headings. Used by \[\[ and \]\].") + +(defvar vip-heading-end + (concat "^}\\|" ; C/C++ + "^\\\\end{\\|" ; latex + "^@end \\|" ; texinfo + ")\n\n[ \t\n]*\\|" ; lisp + "\\.\\s-*$") ; prolog + "*Regexps to end Headings/Sections. Used by \[\].") + + +;; These two vars control the interaction of jumps performed by ' and `. +;; In this new version, '' doesn't erase the marks set by ``, so one can +;; use both kinds of jumps interchangeably and without loosing positions +;; inside the lines. + +;; Remembers position of the last jump done using ``'. +(vip-deflocalvar vip-last-jump nil) +;; Remembers position of the last jump done using `''. +(vip-deflocalvar vip-last-jump-ignore 0) + +;; History variables + +;; History of search strings. +(defvar vip-search-history (list "")) +;; History of query-replace strings used as a source. +(defvar vip-replace1-history nil) +;; History of query-replace strings used as replacement. +(defvar vip-replace2-history nil) +;; History of region quoting strings. +(defvar vip-quote-region-history (list vip-quote-string)) +;; History of Ex-style commands. +(defvar vip-ex-history nil) +;; History of shell commands. +(defvar vip-shell-history nil) + + +;; Last shell command. There are two of these, one for Ex (in viper-ex) +;; and one for Vi. + +;; Last shell command executed with ! command. +(defvar vip-last-shell-com nil) + + + +;;; Miscellaneous + +;; don't bark when mark is inactive +(setq mark-even-if-inactive t) + +(defvar vip-inhibit-startup-message nil + "Whether Viper startup message should be inhibited.") + +(defvar vip-always t + "t means, arrange that vi-state will be a default.") + +(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.vip") + "Viper customisation file. +This variable must be set _before_ loading Viper.") + + +(defvar vip-spell-function 'ispell-region + "Spell function used by #s command to spell.") + +(defvar vip-tags-file-name "TAGS" + "The tags file used by Viper.") + +;; Indicates if we are in the middle of executing a command that takes another +;; command as an argument, e.g., cw, dw, etc. +(defvar vip-inside-command-argument-action nil) + +;; Minibuffer + +(defvar vip-vi-style-in-minibuffer t + "If t, use vi-style editing in minibuffer. +Should be set in `~/.vip' file.") + +;; overlay used in the minibuffer to indicate which state it is in +(vip-deflocalvar vip-minibuffer-overlay nil) + +;; Hook, specific to Viper, which is run just *before* exiting the minibuffer. +;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run +;; *after* exiting the minibuffer +(defvar vip-minibuffer-exit-hook nil) + +;; setup emacs-supported vi-style feel +(setq next-line-add-newlines nil + require-final-newline t) + +(make-variable-buffer-local 'require-final-newline) + + +;; Mode line +(defconst vip-vi-state-id " " + "Mode line tag identifying the Vi mode of Viper.") +(defconst vip-emacs-state-id " " + "Mode line tag identifying the Emacs mode of Viper.") +(defconst vip-insert-state-id " " + "Mode line tag identifying the Insert mode of Viper.") +(defconst vip-replace-state-id " " + "Mode line tag identifying the Replace mode of Viper.") + +;; Viper changes the default mode-line-buffer-identification +(setq-default mode-line-buffer-identification '(" %b")) + +;; Variable displaying the current Viper state in the mode line. +(vip-deflocalvar vip-mode-string vip-emacs-state-id) +(or (memq 'vip-mode-string global-mode-string) + (setq global-mode-string + (append '("" vip-mode-string) (cdr global-mode-string)))) + + +(defvar vip-vi-state-hook nil + "*Hooks run just before the switch to Vi mode is completed.") +(defvar vip-insert-state-hook nil + "*Hooks run just before the switch to Insert mode is completed.") +(defvar vip-replace-state-hook nil + "*Hooks run just before the switch to Replace mode is completed.") +(defvar vip-emacs-state-hook nil + "*Hooks run just before the switch to Emacs mode is completed.") + +(defvar vip-load-hook nil + "Hooks run just after loading Viper.") + +;;; viper-ex.el ends here diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-keym.el --- a/lisp/emulation/viper-keym.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-keym.el Sat May 31 00:02:53 1997 +0000 @@ -1,6 +1,6 @@ ;;; viper-keym.el --- Viper keymaps -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -21,8 +21,26 @@ ;; Code +(provide 'viper-keym) + +;; compiler pacifier +(defvar vip-always) +(defvar vip-current-state) +(defvar vip-mode-string) +(defvar vip-expert-level) +(defvar vip-ex-style-editing-in-insert) +(defvar vip-ex-style-motion) + +(eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + )) +;; end pacifier + (require 'viper-util) + ;;; Variables (defvar vip-toggle-key "\C-z" @@ -35,6 +53,29 @@ "Key used to ESC. Must be set in .vip file or prior to loading Viper. This setting cannot be changed interactively.") + +;;; Emacs keys in other states. + +(defvar vip-want-emacs-keys-in-insert t + "*Set to nil if you want complete Vi compatibility in insert mode. +Complete compatibility with Vi is not recommended for power use of Viper.") + +(defvar vip-want-emacs-keys-in-vi t + "*Set to nil if you want complete Vi compatibility in Vi mode. +Full Vi compatibility is not recommended for power use of Viper.") + +(defvar vip-no-multiple-ESC t + "*If true, multiple ESC in Vi mode will cause bell to ring. +This is set to t on a windowing terminal and to 'twice on a dumb +terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this +enables cursor keys and is generally more convenient, as terminals usually +don't have a convenient Meta key. +Setting vip-no-multiple-ESC to nil will allow as many multiple ESC, +as is allowed by the major mode in effect.") + +(defvar vip-want-ctl-h-help nil + "*If t then C-h is bound to help-command in insert mode, if nil then it is +bound to delete-backward-char.") ;;; Keymaps @@ -199,8 +240,8 @@ ;; Replace keymap (define-key vip-replace-map "\C-t" 'vip-forward-indent) -(define-key vip-replace-map "\C-j" 'vip-replace-state-exit-cmd) -(define-key vip-replace-map "\C-m" 'vip-replace-state-exit-cmd) +(define-key vip-replace-map "\C-j" 'vip-replace-state-carriage-return) +(define-key vip-replace-map "\C-m" 'vip-replace-state-carriage-return) (define-key vip-replace-map "\C-?" 'vip-del-backward-char-in-replace) @@ -400,6 +441,10 @@ (define-key vip-dired-modifier-map ":" 'vip-ex) (define-key vip-dired-modifier-map "/" 'vip-search-forward) +(defvar vip-help-modifier-map (make-sparse-keymap) + "This map modifies Help mode behavior.") +(define-key vip-help-modifier-map "q" (if vip-xemacs-p 'help-mode-quit)) + ;;; Code @@ -579,6 +624,4 @@ alist)) -(provide 'viper-keym) - ;;; viper-keym.el ends here diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-macs.el --- a/lisp/emulation/viper-macs.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-macs.el Sat May 31 00:02:53 1997 +0000 @@ -1,6 +1,6 @@ ;;; viper-macs.el --- functions implementing keyboard macros for Viper -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -21,6 +21,26 @@ ;; Code +(provide 'viper-macs) + +;; compiler pacifier +(defvar vip-ex-work-buf) +(defvar vip-custom-file-name) +(defvar vip-current-state) + +(eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + (or (featurep 'viper-keym) + (load "viper-keym.el" nil nil 'nosuffix)) + (or (featurep 'viper-mous) + (load "viper-mous.el" nil nil 'nosuffix)) + (or (featurep 'viper) + (load "viper.el" nil nil 'nosuffix)) + )) +;; end pacifier + (require 'viper-util) (require 'viper-keym) @@ -938,6 +958,4 @@ (call-last-kbd-macro))) -(provide 'viper-macs) - ;;; viper-macs.el ends here diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-mous.el --- a/lisp/emulation/viper-mous.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-mous.el Sat May 31 00:02:53 1997 +0000 @@ -1,6 +1,6 @@ ;;; viper-mous.el --- mouse support for Viper -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -21,12 +21,28 @@ ;; Code -(require 'viper-util) +(provide 'viper-mous) ;; compiler pacifier (defvar double-click-time) (defvar mouse-track-multi-click-time) -;; end compiler pacifier +(defvar vip-search-start-marker) +(defvar vip-local-search-start-marker) +(defvar vip-search-history) +(defvar vip-s-string) +(defvar vip-re-search) + +(eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + (or (featurep 'viper) + (load "viper.el" nil nil 'nosuffix)) + )) +;; end pacifier + +(require 'viper-util) + ;;; Variables @@ -453,7 +469,4 @@ ))) - -(provide 'viper-mous) - ;;; viper-mous.el ends here diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper-util.el --- a/lisp/emulation/viper-util.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper-util.el Sat May 31 00:02:53 1997 +0000 @@ -1,6 +1,6 @@ ;;; viper-util.el --- Utilities used by viper.el -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. @@ -22,140 +22,44 @@ ;; Code -(require 'ring) - ;; Compiler pacifier (defvar vip-overriding-map) (defvar pm-color-alist) (defvar zmacs-region-stays) -(defvar vip-search-face) (defvar vip-minibuffer-current-face) (defvar vip-minibuffer-insert-face) (defvar vip-minibuffer-vi-face) (defvar vip-minibuffer-emacs-face) (defvar vip-replace-overlay-face) -(defvar vip-minibuffer-overlay) -(defvar vip-replace-overlay) -(defvar vip-search-overlay) -(defvar vip-replace-overlay-cursor-color) -(defvar vip-intermediate-command) -(defvar vip-use-replace-region-delimiters) (defvar vip-fast-keyseq-timeout) -(defvar vip-related-files-and-buffers-ring) -;; end compiler pacifier +(defvar ex-unix-type-shell) +(defvar ex-unix-type-shell-options) +(defvar vip-ex-tmp-buf-name) + +(require 'cl) +(require 'ring) -;; Is it XEmacs? -(defconst vip-xemacs-p (string-match "\\(Lucid\\|XEmacs\\)" emacs-version)) -;; Is it Emacs? -(defconst vip-emacs-p (not vip-xemacs-p)) -;; Tell whether we are running as a window application or on a TTY -(defsubst vip-device-type () - (if vip-emacs-p - window-system - (device-type (selected-device)))) -;; in XEmacs: device-type is tty on tty and stream in batch. -(defun vip-window-display-p () - (and (vip-device-type) (not (memq (vip-device-type) '(tty stream pc))))) +(and noninteractive + (eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-init) + (load "viper-init.el" nil nil 'nosuffix)) + ))) +;; end pacifier -(defvar vip-ms-style-os-p (memq system-type '(ms-dos windows-nt windows-95)) - "Tells if Emacs is running under an MS-style OS: ms-dos, windows-nt, W95.") -(defvar vip-vms-os-p (memq system-type '(vax-vms axp-vms)) - "Tells if Emacs is running under VMS.") +(require 'viper-init) -(defvar vip-force-faces nil - "If t, Viper will think that it is running on a display that supports faces. -This is provided as a temporary relief for users of face-capable displays -that Viper doesn't know about.") - -(defun vip-has-face-support-p () - (cond ((vip-window-display-p)) - (vip-force-faces) - (vip-emacs-p (memq (vip-device-type) '(pc))) - (vip-xemacs-p (memq (vip-device-type) '(tty pc))))) -;;; Macros - -(defmacro vip-deflocalvar (var default-value &optional documentation) - (` (progn - (defvar (, var) (, default-value) - (, (format "%s\n\(buffer local\)" documentation))) - (make-variable-buffer-local '(, var)) - ))) - -(defmacro vip-loop (count body) - "(vip-loop COUNT BODY) Execute BODY COUNT times." - (list 'let (list (list 'count count)) - (list 'while '(> count 0) - body - '(setq count (1- count)) - ))) +;;; XEmacs support -(defmacro vip-buffer-live-p (buf) - (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf)))))) - -;; return buffer-specific macro definition, given a full macro definition -(defmacro vip-kbd-buf-alist (macro-elt) - (` (nth 1 (, macro-elt)))) -;; get a pair: (curr-buffer . macro-definition) -(defmacro vip-kbd-buf-pair (macro-elt) - (` (assoc (buffer-name) (vip-kbd-buf-alist (, macro-elt))))) -;; get macro definition for current buffer -(defmacro vip-kbd-buf-definition (macro-elt) - (` (cdr (vip-kbd-buf-pair (, macro-elt))))) - -;; return mode-specific macro definitions, given a full macro definition -(defmacro vip-kbd-mode-alist (macro-elt) - (` (nth 2 (, macro-elt)))) -;; get a pair: (major-mode . macro-definition) -(defmacro vip-kbd-mode-pair (macro-elt) - (` (assoc major-mode (vip-kbd-mode-alist (, macro-elt))))) -;; get macro definition for the current major mode -(defmacro vip-kbd-mode-definition (macro-elt) - (` (cdr (vip-kbd-mode-pair (, macro-elt))))) - -;; return global macro definition, given a full macro definition -(defmacro vip-kbd-global-pair (macro-elt) - (` (nth 3 (, macro-elt)))) -;; get global macro definition from an elt of macro-alist -(defmacro vip-kbd-global-definition (macro-elt) - (` (cdr (vip-kbd-global-pair (, macro-elt))))) - -;; last elt of a sequence -(defsubst vip-seq-last-elt (seq) - (elt seq (1- (length seq)))) - -;; Check if arg is a valid character for register -;; TYPE is a list that can contain `letter', `Letter', and `digit'. -;; Letter means lowercase letters, Letter means uppercase letters, and -;; digit means digits from 1 to 9. -;; If TYPE is nil, then down/uppercase letters and digits are allowed. -(defun vip-valid-register (reg &optional type) - (or type (setq type '(letter Letter digit))) - (or (if (memq 'letter type) - (and (<= ?a reg) (<= reg ?z))) - (if (memq 'digit type) - (and (<= ?1 reg) (<= reg ?9))) - (if (memq 'Letter type) - (and (<= ?A reg) (<= reg ?Z))) +;; A fix for NeXT Step +;; Should probably be eliminated in later versions. +(if (and (vip-window-display-p) (eq (vip-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)) )) - -;; checks if object is a marker, has a buffer, and points to within that buffer -(defun vip-valid-marker (marker) - (if (and (markerp marker) (marker-buffer marker)) - (let ((buf (marker-buffer marker)) - (pos (marker-position marker))) - (save-excursion - (set-buffer buf) - (and (<= pos (point-max)) (<= (point-min) pos)))))) - - -(defvar vip-minibuffer-overlay-priority 300) -(defvar vip-replace-overlay-priority 400) -(defvar vip-search-overlay-priority 500) - - -;;; XEmacs support (if vip-xemacs-p (progn @@ -189,6 +93,7 @@ (fset 'vip-color-defined-p (symbol-function 'x-color-defined-p)) ))) + (fset 'vip-characterp (symbol-function (if vip-xemacs-p 'characterp 'integerp))) @@ -242,7 +147,7 @@ (modify-frame-parameters (selected-frame) (list (cons 'cursor-color new-color))))) -(defsubst vip-save-cursor-color () +(defun vip-save-cursor-color () (if (and (vip-window-display-p) (vip-color-display-p)) (let ((color (vip-get-cursor-color))) (if (and (stringp color) (vip-color-defined-p color) @@ -257,6 +162,115 @@ (vip-change-cursor-color vip-saved-cursor-color)) +;; Face-saving tricks + +(defvar vip-search-face + (if (vip-has-face-support-p) + (progn + (make-face 'vip-search-face) + (vip-hide-face 'vip-search-face) + (or (face-differs-from-default-p 'vip-search-face) + ;; face wasn't set in .vip or .Xdefaults + (if (vip-can-use-colors "Black" "khaki") + (progn + (set-face-background 'vip-search-face "khaki") + (set-face-foreground 'vip-search-face "Black")) + (set-face-underline-p 'vip-search-face t) + (vip-set-face-pixmap 'vip-search-face vip-search-face-pixmap))) + 'vip-search-face)) + "*Face used to flash out the search pattern.") + +(defvar vip-replace-overlay-face + (if (vip-has-face-support-p) + (progn + (make-face 'vip-replace-overlay-face) + (vip-hide-face 'vip-replace-overlay-face) + (or (face-differs-from-default-p 'vip-replace-overlay-face) + (progn + (if (vip-can-use-colors "darkseagreen2" "Black") + (progn + (set-face-background + 'vip-replace-overlay-face "darkseagreen2") + (set-face-foreground 'vip-replace-overlay-face "Black"))) + (set-face-underline-p 'vip-replace-overlay-face t) + (vip-set-face-pixmap + 'vip-replace-overlay-face vip-replace-overlay-pixmap))) + 'vip-replace-overlay-face)) + "*Face for highlighting replace regions on a window display.") + +(defvar vip-minibuffer-emacs-face + (if (vip-has-face-support-p) + (progn + (make-face 'vip-minibuffer-emacs-face) + (vip-hide-face 'vip-minibuffer-emacs-face) + (or (face-differs-from-default-p 'vip-minibuffer-emacs-face) + ;; face wasn't set in .vip or .Xdefaults + (if vip-vi-style-in-minibuffer + ;; emacs state is an exception in the minibuffer + (if (vip-can-use-colors "darkseagreen2" "Black") + (progn + (set-face-background + 'vip-minibuffer-emacs-face "darkseagreen2") + (set-face-foreground + 'vip-minibuffer-emacs-face "Black")) + (copy-face 'modeline 'vip-minibuffer-emacs-face)) + ;; emacs state is the main state in the minibuffer + (if (vip-can-use-colors "Black" "pink") + (progn + (set-face-background 'vip-minibuffer-emacs-face "pink") + (set-face-foreground + 'vip-minibuffer-emacs-face "Black")) + (copy-face 'italic 'vip-minibuffer-emacs-face)) + )) + 'vip-minibuffer-emacs-face)) + "Face used in the Minibuffer when it is in Emacs state.") + +(defvar vip-minibuffer-insert-face + (if (vip-has-face-support-p) + (progn + (make-face 'vip-minibuffer-insert-face) + (vip-hide-face 'vip-minibuffer-insert-face) + (or (face-differs-from-default-p 'vip-minibuffer-insert-face) + (if vip-vi-style-in-minibuffer + (if (vip-can-use-colors "Black" "pink") + (progn + (set-face-background 'vip-minibuffer-insert-face "pink") + (set-face-foreground + 'vip-minibuffer-insert-face "Black")) + (copy-face 'italic 'vip-minibuffer-insert-face)) + ;; If Insert state is an exception + (if (vip-can-use-colors "darkseagreen2" "Black") + (progn + (set-face-background + 'vip-minibuffer-insert-face "darkseagreen2") + (set-face-foreground + 'vip-minibuffer-insert-face "Black")) + (copy-face 'modeline 'vip-minibuffer-insert-face)) + (vip-italicize-face 'vip-minibuffer-insert-face))) + 'vip-minibuffer-insert-face)) + "Face used in the Minibuffer when it is in Insert state.") + +(defvar vip-minibuffer-vi-face + (if (vip-has-face-support-p) + (progn + (make-face 'vip-minibuffer-vi-face) + (vip-hide-face 'vip-minibuffer-vi-face) + (or (face-differs-from-default-p 'vip-minibuffer-vi-face) + (if vip-vi-style-in-minibuffer + (if (vip-can-use-colors "Black" "grey") + (progn + (set-face-background 'vip-minibuffer-vi-face "grey") + (set-face-foreground 'vip-minibuffer-vi-face "Black")) + (copy-face 'bold 'vip-minibuffer-vi-face)) + (copy-face 'bold 'vip-minibuffer-vi-face) + (invert-face 'vip-minibuffer-vi-face))) + 'vip-minibuffer-vi-face)) + "Face used in the Minibuffer when it is in Vi state.") + +;; the current face to be used in the minibuffer +(vip-deflocalvar vip-minibuffer-current-face vip-minibuffer-emacs-face "") + + ;; Check the current version against the major and minor version numbers ;; using op: cur-vers op major.minor If emacs-major-version or ;; emacs-minor-version are not defined, we assume that the current version @@ -285,8 +299,8 @@ ((memq op '(< <=)) t)))) ;;;; warn if it is a wrong version of emacs -;;(if (or (vip-check-version '< 19 29 'emacs) -;; (vip-check-version '< 19 12 'xemacs)) +;;(if (or (vip-check-version '< 19 35 'emacs) +;; (vip-check-version '< 19 15 'xemacs)) ;; (progn ;; (with-output-to-temp-buffer " *vip-info*" ;; (switch-to-buffer " *vip-info*") @@ -295,9 +309,9 @@ ;; ;;This version of Viper requires ;; -;;\t Emacs 19.29 and higher +;;\t Emacs 19.35 and higher ;;\t OR -;;\t XEmacs 19.12 and higher +;;\t XEmacs 19.15 and higher ;; ;;It is unlikely to work under Emacs version %s ;;that you are using... " emacs-version)) @@ -556,13 +570,6 @@ (setq tmp (cdr tmp))) (reverse (apply 'append tmp2)))) -(defun vip-convert-standard-file-name (fname) - (if vip-emacs-p - (convert-standard-filename fname) - ;; hopefully, XEmacs adds this functionality - fname)) - - ;;; Insertion ring @@ -774,7 +781,15 @@ (vip-overlay-put vip-replace-overlay (if vip-emacs-p 'evaporate 'detachable) nil) (vip-overlay-put - vip-replace-overlay 'priority vip-replace-overlay-priority)) + vip-replace-overlay 'priority vip-replace-overlay-priority) + ;; If Emacs will start supporting overlay maps, as it currently supports + ;; text-property maps, we could do away with vip-replace-minor-mode and + ;; just have keymap attached to replace overlay. + ;;(vip-overlay-put + ;; vip-replace-overlay + ;; (if vip-xemacs-p 'keymap 'local-map) + ;; vip-replace-map) + ) (if (vip-has-face-support-p) (vip-overlay-put vip-replace-overlay 'face vip-replace-overlay-face)) (vip-save-cursor-color) @@ -782,7 +797,7 @@ ) -(defsubst vip-set-replace-overlay-glyphs (before-glyph after-glyph) +(defun vip-set-replace-overlay-glyphs (before-glyph after-glyph) (if (or (not (vip-has-face-support-p)) vip-use-replace-region-delimiters) (let ((before-name (if vip-xemacs-p 'begin-glyph 'before-string)) @@ -790,7 +805,7 @@ (vip-overlay-put vip-replace-overlay before-name before-glyph) (vip-overlay-put vip-replace-overlay after-name after-glyph)))) -(defsubst vip-hide-replace-overlay () +(defun vip-hide-replace-overlay () (vip-set-replace-overlay-glyphs nil nil) (vip-restore-cursor-color-after-replace) (vip-restore-cursor-color-after-insert) @@ -861,7 +876,15 @@ (let ((ESC-keys '(?\e (control \[) escape)) (key (vip-event-key event))) (member key ESC-keys))) - + +;; checks if object is a marker, has a buffer, and points to within that buffer +(defun vip-valid-marker (marker) + (if (and (markerp marker) (marker-buffer marker)) + (let ((buf (marker-buffer marker)) + (pos (marker-position marker))) + (save-excursion + (set-buffer buf) + (and (<= pos (point-max)) (<= (point-min) pos)))))) (defsubst vip-mark-marker () (if vip-xemacs-p @@ -886,6 +909,21 @@ (if vip-xemacs-p (setq zmacs-region-stays t))) +;; Check if arg is a valid character for register +;; TYPE is a list that can contain `letter', `Letter', and `digit'. +;; Letter means lowercase letters, Letter means uppercase letters, and +;; digit means digits from 1 to 9. +;; If TYPE is nil, then down/uppercase letters and digits are allowed. +(defun vip-valid-register (reg &optional type) + (or type (setq type '(letter Letter digit))) + (or (if (memq 'letter type) + (and (<= ?a reg) (<= reg ?z))) + (if (memq 'digit type) + (and (<= ?1 reg) (<= reg ?9))) + (if (memq 'Letter type) + (and (<= ?A reg) (<= reg ?Z))) + )) + (defsubst vip-events-to-keys (events) (cond (vip-xemacs-p (events-to-keys events)) @@ -947,6 +985,12 @@ (set hook hook-value)))) +;; it is suggested that an event must be copied before it is assigned to +;; last-command-event in XEmacs +(defun vip-copy-event (event) + (if vip-xemacs-p + (copy-event event) + event)) ;; like read-event, but in XEmacs also try to convert to char, if possible (defun vip-read-event-convert-to-char () @@ -979,40 +1023,44 @@ (defun vip-event-key (event) (or (and event (eventp event)) (error "vip-event-key: Wrong type argument, eventp, %S" event)) - (let ((mod (event-modifiers event)) - basis) - (setq basis - (cond - (vip-xemacs-p - (cond ((key-press-event-p event) - (event-key event)) - ((button-event-p event) - (concat "mouse-" (prin1-to-string (event-button event)))) - (t - (error "vip-event-key: Unknown event, %S" event)))) - (t - ;; Emacs doesn't handle capital letters correctly, since - ;; \S-a isn't considered the same as A (it behaves as - ;; plain `a' instead). So we take care of this here - (cond ((and (vip-characterp event) (<= ?A event) (<= event ?Z)) - (setq mod nil - event event)) - ;; Emacs has the oddity whereby characters 128+char - ;; represent M-char *if* this appears inside a string. - ;; So, we convert them manually to (meta char). - ((and (vip-characterp event) (< ?\C-? event) (<= event 255)) - (setq mod '(meta) - event (- event ?\C-? 1))) - (t (event-basic-type event))) - ))) - (if (vip-characterp basis) - (setq basis - (if (= basis ?\C-?) - (list 'control '\?) ; taking care of an emacs bug - (intern (char-to-string basis))))) - (if mod - (append mod (list basis)) - basis))) + (when (cond (vip-xemacs-p (or (key-press-event-p event) + (mouse-event-p event))) + (t t)) + (let ((mod (event-modifiers event)) + basis) + (setq basis + (cond + (vip-xemacs-p + (cond ((key-press-event-p event) + (event-key event)) + ((button-event-p event) + (concat "mouse-" (prin1-to-string (event-button event)))) + (t + (error "vip-event-key: Unknown event, %S" event)))) + (t + ;; Emacs doesn't handle capital letters correctly, since + ;; \S-a isn't considered the same as A (it behaves as + ;; plain `a' instead). So we take care of this here + (cond ((and (vip-characterp event) (<= ?A event) (<= event ?Z)) + (setq mod nil + event event)) + ;; Emacs has the oddity whereby characters 128+char + ;; represent M-char *if* this appears inside a string. + ;; So, we convert them manually to (meta char). + ((and (vip-characterp event) + (< ?\C-? event) (<= event 255)) + (setq mod '(meta) + event (- event ?\C-? 1))) + (t (event-basic-type event))) + ))) + (if (vip-characterp basis) + (setq basis + (if (= basis ?\C-?) + (list 'control '\?) ; taking care of an emacs bug + (intern (char-to-string basis))))) + (if mod + (append mod (list basis)) + basis)))) (defun vip-key-to-emacs-key (key) (let (key-name char-p modifiers mod-char-list base-key base-key-name) @@ -1179,7 +1227,7 @@ (append (vconcat vip-ALPHA-char-class) nil))))) )) -(defsubst vip-looking-at-separator () +(defun vip-looking-at-separator () (let ((char (char-after (point)))) (if char (or (eq char ?\n) ; RET is always a separator in Vi @@ -1189,7 +1237,7 @@ (defsubst vip-looking-at-alphasep (&optional addl-chars) (or (vip-looking-at-separator) (vip-looking-at-alpha addl-chars))) -(defsubst vip-skip-alpha-forward (&optional addl-chars) +(defun vip-skip-alpha-forward (&optional addl-chars) (or (stringp addl-chars) (setq addl-chars "")) (vip-skip-syntax 'forward @@ -1200,7 +1248,7 @@ (concat vip-strict-ALPHA-chars addl-chars)) (t addl-chars)))) -(defsubst vip-skip-alpha-backward (&optional addl-chars) +(defun vip-skip-alpha-backward (&optional addl-chars) (or (stringp addl-chars) (setq addl-chars "")) (vip-skip-syntax 'backward @@ -1227,14 +1275,14 @@ (funcall func (concat "^" vip-SEP-char-class) (vip-line-pos (if (eq direction 'forward) 'end 'start))))) -(defsubst vip-skip-nonalphasep-forward () +(defun vip-skip-nonalphasep-forward () (if (eq vip-syntax-preference 'strict-vi) (skip-chars-forward (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars)) (skip-syntax-forward (concat "^" vip-ALPHA-char-class vip-SEP-char-class) (vip-line-pos 'end)))) -(defsubst vip-skip-nonalphasep-backward () +(defun vip-skip-nonalphasep-backward () (if (eq vip-syntax-preference 'strict-vi) (skip-chars-backward (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars)) diff -r 5c0bcd2a1716 -r 1b06411ccc04 lisp/emulation/viper.el --- a/lisp/emulation/viper.el Fri May 30 23:37:13 1997 +0000 +++ b/lisp/emulation/viper.el Sat May 31 00:02:53 1997 +0000 @@ -6,9 +6,9 @@ ;; Keywords: emulations ;; Author: Michael Kifer -;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. - -(defconst viper-version "2.91 of August 5, 1996" +;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. + +(defconst viper-version "2.93 of May 20, 1997" "The current version of Viper") ;; This file is part of GNU Emacs. @@ -300,7 +300,7 @@ (require 'cl) (require 'ring) -(require 'viper-util) +(provide 'viper) ;; Compiler pacifier (defvar vip-minibuffer-current-face) @@ -309,596 +309,32 @@ (defvar vip-minibuffer-emacs-face) (defvar iso-accents-mode) (defvar zmacs-region-stays) -;; end pacifier - - -;;; Variables - -;; Is t until viper-mode executes for the very first time. -;; Prevents recursive descend into startup messages. -(defvar vip-first-time t) - -(defvar vip-expert-level 0 - "User's expert level. -The minor mode vip-vi-diehard-minor-mode is in effect when -vip-expert-level is 1 or 2 or when vip-want-emacs-keys-in-vi is t. -The minor mode vip-insert-diehard-minor-mode is in effect when -vip-expert-level is 1 or 2 or if vip-want-emacs-keys-in-insert is t. -Use `M-x vip-set-expert-level' to change this.") - -;; Max expert level supported by Viper. This is NOT a user option. -;; It is here to make it hard for the user from resetting it. -(defconst vip-max-expert-level 5) - -;; Contains user settings for vars affected by vip-set-expert-level function. -;; Not a user option. -(defvar vip-saved-user-settings nil) - - -;;; Viper minor modes - -;; This is not local in Emacs, so we make it local. -;; This must be local because although the stack of minor modes can be the same -;; for all buffers, the associated *keymaps* can be different. In Viper, -;; vip-vi-local-user-map, vip-insert-local-user-map, and others can have -;; different keymaps for different buffers. -;; Also, the keymaps associated with vip-vi/insert-state-modifier-minor-mode -;; can be different. -(make-variable-buffer-local 'minor-mode-map-alist) - -;; Mode for vital things like \e, C-z. -(vip-deflocalvar vip-vi-intercept-minor-mode nil) - -(vip-deflocalvar vip-vi-basic-minor-mode nil - "Viper's minor mode for Vi bindings.") - -(vip-deflocalvar vip-vi-local-user-minor-mode nil - "Auxiliary minor mode for user-defined local bindings in Vi state.") - -(vip-deflocalvar vip-vi-global-user-minor-mode nil - "Auxiliary minor mode for user-defined global bindings in Vi state.") - -(vip-deflocalvar vip-vi-state-modifier-minor-mode nil - "Minor mode used to make major-mode-specific modification to Vi state.") - -(vip-deflocalvar vip-vi-diehard-minor-mode nil - "This minor mode is in effect when the user wants Viper to be Vi.") - -(vip-deflocalvar vip-vi-kbd-minor-mode nil - "Minor mode for Ex command macros in Vi state. -The corresponding keymap stores key bindings of Vi macros defined with -the Ex command :map.") - -;; Mode for vital things like \e, C-z. -(vip-deflocalvar vip-insert-intercept-minor-mode nil) - -(vip-deflocalvar vip-insert-basic-minor-mode nil - "Viper's minor mode for bindings in Insert mode.") - -(vip-deflocalvar vip-insert-local-user-minor-mode nil - "Auxiliary minor mode for buffer-local user-defined bindings in Insert state. -This is a way to overshadow normal Insert mode bindings locally to certain -designated buffers.") - -(vip-deflocalvar vip-insert-global-user-minor-mode nil - "Auxiliary minor mode for global user-defined bindings in Insert state.") - -(vip-deflocalvar vip-insert-state-modifier-minor-mode nil - "Minor mode used to make major-mode-specific modification to Insert state.") - -(vip-deflocalvar vip-insert-diehard-minor-mode nil - "Minor mode that simulates Vi very closely. -Not recommened, except for the novice user.") - -(vip-deflocalvar vip-insert-kbd-minor-mode nil -"Minor mode for Ex command macros Insert state. -The corresponding keymap stores key bindings of Vi macros defined with -the Ex command :map!.") - -(vip-deflocalvar vip-replace-minor-mode nil - "Minor mode in effect in replace state (cw, C, and the like commands).") - -;; Mode for vital things like \C-z and \C-x) -;; This is t, by default. So, any new buffer will have C-z defined as -;; switch to Vi, unless we switched states in this buffer -(vip-deflocalvar vip-emacs-intercept-minor-mode t) - -(vip-deflocalvar vip-emacs-local-user-minor-mode t - "Minor mode for local user bindings effective in Emacs state. -Users can use it to override Emacs bindings when Viper is in its Emacs -state.") - -(vip-deflocalvar vip-emacs-global-user-minor-mode t - "Minor mode for global user bindings in effect in Emacs state. -Users can use it to override Emacs bindings when Viper is in its Emacs -state.") - -(vip-deflocalvar vip-emacs-kbd-minor-mode t - "Minor mode for Vi style macros in Emacs state. -The corresponding keymap stores key bindings of Vi macros defined with -`vip-record-kbd-macro' command. There is no Ex-level command to do this -interactively.") - -(vip-deflocalvar vip-emacs-state-modifier-minor-mode t - "Minor mode used to make major-mode-specific modification to Emacs state. -For instance, a Vi purist may want to bind `dd' in Dired mode to a function -that deletes a file.") - - - -;;; ISO characters - -(vip-deflocalvar vip-automatic-iso-accents nil - "*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state. -For some users, this behavior may be too primitive. In this case, use -insert/emacs/vi state hooks.") - - -;;; Emacs keys in other states. - -(defvar vip-want-emacs-keys-in-insert t - "*Set to nil if you want complete Vi compatibility in insert mode. -Complete compatibility with Vi is not recommended for power use of Viper.") - -(defvar vip-want-emacs-keys-in-vi t - "*Set to nil if you want complete Vi compatibility in Vi mode. -Full Vi compatibility is not recommended for power use of Viper.") - - - -;; VI-style Undo - -;; Used to 'undo' complex commands, such as replace and insert commands. -(vip-deflocalvar vip-undo-needs-adjustment nil) -(put 'vip-undo-needs-adjustment 'permanent-local t) - -;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a -;; complex command that must be undone atomically. If inserted, it is -;; erased by vip-change-state-to-vi and vip-repeat. -(defconst vip-buffer-undo-list-mark 'viper) - -(defvar vip-keep-point-on-undo nil - "*Non-nil means not to move point while undoing commands. -This style is different from Emacs and Vi. Try it to see if -it better fits your working style.") - -;; Replace mode and changing text - -;; Viper's own after/before change functions, which get vip-add-hook'ed to -;; Emacs's -(vip-deflocalvar vip-after-change-functions nil "") -(vip-deflocalvar vip-before-change-functions nil "") -(vip-deflocalvar vip-post-command-hooks nil "") -(vip-deflocalvar vip-pre-command-hooks nil "") - -;; Can be used to pass global states around for short period of time -(vip-deflocalvar vip-intermediate-command nil "") - -;; Indicates that the current destructive command has started in replace mode. -(vip-deflocalvar vip-began-as-replace nil "") - -(defvar vip-replace-overlay-cursor-color "Red" - "*Cursor color to use in Replace state") -(defvar vip-insert-state-cursor-color nil - "Cursor color for Viper insert state.") -(put 'vip-insert-state-cursor-color 'permanent-local t) -;; place to save cursor colow when switching to insert mode -(vip-deflocalvar vip-saved-cursor-color nil "") - -(vip-deflocalvar vip-replace-overlay nil "") -(put 'vip-replace-overlay 'permanent-local t) - -(defvar vip-replace-overlay-pixmap "gray3" - "Pixmap to use for search face on non-color displays.") -(defvar vip-search-face-pixmap "gray3" - "Pixmap to use for search face on non-color displays.") - - -(defun vip-set-replace-overlay-face () - (if (vip-has-face-support-p) - (defvar vip-replace-overlay-face - (progn - (make-face 'vip-replace-overlay-face) - (vip-hide-face 'vip-replace-overlay-face) - (or (face-differs-from-default-p 'vip-replace-overlay-face) - (progn - (if (vip-can-use-colors "darkseagreen2" "Black") - (progn - (set-face-background - 'vip-replace-overlay-face "darkseagreen2") - (set-face-foreground 'vip-replace-overlay-face "Black"))) - (set-face-underline-p 'vip-replace-overlay-face t) - (vip-set-face-pixmap - 'vip-replace-overlay-face vip-replace-overlay-pixmap))) - 'vip-replace-overlay-face) - "*Face for highlighting replace regions on a window display.") +(defvar mark-even-if-inactive) + +(eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + (or (featurep 'viper-keym) + (load "viper-keym.el" nil nil 'nosuffix)) + (or (featurep 'viper-mous) + (load "viper-mous.el" nil nil 'nosuffix)) + (or (featurep 'viper-macs) + (load "viper-macs.el" nil nil 'nosuffix)) + (or (featurep 'viper-ex) + (load "viper-ex.el" nil nil 'nosuffix)) )) - -(defvar vip-replace-region-end-delimiter "$" - "A string marking the end of replacement regions. -It is used only with TTYs or if `vip-use-replace-region-delimiters' -is non-nil.") -(defvar vip-replace-region-start-delimiter "" - "A string marking the beginning of replacement regions. -It is used only with TTYs or if `vip-use-replace-region-delimiters' -is non-nil.") -(defvar vip-use-replace-region-delimiters (not (vip-has-face-support-p)) - "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and -`vip-replace-region-start-delimiter' to delimit replacement regions, even on -color displays. By default, the delimiters are used only on TTYs.") - -;; XEmacs requires glyphs -(if vip-xemacs-p - (progn - (or (glyphp vip-replace-region-end-delimiter) - (setq vip-replace-region-end-delimiter - (make-glyph vip-replace-region-end-delimiter))) - (or (glyphp vip-replace-region-start-delimiter) - (setq vip-replace-region-start-delimiter - (make-glyph vip-replace-region-start-delimiter))) - )) - - -;; These are local marker that must be initialized to nil and moved with -;; `vip-move-marker-locally' -;; -;; Remember the last position inside the replace region. -(vip-deflocalvar vip-last-posn-in-replace-region nil) -;; Remember the last position while inserting -(vip-deflocalvar vip-last-posn-while-in-insert-state nil) -(put 'vip-last-posn-in-replace-region 'permanent-local t) -(put 'vip-last-posn-while-in-insert-state 'permanent-local t) - -(vip-deflocalvar vip-sitting-in-replace nil "") -(put 'vip-sitting-in-replace 'permanent-local t) - -;; Remember the number of characters that have to be deleted in replace -;; mode to compensate for the inserted characters. -(vip-deflocalvar vip-replace-chars-to-delete 0 "") -(vip-deflocalvar vip-replace-chars-deleted 0 "") - -;; Insertion ring and command ring -(defvar vip-insertion-ring-size 14 - "The size of the insertion ring.") -;; The insertion ring. -(defvar vip-insertion-ring nil) -;; This is temp insertion ring. Used to do rotation for display purposes. -;; When rotation just started, it is initialized to vip-insertion-ring. -(defvar vip-temp-insertion-ring nil) -(defvar vip-last-inserted-string-from-insertion-ring "") - -(defvar vip-command-ring-size 14 - "The size of the command ring.") -;; The command ring. -(defvar vip-command-ring nil) -;; This is temp command ring. Used to do rotation for display purposes. -;; When rotation just started, it is initialized to vip-command-ring. -(defvar vip-temp-command-ring nil) - -;; Modes and related variables - -;; Current mode. One of: `emacs-state', `vi-state', `insert-state' -(vip-deflocalvar vip-current-state 'emacs-state) - -(defvar vip-no-multiple-ESC t - "*If true, multiple ESC in Vi mode will cause bell to ring. -This is set to t on a windowing terminal and to 'twice on a dumb -terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this -enables cursor keys and is generally more convenient, as terminals usually -don't have a convenient Meta key. -Setting vip-no-multiple-ESC to nil will allow as many multiple ESC, -as is allowed by the major mode in effect.") - - -(defvar vip-want-ctl-h-help nil - "*If t then C-h is bound to help-command in insert mode, if nil then it is -bound to delete-backward-char.") - -;; Autoindent in insert - -;; Variable that keeps track of whether C-t has been pressed. -(vip-deflocalvar vip-cted nil "") - -;; Preserve the indent value, used by C-d in insert mode. -(vip-deflocalvar vip-current-indent 0) - -;; Whether to preserve the indent, used by C-d in insert mode. -(vip-deflocalvar vip-preserve-indent nil) - -(vip-deflocalvar vip-auto-indent nil - "*Autoindent if t.") -(vip-deflocalvar vip-electric-mode t - "*If t, enable electric behavior. -Currently only enables auto-indentation `according to mode'.") - -(defconst vip-shift-width 8 - "*The shiftwidth variable.") - -;; Variables for repeating destructive commands - -(defconst vip-keep-point-on-repeat t - "*If t, don't move point when repeating previous command. -This is useful for doing repeated changes with the '.' key. -The user can change this to nil, if she likes when the cursor moves -to a new place after repeating previous Vi command.") - -;; Remember insert point as a marker. This is a local marker that must be -;; initialized to nil and moved with `vip-move-marker-locally'. -(vip-deflocalvar vip-insert-point nil) -(put 'vip-insert-point 'permanent-local t) - -;; This remembers the point before dabbrev-expand was called. -;; If vip-insert-point turns out to be bigger than that, it is reset -;; back to vip-pre-command-point. -;; The reason this is needed is because dabbrev-expand (and possibly -;; others) may jump to before the insertion point, delete something and -;; then reinsert a bigger piece. For instance: bla^blo -;; If dabbrev-expand is called after `blo' and ^ undicates vip-insert-point, -;; then point jumps to the beginning of `blo'. If expansion is found, `blablo' -;; is deleted, and we have |^, where | denotes point. Next, dabbrev-expand -;; will insert the expansion, and we get: blablo^ -;; Whatever we insert next goes before the ^, i.e., before the -;; vip-insert-point marker. So, Viper will think that nothing was -;; inserted. Remembering the orig position of the marker circumvents the -;; problem. -;; We don't know of any command, except dabbrev-expand, that has the same -;; problem. However, the same trick can be used if such a command is -;; discovered later. -;; -(vip-deflocalvar vip-pre-command-point nil) -(put 'vip-pre-command-point 'permanent-local t) ; this is probably an overkill - -;; This is used for saving inserted text. -(defvar vip-last-insertion nil) - -;; Remembers the last replaced region. -(defvar vip-last-replace-region "") - -;; Remember com point as a marker. -;; This is a local marker. Should be moved with `vip-move-marker-locally' -(vip-deflocalvar vip-com-point nil) - -;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys) -;; It is used to re-execute last destructive command. -;; M-COM is a Lisp symbol representing the function to be executed. -;; VAL is the prefix argument that was used with that command. -;; COM is an internal descriptor, such as ?r, ?c, ?C, which contains -;; additional information on how the function in M-COM is to be handled. -;; REG is the register used by command -;; INSERTED-TEXT is text inserted by that command (in case of o, c, C, i, r -;; commands). -;; COMMAND-KEYS are the keys that were typed to invoke the command. -(defvar vip-d-com nil) - -;; The character remembered by the Vi `r' command. -(defvar vip-d-char nil) - -;; Name of register to store deleted or yanked strings -(defvar vip-use-register nil) - - - -;; Variables for Moves and Searches - -;; For use by `;' command. -(defvar vip-f-char nil) - -;; For use by `.' command. -(defvar vip-F-char nil) - -;; For use by `;' command. -(defvar vip-f-forward nil) - -;; For use by `;' command. -(defvar vip-f-offset nil) - -;; Last search string -(defvar vip-s-string "") - -(defvar vip-quote-string "> " - "String inserted at the beginning of quoted region.") - -;; If t, search is forward. -(defvar vip-s-forward nil) - -(defconst vip-case-fold-search nil - "*If not nil, search ignores cases.") - -(defconst vip-re-search t - "*If not nil, search is reg-exp search, otherwise vanilla search.") - -(defvar vip-adjust-window-after-search t - "*If not nil, pull the window up or down, depending on the direction of the -search, if search ends up near the bottom or near the top of the window.") - -(defconst vip-re-query-replace t - "*If t then do regexp replace, if nil then do string replace.") - -(defconst vip-re-replace t - "*If t, do regexp replace. nil means do string replace.") - -(vip-deflocalvar vip-ex-style-motion t - "*Ex-style: the commands l,h do not cross lines, etc.") - -(vip-deflocalvar vip-ex-style-editing-in-insert t - "*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc. -Note: this doesn't preclude ^H and ^? from deleting characters by moving -past the insertion point. This is a feature, not a bug. ") - -(vip-deflocalvar vip-delete-backwards-in-replace nil - "*If t, DEL key will delete characters while moving the cursor backwards. -If nil, the cursor will move backwards without deleting anything.") - -(defconst vip-buffer-search-char nil - "*Key bound for buffer-searching.") - -(defconst vip-search-wrap-around-t t - "*If t, search wraps around.") - -(vip-deflocalvar vip-related-files-and-buffers-ring nil - "*Ring of file and buffer names that are considered to be related to the -current buffer. -These buffers can be cycled through via :R and :P commands.") -(put 'vip-related-files-and-buffers-ring 'permanent-local t) - -;; Used to find out if we are done with searching the current buffer. -(vip-deflocalvar vip-local-search-start-marker nil) -;; As above, but global -(defvar vip-search-start-marker (make-marker)) - -;; the search overlay -(vip-deflocalvar vip-search-overlay nil) - - -(defvar vip-heading-start - (concat "^\\s-*(\\s-*defun\\s-\\|" ; lisp - "^{\\s-*$\\|^[_a-zA-Z][^()]*[()].*{\\s-*$\\|" ; C/C++ - "^\\s-*class.*{\\|^\\s-*struct.*{\\|^\\s-*enum.*{\\|" - "^\\\\[sb][a-z]*{.*}\\s-*$\\|" ; latex - "^@node\\|@table\\|^@m?enu\\|^@itemize\\|^@if\\|" ; texinfo - "^.+:-") ; prolog - "*Regexps for Headings. Used by \[\[ and \]\].") - -(defvar vip-heading-end - (concat "^}\\|" ; C/C++ - "^\\\\end{\\|" ; latex - "^@end \\|" ; texinfo - ")\n\n[ \t\n]*\\|" ; lisp - "\\.\\s-*$") ; prolog - "*Regexps to end Headings/Sections. Used by \[\].") - - -;; These two vars control the interaction of jumps performed by ' and `. -;; In this new version, '' doesn't erase the marks set by ``, so one can -;; use both kinds of jumps interchangeably and without loosing positions -;; inside the lines. - -;; Remembers position of the last jump done using ``'. -(vip-deflocalvar vip-last-jump nil) -;; Remembers position of the last jump done using `''. -(vip-deflocalvar vip-last-jump-ignore 0) - -;; Some common error messages - -(defconst vip-SpuriousText "Spurious text after command" "") -(defconst vip-BadExCommand "Not an editor command" "") -(defconst vip-InvalidCommandArgument "Invalid command argument" "") -(defconst vip-NoPrevSearch "No previous search string" "") -(defconst vip-EmptyRegister "`%c': Nothing in this register" "") -(defconst vip-InvalidRegister "`%c': Invalid register" "") -(defconst vip-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "") -(defconst vip-InvalidTextmarker "`%c': Invalid text marker" "") -(defconst vip-InvalidViCommand "Invalid command" "") -(defconst vip-BadAddress "Ill-formed address" "") -(defconst vip-FirstAddrExceedsSecond "First address exceeds second" "") -(defconst vip-NoFileSpecified "No file specified" "") - - -;; History variables - -;; History of search strings. -(defvar vip-search-history (list "")) -;; History of query-replace strings used as a source. -(defvar vip-replace1-history nil) -;; History of query-replace strings used as replacement. -(defvar vip-replace2-history nil) -;; History of region quoting strings. -(defvar vip-quote-region-history (list vip-quote-string)) -;; History of Ex-style commands. -(defvar vip-ex-history nil) -;; History of shell commands. -(defvar vip-shell-history nil) - - -;; Last shell command. There are two of these, one for Ex (in viper-ex) -;; and one for Vi. - -;; Last shell command executed with ! command. -(defvar vip-last-shell-com nil) +;; end pacifier + + +(require 'viper-util) +(require 'viper-keym) +(require 'viper-mous) +(require 'viper-macs) +(require 'viper-ex) -;;; Miscellaneous - -;; don't bark when mark is inactive -(setq mark-even-if-inactive t) - -(defvar vip-inhibit-startup-message nil - "Whether Viper startup message should be inhibited.") - -(defvar vip-always t - "t means, arrange that vi-state will be a default.") - -(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.vip") - "Viper customisation file. -This variable must be set _before_ loading Viper.") - - -(defvar vip-spell-function 'ispell-region - "Spell function used by #s command to spell.") - -(defvar vip-tags-file-name "TAGS" - "The tags file used by Viper.") - -;; Minibuffer - -(defvar vip-vi-style-in-minibuffer t - "If t, use vi-style editing in minibuffer. -Should be set in `~/.vip' file.") - -;; overlay used in the minibuffer to indicate which state it is in -(vip-deflocalvar vip-minibuffer-overlay nil) - -;; Hook, specific to Viper, which is run just *before* exiting the minibuffer. -;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run -;; *after* exiting the minibuffer -(defvar vip-minibuffer-exit-hook nil) - -(vip-deflocalvar vip-vi-minibuffer-minor-mode nil - "Minor mode that forces Vi-style when the Minibuffer is in Vi state.") -(vip-deflocalvar vip-insert-minibuffer-minor-mode nil - "Minor mode that forces Vi-style when the Minibuffer is in Insert state.") - -;; setup emacs-supported vi-style feel -(setq next-line-add-newlines nil - require-final-newline t) - -(make-variable-buffer-local 'require-final-newline) - - -;; Mode line -(defconst vip-vi-state-id " " - "Mode line tag identifying the Vi mode of Viper.") -(defconst vip-emacs-state-id " " - "Mode line tag identifying the Emacs mode of Viper.") -(defconst vip-insert-state-id " " - "Mode line tag identifying the Insert mode of Viper.") -(defconst vip-replace-state-id " " - "Mode line tag identifying the Replace mode of Viper.") - -;; Viper changes the default mode-line-buffer-identification -(setq-default mode-line-buffer-identification '(" %b")) - -;; Variable displaying the current Viper state in the mode line. -(vip-deflocalvar vip-mode-string vip-emacs-state-id) -(or (memq 'vip-mode-string global-mode-string) - (setq global-mode-string - (append '("" vip-mode-string) (cdr global-mode-string)))) - - -(defvar vip-vi-state-hook nil - "*Hooks run just before the switch to Vi mode is completed.") -(defvar vip-insert-state-hook nil - "*Hooks run just before the switch to Insert mode is completed.") -(defvar vip-replace-state-hook nil - "*Hooks run just before the switch to Replace mode is completed.") -(defvar vip-emacs-state-hook nil - "*Hooks run just before the switch to Emacs mode is completed.") - -(defvar vip-load-hook nil - "Hooks run just after loading Viper.") - - ;; Generic predicates ;; These test functions are shamelessly lifted from vip 4.4.2 by Aamod Sane @@ -920,46 +356,55 @@ ;; Modifying commands that can be prefixes to movement commands (defconst vip-prefix-commands '(?c ?d ?y ?! ?= ?# ?< ?> ?\")) +;; define vip-prefix-command-p (vip-test-com-defun vip-prefix-command) ;; Commands that are pairs eg. dd. r and R here are a hack (defconst vip-charpair-commands '(?c ?d ?y ?! ?= ?< ?> ?r ?R)) +;; define vip-charpair-command-p (vip-test-com-defun vip-charpair-command) (defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l - ?H ?M ?n ?t ?T ?w ?W ?$ ?% + ?H ?M ?L ?n ?t ?T ?w ?W ?$ ?% ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?` ?; ?, ?0 ?? ?/ ) "Movement commands") +;; define vip-movement-command-p (vip-test-com-defun vip-movement-command) +(defconst vip-digit-commands '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9) + "Digit commands") +;; define vip-digit-command-p +(vip-test-com-defun vip-digit-command) + ;; Commands that can be repeated by . (dotted) -(defconst vip-dotable-commands '(?c ?d ?C ?D ?> ?<)) +(defconst vip-dotable-commands '(?c ?d ?C ?s ?S ?D ?> ?<)) +;; define vip-dotable-command-p (vip-test-com-defun vip-dotable-command) ;; Commands that can follow a # -(defconst vip-hash-cmds '(?c ?C ?g ?q ?S)) -(vip-test-com-defun vip-hash-cmd) +(defconst vip-hash-commands '(?c ?C ?g ?q ?s)) +;; define vip-hash-command-p +(vip-test-com-defun vip-hash-command) ;; Commands that may have registers as prefix (defconst vip-regsuffix-commands '(?d ?y ?Y ?D ?p ?P ?x ?X)) +;; define vip-regsuffix-command-p (vip-test-com-defun vip-regsuffix-command) (defconst vip-vi-commands (append vip-movement-commands + vip-digit-commands vip-dotable-commands vip-charpair-commands - vip-hash-cmds + vip-hash-commands vip-prefix-commands vip-regsuffix-commands) "The list of all commands in Vi-state.") +;; define vip-vi-command-p (vip-test-com-defun vip-vi-command) -;;; Arrange the keymaps -(require 'viper-keym) - - ;;; CODE ;; sentinels @@ -1162,7 +607,9 @@ ;; expert (define-key vip-insert-basic-map "\C-j" nil) ;; novice - (define-key vip-insert-basic-map "\C-j" 'vip-autoindent)))) + (define-key vip-insert-basic-map "\C-j" 'vip-autoindent))) + (define-key vip-insert-basic-map "\C-m" nil) + (define-key vip-insert-basic-map "\C-j" nil)) (setq vip-insert-diehard-minor-mode (not vip-want-emacs-keys-in-insert)) @@ -1575,10 +1022,10 @@ ;; this-command, last-command-char, last-command-event (setq this-command com) (if vip-xemacs-p ; XEmacs represents key sequences as vectors - (setq last-command-event (vip-seq-last-elt key) + (setq last-command-event (vip-copy-event (vip-seq-last-elt key)) last-command-char (event-to-character last-command-event)) ;; Emacs represents them as sequences (str or vec) - (setq last-command-event (vip-seq-last-elt key) + (setq last-command-event (vip-copy-event (vip-seq-last-elt key)) last-command-char last-command-event)) (if (commandp com) @@ -1596,7 +1043,12 @@ (let ((buff (current-buffer)) result) (vip-set-mode-vars-for 'vi-state) - (setq result (eval form)) + + (condition-case nil + (setq result (eval form)) + (error + (signal 'quit nil))) + (if (not (equal buff (current-buffer))) ; cmd switched buffer (save-excursion (set-buffer buff) @@ -1745,7 +1197,7 @@ (setq last-input-event event keyseq (vector (character-to-event ?\e)))) ((eventp first-key) - (setq last-command-event first-key)) + (setq last-command-event (vip-copy-event first-key))) )) ) ; end progn @@ -1814,6 +1266,7 @@ (t 'vip-change-state-to-vi) ))) (call-interactively cmd))) + @@ -1857,7 +1310,7 @@ (let (value func) ;; read while number (while (and (vip-characterp event) (>= event ?0) (<= event ?9)) - (setq value (+ (* (if (vip-characterp value) value 0) 10) (- event ?0))) + (setq value (+ (* (if (integerp value) value 0) 10) (- event ?0))) (setq event (vip-read-event-convert-to-char))) (setq prefix-arg value) @@ -1880,9 +1333,9 @@ ;; the user typed, say, d2. In this case, `com' would be `d', `w', ;; etc. ;; If vip-digit-argument was invoked by vip-escape-to-vi (which is - ;; indicated by the fact that the current state is not vi-state, + ;; indicated by the fact that the current state is not vi-state), ;; then `event' represents the vi command to be executed (e.g., `d', - ;; `w', etc. Again, last-command-char must make emacs believe that + ;; `w', etc). Again, last-command-char must make emacs believe that ;; this is the command we typed. (setq last-command-char (or com event)) (setq func (vip-exec-form-in-vi @@ -1931,7 +1384,7 @@ (setq char (read-char)))) (t (setq com char) - (setq char (vip-read-char-exclusive)))))) + (setq char (read-char)))))) (if (atom com) ;; `com' is a single char, so we construct the command argument @@ -1942,8 +1395,12 @@ (while (= char ?U) (vip-describe-arg cmd-info) (setq char (read-char))) - ;; `char' is a movement command or a digit arg command---so we execute - ;; it at the very end + ;; `char' is a movement cmd, a digit arg cmd, or a register cmd---so we + ;; execute it at the very end + (or (vip-movement-command-p char) + (vip-digit-command-p char) + (vip-regsuffix-command-p char) + (error "")) (setq mv-or-digit-cmd (vip-exec-form-in-vi (` (key-binding (char-to-string (, char))))))) @@ -1973,7 +1430,13 @@ (if mv-or-digit-cmd (progn (setq last-command-char char) - (funcall mv-or-digit-cmd cmd-info))) + (setq last-command-event + (vip-copy-event + (if vip-xemacs-p (character-to-event char) char))) + (condition-case nil + (funcall mv-or-digit-cmd cmd-info) + (error + (error ""))))) )) (defun vip-describe-arg (arg) @@ -1998,20 +1461,21 @@ (defun vip-command-argument (arg) "Accept a motion command as an argument." (interactive "P") - (condition-case nil - (vip-prefix-arg-com - last-command-char - (cond ((null arg) nil) - ((consp arg) (car arg)) - ((integerp arg) arg) - (t (error vip-InvalidCommandArgument))) - (cond ((null arg) nil) - ((consp arg) (cdr arg)) - ((integerp arg) nil) - (t (error vip-InvalidCommandArgument)))) - (quit (setq vip-use-register nil) - (signal 'quit nil))) - (vip-deactivate-mark)) + (let ((vip-inside-command-argument-action t)) + (condition-case nil + (vip-prefix-arg-com + last-command-char + (cond ((null arg) nil) + ((consp arg) (car arg)) + ((integerp arg) arg) + (t (error vip-InvalidCommandArgument))) + (cond ((null arg) nil) + ((consp arg) (cdr arg)) + ((integerp arg) nil) + (t (error vip-InvalidCommandArgument)))) + (quit (setq vip-use-register nil) + (signal 'quit nil))) + (vip-deactivate-mark))) ;; repeat last destructive command @@ -2048,6 +1512,8 @@ ;; invoked by the `C' command (defun vip-exec-change (m-com com) + (or (and (markerp vip-com-point) (marker-position vip-com-point)) + (set-marker vip-com-point (point) (current-buffer))) ;; handle C cmd at the eol and at eob. (if (or (and (eolp) (= vip-com-point (point))) (= vip-com-point (point-max))) @@ -2081,6 +1547,8 @@ (if (= com ?C) (vip-change-mode-to-insert) (vip-yank-last-insertion))) (defun vip-exec-delete (m-com com) + (or (and (markerp vip-com-point) (marker-position vip-com-point)) + (set-marker vip-com-point (point) (current-buffer))) (if vip-use-register (progn (cond ((vip-valid-register vip-use-register '(letter digit)) @@ -2123,6 +1591,8 @@ (back-to-indentation)) (defun vip-exec-yank (m-com com) + (or (and (markerp vip-com-point) (marker-position vip-com-point)) + (set-marker vip-com-point (point) (current-buffer))) (if vip-use-register (progn (cond ((vip-valid-register vip-use-register '(letter digit)) @@ -2331,7 +1801,8 @@ )) -;; This command is invoked interactively by the key sequence # +;; The hash-command. It is invoked interactively by the key sequence #. +;; The chars that can follow `#' are determined by vip-hash-command-p (defun vip-special-prefix-com (char) (cond ((= char ?c) (downcase-region (min vip-com-point (point)) @@ -2633,100 +2104,6 @@ (command-execute command) (exit-minibuffer)))) - -(defun vip-set-search-face () - (if (vip-has-face-support-p) - (defvar vip-search-face - (progn - (make-face 'vip-search-face) - (vip-hide-face 'vip-search-face) - (or (face-differs-from-default-p 'vip-search-face) - ;; face wasn't set in .vip or .Xdefaults - (if (vip-can-use-colors "Black" "khaki") - (progn - (set-face-background 'vip-search-face "khaki") - (set-face-foreground 'vip-search-face "Black")) - (set-face-underline-p 'vip-search-face t) - (vip-set-face-pixmap 'vip-search-face vip-search-face-pixmap))) - 'vip-search-face) - "*Face used to flash out the search pattern.") - )) - - -(defun vip-set-minibuffer-faces () - (if (not (vip-has-face-support-p)) - () - (defvar vip-minibuffer-emacs-face - (progn - (make-face 'vip-minibuffer-emacs-face) - (vip-hide-face 'vip-minibuffer-emacs-face) - (or (face-differs-from-default-p 'vip-minibuffer-emacs-face) - ;; face wasn't set in .vip or .Xdefaults - (if vip-vi-style-in-minibuffer - ;; emacs state is an exception in the minibuffer - (if (vip-can-use-colors "darkseagreen2" "Black") - (progn - (set-face-background - 'vip-minibuffer-emacs-face "darkseagreen2") - (set-face-foreground - 'vip-minibuffer-emacs-face "Black")) - (copy-face 'modeline 'vip-minibuffer-emacs-face)) - ;; emacs state is the main state in the minibuffer - (if (vip-can-use-colors "Black" "pink") - (progn - (set-face-background 'vip-minibuffer-emacs-face "pink") - (set-face-foreground - 'vip-minibuffer-emacs-face "Black")) - (copy-face 'italic 'vip-minibuffer-emacs-face)) - )) - 'vip-minibuffer-emacs-face) - "Face used in the Minibuffer when it is in Emacs state.") - - (defvar vip-minibuffer-insert-face - (progn - (make-face 'vip-minibuffer-insert-face) - (vip-hide-face 'vip-minibuffer-insert-face) - (or (face-differs-from-default-p 'vip-minibuffer-insert-face) - (if vip-vi-style-in-minibuffer - (if (vip-can-use-colors "Black" "pink") - (progn - (set-face-background 'vip-minibuffer-insert-face "pink") - (set-face-foreground - 'vip-minibuffer-insert-face "Black")) - (copy-face 'italic 'vip-minibuffer-insert-face)) - ;; If Insert state is an exception - (if (vip-can-use-colors "darkseagreen2" "Black") - (progn - (set-face-background - 'vip-minibuffer-insert-face "darkseagreen2") - (set-face-foreground - 'vip-minibuffer-insert-face "Black")) - (copy-face 'modeline 'vip-minibuffer-insert-face)) - (vip-italicize-face 'vip-minibuffer-insert-face))) - 'vip-minibuffer-insert-face) - "Face used in the Minibuffer when it is in Insert state.") - - (defvar vip-minibuffer-vi-face - (progn - (make-face 'vip-minibuffer-vi-face) - (vip-hide-face 'vip-minibuffer-vi-face) - (or (face-differs-from-default-p 'vip-minibuffer-vi-face) - (if vip-vi-style-in-minibuffer - (if (vip-can-use-colors "Black" "grey") - (progn - (set-face-background 'vip-minibuffer-vi-face "grey") - (set-face-foreground 'vip-minibuffer-vi-face "Black")) - (copy-face 'bold 'vip-minibuffer-vi-face)) - (copy-face 'bold 'vip-minibuffer-vi-face) - (invert-face 'vip-minibuffer-vi-face))) - 'vip-minibuffer-vi-face) - "Face used in the Minibuffer when it is in Vi state.") - - ;; the current face used in the minibuffer - (vip-deflocalvar vip-minibuffer-current-face vip-minibuffer-emacs-face "") - )) - - ;;; Reading string with history @@ -2968,6 +2345,10 @@ 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel t) (vip-add-hook 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) + ;; guard against a smartie who switched from R-replace to normal replace + (vip-remove-hook + 'vip-post-command-hooks 'vip-R-state-post-command-sentinel) + (if overwrite-mode (overwrite-mode nil)) ) @@ -3043,9 +2424,11 @@ )) (setq vip-replace-chars-to-delete - (max 0 (min vip-replace-chars-to-delete - (- (vip-replace-end) - vip-last-posn-in-replace-region)))) + (max 0 + (min vip-replace-chars-to-delete + (- (vip-replace-end) vip-last-posn-in-replace-region) + (- (vip-line-pos 'end) vip-last-posn-in-replace-region) + ))) ))) @@ -3097,6 +2480,9 @@ 'vip-post-command-hooks 'vip-R-state-post-command-sentinel t) (vip-add-hook 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) + ;; guard against a smartie who switched from R-replace to normal replace + (vip-remove-hook + 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel) ) @@ -3121,6 +2507,29 @@ ) (vip-hide-replace-overlay)) +(defun vip-replace-state-carriage-return () + "Implements carriage return in Viper replace state." + (interactive) + ;; If Emacs start supporting overlay maps, as it currently supports + ;; text-property maps, we could do away with vip-replace-minor-mode and + ;; just have keymap attached to replace overlay. Then the "if part" of this + ;; statement can be deleted. + (if (or (< (point) (vip-replace-start)) + (> (point) (vip-replace-end))) + (let (vip-replace-minor-mode com) + (vip-set-unread-command-events last-input-char) + (setq com (key-binding (read-key-sequence nil))) + (condition-case conds + (command-execute com) + (error + (vip-message-conditions conds)))) + (if (not vip-allow-multiline-replace-regions) + (vip-replace-state-exit-cmd) + (if (vip-same-line (point) (vip-replace-end)) + (vip-replace-state-exit-cmd) + (vip-kill-line nil) + (vip-next-line-at-bol nil))))) + ;; This is the function bound to 'R'---unlimited replace. ;; Similar to Emacs's own overwrite-mode. @@ -3516,14 +2925,19 @@ (interactive "P") (vip-leave-region-active) (let ((val (vip-p-val arg)) - (com (vip-getcom arg))) + (com (vip-getcom arg)) + line-len) + (setq line-len (- (vip-line-pos 'end) (vip-line-pos 'start))) + (if com (vip-move-marker-locally 'vip-com-point (point))) + (beginning-of-line) + (forward-char (1- (min line-len val))) + (while (> (current-column) (1- val)) + (backward-char 1)) + (if com (vip-execute-com 'vip-goto-col val com)) (save-excursion (end-of-line) - (if (> val (1+ (current-column))) (error ""))) - (if com (vip-move-marker-locally 'vip-com-point (point))) - (beginning-of-line) - (forward-char (1- val)) - (if com (vip-execute-com 'vip-goto-col val com)))) + (if (> val (current-column)) (error ""))) + )) (defun vip-next-line (arg) @@ -3874,10 +3288,11 @@ (interactive "p") (recenter (- (window-height) (1+ arg)))) -;; If vip-adjust-window-after-search is t, scroll up or down 1/4 of window -;; height, depending on whether we are at the bottom or at the top of the -;; window. This function is called by vip-search (which is called from -;; vip-search-forward/backward/next) +;; If point is within vip-search-scroll-threshold of window top or bottom, +;; scroll up or down 1/7 of window height, depending on whether we are at the +;; bottom or at the top of the window. This function is called by vip-search +;; (which is called from vip-search-forward/backward/next). If the value of +;; vip-search-scroll-threshold is negative - don't scroll. (defun vip-adjust-window () (let ((win-height (if vip-emacs-p (1- (window-height)) ; adjust for modeline @@ -3887,15 +3302,18 @@ min-scroll direction) (save-excursion (move-to-window-line 0) ; top - (setq at-top-p (<= (count-lines pt (point)) 2)) + (setq at-top-p + (<= (count-lines pt (point)) + vip-search-scroll-threshold)) (move-to-window-line -1) ; bottom - (setq at-bottom-p (<= (count-lines pt (point)) 2)) + (setq at-bottom-p + (<= (count-lines pt (point)) vip-search-scroll-threshold)) ) - (cond (at-top-p (setq min-scroll 1 + (cond (at-top-p (setq min-scroll (1- vip-search-scroll-threshold) direction 1)) - (at-bottom-p (setq min-scroll 2 + (at-bottom-p (setq min-scroll (1+ vip-search-scroll-threshold) direction -1))) - (if (and vip-adjust-window-after-search min-scroll) + (if min-scroll (recenter (* (max min-scroll (/ win-height 7)) direction))) )) @@ -3911,7 +3329,8 @@ (interactive "P") (vip-leave-region-active) (let ((com (vip-getcom arg)) - parse-sexp-ignore-comments anchor-point) + (parse-sexp-ignore-comments vip-parse-sexp-ignore-comments) + anchor-point) (if (integerp arg) (if (or (> arg 99) (< arg 1)) (error "Prefix must be between 1 and 99") @@ -3954,6 +3373,13 @@ (if com (vip-execute-com 'vip-paren-match nil com))) (t (error "")))))) +(defun vip-toggle-parse-sexp-ignore-comments () + (interactive) + (setq vip-parse-sexp-ignore-comments (not vip-parse-sexp-ignore-comments)) + (prin1 (format "`%%' will %signore parentheses inside the comments" + (if vip-parse-sexp-ignore-comments "" "NOT "))) + ) + ;; sentence ,paragraph and heading @@ -4322,6 +3748,7 @@ ;; highlight the result of search ;; don't wait and don't highlight in macros (or executing-kbd-macro + vip-inside-command-argument-action (vip-flash-search-pattern)) ))) @@ -4424,7 +3851,8 @@ (error "Buffer not killed")))) -(defvar vip-smart-suffix-list '("" "tex" "c" "cc" "el" "p") +(defvar vip-smart-suffix-list + '("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p") "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'. This is useful when you the current directory contains files with the same prefix and many different suffixes. Usually, only one of the suffixes @@ -4482,18 +3910,38 @@ (defadvice find-file (before vip-add-suffix-advice activate) "Use `read-file-name' for reading arguments." - (interactive (list (read-file-name "Find file: " - nil default-directory)))) + (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: ")))) + ))) (defadvice find-file-other-window (before vip-add-suffix-advice activate) "Use `read-file-name' for reading arguments." - (interactive (list (read-file-name "Find file in other window: " - nil default-directory)))) + (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: ")))) + ))) (defadvice find-file-other-frame (before vip-add-suffix-advice activate) "Use `read-file-name' for reading arguments." - (interactive (list (read-file-name "Find file in other frame: " - nil default-directory)))) + (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: ")))) + ))) (defadvice read-file-name (around vip-suffix-advice activate) "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook." @@ -4723,8 +4171,9 @@ ;; protect against error while inserting "@" and other disasters ;; (e.g., read-only buff) (condition-case conds - (if (vip-same-line (vip-replace-start) - (vip-replace-end)) + (if (or vip-allow-multiline-replace-regions + (vip-same-line (vip-replace-start) + (vip-replace-end))) (progn ;; tabs cause problems in replace, so untabify (goto-char (vip-replace-end)) @@ -4844,16 +4293,16 @@ (defun vip-mark-point () "Set mark at point of buffer." (interactive) - (let ((char (vip-read-char-exclusive))) - (cond ((and (<= ?a char) (<= char ?z)) - (point-to-register (1+ (- char ?a)))) - ((= char ?<) (vip-mark-beginning-of-buffer)) - ((= char ?>) (vip-mark-end-of-buffer)) - ((= char ?.) (vip-set-mark-if-necessary)) - ((= char ?,) (vip-cycle-through-mark-ring)) - ((= char ?D) (mark-defun)) - (t (error "")) - ))) + (let ((char (read-char))) + (cond ((and (<= ?a char) (<= char ?z)) + (point-to-register (1+ (- char ?a)))) + ((= char ?<) (vip-mark-beginning-of-buffer)) + ((= char ?>) (vip-mark-end-of-buffer)) + ((= char ?.) (vip-set-mark-if-necessary)) + ((= char ?,) (vip-cycle-through-mark-ring)) + ((= char ?D) (mark-defun)) + (t (error "")) + ))) ;; Algorithm: If first invocation of this command save mark on ring, goto ;; mark, M0, and pop the most recent elt from the mark ring into mark, @@ -5012,6 +4461,7 @@ "Auto Indentation, Vi-style." (interactive) (let ((col (current-indentation))) + (if abbrev-mode (expand-abbrev)) (if vip-preserve-indent (setq vip-preserve-indent nil) (setq vip-current-indent col)) @@ -5547,13 +4997,6 @@ -;;; Bring in the rest of the files -(require 'viper-mous) -(require 'viper-macs) -(require 'viper-ex) - - - ;; The following is provided for compatibility with older VIP's (defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi) @@ -5591,6 +5034,7 @@ (defvar help-mode-hook) (add-hook 'help-mode-hook 'viper-mode) + (vip-modify-major-mode 'help-mode 'vi-state vip-help-modifier-map) (defvar awk-mode-hook) (add-hook 'awk-mode-hook 'viper-mode) @@ -5802,6 +5246,12 @@ ;; set the toggle case sensitivity and regexp search macros (vip-set-vi-search-style-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 is loaded if it exists @@ -5830,9 +5280,6 @@ (vip-set-minibuffer-style) -(vip-set-minibuffer-faces) -(vip-set-search-face) -(vip-set-replace-overlay-face) (if vip-buffer-search-char (vip-buffer-search-enable)) (vip-update-alphanumeric-class) @@ -5885,7 +5332,6 @@ (run-hooks 'vip-load-hook) ; the last chance to change something -(provide 'viper) (provide 'vip19) (provide 'vip)