1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-24 10:38:38 +00:00

new version

This commit is contained in:
Michael Kifer 1997-07-17 19:37:07 +00:00
parent 99358b9788
commit 1e70790f2f
15 changed files with 969 additions and 482 deletions

View File

@ -243,6 +243,7 @@
(autoload 'ediff-buffers3 "ediff" "Compare three bufers" t) (autoload 'ediff-buffers3 "ediff" "Compare three bufers" t)
(autoload 'ebuffers3 "ediff" "Compare three bufers" t) (autoload 'ebuffers3 "ediff" "Compare three bufers" t)
(autoload 'erevision "ediff" "Compare versions of a file" t)
(autoload 'ediff-revision "ediff" "Compare versions of a file" t) (autoload 'ediff-revision "ediff" "Compare versions of a file" t)
;; compare regions and windows ;; compare regions and windows
@ -317,6 +318,10 @@
"ediff-mult" "ediff-mult"
"Display the registry of active Ediff sessions." "Display the registry of active Ediff sessions."
t) t)
(autoload 'eregistry
"ediff-mult"
"Display the registry of active Ediff sessions."
t)
(autoload 'ediff-documentation (autoload 'ediff-documentation
"ediff" "ediff"
"Display Ediff's manual." "Display Ediff's manual."

View File

@ -328,53 +328,79 @@ that Ediff doesn't know about.")
;; Hook variables ;; Hook variables
(defvar ediff-before-setup-windows-hook nil (defcustom ediff-before-setup-windows-hook nil
"*Hooks to run before Ediff sets its window configuration. "*Hooks to run before Ediff sets its window configuration.
This can be used to save the previous window config, which can be restored This can be used to save the previous window config, which can be restored
on ediff-quit or ediff-suspend.") on ediff-quit or ediff-suspend."
(defvar ediff-after-setup-windows-hook nil :type 'hook
:group 'ediff)
(defcustom ediff-after-setup-windows-hook nil
"*Hooks to run after Ediff sets its window configuration. "*Hooks to run after Ediff sets its window configuration.
This can be used to set up control window or icon in a desired place.") This can be used to set up control window or icon in a desired place."
(defvar ediff-before-setup-control-frame-hook nil :type 'hook
:group 'ediff)
(defcustom ediff-before-setup-control-frame-hook nil
"*Hooks run before setting up the frame to display Ediff Control Panel. "*Hooks run before setting up the frame to display Ediff Control Panel.
Can be used to change control frame parameters to position it where it Can be used to change control frame parameters to position it where it
is desirable.") is desirable."
(defvar ediff-after-setup-control-frame-hook nil :type 'hook
:group 'ediff)
(defcustom ediff-after-setup-control-frame-hook nil
"*Hooks run after setting up the frame to display Ediff Control Panel. "*Hooks run after setting up the frame to display Ediff Control Panel.
Can be used to move the frame where it is desired.") Can be used to move the frame where it is desired."
(defvar ediff-startup-hook nil :type 'hook
"*Hooks to run in the control buffer after Ediff has been set up.") :group 'ediff)
(defvar ediff-select-hook nil (defcustom ediff-startup-hook nil
"*Hooks to run after a difference has been selected.") "*Hooks to run in the control buffer after Ediff has been set up."
(defvar ediff-unselect-hook nil :type 'hook
"*Hooks to run after a difference has been unselected.") :group 'ediff)
(defvar ediff-prepare-buffer-hook nil (defcustom ediff-select-hook nil
"*Hooks called after buffers A, B, and C are set up.") "*Hooks to run after a difference has been selected."
(defvar ediff-load-hook nil :type 'hook
"*Hook run after Ediff is loaded. Can be used to change defaults.") :group 'ediff)
(defcustom ediff-unselect-hook nil
"*Hooks to run after a difference has been unselected."
:type 'hook
:group 'ediff)
(defcustom ediff-prepare-buffer-hook nil
"*Hooks called after buffers A, B, and C are set up."
:type 'hook
:group 'ediff)
(defcustom ediff-load-hook nil
"*Hook run after Ediff is loaded. Can be used to change defaults."
:type 'hook
:group 'ediff)
(defvar ediff-mode-hook nil (defcustom ediff-mode-hook nil
"*Hook run just after ediff-mode is set up in the control buffer. "*Hook run just after ediff-mode is set up in the control buffer.
This is done before any windows or frames are created. One can use it to This is done before any windows or frames are created. One can use it to
set local variables that determine how the display looks like.") set local variables that determine how the display looks like."
(defvar ediff-keymap-setup-hook nil :type 'hook
"*Hook run just after the default bindings in Ediff keymap are set up.") :group 'ediff)
(defcustom ediff-keymap-setup-hook nil
"*Hook run just after the default bindings in Ediff keymap are set up."
:type 'hook
:group 'ediff)
(defvar ediff-display-help-hook nil (defcustom ediff-display-help-hook nil
"*Hooks run after preparing the help message.") "*Hooks run after preparing the help message."
:type 'hook
:group 'ediff)
(defvar ediff-suspend-hook (list 'ediff-default-suspend-function) (defcustom ediff-suspend-hook (list 'ediff-default-suspend-function)
"*Hooks to run in the Ediff control buffer when Ediff is suspended.") "*Hooks to run in the Ediff control buffer when Ediff is suspended."
(defvar ediff-quit-hook (list 'ediff-cleanup-mess) :type 'hook
"*Hooks to run in the Ediff control buffer after finishing Ediff.") :group 'ediff)
(defvar ediff-cleanup-hook nil (defcustom ediff-quit-hook (list 'ediff-cleanup-mess)
"*Hooks to run in the Ediff control buffer after finishing Ediff."
:type 'hook
:group 'ediff)
(defcustom ediff-cleanup-hook nil
"*Hooks to run on exiting Ediff but before killing the control buffer. "*Hooks to run on exiting Ediff but before killing the control buffer.
This is a place to do various cleanups, such as deleting the variant buffers. This is a place to do various cleanups, such as deleting the variant buffers.
Ediff provides a function, `ediff-janitor', as one such possible hook.") Ediff provides a function, `ediff-janitor', as one such possible hook."
(defvar ediff-quit-merge-hook 'ediff-maybe-save-and-delete-merge :type 'hook
"*Hooks to run before quitting a merge job. :group 'ediff)
The most common use is to save and delete the merge buffer.")
;; Error messages ;; Error messages
(defconst ediff-KILLED-VITAL-BUFFER (defconst ediff-KILLED-VITAL-BUFFER
@ -430,29 +456,39 @@ See the documentation string of `ediff-focus-on-regexp-matches' for details.")
(ediff-defvar-local ediff-hide-regexp-connective 'and "") (ediff-defvar-local ediff-hide-regexp-connective 'and "")
;; Copying difference regions between buffers. ;;; Copying difference regions between buffers.
(ediff-defvar-local ediff-killed-diffs-alist nil
"A list of killed diffs. ;; A list of killed diffs.
A diff is saved here if it is replaced by a diff ;; A diff is saved here if it is replaced by a diff
from another buffer. This alist has the form: ;; from another buffer. This alist has the form:
\((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...), ;; \((num (buff-object . diff) (buff-object . diff) (buff-object . diff)) ...),
where some buffer-objects may be missing.") ;; where some buffer-objects may be missing.
(ediff-defvar-local ediff-killed-diffs-alist nil "")
;; Highlighting ;; Highlighting
;;(defvar ediff-before-flag-bol (if ediff-emacs-p "->>\n" (make-glyph "->>\n")) (defcustom ediff-before-flag-bol (if ediff-xemacs-p (make-glyph "->>") "->>")
(defvar ediff-before-flag-bol (if ediff-xemacs-p (make-glyph "->>") "->>") "*Flag placed before a highlighted block of differences, if block starts at beginning of a line."
"*Flag placed above the highlighted block of differences. :type 'string
Must end with newline.") :tag "Region before-flag at beginning of line"
;;(defvar ediff-after-flag-eol (if ediff-emacs-p "<<-\n" (make-glyph "<<-")) :group 'ediff)
(defvar ediff-after-flag-eol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
"*Flag placed below the highlighted block of differences.
Must end with newline.")
(defvar ediff-before-flag-mol (if ediff-xemacs-p (make-glyph "->>") "->>") (defcustom ediff-after-flag-eol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
"*Like ediff-before-flag, used when a difference starts in mid-line.") "*Flag placed after a highlighted block of differences, if block ends at end of a line."
(defvar ediff-after-flag-mol (if ediff-xemacs-p (make-glyph "<<-") "<<-") :type 'string
"*Like ediff-after-flag, used when a difference starts in mid-line.") :tag "Region after-flag at end of line"
:group 'ediff)
(defcustom ediff-before-flag-mol (if ediff-xemacs-p (make-glyph "->>") "->>")
"*Flag placed before a highlighted block of differences, if block starts in mid-line."
:type 'string
:tag "Region before-flag in the middle of line"
:group 'ediff)
(defcustom ediff-after-flag-mol (if ediff-xemacs-p (make-glyph "<<-") "<<-")
"*Flag placed after a highlighted block of differences, if block ends in mid-line."
:type 'string
:tag "Region after-flag in the middle of line"
:group 'ediff)
(ediff-defvar-local ediff-use-faces t (ediff-defvar-local ediff-use-faces t
@ -490,11 +526,13 @@ Use `setq-default' if setting it in .emacs")
(ediff-defvar-local ediff-quit-widened t (ediff-defvar-local ediff-quit-widened t
"*Non-nil means: when finished, Ediff widens buffers A/B. "*Non-nil means: when finished, Ediff widens buffers A/B.
Actually, Ediff restores the scope of visibility that existed at startup.") Actually, Ediff restores the scope of visibility that existed at startup.")
(defvar ediff-keep-variants t
"*Nil means that non-modified variant buffers should be removed after some (defcustom ediff-keep-variants t
interrogation. "*Nil means that non-modified variant buffers should be removed at the end of the session after some interrogation.
Supplying a prefix argument to the quit command `q' temporarily reverses the Supplying a prefix argument to the quit command `q' temporarily reverses the
meaning of this variable.") meaning of this variable."
:type 'boolean
:group 'ediff)
(ediff-defvar-local ediff-highlight-all-diffs t (ediff-defvar-local ediff-highlight-all-diffs t
"If nil, only the selected differences are highlighted. "If nil, only the selected differences are highlighted.
@ -522,7 +560,7 @@ ediff-toggle-hilit. Use `setq-default' to set it.")
(ediff-defvar-local ediff-buffer-values-orig-C nil "") (ediff-defvar-local ediff-buffer-values-orig-C nil "")
;; The original values of ediff-protected-variables for buffer Ancestor ;; The original values of ediff-protected-variables for buffer Ancestor
(ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "") (ediff-defvar-local ediff-buffer-values-orig-Ancestor nil "")
;; Buffer-local variables to be saved then restored during Ediff sessions
;; Buffer-local variables to be saved then restored during Ediff sessions ;; Buffer-local variables to be saved then restored during Ediff sessions
(defconst ediff-protected-variables '( (defconst ediff-protected-variables '(
;;buffer-read-only ;;buffer-read-only
@ -589,12 +627,14 @@ ediff-toggle-hilit. Use `setq-default' to set it.")
;; Priority of non-selected overlays. ;; Priority of non-selected overlays.
(defvar ediff-shadow-overlay-priority 100 "") (defvar ediff-shadow-overlay-priority 100 "")
(defvar ediff-version-control-package 'vc (defcustom ediff-version-control-package 'vc
"Version control package used. "Version control package used.
Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The Currently, Ediff supports vc.el, rcs.el, pcl-cvs.el, and generic-sc.el. The
standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some standard Emacs interface to RCS, CVS, SCCS, etc., is vc.el. However, some
people find the other two packages more convenient. Set this variable to the people find the other two packages more convenient. Set this variable to the
appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire.") appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire."
:type 'symbol
:group 'ediff)
(if ediff-xemacs-p (if ediff-xemacs-p
@ -1106,6 +1146,12 @@ If nil, Ediff tries to deduce the function from the binding of C-x C-q.
Normally, this is the `toggle-read-only' function, but, if version Normally, this is the `toggle-read-only' function, but, if version
control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.") control is used, it could be `vc-toggle-read-only' or `rcs-toggle-read-only'.")
(defcustom ediff-make-buffers-readonly-at-startup nil
"*Make all variant buffers read-only when Ediff starts up.
This property can be toggled interactively."
:type 'boolean
:group 'ediff)
;;; Misc ;;; Misc
@ -1121,9 +1167,11 @@ as `ediff-merge-directory' or `ediff-merge-directory-revisions'.")
;; file where the result of the merge is to be saved. used internally ;; file where the result of the merge is to be saved. used internally
(ediff-defvar-local ediff-merge-store-file nil "") (ediff-defvar-local ediff-merge-store-file nil "")
(defvar ediff-no-emacs-help-in-control-buffer nil (defcustom ediff-no-emacs-help-in-control-buffer nil
"*Non-nil means C-h should not invoke Emacs help in control buffer. "*Non-nil means C-h should not invoke Emacs help in control buffer.
Instead, C-h jumps to previous difference.") Instead, C-h would jump to previous difference."
:type 'boolean
:group 'ediff)
(defvar ediff-temp-file-prefix (defvar ediff-temp-file-prefix
(let ((env (or (getenv "TMPDIR") (let ((env (or (getenv "TMPDIR")
@ -1155,12 +1203,13 @@ More precisely, a regexp to match any one such character.")
(defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H"))) (defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H")))
(ediff-defvar-local ediff-temp-file-A nil ;; Temporary file used for refining difference regions in buffer A.
"Temporary file used for refining difference regions in buffer A.") (ediff-defvar-local ediff-temp-file-A nil "")
(ediff-defvar-local ediff-temp-file-B nil ;; Temporary file used for refining difference regions in buffer B.
"Temporary file used for refining difference regions in buffer B.") (ediff-defvar-local ediff-temp-file-B nil "")
(ediff-defvar-local ediff-temp-file-C nil ;; Temporary file used for refining difference regions in buffer C.
"Temporary file used for refining difference regions in buffer C.") (ediff-defvar-local ediff-temp-file-C nil "")
;;; In-line functions ;;; In-line functions

View File

@ -49,6 +49,12 @@
(require 'ediff-init) (require 'ediff-init)
(defcustom ediff-quit-merge-hook 'ediff-maybe-save-and-delete-merge
"*Hooks to run before quitting a merge job.
The most common use is to save and delete the merge buffer."
:type 'hook
:group 'ediff-merge)
(defcustom ediff-default-variant 'combined (defcustom ediff-default-variant 'combined
"*The variant to be used as a default for buffer C in merging. "*The variant to be used as a default for buffer C in merging.

View File

@ -50,28 +50,62 @@
(require 'ediff-init) (require 'ediff-init)
(defcustom ediff-patch-program "patch"
"*Name of the program that applies patches.
It is recommended to use GNU-compatible versions."
:type 'string
:group 'ediff-ptch)
(defcustom ediff-patch-options "-f"
"*Options to pass to ediff-patch-program.
Note: the `-b' option should be specified in `ediff-backup-specs'.
It is recommended to pass the `-f' option to the patch program, so it won't ask
questions. However, some implementations don't accept this option, in which
case the default value for this variable should be changed."
:type 'string
:group 'ediff-ptch)
(defvar ediff-last-dir-patch nil (defvar ediff-last-dir-patch nil
"Last directory used by an Ediff command for file to patch.") "Last directory used by an Ediff command for file to patch.")
(defvar ediff-backup-extension ;; the default backup extension
(if (memq system-type '(vax-vms axp-vms emx ms-dos windows-nt windows-95)) (defconst ediff-default-backup-extension
"_orig" ".orig") (if (memq system-type '(vax-vms axp-vms emx ms-dos))
"Backup extension used by the patch program. "_orig" ".orig"))
See also `ediff-backup-specs'.")
(defcustom ediff-backup-specs (format "-b %s" ediff-backup-extension) (defcustom ediff-backup-extension ediff-default-backup-extension
"Backup extension used by the patch program.
See also `ediff-backup-specs'."
:type 'string
:group 'ediff-ptch)
(defcustom ediff-backup-specs
(cond
((zerop (call-process ediff-patch-program nil nil nil "-z." "-b"))
;; GNU `patch' v. >= 2.2
(format "-z%s -b" ediff-backup-extension))
((zerop (call-process ediff-patch-program nil nil nil "-b"))
;; POSIX `patch' -- ediff-backup-extension must be ".orig"
(setq ediff-backup-extension ediff-default-backup-extension)
"-b")
(t
;; traditional `patch'
(format "-b %s" ediff-backup-extension)))
"*Backup directives to pass to the patch program. "*Backup directives to pass to the patch program.
Ediff requires that the old version of the file \(before applying the patch\) Ediff requires that the old version of the file \(before applying the patch\)
is saved in a file named `the-patch-file.extension'. Usually `extension' is be saved in a file named `the-patch-file.extension'. Usually `extension' is
`.orig', but this can be changed by the user and may depend on the system. `.orig', but this can be changed by the user and may depend on the system.
Therefore, Ediff needs to know the backup extension used by the patch program. Therefore, Ediff needs to know the backup extension used by the patch program.
Some versions of the patch program let you specify `-b backup-extension'. Some versions of the patch program let you specify `-b backup-extension'.
Other versions only permit `-b', which assumes some canned extension Other versions only permit `-b', which assumes the extension `.orig'
\(usually `.orig'\). \(in which case ediff-backup-extension MUST be also `.orig'\). The latest
versions of GNU patch require `-b -z backup-extension'.
Note that both `ediff-backup-extension' and `ediff-backup-specs' Note that both `ediff-backup-extension' and `ediff-backup-specs'
must be properly set. If your patch program takes the option `-b', must be set properly. If your patch program takes the option `-b',
but not `-b extension', the variable `ediff-backup-extension' must but not `-b extension', the variable `ediff-backup-extension' must
still be set so Ediff will know which extension to use." still be set so Ediff will know which extension to use."
:type 'string :type 'string
@ -89,26 +123,12 @@ still be set so Ediff will know which extension to use."
"\\|" ; GNU unified format diff 2-liner "\\|" ; GNU unified format diff 2-liner
"^--- \\([^ \t]+\\)[\t ]+.*\n\\+\\+\\+ \\([^ \t]+\\)" "^--- \\([^ \t]+\\)[\t ]+.*\n\\+\\+\\+ \\([^ \t]+\\)"
"\\)") "\\)")
"*Regexp matching filename 2-liners at the start of each context diff." "*Regexp matching filename 2-liners at the start of each context diff.
You probably don't want to change that, unless you are using an obscure patch
program."
:type 'regexp :type 'regexp
:group 'ediff-ptch) :group 'ediff-ptch)
(defcustom ediff-patch-program "patch"
"*Name of the program that applies patches.
It is recommended to use GNU-compatible versions."
:type 'string
:group 'ediff-ptch)
(defcustom ediff-patch-options "-f"
"*Options to pass to ediff-patch-program.
Note: the `-b' option should be specified in `ediff-backup-specs'.
It is recommended to pass the `-f' option to the patch program, so it won't ask
questions. However, some implementations don't accept this option, in which
case the default value for this variable should be changed."
:type 'string
:group 'ediff-ptch)
;; The buffer of the patch file. Local to control buffer. ;; The buffer of the patch file. Local to control buffer.
(ediff-defvar-local ediff-patchbufer nil "") (ediff-defvar-local ediff-patchbufer nil "")
@ -476,7 +496,7 @@ Else, read patch file into a new buffer."
(true-source-filename source-filename) (true-source-filename source-filename)
(target-filename source-filename) (target-filename source-filename)
target-buf buf-to-patch file-name-magic-p target-buf buf-to-patch file-name-magic-p
patch-return-code ctl-buf backup-style aux-wind) patch-return-code ctl-buf backup-style)
(if (string-match "-V" ediff-patch-options) (if (string-match "-V" ediff-patch-options)
(error (error
@ -535,44 +555,33 @@ Else, read patch file into a new buffer."
(concat true-source-filename ediff-backup-extension))) (concat true-source-filename ediff-backup-extension)))
(progn (progn
(with-output-to-temp-buffer ediff-msg-buffer (with-output-to-temp-buffer ediff-msg-buffer
(princ (format " (princ (format
Patch has failed OR the backup version of the patched file was not created by "Patch program has failed due to a bad patch file OR
the patch program. because it couldn't create the backup for the file to be patched.
One reason may be that the values of the variables The former could be caused by a corrupt patch file or because the %S
program doesn't understand the format of the patch file in use.
The second problem might be due to an incompatibility among these settings:
ediff-patch-program = %S
ediff-patch-options = %S ediff-patch-options = %S
ediff-backup-extension = %S ediff-backup-extension = %S
ediff-backup-specs = %S ediff-backup-specs = %S
are not appropriate for the program specified in the variable
ediff-patch-program = %S
Another reason could be that the %S program doesn't understand
the format of the patch file you used.
See Ediff on-line manual for more details on these variables. See Ediff on-line manual for more details on these variables.
\(Or use a GNU-compatible patch program and stay out of trouble.\) In particular, check the documentation for `ediff-backup-specs'. "
ediff-patch-program
Type any key to continue... ediff-patch-program
"
ediff-patch-options ediff-patch-options
ediff-backup-extension ediff-backup-extension
ediff-backup-specs ediff-backup-specs
ediff-patch-program )))
ediff-patch-program)))
(beep 1) (beep 1)
(if (setq aux-wind (get-buffer-window ediff-msg-buffer)) (if (setq aux-wind (get-buffer-window ediff-msg-buffer))
(progn (progn
(select-window aux-wind) (select-window aux-wind)
(goto-char (point-max)))) (goto-char (point-max))))
(read-char-exclusive) (switch-to-buffer-other-window patch-diagnostics)
(if aux-wind (bury-buffer)) ; ediff-msg-buffer
(if (setq aux-wind (get-buffer-window patch-diagnostics))
(progn
(select-window aux-wind)
(bury-buffer)))
(error "Patch appears to have failed"))) (error "Patch appears to have failed")))
;; If black magic is involved, apply patch to a temp copy of the ;; If black magic is involved, apply patch to a temp copy of the

View File

@ -101,6 +101,7 @@ This mode is entered through one of the following commands:
`ediff-patch-file' `ediff-patch-file'
`ediff-patch-buffer' `ediff-patch-buffer'
`epatch-buffer' `epatch-buffer'
`erevision'
`ediff-revision' `ediff-revision'
Commands: Commands:
@ -404,7 +405,10 @@ to invocation.")
(or (memq control-buffer ediff-this-buffer-ediff-sessions) (or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions (setq ediff-this-buffer-ediff-sessions
(cons control-buffer ediff-this-buffer-ediff-sessions))) (cons control-buffer ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t))
) )
(ediff-eval-in-buffer ediff-buffer-B (ediff-eval-in-buffer ediff-buffer-B
(ediff-nuke-selective-display) (ediff-nuke-selective-display)
(run-hooks 'ediff-prepare-buffer-hook) (run-hooks 'ediff-prepare-buffer-hook)
@ -414,7 +418,10 @@ to invocation.")
(or (memq control-buffer ediff-this-buffer-ediff-sessions) (or (memq control-buffer ediff-this-buffer-ediff-sessions)
(setq ediff-this-buffer-ediff-sessions (setq ediff-this-buffer-ediff-sessions
(cons control-buffer ediff-this-buffer-ediff-sessions))) (cons control-buffer ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t))
) )
(if ediff-3way-job (if ediff-3way-job
(ediff-eval-in-buffer ediff-buffer-C (ediff-eval-in-buffer ediff-buffer-C
(ediff-nuke-selective-display) (ediff-nuke-selective-display)
@ -424,6 +431,8 @@ to invocation.")
(setq ediff-this-buffer-ediff-sessions (setq ediff-this-buffer-ediff-sessions
(cons control-buffer (cons control-buffer
ediff-this-buffer-ediff-sessions))) ediff-this-buffer-ediff-sessions)))
(if ediff-make-buffers-readonly-at-startup
(setq buffer-read-only t))
)) ))
(if (ediff-buffer-live-p ediff-ancestor-buffer) (if (ediff-buffer-live-p ediff-ancestor-buffer)

View File

@ -177,7 +177,7 @@ responsibility."
Expects three parameters: the control buffer, the desired width and height Expects three parameters: the control buffer, the desired width and height
of the control frame. It returns an association list of the control frame. It returns an association list
of the form \(\(top . <position>\) \(left . <position>\)\)" of the form \(\(top . <position>\) \(left . <position>\)\)"
:type 'boolean :type 'function
:group 'ediff-window) :group 'ediff-window)
(defcustom ediff-control-frame-upward-shift (if ediff-xemacs-p 42 14) (defcustom ediff-control-frame-upward-shift (if ediff-xemacs-p 42 14)

View File

@ -6,8 +6,8 @@
;; Created: February 2, 1994 ;; Created: February 2, 1994
;; Keywords: comparing, merging, patching, version control. ;; Keywords: comparing, merging, patching, version control.
(defconst ediff-version "2.65" "The current version of Ediff") (defconst ediff-version "2.66" "The current version of Ediff")
(defconst ediff-date "May 1, 1997" "Date of last update") (defconst ediff-date "July 9, 1997" "Date of last update")
;; This file is part of GNU Emacs. ;; This file is part of GNU Emacs.
@ -109,6 +109,10 @@
(provide 'ediff) (provide 'ediff)
;; Compiler pacifier ;; Compiler pacifier
(defvar cvs-cookie-handle)
(defvar ediff-last-dir-patch)
(defvar ediff-patch-default-directory)
(and noninteractive (and noninteractive
(eval-when-compile (eval-when-compile
(load-library "dired") (load-library "dired")
@ -136,26 +140,20 @@
(defcustom ediff-use-last-dir nil (defcustom ediff-use-last-dir nil
"*If t, Ediff uses previous directory as default when reading file name." "*If t, Ediff will use previous directory as default when reading file name."
:type 'boolean :type 'boolean
:group 'ediff) :group 'ediff)
(defvar ediff-last-dir-A nil ;; Last directory used by an Ediff command for file-A.
"Last directory used by an Ediff command for file-A.") (defvar ediff-last-dir-A nil)
(defvar ediff-last-dir-B nil ;; Last directory used by an Ediff command for file-B.
"Last directory used by an Ediff command for file-B.") (defvar ediff-last-dir-B nil)
(defvar ediff-last-dir-C nil ;; Last directory used by an Ediff command for file-C.
"Last directory used by an Ediff command for file-C.") (defvar ediff-last-dir-C nil)
(defvar ediff-last-dir-ancestor nil ;; Last directory used by an Ediff command for the ancestor file.
"Last directory used by an Ediff command for the ancestor file.") (defvar ediff-last-dir-ancestor nil)
(defvar ediff-last-merge-autostore-dir ;; Last directory used by an Ediff command as the output directory for merge.
"Last directory used by an Ediff command as the output directory for merge.") (defvar ediff-last-merge-autostore-dir)
;; Some defvars to reduce the number of compiler warnings
(defvar cvs-cookie-handle)
(defvar ediff-last-dir-patch)
(defvar ediff-patch-default-directory)
;; end of compiler pacifier
;; Used as a startup hook to set `_orig' patch file read-only. ;; Used as a startup hook to set `_orig' patch file read-only.
@ -878,7 +876,7 @@ lines. For small regions, use `ediff-regions-wordwise'."
(ediff-regions-internal (ediff-regions-internal
(get-buffer buffer-A) reg-A-beg reg-A-end (get-buffer buffer-A) reg-A-beg reg-A-end
(get-buffer buffer-B) reg-B-beg reg-B-end (get-buffer buffer-B) reg-B-beg reg-B-end
startup-hooks 'ediff-regions-linewise nil))) ; no word mode startup-hooks 'ediff-regions-linewise nil nil))) ; no word mode
;; compare region beg-A to end-A of buffer-A ;; compare region beg-A to end-A of buffer-A
;; to regions beg-B -- end-B in buffer-B. ;; to regions beg-B -- end-B in buffer-B.
@ -1235,6 +1233,10 @@ buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'."
(intern (format "ediff-%S-internal" ediff-version-control-package)) (intern (format "ediff-%S-internal" ediff-version-control-package))
rev1 rev2 startup-hooks) rev1 rev2 startup-hooks)
)) ))
;;;###autoload
(defalias 'erevision 'ediff-revision)
;; Test if version control package is loaded and load if not ;; Test if version control package is loaded and load if not

View File

@ -13,7 +13,8 @@
(defvar vip-minibuffer-vi-face) (defvar vip-minibuffer-vi-face)
(defvar vip-minibuffer-emacs-face) (defvar vip-minibuffer-emacs-face)
(defvar viper-always) (defvar viper-always)
(defvar vip-mode-string ) (defvar vip-mode-string)
(defvar vip-custom-file-name)
(defvar iso-accents-mode) (defvar iso-accents-mode)
(defvar zmacs-region-stays) (defvar zmacs-region-stays)
(defvar mark-even-if-inactive) (defvar mark-even-if-inactive)
@ -77,14 +78,15 @@
(defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l (defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l
?H ?M ?L ?n ?t ?T ?w ?W ?$ ?% ?H ?M ?L ?n ?t ?T ?w ?W ?$ ?%
?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?` ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?`
?; ?, ?0 ?? ?/ ?; ?, ?0 ?? ?/ ?\C-m ?\
) )
"Movement commands") "Movement commands")
;; define vip-movement-command-p ;; define vip-movement-command-p
(vip-test-com-defun vip-movement-command) (vip-test-com-defun vip-movement-command)
(defconst vip-digit-commands '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9) ;; Vi digit commands
"Digit commands") (defconst vip-digit-commands '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
;; define vip-digit-command-p ;; define vip-digit-command-p
(vip-test-com-defun vip-digit-command) (vip-test-com-defun vip-digit-command)
@ -765,7 +767,7 @@ as a Meta key and any number of multiple escapes is allowed."
(defun vip-toggle-key-action () (defun vip-toggle-key-action ()
"Action bound to `vip-toggle-key'." "Action bound to `vip-toggle-key'."
(interactive) (interactive)
(if (and (< vip-expert-level 2) (equal vip-toggle-key "\C-z")) (if (and (< viper-expert-level 2) (equal vip-toggle-key "\C-z"))
(if (vip-window-display-p) (if (vip-window-display-p)
(vip-iconify) (vip-iconify)
(suspend-emacs)) (suspend-emacs))
@ -1358,8 +1360,10 @@ If the prefix argument, ARG, is non-nil, it is used instead of `val'."
(setq vip-last-insertion (nth 4 vip-d-com) (setq vip-last-insertion (nth 4 vip-d-com)
vip-d-char (nth 4 vip-d-com))) vip-d-char (nth 4 vip-d-com)))
(funcall m-com (cons val com)) (funcall m-com (cons val com))
(if (and vip-keep-point-on-repeat (< save-point (point))) (cond ((and (< save-point (point)) vip-keep-point-on-repeat)
(goto-char save-point)) ; go back to before repeat. (goto-char save-point)) ; go back to before repeat.
((and (< save-point (point)) vip-ex-style-editing-in-insert)
(or (bolp) (backward-char 1))))
(if (and (eolp) (not (bolp))) (if (and (eolp) (not (bolp)))
(backward-char 1)) (backward-char 1))
)) ))
@ -2983,9 +2987,9 @@ controlled by the sign of prefix numeric value."
(defun vip-toggle-parse-sexp-ignore-comments () (defun vip-toggle-parse-sexp-ignore-comments ()
(interactive) (interactive)
(setq vip-parse-sexp-ignore-comments (not vip-parse-sexp-ignore-comments)) (setq vip-parse-sexp-ignore-comments (not vip-parse-sexp-ignore-comments))
(prin1 (format "`%%' will %signore parentheses inside the comments" (princ (format
(if vip-parse-sexp-ignore-comments "" "NOT "))) "From now on, `%%' will %signore parentheses inside comment fields"
) (if vip-parse-sexp-ignore-comments "" "NOT "))))
;; sentence ,paragraph and heading ;; sentence ,paragraph and heading
@ -3180,9 +3184,9 @@ the Emacs binding of `/'."
(setq msg "Search becomes vanilla-style"))) (setq msg "Search becomes vanilla-style")))
(t (t
(setq msg "Search style remains unchanged"))) (setq msg "Search style remains unchanged")))
(prin1 msg t))) (princ msg t)))
(defun vip-set-vi-search-style-macros (unset) (defun vip-set-search-style-toggling-macros (unset)
"Set the macros for toggling the search style in Viper's vi-state. "Set the macros for toggling the search style in Viper's vi-state.
The macro that toggles case sensitivity is bound to `//', and the one that The macro that toggles case sensitivity is bound to `//', and the one that
toggles regexp search is bound to `///'. toggles regexp search is bound to `///'.
@ -3203,12 +3207,33 @@ With a prefix argument, this function unsets the macros. "
't) 't)
(if (interactive-p) (if (interactive-p)
(message (message
"// and /// now toggle case-sensitivity and regexp search."))) "// and /// now toggle case-sensitivity and regexp search")))
(vip-unrecord-kbd-macro "//" 'vi-state) (vip-unrecord-kbd-macro "//" 'vi-state)
(sit-for 2) (sit-for 2)
(vip-unrecord-kbd-macro "///" 'vi-state)))) (vip-unrecord-kbd-macro "///" 'vi-state))))
(defun vip-set-emacs-search-style-macros (unset &optional arg-majormode)
(defun vip-set-parsing-style-toggling-macro (unset)
"Set `%%%' to be a macro that toggles whether comment fields should be parsed for matching parentheses.
This is used in conjunction with the `%' command.
With a prefix argument, unsets the macro."
(interactive "P")
(or noninteractive
(if (not unset)
(progn
;; 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)
(if (interactive-p)
(message
"%%%%%% now toggles whether comments should be parsed for matching parentheses")))
(vip-unrecord-kbd-macro "%%%" 'vi-state))))
(defun vip-set-emacs-state-search-style-macros (unset &optional arg-majormode)
"Set the macros for toggling the search style in Viper's emacs-state. "Set the macros for toggling the search style in Viper's emacs-state.
The macro that toggles case sensitivity is bound to `//', and the one that The macro that toggles case sensitivity is bound to `//', and the one that
toggles regexp search is bound to `///'. toggles regexp search is bound to `///'.
@ -3456,7 +3481,7 @@ Null string will repeat previous search."
(error "Buffer not killed")))) (error "Buffer not killed"))))
(defvar vip-smart-suffix-list (defcustom vip-smart-suffix-list
'("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p") '("" "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 `.'. "*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 This is useful when you the current directory contains files with the same
@ -3469,7 +3494,9 @@ Suffixes are tried in the order given and the first suffix for which a
corresponding file exists is selected. If no file exists for any of the corresponding file exists is selected. If no file exists for any of the
suffixes, the user is asked to confirm. suffixes, the user is asked to confirm.
To turn this feature off, set this variable to nil.") To turn this feature off, set this variable to nil."
:type '(set string)
:group 'viper)
;; Try to add suffix to files ending with a `.' ;; Try to add suffix to files ending with a `.'
;; Useful when the user hits RET on a non-completed file name. ;; Useful when the user hits RET on a non-completed file name.
@ -3702,7 +3729,13 @@ cursor move past the beginning of line."
(progn (progn
(forward-line 1) (forward-line 1)
(delete-region (point) (1- (point))) (delete-region (point) (1- (point)))
(fixup-whitespace))))))) (fixup-whitespace)
;; fixup-whitespace sometimes does not leave space
;; between objects, so we insert it as in Vi
(or (looking-at " ")
(insert " ")
(backward-char 1))
))))))
;; Replace state ;; Replace state
@ -4131,7 +4164,7 @@ One can use `` and '' to temporarily jump 1 step back."
(pop-mark))) (pop-mark)))
(defun vip-set-expert-level (&optional dont-change-unless) (defun viper-set-expert-level (&optional dont-change-unless)
"Sets the expert level for a Viper user. "Sets the expert level for a Viper user.
Can be called interactively to change (temporarily or permanently) the Can be called interactively to change (temporarily or permanently) the
current expert level. current expert level.
@ -4145,11 +4178,11 @@ sensitive for VI-style look-and-feel."
(interactive) (interactive)
(if (not (natnump vip-expert-level)) (setq vip-expert-level 0)) (if (not (natnump viper-expert-level)) (setq viper-expert-level 0))
(save-window-excursion (save-window-excursion
(delete-other-windows) (delete-other-windows)
;; if 0 < vip-expert-level < vip-max-expert-level ;; if 0 < viper-expert-level < viper-max-expert-level
;; & dont-change-unless = t -- use it; else ask ;; & dont-change-unless = t -- use it; else ask
(vip-ask-level dont-change-unless)) (vip-ask-level dont-change-unless))
@ -4158,7 +4191,7 @@ sensitive for VI-style look-and-feel."
vip-ex-style-editing-in-insert t vip-ex-style-editing-in-insert t
vip-want-ctl-h-help nil) vip-want-ctl-h-help nil)
(cond ((eq vip-expert-level 1) ; novice or beginner (cond ((eq viper-expert-level 1) ; novice or beginner
(global-set-key ; in emacs-state (global-set-key ; in emacs-state
vip-toggle-key vip-toggle-key
(if (vip-window-display-p) 'vip-iconify 'suspend-emacs)) (if (vip-window-display-p) 'vip-iconify 'suspend-emacs))
@ -4170,68 +4203,60 @@ sensitive for VI-style look-and-feel."
vip-want-emacs-keys-in-vi nil vip-want-emacs-keys-in-vi nil
vip-want-emacs-keys-in-insert nil)) vip-want-emacs-keys-in-insert nil))
((and (> vip-expert-level 1) (< vip-expert-level 5)) ((and (> viper-expert-level 1) (< viper-expert-level 5))
;; intermediate to guru ;; intermediate to guru
(setq vip-no-multiple-ESC (if (vip-window-display-p) (setq vip-no-multiple-ESC (if (vip-window-display-p)
t 'twice) t 'twice)
vip-electric-mode t vip-electric-mode t
vip-want-emacs-keys-in-vi t vip-want-emacs-keys-in-vi t
vip-want-emacs-keys-in-insert (> vip-expert-level 2)) vip-want-emacs-keys-in-insert (> viper-expert-level 2))
(if (eq vip-expert-level 4) ; respect user's ex-style motion (if (eq viper-expert-level 4) ; respect user's ex-style motion
; and vip-no-multiple-ESC ; and vip-no-multiple-ESC
(progn (progn
(setq-default vip-ex-style-editing-in-insert (setq-default
(cdr (assoc 'vip-ex-style-editing-in-insert vip-ex-style-editing-in-insert
vip-saved-user-settings)) (viper-standard-value 'vip-ex-style-editing-in-insert)
vip-ex-style-motion vip-ex-style-motion
(cdr (assoc 'vip-ex-style-motion (viper-standard-value 'vip-ex-style-motion))
vip-saved-user-settings)))
(setq vip-ex-style-motion (setq vip-ex-style-motion
(cdr (assoc 'vip-ex-style-motion vip-saved-user-settings)) (viper-standard-value 'vip-ex-style-motion)
vip-ex-style-editing-in-insert vip-ex-style-editing-in-insert
(cdr (assoc 'vip-ex-style-editing-in-insert (viper-standard-value 'vip-ex-style-editing-in-insert)
vip-saved-user-settings))
vip-re-search vip-re-search
(cdr (assoc 'vip-re-search vip-saved-user-settings)) (viper-standard-value 'vip-re-search)
vip-no-multiple-ESC vip-no-multiple-ESC
(cdr (assoc 'vip-no-multiple-ESC (viper-standard-value 'vip-no-multiple-ESC)))))
vip-saved-user-settings))))))
;; A wizard!! ;; A wizard!!
;; Ideally, if 5 is selected, a buffer should pop up to let the ;; Ideally, if 5 is selected, a buffer should pop up to let the
;; user toggle the values of variables. ;; user toggle the values of variables.
(t (setq-default vip-ex-style-editing-in-insert (t (setq-default vip-ex-style-editing-in-insert
(cdr (assoc 'vip-ex-style-editing-in-insert (viper-standard-value 'vip-ex-style-editing-in-insert)
vip-saved-user-settings))
vip-ex-style-motion vip-ex-style-motion
(cdr (assoc 'vip-ex-style-motion (viper-standard-value 'vip-ex-style-motion))
vip-saved-user-settings)))
(setq vip-want-ctl-h-help (setq vip-want-ctl-h-help
(cdr (assoc 'vip-want-ctl-h-help vip-saved-user-settings)) (viper-standard-value 'vip-want-ctl-h-help)
viper-always viper-always
(cdr (assoc 'viper-always vip-saved-user-settings)) (viper-standard-value 'viper-always)
vip-no-multiple-ESC vip-no-multiple-ESC
(cdr (assoc 'vip-no-multiple-ESC vip-saved-user-settings)) (viper-standard-value 'vip-no-multiple-ESC)
vip-ex-style-motion vip-ex-style-motion
(cdr (assoc 'vip-ex-style-motion vip-saved-user-settings)) (viper-standard-value 'vip-ex-style-motion)
vip-ex-style-editing-in-insert vip-ex-style-editing-in-insert
(cdr (assoc 'vip-ex-style-editing-in-insert (viper-standard-value 'vip-ex-style-editing-in-insert)
vip-saved-user-settings))
vip-re-search vip-re-search
(cdr (assoc 'vip-re-search vip-saved-user-settings)) (viper-standard-value 'vip-re-search)
vip-electric-mode vip-electric-mode
(cdr (assoc 'vip-electric-mode (viper-standard-value 'vip-electric-mode)
vip-saved-user-settings))
vip-want-emacs-keys-in-vi vip-want-emacs-keys-in-vi
(cdr (assoc 'vip-want-emacs-keys-in-vi (viper-standard-value 'vip-want-emacs-keys-in-vi)
vip-saved-user-settings))
vip-want-emacs-keys-in-insert vip-want-emacs-keys-in-insert
(cdr (assoc 'vip-want-emacs-keys-in-insert (viper-standard-value 'vip-want-emacs-keys-in-insert))))
vip-saved-user-settings)))))
(vip-set-mode-vars-for vip-current-state) (vip-set-mode-vars-for vip-current-state)
(if (or viper-always (if (or viper-always
(and (> vip-expert-level 0) (> 5 vip-expert-level))) (and (> viper-expert-level 0) (> 5 viper-expert-level)))
(vip-set-hooks))) (vip-set-hooks)))
;; Ask user expert level. ;; Ask user expert level.
@ -4241,48 +4266,8 @@ sensitive for VI-style look-and-feel."
(save-window-excursion (save-window-excursion
(switch-to-buffer ask-buffer) (switch-to-buffer ask-buffer)
(or (eq this-command 'vip-set-expert-level) (while (or (> viper-expert-level viper-max-expert-level)
(and (< viper-expert-level 1)
(<= vip-expert-level vip-max-expert-level)
(>= vip-expert-level 1))
(progn
(insert "
*** Important Notice for VIP users***
This is VIPER
@joke
Viper Is a Package for Emacs Rebels,
a VI Plan for Emacs Rescue,
and a venomous VI PERil.
@end joke
Technically speaking, Viper is a new Vi emulator that replaces
the old VIP package.
Viper emulates Vi much better than VIP. It also significantly
extends and improves upon Vi in many useful ways.
Although many VIP settings in your ~/.vip are compatible with Viper,
you may have to change some of them. Please refer to the documentation,
which can be obtained by executing
:help
when Viper is in Vi state.
If you will be so lucky as to find a bug, report it via the command
:submitReport
Type any key to continue... ")
(read-char)
(erase-buffer)))
(while (or (> vip-expert-level vip-max-expert-level)
(< vip-expert-level 1)
(null dont-change-unless)) (null dont-change-unless))
(erase-buffer) (erase-buffer)
(if repeated (if repeated
@ -4295,7 +4280,7 @@ Type any key to continue... ")
(insert " (insert "
Please specify your level of familiarity with the venomous VI PERil Please specify your level of familiarity with the venomous VI PERil
(and the VI Plan for Emacs Rescue). (and the VI Plan for Emacs Rescue).
You can change it at any time by typing `M-x vip-set-expert-level RET' You can change it at any time by typing `M-x viper-set-expert-level RET'
1 -- BEGINNER: Almost all Emacs features are suppressed. 1 -- BEGINNER: Almost all Emacs features are suppressed.
Feels almost like straight Vi. File name completion and Feels almost like straight Vi. File name completion and
@ -4315,7 +4300,7 @@ You can change it at any time by typing `M-x vip-set-expert-level RET'
Please, specify your level now: ") Please, specify your level now: ")
(setq vip-expert-level (- (vip-read-char-exclusive) ?0)) (setq viper-expert-level (- (vip-read-char-exclusive) ?0))
) ; end while ) ; end while
;; tell the user if level was changed ;; tell the user if level was changed
@ -4323,12 +4308,12 @@ Please, specify your level now: ")
(progn (progn
(insert (insert
(format "\n\n\n\n\n\t\tYou have selected user level %d" (format "\n\n\n\n\n\t\tYou have selected user level %d"
vip-expert-level)) viper-expert-level))
(if (y-or-n-p "Do you wish to make this change permanent? ") (if (y-or-n-p "Do you wish to make this change permanent? ")
;; save the setting for vip-expert-level ;; save the setting for viper-expert-level
(vip-save-setting (vip-save-setting
'vip-expert-level 'viper-expert-level
(format "Saving user level %d ..." vip-expert-level) (format "Saving user level %d ..." viper-expert-level)
vip-custom-file-name)) vip-custom-file-name))
)) ))
(bury-buffer) ; remove ask-buffer from screen (bury-buffer) ; remove ask-buffer from screen
@ -4368,7 +4353,7 @@ Please, specify your level now: ")
(defun vip-save-kill-buffer () (defun vip-save-kill-buffer ()
"Save then kill current buffer. " "Save then kill current buffer. "
(interactive) (interactive)
(if (< vip-expert-level 2) (if (< viper-expert-level 2)
(save-buffers-kill-emacs) (save-buffers-kill-emacs)
(save-buffer) (save-buffer)
(kill-buffer (current-buffer)))) (kill-buffer (current-buffer))))
@ -4442,7 +4427,7 @@ Please, specify your level now: ")
'vip-emacs-state-hook 'vip-emacs-state-hook
'ex-cycle-other-window 'ex-cycle-other-window
'ex-cycle-through-non-files 'ex-cycle-through-non-files
'vip-expert-level 'viper-expert-level
'major-mode 'major-mode
'vip-device-type 'vip-device-type
'color-display-p 'color-display-p

View File

@ -31,7 +31,7 @@
(defvar vip-ex-history) (defvar vip-ex-history)
(defvar vip-related-files-and-buffers-ring) (defvar vip-related-files-and-buffers-ring)
(defvar vip-local-search-start-marker) (defvar vip-local-search-start-marker)
(defvar vip-expert-level) (defvar viper-expert-level)
(defvar vip-custom-file-name) (defvar vip-custom-file-name)
(defvar vip-case-fold-search) (defvar vip-case-fold-search)
(defvar explicit-shell-file-name) (defvar explicit-shell-file-name)
@ -52,6 +52,12 @@
(require 'viper-util) (require 'viper-util)
(defgroup viper-ex nil
"Viper support for Ex commands"
:prefix "ex-"
:group 'viper)
;;; Variables ;;; Variables
@ -112,10 +118,9 @@
;; Value of ex count. ;; Value of ex count.
(defvar ex-count nil) (defvar ex-count nil)
;; Flag for global command. ;; Flag indicating that :global Ex command is being executed.
(defvar ex-g-flag nil) (defvar ex-g-flag nil)
;; Flag indicating that :vglobal Ex command is being executed.
;; If t, global command is executed on lines not matching ex-g-pat.
(defvar ex-g-variant nil) (defvar ex-g-variant nil)
;; Save reg-exp used in substitute. ;; Save reg-exp used in substitute.
@ -128,8 +133,7 @@
;; Pattern for global command. ;; Pattern for global command.
(defvar ex-g-pat nil) (defvar ex-g-pat nil)
(defcustom ex-unix-type-shell
(defvar ex-unix-type-shell
(let ((case-fold-search t)) (let ((case-fold-search t))
(and (stringp shell-file-name) (and (stringp shell-file-name)
(string-match (string-match
@ -146,9 +150,11 @@
"bash$\\|bash.exe$" "bash$\\|bash.exe$"
"\\)") "\\)")
shell-file-name))) shell-file-name)))
"Is the user using a unix-type shell?") "Is the user using a unix-type shell under a non-OS?"
:type 'string
:group 'viper-ex)
(defvar ex-unix-type-shell-options (defcustom ex-unix-type-shell-options
(let ((case-fold-search t)) (let ((case-fold-search t))
(if ex-unix-type-shell (if ex-unix-type-shell
(cond ((string-match "\\(csh$\\|csh.exe$\\)" shell-file-name) (cond ((string-match "\\(csh$\\|csh.exe$\\)" shell-file-name)
@ -157,7 +163,9 @@
"-noprofile") ; bash: ignore .profile "-noprofile") ; bash: ignore .profile
))) )))
"Options to pass to the Unix-style shell. "Options to pass to the Unix-style shell.
Don't put `-c' here, as it is added automatically.") Don't put `-c' here, as it is added automatically."
:type 'string
:group 'viper-ex)
(defvar ex-nontrivial-find-file-function (defvar ex-nontrivial-find-file-function
(cond (ex-unix-type-shell 'vip-ex-nontrivial-find-file-unix) (cond (ex-unix-type-shell 'vip-ex-nontrivial-find-file-unix)
@ -190,13 +198,17 @@ Don't put `-c' here, as it is added automatically.")
;; multiple file names. Used for :edit and :next ;; multiple file names. Used for :edit and :next
(defvar vip-keep-reading-filename nil) (defvar vip-keep-reading-filename nil)
(defconst ex-cycle-other-window t (defcustom ex-cycle-other-window t
"*If t, :n and :b cycles through files and buffers in other window. "*If t, :n and :b cycles through files and buffers in other window.
Then :N and :B cycles in the current window. If nil, this behavior is Then :N and :B cycles in the current window. If nil, this behavior is
reversed.") reversed."
:type 'boolean
:group 'viper-ex)
(defconst ex-cycle-through-non-files nil (defcustom ex-cycle-through-non-files nil
"*Cycle through *scratch* and other buffers that don't visit any file.") "*Cycle through *scratch* and other buffers that don't visit any file."
:type 'boolean
:group 'viper-ex)
;; Last shell command executed with :! command. ;; Last shell command executed with :! command.
(defvar vip-ex-last-shell-com nil) (defvar vip-ex-last-shell-com nil)
@ -427,7 +439,7 @@ reversed.")
"*[ \t]*$")) "*[ \t]*$"))
(stay-regex (concat (stay-regex (concat
"\\(" "^[ \t]*$" "\\(" "^[ \t]*$"
"\\|" "[?/].*[?/].*" "\\|" "[?/].*"
"\\|" "[ktgjmsz][ \t]*$" "\\|" "[ktgjmsz][ \t]*$"
"\\|" "^[ \t]*ab.*" "\\|" "^[ \t]*ab.*"
"\\|" "tr[ansfer \t]*" "\\|" "tr[ansfer \t]*"
@ -503,7 +515,6 @@ reversed.")
;; Read Ex commands ;; Read Ex commands
;; Ex commands themselves are implemented in viper-ex.el
(defun vip-ex (&optional string) (defun vip-ex (&optional string)
(interactive) (interactive)
(or string (or string
@ -613,7 +624,15 @@ reversed.")
(setq ex-token (setq ex-token
(if (= (mark t) (point)) "" (if (= (mark t) (point)) ""
(buffer-substring (1- (point)) (mark t)))) (buffer-substring (1- (point)) (mark t))))
(backward-char 1)) (backward-char 1)
;; if the user doesn't specify the final pattern delimiter, we're
;; at newline now. In this case, insert the initial delimiter
;; specified in variable c
(if (looking-at "\n")
(progn
(insert c)
(backward-char 1)))
)
(setq ex-token nil)) (setq ex-token nil))
c))) c)))
@ -1233,6 +1252,14 @@ reversed.")
;; Ex global command ;; Ex global command
;; This is executed in response to:
;; :global "pattern" ex-command
;; :vglobal "pattern" ex-command
;; :global executes ex-command on all lines matching <pattern>
;; :vglobal executes ex-command on all lines that don't match <pattern>
;;
;; With VARIANT nil, this functions executes :global
;; With VARIANT t, executes :vglobal
(defun ex-global (variant) (defun ex-global (variant)
(let ((gcommand ex-token)) (let ((gcommand ex-token))
(if (or ex-g-flag ex-g-variant) (if (or ex-g-flag ex-g-variant)
@ -1255,8 +1282,11 @@ reversed.")
(if (null ex-addresses) (if (null ex-addresses)
(setq ex-addresses (list (point-max) (point-min))) (setq ex-addresses (list (point-max) (point-min)))
(vip-default-ex-addresses)) (vip-default-ex-addresses))
(let ((marks nil) (mark-count 0) (let ((marks nil)
com-str (end (car ex-addresses)) (beg (car (cdr ex-addresses)))) (mark-count 0)
(end (car ex-addresses))
(beg (car (cdr ex-addresses)))
com-str)
(if (> beg end) (error vip-FirstAddrExceedsSecond)) (if (> beg end) (error vip-FirstAddrExceedsSecond))
(save-excursion (save-excursion
(vip-enlarge-region beg end) (vip-enlarge-region beg end)
@ -1492,7 +1522,7 @@ reversed.")
(setq vip-ex-work-buf (get-buffer-create vip-ex-work-buf-name)) (setq vip-ex-work-buf (get-buffer-create vip-ex-work-buf-name))
(set-buffer vip-ex-work-buf) (set-buffer vip-ex-work-buf)
(if (looking-at "!") (forward-char 1))) (if (looking-at "!") (forward-char 1)))
(if (< vip-expert-level 3) (if (< viper-expert-level 3)
(save-buffers-kill-emacs) (save-buffers-kill-emacs)
(kill-buffer (current-buffer)))) (kill-buffer (current-buffer))))
@ -1984,7 +2014,7 @@ Please contact your system administrator. "
(not writing-same-file) (not writing-same-file)
(set-buffer-modified-p t)) (set-buffer-modified-p t))
(if q-flag (if q-flag
(if (< vip-expert-level 2) (if (< viper-expert-level 2)
(save-buffers-kill-emacs) (save-buffers-kill-emacs)
(kill-buffer (current-buffer)))) (kill-buffer (current-buffer))))
))) )))

View File

@ -26,6 +26,8 @@
;; compiler pacifier ;; compiler pacifier
(defvar mark-even-if-inactive) (defvar mark-even-if-inactive)
(defvar viper-version) (defvar viper-version)
(defvar viper-expert-level)
(defvar vip-expert-level)
;; end pacifier ;; end pacifier
@ -48,15 +50,24 @@
(defun vip-window-display-p () (defun vip-window-display-p ()
(and (vip-device-type) (not (memq (vip-device-type) '(tty stream pc))))) (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)) (defcustom 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.") "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)) :type 'boolean
"Tells if Emacs is running under VMS.") :tag "Is it Microsoft-made OS?"
:group 'viper)
(defcustom vip-vms-os-p (memq system-type '(vax-vms axp-vms))
"Tells if Emacs is running under VMS."
:type 'boolean
:tag "Is it VMS?"
:group 'viper)
(defvar vip-force-faces nil (defcustom vip-force-faces nil
"If t, Viper will think that it is running on a display that supports faces. "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 This is provided as a temporary relief for users of graphics-capable terminals
that Viper doesn't know about.") that Viper doesn't know about.
In all likelihood, you don't need to bother with this setting."
:type 'boolean
:group 'viper)
(defun vip-has-face-support-p () (defun vip-has-face-support-p ()
(cond ((vip-window-display-p)) (cond ((vip-window-display-p))
@ -235,29 +246,28 @@ that deletes a file.")
;; Prevents recursive descend into startup messages. ;; Prevents recursive descend into startup messages.
(defvar vip-first-time t) (defvar vip-first-time t)
(defvar vip-expert-level 0 (defvar viper-expert-level (if (boundp 'vip-expert-level) vip-expert-level 0)
"User's expert level. "User's expert level.
The minor mode vip-vi-diehard-minor-mode is in effect when 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. viper-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 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. viper-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.") Use `M-x viper-set-expert-level' to change this.")
;; Max expert level supported by Viper. This is NOT a user option. ;; 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. ;; It is here to make it hard for the user from resetting it.
(defconst vip-max-expert-level 5) (defconst viper-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 ;;; ISO characters
(vip-deflocalvar vip-automatic-iso-accents nil (vip-deflocalvar vip-automatic-iso-accents nil "")
(defcustom 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. "*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 For some users, this behavior may be too primitive. In this case, use
insert/emacs/vi state hooks.") insert/emacs/vi state hooks."
:type 'boolean
:group 'viper)
;; VI-style Undo ;; VI-style Undo
@ -271,10 +281,13 @@ insert/emacs/vi state hooks.")
;; erased by vip-change-state-to-vi and vip-repeat. ;; erased by vip-change-state-to-vi and vip-repeat.
(defconst vip-buffer-undo-list-mark 'viper) (defconst vip-buffer-undo-list-mark 'viper)
(defvar vip-keep-point-on-undo nil (defcustom vip-keep-point-on-undo nil
"*Non-nil means not to move point while undoing commands. "*Non-nil means not to move point while undoing commands.
This style is different from Emacs and Vi. Try it to see if This style is different from Emacs and Vi. Try it to see if
it better fits your working style.") it better fits your working style."
:type 'boolean
:tag "Preserve Position of Point After Undo"
:group 'viper)
;; Replace mode and changing text ;; Replace mode and changing text
@ -291,41 +304,57 @@ it better fits your working style.")
;; Indicates that the current destructive command has started in replace mode. ;; Indicates that the current destructive command has started in replace mode.
(vip-deflocalvar vip-began-as-replace nil "") (vip-deflocalvar vip-began-as-replace nil "")
(defvar vip-allow-multiline-replace-regions t (defcustom vip-allow-multiline-replace-regions t
"If non-nil, Viper will allow multi-line replace regions. "If non-nil, Viper will allow multi-line replace regions.
This is an extension to standard Vi. This is an extension to standard Vi.
If nil, commands that attempt to replace text spanning multiple lines first If nil, commands that attempt to replace text spanning multiple lines first
delete the text being replaced, as in standard Vi.") delete the text being replaced, as in standard Vi."
:type 'boolean
:group 'viper)
(defcustom vip-replace-overlay-cursor-color "Red"
"*Cursor color when Viper is in Replace state."
:type 'string
:group 'viper)
(defcustom vip-insert-state-cursor-color "Green"
"Cursor color when Viper is in insert state."
:type 'string
:group 'viper)
(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 ;; place to save cursor colow when switching to insert mode
(vip-deflocalvar vip-saved-cursor-color nil "") (vip-deflocalvar vip-saved-cursor-color nil "")
(vip-deflocalvar vip-replace-overlay nil "") (vip-deflocalvar vip-replace-overlay nil "")
(put 'vip-replace-overlay 'permanent-local t) (put 'vip-replace-overlay 'permanent-local t)
(defvar vip-replace-overlay-pixmap "gray3" (defcustom vip-replace-overlay-pixmap "gray3"
"Pixmap to use for search face on non-color displays.") "Pixmap to use for search face on non-color displays."
(defvar vip-search-face-pixmap "gray3" :type 'string
"Pixmap to use for search face on non-color displays.") :group 'viper)
(defcustom vip-search-face-pixmap "gray3"
"Pixmap to use for search face on non-color displays."
:type 'string
:group 'viper)
(defvar vip-replace-region-end-delimiter "$" (defcustom vip-replace-region-end-delimiter "$"
"A string marking the end of replacement regions. "A string marking the end of replacement regions.
It is used only with TTYs or if `vip-use-replace-region-delimiters' It is used only with TTYs or if `vip-use-replace-region-delimiters'
is non-nil.") is non-nil."
(defvar vip-replace-region-start-delimiter "" :type 'string
:group 'viper)
(defcustom vip-replace-region-start-delimiter ""
"A string marking the beginning of replacement regions. "A string marking the beginning of replacement regions.
It is used only with TTYs or if `vip-use-replace-region-delimiters' It is used only with TTYs or if `vip-use-replace-region-delimiters'
is non-nil.") is non-nil."
(defvar vip-use-replace-region-delimiters (not (vip-has-face-support-p)) :type 'string
:group 'viper)
(defcustom vip-use-replace-region-delimiters (not (vip-has-face-support-p))
"*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and
`vip-replace-region-start-delimiter' to delimit replacement regions, even on `vip-replace-region-start-delimiter' to delimit replacement regions, even on
color displays. By default, the delimiters are used only on TTYs.") color displays. By default, the delimiters are used only on TTYs."
:type 'boolean
:group 'viper)
;; XEmacs requires glyphs ;; XEmacs requires glyphs
(if vip-xemacs-p (if vip-xemacs-p
@ -358,8 +387,12 @@ color displays. By default, the delimiters are used only on TTYs.")
(vip-deflocalvar vip-replace-chars-deleted 0 "") (vip-deflocalvar vip-replace-chars-deleted 0 "")
;; Insertion ring and command ring ;; Insertion ring and command ring
(defvar vip-insertion-ring-size 14 (defcustom vip-insertion-ring-size 14
"The size of the insertion ring.") "The size of history of inserted text.
This is a list where Viper keeps the history of previously inserted pieces of
text."
:type 'integer
:group 'viper)
;; The insertion ring. ;; The insertion ring.
(defvar vip-insertion-ring nil) (defvar vip-insertion-ring nil)
;; This is temp insertion ring. Used to do rotation for display purposes. ;; This is temp insertion ring. Used to do rotation for display purposes.
@ -367,14 +400,33 @@ color displays. By default, the delimiters are used only on TTYs.")
(defvar vip-temp-insertion-ring nil) (defvar vip-temp-insertion-ring nil)
(defvar vip-last-inserted-string-from-insertion-ring "") (defvar vip-last-inserted-string-from-insertion-ring "")
(defvar vip-command-ring-size 14 (defcustom vip-command-ring-size 14
"The size of the command ring.") "The size of history of Vi commands repeatable with dot."
:type 'integer
:group 'viper)
;; The command ring. ;; The command ring.
(defvar vip-command-ring nil) (defvar vip-command-ring nil)
;; This is temp command ring. Used to do rotation for display purposes. ;; This is temp command ring. Used to do rotation for display purposes.
;; When rotation just started, it is initialized to vip-command-ring. ;; When rotation just started, it is initialized to vip-command-ring.
(defvar vip-temp-command-ring nil) (defvar vip-temp-command-ring nil)
;; Fast keyseq and ESC keyseq timeouts
(defcustom vip-fast-keyseq-timeout 200
"*Key sequence separated by no more than this many milliseconds is viewed as a Vi-style macro, if such a macro is defined.
Setting this too high may slow down your typing. Setting this value too low
will make it hard to use Vi-stile timeout macros."
:type 'integer
:group 'viper)
(defcustom vip-ESC-keyseq-timeout (if (vip-window-display-p)
0 vip-fast-keyseq-timeout)
"*Key sequence beginning with ESC and separated by no more than this many milliseconds is considered to be generated by a keyboard function key.
Setting this too high may slow down switching from insert to vi state. Setting
this value too low will make it impossible to use function keys in insert mode
on a dumb terminal."
:type 'integer
:group 'viper)
;; Modes and related variables ;; Modes and related variables
;; Current mode. One of: `emacs-state', `vi-state', `insert-state' ;; Current mode. One of: `emacs-state', `vi-state', `insert-state'
@ -392,22 +444,38 @@ color displays. By default, the delimiters are used only on TTYs.")
;; Whether to preserve the indent, used by C-d in insert mode. ;; Whether to preserve the indent, used by C-d in insert mode.
(vip-deflocalvar vip-preserve-indent nil) (vip-deflocalvar vip-preserve-indent nil)
(vip-deflocalvar vip-auto-indent nil (vip-deflocalvar vip-auto-indent nil "")
"*Autoindent if t.") (defcustom vip-auto-indent nil
(vip-deflocalvar vip-electric-mode t "*Enable autoindent, if t.
"*If t, enable electric behavior. This is a buffer-local variable."
Currently only enables auto-indentation `according to mode'.") :type 'boolean
:group 'viper)
(defconst vip-shift-width 8 (vip-deflocalvar vip-electric-mode t "")
"*The shiftwidth variable.") (defcustom vip-electric-mode t
"*If t, electrify Viper.
Currently, this only electrifies auto-indentation, making it appropriate to the
mode of the buffer.
This means that auto-indentation will depart from standard Vi and will indent
appropriate to the mode of the buffer. This is especially useful for editing
programs and LaTeX documents."
:type 'boolean
:group 'viper)
(defcustom vip-shift-width 8
"*The shiftwidth variable."
:type 'integer
:group 'viper)
;; Variables for repeating destructive commands ;; Variables for repeating destructive commands
(defconst vip-keep-point-on-repeat t (defcustom vip-keep-point-on-repeat t
"*If t, don't move point when repeating previous command. "*If t, don't move point when repeating previous command.
This is useful for doing repeated changes with the '.' key. This is useful for doing repeated changes with the '.' key.
The user can change this to nil, if she likes when the cursor moves The user can change this to nil, if she likes when the cursor moves
to a new place after repeating previous Vi command.") to a new place after repeating previous Vi command."
:type 'boolean
:group 'viper)
;; Remember insert point as a marker. This is a local marker that must be ;; Remember insert point as a marker. This is a local marker that must be
;; initialized to nil and moved with `vip-move-marker-locally'. ;; initialized to nil and moved with `vip-move-marker-locally'.
@ -482,55 +550,96 @@ to a new place after repeating previous Vi command.")
;; Last search string ;; Last search string
(defvar vip-s-string "") (defvar vip-s-string "")
(defvar vip-quote-string "> " (defcustom vip-quote-string "> "
"String inserted at the beginning of quoted region.") "String inserted at the beginning of quoted region."
:type 'string
:group 'viper)
;; If t, search is forward. ;; If t, search is forward.
(defvar vip-s-forward nil) (defvar vip-s-forward nil)
(defconst vip-case-fold-search nil (defcustom vip-case-fold-search nil
"*If not nil, search ignores cases.") "*If not nil, search ignores cases."
:type 'boolean
:group 'viper)
(defconst vip-re-search t (defcustom vip-re-search t
"*If not nil, search is reg-exp search, otherwise vanilla search.") "*If not nil, search is regexp search, otherwise vanilla search."
:type 'boolean
:tag "Regexp Search"
:group 'viper)
(defvar vip-search-scroll-threshold 2 (defcustom vip-search-scroll-threshold 2
"*If search lands within this threshnold from the window top/bottom, "*If search lands within this threshnold from the window top/bottom,
the window will be scrolled up or down appropriately, to reveal context. 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 If you want Viper search to behave as usual in Vi, set this variable to a
negative number.") negative number."
:type 'boolean
:group 'viper)
(defconst vip-re-query-replace t (defcustom vip-re-query-replace t
"*If t then do regexp replace, if nil then do string replace.") "*If t then do regexp replace, if nil then do string replace."
:type 'boolean
:tag "Regexp Query Replace"
:group 'viper)
(defconst vip-re-replace t (defcustom vip-re-replace t
"*If t, do regexp replace. nil means do string replace.") "*If t, do regexp replace. nil means do string replace."
:type 'boolean
:tag "Regexp Replace"
:group 'viper)
(defvar vip-parse-sexp-ignore-comments t (defcustom vip-parse-sexp-ignore-comments t
"*If t, `%' ignores the parentheses that occur inside comments.") "*If t, `%' ignores the parentheses that occur inside comments."
:type 'boolean
:group 'viper)
(vip-deflocalvar vip-ex-style-motion t (vip-deflocalvar vip-ex-style-motion t "")
"*Ex-style: the commands l,h do not cross lines, etc.") (defcustom vip-ex-style-motion t
"*If t, the commands l,h do not cross lines, etc (Ex-style).
If nil, these commands cross line boundaries."
:type 'boolean
:group 'viper)
(vip-deflocalvar vip-ex-style-editing-in-insert t (vip-deflocalvar vip-ex-style-editing-in-insert t "")
"*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc. (defcustom vip-ex-style-editing-in-insert t
Note: this doesn't preclude ^H and ^? from deleting characters by moving "*If t, `Backspace' and `Delete' don't cross line boundaries in insert, etc.
past the insertion point. This is a feature, not a bug. ") Note: this doesn't preclude `Backspace' and `Delete' from deleting characters
by moving past the insertion point. This is a feature, not a bug."
:type 'boolean
:group 'viper)
(vip-deflocalvar vip-delete-backwards-in-replace nil (vip-deflocalvar vip-ESC-moves-cursor-back vip-ex-style-editing-in-insert "")
(defcustom vip-ESC-moves-cursor-back nil
"*If t, ESC moves cursor back when changing from insert to vi state.
If nil, the cursor stays where it was."
:type 'boolean
:group 'viper)
(vip-deflocalvar vip-delete-backwards-in-replace nil "")
(defcustom vip-delete-backwards-in-replace nil
"*If t, DEL key will delete characters while moving the cursor backwards. "*If t, DEL key will delete characters while moving the cursor backwards.
If nil, the cursor will move backwards without deleting anything.") If nil, the cursor will move backwards without deleting anything."
:type 'boolean
:group 'viper)
(defconst vip-buffer-search-char nil (defcustom vip-buffer-search-char nil
"*Key bound for buffer-searching.") "*Key used for buffer-searching. Must be a character type, e.g., ?g."
:type '(choice (const nil) character)
:group 'viper)
(defconst vip-search-wrap-around-t t (defcustom vip-search-wrap-around-t t
"*If t, search wraps around.") "*If t, search wraps around."
:type 'boolean
:tag "Search Wraps Around"
:group 'viper)
(vip-deflocalvar vip-related-files-and-buffers-ring nil (vip-deflocalvar vip-related-files-and-buffers-ring nil "")
"*Ring of file and buffer names that are considered to be related to the (defcustom vip-related-files-and-buffers-ring nil
current buffer. "*List 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.") Related buffers can be cycled through via :R and :P commands."
:type 'boolean
:group 'viper)
(put 'vip-related-files-and-buffers-ring 'permanent-local t) (put 'vip-related-files-and-buffers-ring 'permanent-local t)
;; Used to find out if we are done with searching the current buffer. ;; Used to find out if we are done with searching the current buffer.
@ -599,16 +708,15 @@ These buffers can be cycled through via :R and :P commands.")
(defvar vip-inhibit-startup-message nil (defvar vip-inhibit-startup-message nil
"Whether Viper startup message should be inhibited.") "Whether Viper startup message should be inhibited.")
(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.viper") (defcustom vip-spell-function 'ispell-region
"Viper customisation file. "Spell function used by #s<move> command to spell."
This variable must be set _before_ loading Viper.") :type 'function
:group 'viper)
(defcustom vip-tags-file-name "TAGS"
(defvar vip-spell-function 'ispell-region "The tags file used by Viper."
"Spell function used by #s<move> command to spell.") :type 'string
:group 'viper)
(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 ;; Indicates if we are in the middle of executing a command that takes another
;; command as an argument, e.g., cw, dw, etc. ;; command as an argument, e.g., cw, dw, etc.
@ -616,9 +724,11 @@ This variable must be set _before_ loading Viper.")
;; Minibuffer ;; Minibuffer
(defvar vip-vi-style-in-minibuffer t (defcustom vip-vi-style-in-minibuffer t
"If t, use vi-style editing in minibuffer. "If t, use vi-style editing in minibuffer.
Should be set in `~/.vip' file.") Should be set in `~/.vip' file."
:type 'boolean
:group 'viper)
;; overlay used in the minibuffer to indicate which state it is in ;; overlay used in the minibuffer to indicate which state it is in
(vip-deflocalvar vip-minibuffer-overlay nil) (vip-deflocalvar vip-minibuffer-overlay nil)
@ -640,16 +750,31 @@ Should be set in `~/.vip' file.")
"Mode line tag identifying the Replace mode of Viper.") "Mode line tag identifying the Replace mode of Viper.")
(defvar vip-vi-state-hook nil (defcustom vip-vi-state-hook nil
"*Hooks run just before the switch to Vi mode is completed.") "*Hooks run just before the switch to Vi mode is completed."
(defvar vip-insert-state-hook nil :type 'hook
"*Hooks run just before the switch to Insert mode is completed.") :group 'viper)
(defvar vip-replace-state-hook nil (defcustom vip-insert-state-hook nil
"*Hooks run just before the switch to Replace mode is completed.") "*Hooks run just before the switch to Insert mode is completed."
(defvar vip-emacs-state-hook nil :type 'hook
"*Hooks run just before the switch to Emacs mode is completed.") :group 'viper)
(defcustom vip-replace-state-hook nil
"*Hooks run just before the switch to Replace mode is completed."
:type 'hook
:group 'viper)
(defcustom vip-emacs-state-hook nil
"*Hooks run just before the switch to Emacs mode is completed."
:type 'hook
:group 'viper)
(defvar vip-load-hook nil (defcustom vip-load-hook nil
"Hooks run just after loading Viper.") "Hooks run just after loading Viper."
:type 'hook
:group 'viper)
;;; Local Variables:
;;; eval: (put 'vip-deflocalvar 'lisp-indent-hook 'defun)
;;; End:
;;; viper-ex.el ends here ;;; viper-ex.el ends here

View File

@ -27,7 +27,7 @@
(defvar viper-always) (defvar viper-always)
(defvar vip-current-state) (defvar vip-current-state)
(defvar vip-mode-string) (defvar vip-mode-string)
(defvar vip-expert-level) (defvar viper-expert-level)
(defvar vip-ex-style-editing-in-insert) (defvar vip-ex-style-editing-in-insert)
(defvar vip-ex-style-motion) (defvar vip-ex-style-motion)
@ -59,26 +59,34 @@ This setting cannot be changed interactively.")
;;; Emacs keys in other states. ;;; Emacs keys in other states.
(defvar vip-want-emacs-keys-in-insert t (defcustom vip-want-emacs-keys-in-insert t
"*Set to nil if you want complete Vi compatibility in insert mode. "*Set to nil if you want complete Vi compatibility in insert mode.
Complete compatibility with Vi is not recommended for power use of Viper.") Complete compatibility with Vi is not recommended for power use of Viper."
:type 'boolean
:group 'viper)
(defvar vip-want-emacs-keys-in-vi t (defcustom vip-want-emacs-keys-in-vi t
"*Set to nil if you want complete Vi compatibility in Vi mode. "*Set to nil if you want complete Vi compatibility in Vi mode.
Full Vi compatibility is not recommended for power use of Viper.") Full Vi compatibility is not recommended for power use of Viper."
:type 'boolean
:group 'viper)
(defvar vip-no-multiple-ESC t (defcustom vip-no-multiple-ESC t
"*If true, multiple ESC in Vi mode will cause bell to ring. "*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 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 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 enables cursor keys and is generally more convenient, as terminals usually
don't have a convenient Meta key. don't have a convenient Meta key.
Setting vip-no-multiple-ESC to nil will allow as many multiple ESC, Setting vip-no-multiple-ESC to nil will allow as many multiple ESC,
as is allowed by the major mode in effect.") as is allowed by the major mode in effect."
:type 'boolean
:group 'viper)
(defvar vip-want-ctl-h-help nil (defcustom vip-want-ctl-h-help nil
"*If t then C-h is bound to help-command in insert mode, if nil then it is "*If t then C-h is bound to help-command in insert mode, if nil then it is
bound to delete-backward-char.") bound to delete-backward-char."
:type 'boolean
:group 'viper)
;;; Keymaps ;;; Keymaps
@ -114,7 +122,7 @@ This map is global, shared by all buffers.")
(defvar vip-vi-diehard-map (make-sparse-keymap) (defvar vip-vi-diehard-map (make-sparse-keymap)
"This keymap is in use when the user asks Viper to simulate Vi very closely. "This keymap is in use when the user asks Viper to simulate Vi very closely.
This happens when vip-expert-level is 1 or 2. See vip-set-expert-level.") This happens when viper-expert-level is 1 or 2. See viper-set-expert-level.")
(vip-deflocalvar vip-insert-local-user-map (make-sparse-keymap) (vip-deflocalvar vip-insert-local-user-map (make-sparse-keymap)
@ -584,7 +592,7 @@ Arguments: (major-mode vip-state keymap)"
(princ (format "vip-emacs-state-modifier-minor-mode: %S\n" (princ (format "vip-emacs-state-modifier-minor-mode: %S\n"
vip-emacs-state-modifier-minor-mode)) vip-emacs-state-modifier-minor-mode))
(princ (format "\nvip-expert-level %S\n" vip-expert-level)) (princ (format "\nviper-expert-level %S\n" viper-expert-level))
(princ (format "vip-no-multiple-ESC %S\n" vip-no-multiple-ESC)) (princ (format "vip-no-multiple-ESC %S\n" vip-no-multiple-ESC))
(princ (format "viper-always %S\n" viper-always)) (princ (format "viper-always %S\n" viper-always))
(princ (format "vip-ex-style-motion %S\n" (princ (format "vip-ex-style-motion %S\n"
@ -627,4 +635,9 @@ form ((key . function) (key . function) ... )."
alist)) alist))
;;; Local Variables:
;;; eval: (put 'vip-deflocalvar 'lisp-indent-hook 'defun)
;;; End:
;;; viper-keym.el ends here ;;; viper-keym.el ends here

View File

@ -27,6 +27,7 @@
(defvar vip-ex-work-buf) (defvar vip-ex-work-buf)
(defvar vip-custom-file-name) (defvar vip-custom-file-name)
(defvar vip-current-state) (defvar vip-current-state)
(defvar vip-fast-keyseq-timeout)
;; loading happens only in non-interactive compilation ;; loading happens only in non-interactive compilation
;; in order to spare non-viperized emacs from being viperized ;; in order to spare non-viperized emacs from being viperized
@ -71,19 +72,17 @@
(defvar vip-last-kbd-macro nil (defvar vip-last-kbd-macro nil
"Vector of keys representing the name of last Viper keyboard macro.") "Vector of keys representing the name of last Viper keyboard macro.")
(defconst vip-fast-keyseq-timeout 200 (defcustom vip-repeat-from-history-key 'f12
"*Key sequence separated by no more than this many milliseconds is viewed as a macro, if such a macro is defined. "Prefix key for accessing previously typed Vi commands.
This also controls ESC-keysequences generated by keyboard function keys.")
The previous command is accessible, as usual, via `.'. The command before this
(defvar vip-repeat-from-history-key 'f12 can be invoked as `<this key> 1', and the command before that, and the command
"Prefix key for invocation of vip-repeat-from-history function, before that one is accessible as `<this key> 2'.
which repeats previous destructive commands from the history of such
commands.
This function can then be invoked as <this-key> 1 or <this-key> 2.
The notation for these keys is borrowed from XEmacs. Basically, The notation for these keys is borrowed from XEmacs. Basically,
a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g., a key is a symbol, e.g., `a', `\\1', `f2', etc., or a list, e.g.,
`(meta control f1)'.") `(meta control f1)'."
:type 'key
:group 'viper)
@ -544,7 +543,7 @@ there."
(vip-display-macro macro-name) state-name major-mode)) (vip-display-macro macro-name) state-name major-mode))
((cdr (setq macro-pair (vip-kbd-global-pair macro-entry))) ((cdr (setq macro-pair (vip-kbd-global-pair macro-entry)))
(message (message
"Global mapping of %S for %s is removed" "Global mapping for %S in %s is removed"
(vip-display-macro macro-name) state-name)) (vip-display-macro macro-name) state-name))
(t (error "%S is not mapped to a macro for %s in `%s'" (t (error "%S is not mapped to a macro for %s in `%s'"
(vip-display-macro macro-name) (vip-display-macro macro-name)

View File

@ -47,6 +47,11 @@
(require 'viper-util) (require 'viper-util)
(defgroup viper-mouse nil
"Support for Viper special mouse-bound commands"
:prefix "vip-"
:group 'viper)
;;; Variables ;;; Variables
@ -58,21 +63,25 @@
;; Frame that was selected before the switch-frame event. ;; Frame that was selected before the switch-frame event.
(defconst vip-current-frame-saved (selected-frame)) (defconst vip-current-frame-saved (selected-frame))
(defvar vip-surrounding-word-function 'vip-surrounding-word (defcustom vip-surrounding-word-function 'vip-surrounding-word
"*Function that determines what constitutes a word for clicking events. "*Function that determines what constitutes a word for clicking events.
Takes two parameters: a COUNT, indicating how many words to return, Takes two parameters: a COUNT, indicating how many words to return,
and CLICK-COUNT, telling whether this is the first click, a double-click, and CLICK-COUNT, telling whether this is the first click, a double-click,
or a tripple-click.") or a tripple-click."
:type 'boolean
:group 'viper-mouse)
;; time interval in millisecond within which successive clicks are ;; time interval in millisecond within which successive clicks are
;; considered related ;; considered related
(defconst vip-multiclick-timeout (if (vip-window-display-p) (defcustom vip-multiclick-timeout (if (vip-window-display-p)
(if vip-xemacs-p (if vip-xemacs-p
mouse-track-multi-click-time mouse-track-multi-click-time
double-click-time) double-click-time)
500) 500)
"*Time interval in millisecond within which successive clicks are "*Time interval in millisecond within which successive mouse clicks are
considered related.") considered related."
:type 'integer
:group 'viper-mouse)
;; current event click count; XEmacs only ;; current event click count; XEmacs only
(defvar vip-current-click-count 0) (defvar vip-current-click-count 0)
@ -432,5 +441,9 @@ bindings in the Viper manual."
vip-current-frame-saved (selected-frame))) vip-current-frame-saved (selected-frame)))
;;; Local Variables:
;;; eval: (put 'vip-deflocalvar 'lisp-indent-hook 'defun)
;;; End:
;;; viper-mous.el ends here ;;; viper-mous.el ends here

View File

@ -1065,11 +1065,22 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
(defun vip-key-to-emacs-key (key) (defun vip-key-to-emacs-key (key)
(let (key-name char-p modifiers mod-char-list base-key base-key-name) (let (key-name char-p modifiers mod-char-list base-key base-key-name)
(cond (vip-xemacs-p key) (cond (vip-xemacs-p key)
((symbolp key) ((symbolp key)
(setq key-name (symbol-name key)) (setq key-name (symbol-name key))
(if (= (length key-name) 1) ; character event (cond ((= (length key-name) 1) ; character event
(string-to-char key-name) (string-to-char key-name))
key)) ;; Emacs doesn't recognize `return' and `escape' as events on
;; dumb terminals, so we translate them into characters
((and vip-emacs-p (not (vip-window-display-p))
(string= key-name "return"))
?\C-m)
((and vip-emacs-p (not (vip-window-display-p))
(string= key-name "escape"))
?\e)
;; pass symbol-event as is
(t key)))
((listp key) ((listp key)
(setq modifiers (subseq key 0 (1- (length key))) (setq modifiers (subseq key 0 (1- (length key)))
base-key (vip-seq-last-elt key) base-key (vip-seq-last-elt key)
@ -1129,8 +1140,13 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
"")) ""))
;; Uses different timeouts for ESC-sequences and others
(defsubst vip-fast-keysequence-p () (defsubst vip-fast-keysequence-p ()
(not (vip-sit-for-short vip-fast-keyseq-timeout t))) (not (vip-sit-for-short
(if (vip-ESC-event-p last-input-event)
vip-ESC-keyseq-timeout
vip-fast-keyseq-timeout)
t)))
(defun vip-read-char-exclusive () (defun vip-read-char-exclusive ()
(let (char (let (char
@ -1174,7 +1190,7 @@ the `Local variables' section of a file."
;;; Movement utilities ;;; Movement utilities
(defvar vip-syntax-preference 'strict-vi (defcustom vip-syntax-preference 'strict-vi
"*Syntax type characterizing Viper's alphanumeric symbols. "*Syntax type characterizing Viper's alphanumeric symbols.
`emacs' means only word constituents are considered to be alphanumeric. `emacs' means only word constituents are considered to be alphanumeric.
Word constituents are symbols specified as word constituents by the current Word constituents are symbols specified as word constituents by the current
@ -1183,7 +1199,10 @@ syntax table.
`reformed-vi' means Vi-ish behavior: word constituents and the symbol `_'. `reformed-vi' means Vi-ish behavior: word constituents and the symbol `_'.
However, word constituents are determined according to Emacs syntax tables, However, word constituents are determined according to Emacs syntax tables,
which may be different from Vi in some major modes. which may be different from Vi in some major modes.
`strict-vi' means Viper words are exactly as in Vi.") `strict-vi' means Viper words are exactly as in Vi."
:type '(radio (const strict-vi) (const reformed-vi)
(const extended) (const emacs))
:group 'viper)
(vip-deflocalvar vip-ALPHA-char-class "w" (vip-deflocalvar vip-ALPHA-char-class "w"
"String of syntax classes characterizing Viper's alphanumeric symbols. "String of syntax classes characterizing Viper's alphanumeric symbols.
@ -1311,7 +1330,11 @@ Must be called in order for changes to `vip-syntax-preference' to take effect."
(provide 'viper-util) (provide 'viper-util)
;;; Local Variables:
;;; eval: (put 'vip-deflocalvar 'lisp-indent-hook 'defun)
;;; End:
;;; viper-util.el ends here ;;; viper-util.el ends here

View File

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