emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 685ec273ecb: Delete some libraries obsolete since Emacs 24.4/24.5


From: Stefan Kangas
Subject: master 685ec273ecb: Delete some libraries obsolete since Emacs 24.4/24.5
Date: Sun, 29 Sep 2024 21:31:29 -0400 (EDT)

branch: master
commit 685ec273ecbb54439ed84474fb96ec847bebb630
Author: Stefan Kangas <stefankangas@gmail.com>
Commit: Stefan Kangas <stefankangas@gmail.com>

    Delete some libraries obsolete since Emacs 24.4/24.5
    
    * lisp/obsolete/cc-compat.el:
    * lisp/obsolete/info-edit.el:
    * lisp/obsolete/meese.el:
    * lisp/obsolete/otodo-mode.el:
    * lisp/obsolete/rcompile.el:
    * lisp/obsolete/sup-mouse.el:
    * lisp/obsolete/terminal.el:
    * lisp/obsolete/vi.el:
    * lisp/obsolete/vip.el:
    * lisp/obsolete/ws-mode.el:
    * lisp/obsolete/yow.el: Delete libraries obsolete since Emacs 24.4 and
    24.5.  (Bug#73257)
    
    * doc/misc/vip.texi:
    * etc/refcards/vipcard.tex: Delete vip.el documentation.
    
    * doc/emacs/ack.texi (Acknowledgments):
    * doc/misc/Makefile.in (INFO_COMMON):
    * etc/refcards/Makefile (PDF_ENGLISH, survival.dvi):
    * etc/refcards/README:
    * lisp/info.el (Info-url-alist):
    (Info-file-list-for-emacs): Delete references to above libraries.
---
 doc/emacs/ack.texi          |    2 +-
 doc/misc/Makefile.in        |    2 +-
 doc/misc/vip.texi           | 1952 ---------------------------
 etc/NEWS                    |    4 +
 etc/refcards/Makefile       |    7 -
 etc/refcards/README         |    1 -
 etc/refcards/vipcard.tex    |  681 ----------
 lisp/info.el                |    4 +-
 lisp/obsolete/cc-compat.el  |  165 ---
 lisp/obsolete/info-edit.el  |   89 --
 lisp/obsolete/meese.el      |   38 -
 lisp/obsolete/otodo-mode.el |  965 --------------
 lisp/obsolete/rcompile.el   |  180 ---
 lisp/obsolete/sup-mouse.el  |  203 ---
 lisp/obsolete/terminal.el   | 1333 -------------------
 lisp/obsolete/vi.el         | 1495 ---------------------
 lisp/obsolete/vip.el        | 3050 -------------------------------------------
 lisp/obsolete/ws-mode.el    |  539 --------
 lisp/obsolete/yow.el        |   94 --
 19 files changed, 8 insertions(+), 10796 deletions(-)

diff --git a/doc/emacs/ack.texi b/doc/emacs/ack.texi
index 8fd3d61ec64..3fc65476591 100644
--- a/doc/emacs/ack.texi
+++ b/doc/emacs/ack.texi
@@ -1044,7 +1044,7 @@ a package for running source-level debuggers like GDB and 
SDB in
 Emacs; @file{asm-mode.el}, a mode for editing assembly language code;
 @file{AT386.el}, terminal support package for IBM's AT keyboards;
 @file{cookie1.el}, support for fortune-cookie programs like
-@file{yow.el} and @file{spook.el}; @file{finder.el}, a package for
+@file{spook.el}; @file{finder.el}, a package for
 finding Emacs Lisp packages by keyword and topic; @file{keyswap.el},
 code to swap the @key{BS} and @key{DEL} keys; @file{loadhist.el},
 functions for loading and unloading Emacs features;
diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in
index 087742f6a9c..4e2cd6448d1 100644
--- a/doc/misc/Makefile.in
+++ b/doc/misc/Makefile.in
@@ -74,7 +74,7 @@ INFO_COMMON = auth autotype bovine calc ccmode cl dbus 
dired-x                \
        modus-themes newsticker nxml-mode octave-mode org pcl-cvs pgg   \
        rcirc reftex remember sasl sc semantic ses sieve smtpmail       \
        speedbar srecode todo-mode tramp transient url use-package      \
-       vhdl-mode vip viper vtable widget wisent woman
+       vhdl-mode viper vtable widget wisent woman
 
 ## Info files to install on current platform.
 INFO_INSTALL = $(INFO_COMMON) $(DOCMISC_W32)
diff --git a/doc/misc/vip.texi b/doc/misc/vip.texi
deleted file mode 100644
index 6907966f861..00000000000
--- a/doc/misc/vip.texi
+++ /dev/null
@@ -1,1952 +0,0 @@
-\input texinfo
-@setfilename ../../info/vip.info
-@settitle VIP
-@include docstyle.texi
-
-@copying
-Copyright @copyright{} 1987, 2001--2024 Free Software Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with the Front-Cover Texts being ``A GNU Manual'',
-and with the Back-Cover Texts as in (a) below.  A copy of the license
-is included in the section entitled ``GNU Free Documentation License''.
-
-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and
-modify this GNU manual.''
-@end quotation
-@end copying
-
-@titlepage
-@sp 10
-@center @titlefont{VIP}
-@sp 1
-@center A Vi Package for GNU Emacs
-@center (Version 3.5, September 15, 1987)
-@sp 2
-@center Masahiko Sato
-@page
-@vskip 0pt plus1filll
-@insertcopying
-@end titlepage
-
-@finalout
-@contents
-
-@dircategory Emacs misc features
-@direntry
-* VIP: (vip).                   An obsolete VI-emulation for Emacs.
-@end direntry
-
-@ifnottex
-@node Top
-@top VIP
-
-VIP is a Vi emulating package written in Emacs Lisp.  VIP implements most
-Vi commands including Ex commands.  It is therefore hoped that this package
-will enable you to do Vi style editing under the powerful GNU Emacs
-environment.  This info file describes the usage of VIP assuming that you
-are fairly accustomed to Vi but not so much with Emacs.  Also we will
-concentrate mainly on differences from Vi, especially features unique to
-VIP.
-
-VIP is obsolete since Emacs 24.5---consider using Viper instead.
-@xref{Top, Viper,, viper, The Viper VI-emulation mode for Emacs}.
-
-It is recommended that you read nodes on survey and on customization before
-you start using VIP@.  Other nodes may be visited as needed.
-
-Comments and bug reports are welcome.  Please send messages to
-@code{ms@@Sail.Stanford.Edu} if you are outside of Japan and to
-@code{masahiko@@sato.riec.tohoku.junet} if you are in Japan.
-
-@insertcopying
-
-@end ifnottex
-
-@menu
-* Survey::              A survey of VIP.
-* Vi Commands::         Details of Vi commands.
-* Ex Commands::         Details of Ex commands.
-* Customization::       How to customize VIP.
-* GNU Free Documentation License:: The license for this documentation.
-
-@end menu
-@iftex
-@unnumbered Introduction
-
-VIP is a Vi emulating package written in Emacs Lisp.  VIP implements most
-Vi commands including Ex commands.  It is therefore hoped that this package
-will enable you to do Vi style editing under the powerful GNU Emacs
-environment.  This manual describes the usage of VIP assuming that you are
-fairly accustomed to Vi but not so much with Emacs.  Also we will
-concentrate mainly on differences from Vi, especially features unique to
-VIP.
-
-VIP is obsolete since Emacs 24.5---consider using Viper instead.
-@xref{Top, Viper,, viper, The Viper VI-emulation mode for Emacs}.
-
-It is recommended that you read chapters on survey and on customization
-before you start using VIP@.  Other chapters may be used as future
-references.
-
-Comments and bug reports are welcome.  Please send messages to
-@code{ms@@Sail.Stanford.Edu} if you are outside of Japan and to
-@code{masahiko@@unsun.riec.tohoku.junet} if you are in Japan.
-@end iftex
-
-@node Survey
-@chapter A Survey of VIP
-
-In this chapter we describe basics of VIP with emphasis on the features not
-found in Vi and on how to use VIP under GNU Emacs.
-
-@menu
-* Basic Concepts::      Basic concepts in Emacs.
-* Loading VIP::         How to load VIP automatically.
-* Modes in VIP::        VIP has three modes, which are orthogonal to modes
-                          in Emacs.
-* Differences from Vi:: Differences of VIP from Vi is explained.
-@end menu
-
-@node Basic Concepts
-@section Basic Concepts
-
-We begin by explaining some basic concepts of Emacs.  These concepts are
-explained in more detail in the GNU Emacs Manual.
-
-@cindex buffer
-@cindex point
-@cindex mark
-@cindex text
-@cindex looking at
-@cindex end (of buffer)
-@cindex region
-
-Conceptually, a @dfn{buffer} is just a string of @acronym{ASCII} characters 
and two
-special characters @key{PNT} (@dfn{point}) and @key{MRK} (@dfn{mark}) such
-that the character @key{PNT} occurs exactly once and @key{MRK} occurs at
-most once.  The @dfn{text} of a buffer is obtained by deleting the
-occurrences of @key{PNT} and @key{MRK}.  If, in a buffer, there is a
-character following @key{PNT} then we say that point is @dfn{looking at}
-the character; otherwise we say that point is @dfn{at the end of buffer}.
-@key{PNT} and @key{MRK} are used
-to indicate positions in a buffer and they are not part of the text of the
-buffer.  If a buffer contains a @key{MRK} then the text between @key{MRK}
-and @key{PNT} is called the @dfn{region} of the buffer.
-
-@cindex window
-
-Emacs provides (multiple) @dfn{windows} on the screen, and you can see the
-content of a buffer through the window associated with the buffer.  The
-cursor of the screen is always positioned on the character after @key{PNT}.
-
-@cindex mode
-@cindex keymap
-@cindex local keymap
-@cindex global keymap
-
-A @dfn{keymap} is a table that records the bindings between characters and
-command functions.  There is the @dfn{global keymap} common to all the
-buffers.  Each buffer has its @dfn{local keymap} that determines the
-@dfn{mode} of the buffer.  Local keymap overrides global keymap, so that if
-a function is bound to some key in the local keymap then that function will
-be executed when you type the key.  If no function is bound to a key in the
-local map, however, the function bound to the key in the global map becomes
-in effect.
-
-@node Loading VIP
-@section Loading VIP
-
-The recommended way to load VIP automatically is to include the line:
-@example
-(load "vip")
-@end example
-@noindent
-in your @file{.emacs} file.  The @file{.emacs} file is placed in your home
-directory and it will be executed every time you invoke Emacs.  If you wish
-to be in vi mode whenever Emacs starts up, you can include the following
-line in your @file{.emacs} file instead of the above line:
-@example
-(add-hook 'emacs-startup-hook 'vip-mode)
-@end example
-@noindent
-(@xref{Vi Mode}, for the explanation of vi mode.)
-
-Even if your @file{.emacs} file does not contain any of the above lines,
-you can load VIP and enter vi mode by typing the following from within
-Emacs.
-@example
-M-x vip-mode
-@end example
-@noindent
-
-@node Modes in VIP
-@section Modes in VIP
-
-@kindex 032 C-z @r{(}@code{vip-change-mode-to-vi}@r{)}
-@kindex 0301 C-x C-z @r{(}@code{suspend-emacs}@r{)}
-
-Loading VIP has the effect of globally binding @kbd{C-z} (@kbd{Control-z})
-to the function @code{vip-change-mode-to-vi}.  The default binding of @kbd{C-z}
-in GNU Emacs is @code{suspend-emacs}, but, you can also call
-@code{suspend-emacs} by typing @kbd{C-x C-z}.  Other than this, all the
-key bindings of Emacs remain the same after loading VIP.
-
-@cindex vi mode
-
-Now, if you hit @kbd{C-z}, the function @code{vip-change-mode-to-vi} will be
-called and you will be in @dfn{vi mode}.  (Some major modes may locally bind
-@kbd{C-z} to some special functions.  In such cases, you can call
-@code{vip-change-mode-to-vi} by @code{execute-extended-command} which is
-invoked by @kbd{M-x}.  Here @kbd{M-x} means @kbd{Meta-x}, and if your
-terminal does not have a @key{META} key you can enter it by typing
-@kbd{@key{ESC} x}.  The same effect can also be achieve by typing
-@kbd{M-x vip-mode}.)
-
-@cindex mode line
-
-You can observe the change of mode by looking at the @dfn{mode line}.  For
-instance, if the mode line is:
-@example
------Emacs: *scratch*              (Lisp Interaction)----All------------
-@end example
-@noindent
-then it will change to:
-@example
------Vi:    *scratch*              (Lisp Interaction)----All------------
-@end example
-@noindent
-Thus the word @samp{Emacs} in the mode line will change to @samp{Vi}.
-
-@cindex insert mode
-@cindex emacs mode
-
-You can go back to the original @dfn{emacs mode} by typing @kbd{C-z} in
-vi mode.  Thus @kbd{C-z} toggles between these two modes.
-
-Note that modes in VIP exist orthogonally to modes in Emacs.  This means
-that you can be in vi mode and at the same time, say, shell mode.
-
-Vi mode corresponds to Vi's command mode.  From vi mode you can enter
-@dfn{insert mode} (which corresponds to Vi's insert mode) by usual Vi command
-keys like @kbd{i}, @kbd{a}, @kbd{o} @dots{} etc.
-
-In insert mode, the mode line will look like this:
-@example
------Insert *scratch*              (Lisp Interaction)----All------------
-@end example
-@noindent
-You can exit from insert mode by hitting @key{ESC} key as you do in Vi.
-
-That VIP has three modes may seem very complicated, but in fact it is not
-so.  VIP is implemented so that you can do most editing remaining only
-in the two modes for Vi (that is vi mode and insert mode).
-
-@ifinfo
-The figure below shows the transition of three modes in VIP.
-@display
-
-
-           === C-z ==>          == i,o ... ==>
-emacs mode             vi mode                 insert mode
-           <== X-z ===          <=== ESC ====
-@end display
-@end ifinfo
-
-@menu
-* Emacs Mode::          This is the mode you should know better.
-* Vi Mode::             Vi commands are executed in this mode.
-* Insert Mode::         You can enter text, and also can do editing if you
-                          know enough Emacs commands.
-@end menu
-
-@node Emacs Mode
-@subsection Emacs Mode
-
-@kindex 032 C-z @r{(}@code{vip-change-mode-to-vi}@r{)}
-
-You will be in this mode just after you loaded VIP@.  You can do all
-normal Emacs editing in this mode.  Note that the key @kbd{C-z} is globally
-bound to @code{vip-change-mode-to-vi}.  So, if you type @kbd{C-z} in this mode
-then you will be in vi mode.
-
-@node Vi Mode
-@subsection Vi Mode
-
-This mode corresponds to Vi's command mode.  Most Vi commands work as they
-do in Vi.  You can go back to emacs mode by typing @kbd{C-z}.  You can
-enter insert mode, just as in Vi, by typing @kbd{i}, @kbd{a} etc.
-
-@node Insert Mode
-@subsection Insert Mode
-
-The key bindings in this mode is the same as in the emacs mode except for
-the following 4 keys.  So, you can move around in the buffer and change
-its content while you are in insert mode.
-
-@table @kbd
-@item @key{ESC}
-@kindex 033 ESC @r{(}@code{vip-change-mode-to-vi}@r{) (insert mode)}
-This key will take you back to vi mode.
-@item C-h
-@kindex 010 C-h @r{(}@code{vip-delete-backward-char}@r{) (insert mode)}
-Delete previous character.
-@item C-w
-@kindex 027 C-w @r{(}@code{vip-delete-backward-word}@r{) (insert mode)}
-Delete previous word.
-@item C-z
-@kindex 032 C-z @r{(}@code{vip-ESC}@r{) (insert mode)}
-Typing this key has the same effect as typing @key{ESC} in emacs mode.
-Thus typing @kbd{C-z x} in insert mode will have the same effect as typing
-@kbd{ESC x} in emacs mode.
-@end table
-
-@node Differences from Vi
-@section Differences from Vi
-
-The major differences from Vi are explained below.
-
-@menu
-* Undoing::             You can undo more in VIP.
-* Changing::            Commands for changing the text.
-* Searching::           Search commands.
-* z Command::           You can now use zH, zM and zL as well as z- etc.
-* Counts::              Some Vi commands which do not accept a count now
-                        accept one.
-* Marking::             You can now mark the current point, beginning of
-                        the buffer etc.
-* Region Commands::     You can now give a region as an argument for delete
-                        commands etc.
-* New Commands::        Some new commands not available in Vi are added.
-* New Bindings::        Bindings of some keys are changed for the
-                        convenience of editing under Emacs.
-* Window Commands::     Commands for moving among windows etc.
-* Buffer Commands::     Commands for selecting buffers etc.
-* File Commands::       Commands for visiting files etc.
-* Misc Commands::       Other useful commands.
-@end menu
-
-@node Undoing
-@subsection Undoing
-
-@kindex 165 u @r{(}@code{vip-undo}@r{)}
-@kindex 056 . @r{(}@code{vip-repeat}@r{)}
-
-You can repeat undoing by the @kbd{.} key.  So, @kbd{u} will undo
-a single change, while @kbd{u .@: .@: .@:}, for instance, will undo 4 previous
-changes.  Undo is undoable as in Vi.  So the content of the buffer will
-be the same before and after @kbd{u u}.
-
-@node Changing
-@subsection Changing
-
-Some commands which change a small number of characters are executed
-slightly differently.  Thus, if point is at the beginning of a word
-@samp{foo} and you wished to change it to @samp{bar} by typing @w{@kbd{c w}},
-then VIP will prompt you for a new word in the minibuffer by the prompt
-@samp{foo => }.  You can then enter @samp{bar} followed by @key{RET} or
-@key{ESC} to complete the command.  Before you enter @key{RET} or
-@key{ESC} you can abort the command by typing @kbd{C-g}.  In general,
-@kindex 007 C-g @r{(}@code{vip-keyboard-quit})
-you can abort a partially formed command by typing @kbd{C-g}.
-
-@node Searching
-@subsection Searching
-
-@kindex 057 / @r{(}@code{vip-search-forward}@r{)}
-@kindex 077 ? @r{(}@code{vip-search-backward}@r{)}
-
-As in Vi, searching is done by @kbd{/} and @kbd{?}.  The string will be
-searched literally by default.  To invoke a regular expression search,
-first execute the search command @kbd{/} (or @kbd{?}) with empty search
-string.  (I.e., type @kbd{/} followed by @key{RET}.)
-A search for empty string will toggle the search mode between vanilla
-search and regular expression search.  You cannot give an offset to the
-search string.  (It is a limitation.)  By default, search will wrap around
-the buffer as in Vi.  You can change this by rebinding the variable
-@code{vip-search-wrap-around}.  @xref{Customization}, for how to do this.
-
-@node z Command
-@subsection z Command
-
-@kindex 1723 z H @r{(}@code{vip-line-to-top}@r{)}
-@kindex 1721 z RET @r{(}@code{vip-line-to-top}@r{)}
-@kindex 1723 z M @r{(}@code{vip-line-to-middle}@r{)}
-@kindex 1722 z . @r{(}@code{vip-line-to-middle}@r{)}
-@kindex 1723 z L @r{(}@code{vip-line-to-bottom}@r{)}
-@kindex 1722 z - @r{(}@code{vip-line-to-bottom}@r{)}
-
-For those of you who cannot remember which of @kbd{z} followed by @key{RET},
-@kbd{.}@: and @kbd{-} do what.  You can also use @kbd{z} followed by @kbd{H},
-@kbd{M} and @kbd{L} to place the current line in the Home (Middle, and
-Last) line of the window.
-
-@node Counts
-@subsection Counts
-
-Some Vi commands which do not accept a count now accept one
-
-@table @kbd
-@item p
-@itemx P
-@kindex 160 p @r{(}@code{vip-put-back}@r{)}
-@kindex 120 P @r{(}@code{vip-Put-back}@r{)}
-Given counts, text will be yanked (in Vi's sense) that many times.  Thus
-@kbd{3 p} is the same as @kbd{p p p}.
-@item o
-@itemx O
-@kindex 157 o @r{(}@code{vip-open-line}@r{)}
-@kindex 117 O @r{(}@code{vip-Open-line}@r{)}
-Given counts, that many copies of text will be inserted.  Thus
-@kbd{o a b c @key{ESC}} will insert 3 lines of @samp{abc} below the current
-line.
-@item /
-@itemx ?
-@kindex 057 / @r{(}@code{vip-search-forward}@r{)}
-@kindex 077 ? @r{(}@code{vip-search-backward}@r{)}
-Given a count @var{n}, @var{n}-th occurrence will be searched.
-@end table
-
-@node Marking
-@subsection Marking
-
-Typing an @kbd{m} followed by a lower-case character @var{ch} marks the
-point to the register named @var{ch} as in Vi.  In addition to these, we
-have following key bindings for marking.
-
-@kindex 155 m @r{(}@code{vip-mark-point}@r{)}
-
-@table @kbd
-@item m <
-Set mark at the beginning of buffer.
-@item m >
-Set mark at the end of buffer.
-@item m .
-Set mark at point (and push old mark on mark ring).
-@item m ,
-Jump to mark (and pop mark off the mark ring).
-@end table
-
-@node Region Commands
-@subsection Region Commands
-
-@cindex region
-
-Vi operators like @kbd{d}, @kbd{c} etc.@: are usually used in combination
-with motion commands.  It is now possible to use current region as the
-argument to these operators.  (A @dfn{region} is a part of buffer
-delimited by point and mark.)  The key @kbd{r} is used for this purpose.
-Thus @kbd{d r} will delete the current region.  If @kbd{R} is used instead
-of @kbd{r} the region will first be enlarged so that it will become the
-smallest region containing the original region and consisting of whole
-lines.  Thus @kbd{m .@: d R} will have the same effect as @kbd{d d}.
-
-@node New Commands
-@subsection Some New Commands
-
-Note that the keys below (except for @kbd{R}) are not used in Vi.
-
-@table @kbd
-@item C-a
-@kindex 001 C-a @r{(}@code{vip-beginning-of-line}@r{)}
-Move point to the beginning of line.
-@item C-n
-@kindex 016 C-n @r{(}@code{vip-next-window}@r{)}
-If you have two or more windows in the screen, this key will move point to
-the next window.
-@item C-o
-@kindex 017 C-o @r{(}@code{vip-open-line-at-point}@r{)}
-Insert a newline and leave point before it, and then enter insert mode.
-@item C-r
-@kindex 022 C-r @r{(}@code{isearch-backward}@r{)}
-Backward incremental search.
-@item C-s
-@kindex 023 C-s @r{(}@code{isearch-forward}@r{)}
-Forward incremental search.
-@item C-c
-@itemx C-x
-@itemx @key{ESC}
-@kindex 003 C-c @r{(}@code{vip-ctl-c}@r{)}
-@kindex 0300 C-x @r{(}@code{vip-ctl-x}@r{)}
-@kindex 033 ESC @r{(}@code{vip-ESC}@r{)}
-These keys will exit from vi mode and return to emacs mode temporarily.  If
-you hit one of these keys, Emacs will be in emacs mode and will believe
-that you hit that key in emacs mode.  For example, if you hit @kbd{C-x}
-followed by @kbd{2}, then the current window will be split into 2 and you
-will be in vi mode again.
-@item \
-@kindex 134 \ @r{(}@code{vip-escape-to-emacs}@r{)}
-Escape to emacs mode.  Hitting @kbd{\} will take you to emacs mode, and you
-can execute a single Emacs command.  After executing the Emacs command you
-will be in vi mode again.  You can give a count before typing @kbd{\}.
-Thus @kbd{5 \ *}, as well as @kbd{\ C-u 5 *}, will insert @samp{*****}
-before point.  Similarly @kbd{1 0 \ C-p} will move the point 10 lines above
-the current line.
-@item K
-@kindex 113 K @r{(}@code{vip-kill-buffer}@r{)}
-Kill current buffer if it is not modified.  Useful when you selected a
-buffer which you did not want.
-@item Q
-@itemx R
-@kindex 121 Q @r{(}@code{vip-query-replace}@r{)}
-@kindex 122 R @r{(}@code{vip-replace-string}@r{)}
-@kbd{Q} is for query replace and @kbd{R} is for replace.  By default,
-string to be replaced are treated literally.  If you wish to do a regular
-expression replace, first do replace with empty string as the string to be
-replaced.  In this way, you can toggle between vanilla and regular
-expression replacement.
-@item v
-@itemx V
-@kindex 166 v @r{(}@code{vip-find-file}@r{)}
-@kindex 126 V @r{(}@code{vip-find-file-other-window}@r{)}
-These keys are used to Visit files.  @kbd{v} will switch to a buffer
-visiting file whose name can be entered in the minibuffer. @kbd{V} is
-similar, but will use window different from the current window.
-@item #
-@kindex 0430 # @r{(}@code{vip-command-argument}@r{)}
-If followed by a certain character @var{ch}, it becomes an operator whose
-argument is the region determined by the motion command that follows.
-Currently, @var{ch} can be one of @kbd{c}, @kbd{C}, @kbd{g}, @kbd{q} and
-@kbd{s}.
-@item # c
-@kindex 0432 # c @r{(}@code{downcase-region}@r{)}
-Change upper-case characters in the region to lower case
-(@code{downcase-region}).
-@item # C
-@kindex 0431 # C @r{(}@code{upcase-region}@r{)}
-Change lower-case characters in the region to upper case.  For instance,
-@kbd{# C 3 w} will capitalize 3 words from the current point
-(@code{upcase-region}).
-@item # g
-@kindex 0432 # g @r{(}@code{vip-global-execute}@r{)}
-Execute last keyboard macro for each line in the region
-(@code{vip-global-execute}).
-@item # q
-@kindex 0432 # q @r{(}@code{vip-quote-region}@r{)}
-Insert specified string at the beginning of each line in the region
-(@code{vip-quote-region}).
-@item # s
-@kindex 0432 # s @r{(}@code{spell-region}@r{)}
-Check spelling of words in the region (@code{spell-region}).
-@item *
-@kindex 052 * @r{(}@code{vip-call-last-kbd-macro}@r{)}
-Call last keyboard macro.
-@end table
-
-@node New Bindings
-@subsection New Key Bindings
-
-In VIP the meanings of some keys are entirely different from Vi.  These key
-bindings are done deliberately in the hope that editing under Emacs will
-become easier.  It is however possible to rebind these keys to functions
-which behave similarly as in Vi.  @xref{Customizing Key Bindings}, for
-details.
-
-@table @kbd
-@item C-g
-@itemx g
-@kindex 007 C-g @r{(}@code{vip-keyboard-quit}@r{)}
-@kindex 147 g @r{(}@code{vip-info-on-file}@r{)}
-In Vi, @kbd{C-g} is used to get information about the file associated to
-the current buffer.  Here, @kbd{g} will do that, and @kbd{C-g} is
-used to abort a command (this is for compatibility with emacs mode.)
-@item @key{SPC}
-@itemx @key{RET}
-@kindex 040 SPC @r{(}@code{vip-scroll}@r{)}
-@kindex 015 RET @r{(}@code{vip-scroll-back}@r{)}
-Now these keys will scroll up and down the text of current window.
-Convenient for viewing the text.
-@item s
-@itemx S
-@kindex 163 s @r{(}@code{vip-switch-to-buffer}@r{)}
-@kindex 123 S @r{(}@code{vip-switch-to-buffer-other-window}@r{)}
-They are used to switch to a specified buffer.  Useful for switching to
-already existing buffer since buffer name completion is provided.  Also
-a default buffer will be given as part of the prompt, to which you can
-switch by just typing @key{RET} key.  @kbd{s} is used to select buffer
-in the current window, while @kbd{S} selects buffer in another window.
-@item C
-@itemx X
-@kindex 103 C @r{(}@code{vip-ctl-c-equivalent}@r{)}
-@kindex 1300 X @r{(}@code{vip-ctl-x-equivalent}@r{)}
-These keys will exit from vi mode and return to emacs mode temporarily.
-If you type @kbd{C} (@kbd{X}), Emacs will be in emacs mode and will believe
-that you have typed @kbd{C-c} (@kbd{C-x}) in emacs mode.  Moreover,
-if the following character you type is an upper-case letter, then Emacs
-will believe that you have typed the corresponding control character.
-You will be in vi mode again after the command is executed.  For example,
-typing @kbd{X S} in vi mode is the same as typing @kbd{C-x C-s} in emacs
-mode.  You get the same effect by typing @kbd{C-x C-s} in vi mode, but
-the idea here is that you can execute useful Emacs commands without typing
-control characters.  For example, if you hit @kbd{X} (or @kbd{C-x}) followed
-by @kbd{2}, then the current window will be split into 2 and you will be in
-vi mode again.
-@end table
-
-In addition to these, @code{ctl-x-map} is slightly modified:
-
-@kindex 1301 X 3 @r{(}@code{vip-buffer-in-two-windows}@r{)}
-
-@table @kbd
-@item X 3
-@itemx C-x 3
-This is equivalent to @kbd{C-x 1 C-x 2} (1 + 2 = 3).
-@end table
-
-@node Window Commands
-@subsection Window Commands
-
-In this and following subsections, we give a summary of key bindings for
-basic functions related to windows, buffers and files.
-
-@table @kbd
-@item C-n
-@kindex 016 C-n @r{(}@code{vip-next-window}@r{)}
-Switch to next window.
-@item X 1
-@itemx C-x 1
-@kindex 1301 X 1 @r{(}@code{delete-other-windows}@r{)}
-Delete other windows.
-@item X 2
-@itemx C-x 2
-@kindex 1301 X 2 @r{(}@code{split-window-vertically}@r{)}
-Split current window into two windows.
-@item X 3
-@itemx C-x 3
-@kindex 1301 X 3 @r{(}@code{vip-buffer-in-two-windows}@r{)}
-Show current buffer in two windows.
-@end table
-
-@node Buffer Commands
-@subsection Buffer Commands
-
-@table @kbd
-@item s
-@kindex 163 s @r{(}@code{vip-switch-to-buffer}@r{)}
-Switch to the specified buffer in the current window
-(@code{vip-switch-to-buffer}).
-@item S
-@kindex 123 S @r{(}@code{vip-switch-to-buffer-other-window}@r{)}
-Switch to the specified buffer in another window
-(@code{vip-switch-to-buffer-other-window}).
-@item K
-@kindex 113 K @r{(}@code{vip-kill-buffer}@r{)}
-Kill the current buffer if it is not modified.
-@item X S
-@itemx C-x C-s
-@kindex 1302 X S @r{(}@code{save-buffer}@r{)}
-Save the current buffer in the file associated to the buffer.
-@end table
-
-@node File Commands
-@subsection File Commands
-
-@table @kbd
-@item v
-@kindex 166 v @r{(}@code{vip-find-file}@r{)}
-Visit specified file in the current window.
-@item V
-@kindex 126 V @r{(}@code{vip-find-file-other-window}@r{)}
-Visit specified file in another window.
-@item X W
-@itemx C-x C-w
-@kindex 1302 X W @r{(}@code{write-file}@r{)}
-Write current buffer into the specified file.
-@item X I
-@itemx C-x C-i
-@kindex 1302 X I @r{(}@code{insert-file}@r{)}
-
-Insert specified file at point.
-@end table
-
-@node Misc Commands
-@subsection Miscellaneous Commands
-
-@table @kbd
-@item X (
-@itemx C-x (
-@kindex 1301 X ( @r{(}@code{start-kbd-macro}@r{)}
-Start remembering keyboard macro.
-@item X )
-@itemx C-x )
-@kindex 1301 X ) @r{(}@code{end-kbd-macro}@r{)}
-Finish remembering keyboard macro.
-@item *
-@kindex 052 * @r{(}@code{vip-call-last-kbd-macro}@r{)}
-Call last remembered keyboard macro.
-@item X Z
-@itemx C-x C-z
-@kindex 1302 X Z @r{(}@code{suspend-emacs}@r{)}
-Suspend Emacs.
-@item Z Z
-Exit Emacs.
-@item Q
-Query replace.
-@item R
-Replace.
-@end table
-
-@node Vi Commands
-@chapter Vi Commands
-
-This chapter describes Vi commands other than Ex commands implemented in
-VIP@.  Except for the last section which discusses insert mode, all the
-commands described in this chapter are to be used in vi mode.
-
-@menu
-* Numeric Arguments::        Many commands accept numeric arguments
-* Important Keys::           Some very important keys.
-* Buffers and Windows::      Commands for handling buffers and windows.
-* Files::                    Commands for handling files.
-* Viewing the Buffer::       How you can view the current buffer.
-* Mark Commands::            Marking positions in a buffer.
-* Motion Commands::          Commands for moving point.
-* Searching and Replacing::  Commands for searching and replacing.
-* Modifying Commands::       Commands for modifying the buffer.
-* Other Vi Commands::        Miscellaneous Commands.
-* Commands in Insert Mode::  Commands for entering insert mode.
-@end menu
-
-@node Numeric Arguments
-@section Numeric Arguments
-
-@cindex numeric arguments
-@cindex count
-@kindex 061 1 @r{(numeric argument)}
-@kindex 062 2 @r{(numeric argument)}
-@kindex 063 3 @r{(numeric argument)}
-@kindex 064 4 @r{(numeric argument)}
-@kindex 065 5 @r{(numeric argument)}
-@kindex 066 6 @r{(numeric argument)}
-@kindex 067 7 @r{(numeric argument)}
-@kindex 068 8 @r{(numeric argument)}
-@kindex 069 9 @r{(numeric argument)}
-
-Most Vi commands accept a @dfn{numeric argument} which can be supplied as
-a prefix to the commands.  A numeric argument is also called a @dfn{count}.
-In many cases, if a count is given, the command is executed that many times.
-For instance, @kbd{5 d d} deletes 5 lines while simple @kbd{d d} deletes a
-line.  In this manual the metavariable @var{n} will denote a count.
-
-@node Important Keys
-@section Important Keys
-
-The keys @kbd{C-g} and @kbd{C-l} are unique in that their associated
-functions are the same in any of emacs, vi and insert mode.
-
-@table @kbd
-@item C-g
-@kindex 007 C-g (@code{vip-keyboard-quit}@r{)}
-Quit.  Cancel running or partially typed command (@code{keyboard-quit}).
-@item C-l
-@kindex 014 C-l @r{(}@code{recenter}@r{)}
-Clear the screen and reprint everything (@code{recenter}).
-@end table
-
-In Emacs many commands are bound to the key strokes that start with
-@kbd{C-x}, @kbd{C-c} and @key{ESC}.  These commands can be
-accessed from vi mode as easily as from emacs mode.
-
-@table @kbd
-@item C-x
-@itemx C-c
-@itemx @key{ESC}
-@kindex 003 C-c @r{(}@code{vip-ctl-c}@r{)}
-@kindex 0300 C-x @r{(}@code{vip-ctl-x}@r{)}
-@kindex 033 ESC @r{(}@code{vip-ESC}@r{)}
-Typing one of these keys have the same effect as typing it in emacs mode.
-Appropriate command will be executed according as the keys you type after
-it.  You will be in vi mode again after the execution of the command.
-For instance, if you type @kbd{@key{ESC} <} (in vi mode) then the cursor will
-move to the beginning of the buffer and you will still be in vi mode.
-@item C
-@itemx X
-@kindex 103 C @r{(}@code{vip-ctl-c-equivalent}@r{)}
-@kindex 1300 X @r{(}@code{vip-ctl-x-equivalent}@r{)}
-Typing one of these keys have the effect of typing the corresponding
-control character in emacs mode.  Moreover, if you type an upper-case
-character following it, that character will also be translated to the
-corresponding control character.  Thus typing @kbd{X W} in vi mode is the
-same as typing @kbd{C-x C-w} in emacs mode.  You will be in vi mode again
-after the execution of a command.
-@item \
-@kindex 134 \ @r{(}@code{vip-escape-to-emacs}@r{)}
-Escape to emacs mode.  Hitting the @kbd{\} key will take you to emacs mode,
-and you can execute a single Emacs command.  After executing the
-Emacs command you will be in vi mode again.  You can give a count before
-typing @kbd{\}.  Thus @kbd{5 \ +}, as well as @kbd{\ C-u 5 +}, will insert
-@samp{+++++} before point.
-@end table
-
-@node Buffers and Windows
-@section Buffers and Windows
-
-@cindex buffer
-@cindex selected buffer
-@cindex current buffer
-
-In Emacs the text you edit is stored in a @dfn{buffer}.
-See GNU Emacs Manual, for details.  There is always one @dfn{current}
-buffer, also called the @dfn{selected buffer}.
-
-@cindex window
-@cindex modified (buffer)
-
-You can see the contents of buffers through @dfn{windows} created by Emacs.
-When you have multiple windows on the screen only one of them is selected.
-Each buffer has a unique name, and each window has a mode line which shows
-the name of the buffer associated with the window and other information
-about the status of the buffer.  You can change the format of the mode
-line, but normally if you see @samp{**} at the beginning of a mode line it
-means that the buffer is @dfn{modified}.  If you write out the content of
-the buffer to a file, then the buffer will become not modified.  Also if
-you see @samp{%%} at the beginning of the mode line, it means that the file
-associated with the buffer is write protected.
-
-We have the following commands related to windows and buffers.
-
-@table @kbd
-@item C-n
-@kindex 016 C-n @r{(}@code{vip-next-window}@r{)}
-Move cursor to the next-window (@code{vip-next-window}).
-@item X 1
-@kindex 1301 X 1 @r{(}@code{delete-other-windows}@r{)}
-Delete other windows and make the selected window fill the screen
-@*(@code{delete-other-windows}).
-@item X 2
-@kindex 1301 X 2 @r{(}@code{split-window-vertically}@r{)}
-Split current window into two windows (@code{split-window-vertically}).
-@item X 3
-@kindex 1301 X 3 @r{(}@code{vip-buffer-in-two-windows}@r{)}
-Show current buffer in two windows.
-@item s @var{buffer} @key{RET}
-@kindex 163 s @r{(}@code{vip-switch-to-buffer}@r{)}
-Select or create a buffer named @var{buffer} (@code{vip-switch-to-buffer}).
-@item S @var{buffer} @key{RET}
-@kindex 123 S @r{(}@code{vip-switch-to-buffer-other-window}@r{)}
-Similar but select a buffer named @var{buffer} in another window
-@*(@code{vip-switch-to-buffer-other-window}).
-@item K
-@kindex 113 K @r{(}@code{vip-kill-buffer}@r{)}
-Kill the current buffer if it is not modified or if it is not associated
-with a file @*(@code{vip-kill-buffer}).
-@item X B
-@kindex 1302 X B @r{(}@code{list-buffers}@r{)}
-List the existing buffers (@code{list-buffers}).
-@end table
-
-@cindex buffer name completion
-
-As @dfn{buffer name completion} is provided, you have only to type in
-initial substring of the buffer name which is sufficient to identify it
-among names of existing buffers.  After that, if you hit @key{TAB} the rest
-of the buffer name will be supplied by the system, and you can confirm it
-by @key{RET}.  The default buffer name to switch to will also be prompted,
-and you can select it by giving a simple @key{RET}.  See GNU Emacs Manual
-for details of completion.
-
-@node Files
-@section Files
-
-We have the following commands related to files.  They are used to visit,
-save and insert files.
-
-@table @kbd
-@item v @var{file} @key{RET}
-@kindex 166 v @r{(}@code{vip-find-file}@r{)}
-Visit specified file in the current window (@code{vip-find-file}).
-@item V @var{file} @key{RET}
-@kindex 126 V @r{(}@code{vip-find-file-other-window}@r{)}
-Visit specified file in another window (@code{vip-find-file-other-window}).
-@item X S
-@kindex 1302 X S @r{(}@code{save-buffer}@r{)}
-Save current buffer to the file associated with the buffer.  If no file is
-associated with the buffer, the name of the file to write out the content
-of the buffer will be asked in the minibuffer.
-@item X W @var{file} @key{RET}
-@kindex 1302 X W @r{(}@code{write-file}@r{)}
-Write current buffer into a specified file.
-@item X I @var{file} @key{RET}
-@kindex 1302 X I @r{(}@code{insert-file}@r{)}
-Insert a specified file at point.
-@item g
-@kindex 147 g @r{(}@code{vip-info-on-file}@r{)}
-Give information on the file associated with the current buffer.  Tell you
-the name of the file associated with the buffer, the line number of the
-current point and total line numbers in the buffer.  If no file is
-associated with the buffer, this fact will be indicated by the null file
-name @samp{""}.
-@end table
-
-@cindex visiting (a file)
-@cindex default directory
-
-In Emacs, you can edit a file by @dfn{visiting} it.  If you wish to visit a
-file in the current window, you can just type @kbd{v}.  Emacs maintains the
-@dfn{default directory} which is specific to each buffer.  Suppose, for
-instance, that the default directory of the current buffer is
-@file{/usr/masahiko/lisp/}.  Then you will get the following prompt in the
-minibuffer.
-@example
-visit file: /usr/masahiko/lisp/
-@end example
-@noindent
-@cindex file name completion
-If you wish to visit, say, @file{vip.el} in this directory, then you can
-just type @samp{vip.el} followed by @key{RET}.  If the file @file{vip.el}
-already exists in the directory, Emacs will visit that file, and if not,
-the file will be created.  Emacs will use the file name (@file{vip.el}, in
-this case) as the name of the buffer visiting the file.  In order to make
-the buffer name unique, Emacs may add a suffix (@pxref{Uniquify,,,
-emacs, The GNU Emacs Manual}).  As @dfn{file name completion} is provided 
here, you
-can sometimes save typing.  For instance, suppose there is only one file in the
-default directory whose name starts with @samp{v}, that is @samp{vip.el}.
-Then if you just type @kbd{v @key{TAB}} then it will be completed to
-@samp{vip.el}.  Thus, in this case, you just have to type @kbd{v v @key{TAB}
-@key{RET}} to visit @file{/usr/masahiko/lisp/vip.el}.  Continuing the
-example, let us now suppose that you wished to visit the file
-@file{/usr/masahiko/man/vip.texinfo}.  Then to the same prompt which you get
-after you typed @kbd{v}, you can enter @samp{/usr/masahiko/man/vip.texinfo} or
-@samp{../man/vip.texinfo} followed by @key{RET}.
-
-Use @kbd{V} instead of @kbd{v}, if you wish to visit a file in another
-window.
-
-You can verify which file you are editing by typing @kbd{g}.  (You can also
-type @kbd{X B} to get information on other buffers too.)  If you type
-@kbd{g} you will get an information like below in the echo area:
-@example
-"/usr/masahiko/man/vip.texinfo" line 921 of 1949
-@end example
-
-After you edited the buffer (@samp{vip.texinfo}, in our example) for a while,
-you may wish to save it in a file.  If you wish to save it in the file
-associated with the buffer (@file{/usr/masahiko/man/vip.texinfo}, in this
-case), you can just say @kbd{X S}.  If you wish to save it in another file,
-you can type @kbd{X W}.  You will then get a similar prompt as you get for
-@kbd{v}, to which you can enter the file name.
-
-@node Viewing the Buffer
-@section Viewing the Buffer
-
-In this and next section we discuss commands for moving around in the
-buffer.  These command do not change the content of the buffer.  The
-following commands are useful for viewing the content of the current
-buffer.
-
-@table @kbd
-@item @key{SPC}
-@itemx C-f
-@kindex 040 SPC @r{(}@code{vip-scroll}@r{)}
-@kindex 006 C-f @r{(}@code{vip-scroll-back}@r{)}
-Scroll text of current window upward almost full screen.  You can go
-@i{forward} in the buffer by this command (@code{vip-scroll}).
-@item @key{RET}
-@itemx C-b
-@kindex 015 RET @r{(}@code{vip-scroll-back}@r{)}
-@kindex 002 C-b @r{(}@code{vip-scroll-back}@r{)}
-Scroll text of current window downward almost full screen.  You can go
-@i{backward} in the buffer by this command (@code{vip-scroll-back}).
-@item C-d
-@kindex 004 C-d @r{(}@code{vip-scroll-up}@r{)}
-Scroll text of current window upward half screen.  You can go
-@i{down} in the buffer by this command (@code{vip-scroll-down}).
-@item C-u
-@kindex 025 C-u @r{(}@code{vip-scroll-down}@r{)}
-Scroll text of current window downward half screen.  You can go
-@i{up} in the buffer by this command (@code{vip-scroll-up}).
-@item C-y
-@kindex 031 C-y @r{(}@code{vip-scroll-down-one}@r{)}
-Scroll text of current window upward by one line (@code{vip-scroll-down-one}).
-@item C-e
-@kindex 005 C-e @r{(}@code{vip-scroll-up-one}@r{)}
-Scroll text of current window downward by one line (@code{vip-scroll-up-one}).
-@end table
-@noindent
-You can repeat these commands by giving a count.  Thus, @kbd{2 @key{SPC}}
-has the same effect as @kbd{@key{SPC} @key{SPC}}.
-
-The following commands reposition point in the window.
-
-@table @kbd
-@item z H
-@itemx z @key{RET}
-@kindex 1723 z H @r{(}@code{vip-line-to-top}@r{)}
-@kindex 1721 z RET @r{(}@code{vip-line-to-top}@r{)}
-Put point on the top (@i{home}) line in the window.  So the current line
-becomes the top line in the window.  Given a count @var{n}, point will be
-placed in the @var{n}-th line from top (@code{vip-line-to-top}).
-@item z M
-@itemx z .
-@kindex 1723 z M @r{(}@code{vip-line-to-middle}@r{)}
-@kindex 1722 z . @r{(}@code{vip-line-to-middle}@r{)}
-Put point on the @i{middle} line in the window.  Given a count @var{n},
-point will be placed in the @var{n}-th line from the middle line
-(@code{vip-line-to-middle}).
-@item z L
-@itemx z -
-@kindex 1723 z L @r{(}@code{vip-line-to-bottom}@r{)}
-@kindex 1722 z - @r{(}@code{vip-line-to-bottom}@r{)}
-Put point on the @i{bottom} line in the window.  Given a count @var{n},
-point will be placed in the @var{n}-th line from bottom
-(@code{vip-line-to-bottom}).
-@item C-l
-Center point in window and redisplay screen (@code{recenter}).
-@end table
-
-@node Mark Commands
-@section Mark Commands
-
-The following commands are used to mark positions in the buffer.
-
-@table @kbd
-@item m @var{ch}
-@kindex 155 m @r{(}@code{vip-mark-point}@r{)}
-Store current point in the register @var{ch}.  @var{ch} must be a
-lower-case @acronym{ASCII} letter.
-@item m <
-Set mark at the beginning of current buffer.
-@item m >
-Set mark at the end of current buffer.
-@item m .
-Set mark at point.
-@item m ,
-Jump to mark (and pop mark off the mark ring).
-@end table
-
-@cindex mark ring
-
-Emacs uses the @dfn{mark ring} to store marked positions.  The commands
-@kbd{m <}, @kbd{m >} and @kbd{m .}@: not only set mark but also add it as the
-latest element of the mark ring (replacing the oldest one).  By repeating
-the command @kbd{m ,} you can visit older and older marked positions.  You
-will eventually be in a loop as the mark ring is a ring.
-
-@node Motion Commands
-@section Motion Commands
-
-Commands for moving around in the current buffer are collected here.  These
-commands are used as an ``argument'' for the delete, change and yank commands
-to be described in the next section.
-
-@table @kbd
-@item h
-@kindex 150 h @r{(}@code{vip-backward-char}@r{)}
-Move point backward by one character.  Signal error if point is at the
-beginning of buffer, but (unlike Vi) do not complain otherwise
-(@code{vip-backward-char}).
-@item l
-@kindex 154 l @r{(}@code{vip-forward-char}@r{)}
-Move point backward by one character.  Signal error if point is at the
-end of buffer, but (unlike Vi) do not complain otherwise
-(@code{vip-forward-char}).
-@item j
-@kindex 152 j @r{(}@code{vip-next-line}@r{)}
-Move point to the next line keeping the current column.  If point is on the
-last line of the buffer, a new line will be created and point will move to
-that line (@code{vip-next-line}).
-@item k
-@kindex 153 k @r{(}@code{vip-previous-line}@r{)}
-Move point to the previous line keeping the current column
-(@code{vip-next-line}).
-@item +
-@kindex 053 + @r{(}@code{vip-next-line-at-bol}@r{)}
-Move point to the next line at the first non-white character.  If point is
-on the last line of the buffer, a new line will be created and point will
-move to the beginning of that line (@code{vip-next-line-at-bol}).
-@item -
-@kindex 055 - @r{(}@code{vip-previous-line-at-bol}@r{)}
-Move point to the previous line at the first non-white character
-(@code{vip-previous-line-at-bol}).
-@end table
-@noindent
-If a count is given to these commands, the commands will be repeated that
-many times.
-
-@table @kbd
-@item 0
-@kindex 060 0 @r{(}@code{vip-beginning-of-line}@r{)}
-Move point to the beginning of line (@code{vip-beginning-of-line}).
-@item ^
-@kindex 136 ^ @r{(}@code{vip-bol-and-skip-white}@r{)}
-Move point to the first non-white character on the line
-(@code{vip-bol-and-skip-white}).
-@item $
-@kindex 044 $ @r{(}@code{vip-goto-eol}@r{)}
-Move point to the end of line (@code{vip-goto-eol}).
-@item @var{n} |
-@kindex 174 | @r{(}@code{vip-goto-col}@r{)}
-Move point to the @var{n}-th column on the line (@code{vip-goto-col}).
-@end table
-@noindent
-Except for the @kbd{|} command, these commands neglect a count.
-
-@cindex word
-
-@table @kbd
-@item w
-@kindex 167 w @r{(}@code{vip-forward-word}@r{)}
-Move point forward to the beginning of the next word
-(@code{vip-forward-word}).
-@item W
-@kindex 127 W @r{(}@code{vip-forward-Word}@r{)}
-Move point forward to the beginning of the next word, where a @dfn{word} is
-considered as a sequence of non-white characters (@code{vip-forward-Word}).
-@item b
-@kindex 142 b @r{(}@code{vip-backward-word}@r{)}
-Move point backward to the beginning of a word (@code{vip-backward-word}).
-@item B
-@kindex 102 B @r{(}@code{vip-backward-Word}@r{)}
-Move point backward to the beginning of a word, where a @i{word} is
-considered as a sequence of non-white characters (@code{vip-forward-Word}).
-@item e
-@kindex 145 e @r{(}@code{vip-end-of-word}@r{)}
-Move point forward to the end of a word (@code{vip-end-of-word}).
-@item E
-@kindex 105 E @r{(}@code{vip-end-of-Word}@r{)}
-Move point forward to the end of a word, where a @i{word} is
-considered as a sequence of non-white characters (@code{vip-end-of-Word}).
-@end table
-@noindent
-@cindex syntax table
-Here the meaning of the word ``word'' for the @kbd{w}, @kbd{b} and @kbd{e}
-commands is determined by the @dfn{syntax table} effective in the current
-buffer.  Each major mode has its syntax mode, and therefore the meaning of
-a word also changes as the major mode changes.  See GNU Emacs Manual for
-details of syntax table.
-
-@table @kbd
-@item H
-@kindex 110 H @r{(}@code{vip-window-top}@r{)}
-Move point to the beginning of the @i{home} (top) line of the window.
-Given a count @var{n}, go to the @var{n}-th line from top
-(@code{vip-window-top}).
-@item M
-@kindex 115 M @r{(}@code{vip-window-middle}@r{)}
-Move point to the beginning of the @i{middle} line of the window.  Given
-a count @var{n}, go to the @var{n}-th line from the middle line
-(@code{vip-window-middle}).
-@item L
-@kindex 114 L @r{(}@code{vip-window-bottom}@r{)}
-Move point to the beginning of the @i{lowest} (bottom) line of the
-window.  Given count, go to the @var{n}-th line from bottom
-(@code{vip-window-bottom}).
-@end table
-@noindent
-These commands can be used to go to the desired line visible on the screen.
-
-@table @kbd
-@item (
-@kindex 050 ( @r{(}@code{vip-backward-sentence}@r{)}
-Move point backward to the beginning of the sentence
-(@code{vip-backward-sentence}).
-@item )
-@kindex 051 ) @r{(}@code{vip-forward-sentence}@r{)}
-Move point forward to the end of the sentence
-(@code{vip-forward-sentence}).
-@item @{
-@kindex 173 @{ @r{(}@code{vip-backward-paragraph}@r{)}
-Move point backward to the beginning of the paragraph
-(@code{vip-backward-paragraph}).
-@item @}
-@kindex 175 @} @r{(}@code{vip-forward-paragraph}@r{)}
-Move point forward to the end of the paragraph
-(@code{vip-forward-paragraph}).
-@end table
-@noindent
-A count repeats the effect for these commands.
-
-@table @kbd
-@item G
-@kindex 107 G @r{(}@code{vip-goto-line}@r{)}
-Given a count @var{n}, move point to the @var{n}-th line in the buffer on
-the first non-white character.  Without a count, go to the end of the buffer
-(@code{vip-goto-line}).
-@item ` `
-@kindex 140 ` @r{(}@code{vip-goto-mark}@r{)}
-Exchange point and mark (@code{vip-goto-mark}).
-@item ` @var{ch}
-Move point to the position stored in the register @var{ch}.  @var{ch} must
-be a lower-case letter.
-@item ' '
-@kindex 047 ' @r{(}@code{vip-goto-mark-and-skip-white}@r{)}
-Exchange point and mark, and then move point to the first non-white
-character on the line (@code{vip-goto-mark-and-skip-white}).
-@item ' @var{ch}
-Move point to the position stored in the register @var{ch} and skip to the
-first non-white character on the line.  @var{ch} must be a lower-case letter.
-@item %
-@kindex 045 % @r{(}@code{vip-paren-match}@r{)}
-Move point to the matching parenthesis if point is looking at @kbd{(},
-@kbd{)}, @kbd{@{}, @kbd{@}}, @kbd{[} or @kbd{]}
-@*(@code{vip-paren-match}).
-@end table
-@noindent
-The command @kbd{G} mark point before move, so that you can return to the
-original point by @kbd{` `}.  The original point will also be stored in
-the mark ring.
-
-The following commands are useful for moving points on the line.  A count
-will repeat the effect.
-
-@table @kbd
-@item f @var{ch}
-@kindex 146 f @r{(}@code{vip-find-char-forward}@r{)}
-Move point forward to the character @var{ch} on the line.  Signal error if
-@var{ch} could not be found (@code{vip-find-char-forward}).
-@item F @var{ch}
-@kindex 106 F @r{(}@code{vip-find-char-backward}@r{)}
-Move point backward to the character @var{ch} on the line.  Signal error if
-@var{ch} could not be found (@code{vip-find-char-backward}).
-@item t @var{ch}
-@kindex 164 t @r{(}@code{vip-goto-char-forward}@r{)}
-Move point forward up to the character @var{ch} on the line.  Signal error if
-@var{ch} could not be found (@code{vip-goto-char-forward}).
-@item T @var{ch}
-@kindex 124 T @r{(}@code{vip-goto-char-backward}@r{)}
-Move point backward up to the character @var{ch} on the line.  Signal error if
-@var{ch} could not be found (@code{vip-goto-char-backward}).
-@item ;
-@kindex 073 ; @r{(}@code{vip-repeat-find}@r{)}
-Repeat previous @kbd{f}, @kbd{t}, @kbd{F} or @kbd{T} command
-(@code{vip-repeat-find}).
-@item ,
-@kindex 054 , @r{(}@code{vip-repeat-find-opposite}@r{)}
-Repeat previous @kbd{f}, @kbd{t}, @kbd{F} or @kbd{T} command, in the
-opposite direction (@code{vip-repeat-find-opposite}).
-@end table
-
-@node Searching and Replacing
-@section Searching and Replacing
-
-Following commands are available for searching and replacing.
-
-@cindex regular expression (search)
-
-@table @kbd
-@item / @var{string} @key{RET}
-@kindex 057 / @r{(}@code{vip-search-forward}@r{)}
-Search the first occurrence of the string @var{string} forward starting
-from point.  Given a count @var{n}, the @var{n}-th occurrence of
-@var{string} will be searched.  If the variable @code{vip-re-search} has value
-@code{t} then @dfn{regular expression} search is done and the string
-matching the regular expression @var{string} is found.  If you give an
-empty string as @var{string} then the search mode will change from vanilla
-search to regular expression search and vice versa
-(@code{vip-search-forward}).
-@item ? @var{string} @key{RET}
-@kindex 077 ? @r{(}@code{vip-search-backward}@r{)}
-Same as @kbd{/}, except that search is done backward
-(@code{vip-search-backward}).
-@item n
-@kindex 156 n @r{(}@code{vip-search-next}@r{)}
-Search the previous search pattern in the same direction as before
-(@code{vip-search-next}).
-@item N
-@kindex 116 N @r{(}@code{vip-search-Next}@r{)}
-Search the previous search pattern in the opposite direction
-(@code{vip-search-Next}).
-@item C-s
-@kindex 023 C-s @r{(}@code{isearch-forward}@r{)}
-Search forward incrementally.  See GNU Emacs Manual for details
-(@code{isearch-forward}).
-@item C-r
-@kindex 022 C-r @r{(}@code{isearch-backward}@r{)}
-Search backward incrementally (@code{isearch-backward}).
-@cindex vanilla (replacement)
-@cindex regular expression (replacement)
-@item R @var{string} @key{RET} @var{newstring}
-@kindex 122 R @r{(}@code{vip-replace-string}@r{)}
-There are two modes of replacement, @dfn{vanilla} and @dfn{regular expression}.
-If the mode is @i{vanilla} you will get a prompt @samp{Replace string:},
-and if the mode is @i{regular expression} you will ge a prompt
-@samp{Replace regexp:}.  The mode is initially @i{vanilla}, but you can
-toggle these modes by giving a null string as @var{string}.  If the mode is
-vanilla, this command replaces every occurrence of @var{string} with
-@var{newstring}.  If the mode is regular expression, @var{string} is
-treated as a regular expression and every string matching the regular
-expression is replaced with @var{newstring} (@code{vip-replace-string}).
-@item Q @var{string} @key{RET} @var{newstring}
-@kindex 121 Q @r{(}@code{vip-query-replace}@r{)}
-Same as @kbd{R} except that you will be asked form confirmation before each
-replacement
-@*(@code{vip-query-replace}).
-@item r @var{ch}
-@kindex 162 r @r{(}@code{vip-replace-char}@r{)}
-Replace the character point is looking at by the character @var{ch}.  Give
-count, replace that many characters by @var{ch} (@code{vip-replace-char}).
-@end table
-@noindent
-The commands @kbd{/} and @kbd{?} mark point before move, so that you can
-return to the original point by @w{@kbd{` `}}.
-
-@node Modifying Commands
-@section Modifying Commands
-
-In this section, commands for modifying the content of a buffer are
-described.  These commands affect the region determined by a motion command
-which is given to the commands as their argument.
-
-@cindex point commands
-@cindex line commands
-
-We classify motion commands into @dfn{point commands} and
-@dfn{line commands}.  The point commands are as follows:
-@example
-@kbd{h}, @kbd{l}, @kbd{0}, @kbd{^}, @kbd{$}, @kbd{w}, @kbd{W}, @kbd{b}, 
@kbd{B}, @kbd{e}, @kbd{E}, @kbd{(}, @kbd{)}, @kbd{/}, @kbd{?}, @kbd{`}, 
@kbd{f}, @kbd{F}, @kbd{t}, @kbd{T}, @kbd{%}, @kbd{;}, @kbd{,}
-@end example
-@noindent
-The line commands are as follows:
-@example
-@kbd{j}, @kbd{k}, @kbd{+}, @kbd{-}, @kbd{H}, @kbd{M}, @kbd{L}, @kbd{@{}, 
@kbd{@}}, @kbd{G}, @kbd{'}
-@end example
-@noindent
-@cindex expanding (region)
-If a point command is given as an argument to a modifying command, the
-region determined by the point command will be affected by the modifying
-command.  On the other hand, if a line command is given as an argument to a
-modifying command, the region determined by the line command will be
-enlarged so that it will become the smallest region properly containing the
-region and consisting of whole lines (we call this process @dfn{expanding
-the region}), and then the enlarged region will be affected by the modifying
-command.
-
-@menu
-* Delete Commands::     Commands for deleting text.
-* Yank Commands::       Commands for yanking text in Vi's sense.
-* Put Back Commands::   Commands for putting back deleted/yanked text.
-* Change Commands::     Commands for changing text.
-* Repeating and Undoing Modifications::
-@end menu
-@node Delete Commands
-@subsection Delete Commands
-
-@table @kbd
-@item d @var{motion-command}
-@kindex 1440 d @r{(}@code{vip-command-argument}@r{)}
-Delete the region determined by the motion command @var{motion-command}.
-@end table
-@noindent
-For example, @kbd{d $} will delete the region between point and end of
-current line since @kbd{$} is a point command that moves point to end of line.
-@kbd{d G} will delete the region between the beginning of current line and
-end of the buffer, since @kbd{G} is a line command.  A count given to the
-command above will become the count for the associated motion command.
-Thus, @kbd{3 d w} will delete three words.
-
-@kindex 042 " @r{(}@code{vip-command-argument}@r{)}
-It is also possible to save the deleted text into a register you specify.
-For example, you can say @kbd{" t 3 d w} to delete three words and save it
-to register @kbd{t}.  The name of a register is a lower-case letter between
-@kbd{a} and @kbd{z}.  If you give an upper-case letter as an argument to
-a delete command, then the deleted text will be appended to the content of
-the register having the corresponding lower-case letter as its name.  So,
-@kbd{" T d w} will delete a word and append it to register @kbd{t}.  Other
-modifying commands also accept a register name as their argument, and we
-will not repeat similar explanations.
-
-We have more delete commands as below.
-
-@table @kbd
-@item d d
-@kindex 1442 d d
-Delete a line.  Given a count @var{n}, delete @var{n} lines.
-@item d r
-@kindex 1442 d r
-Delete current region.
-@item d R
-@kindex 1441 d R
-Expand current region and delete it.
-@item D
-@kindex 104 D @r{(}@code{vip-kill-line}@r{)}
-Delete to the end of a line (@code{vip-kill-line}).
-@item x
-@kindex 170 x @r{(}@code{vip-delete-char}@r{)}
-Delete a character after point.  Given @var{n}, delete @var{n} characters
-(@code{vip-delete-char}).
-@item @key{DEL}
-@kindex 177 DEL @r{(}@code{vip-delete-backward-char}@r{)}
-Delete a character before point.  Given @var{n}, delete @var{n} characters
-(@code{vip-delete-backward-char}).
-@end table
-
-@node Yank Commands
-@subsection Yank Commands
-
-@cindex yank
-
-Yank commands @dfn{yank} a text of buffer into a (usually anonymous) register.
-Here the word ``yank'' is used in Vi's sense.  Thus yank commands do not
-alter the content of the buffer, and useful only in combination with
-commands that put back the yanked text into the buffer.
-
-@table @kbd
-@item y @var{motion-command}
-@kindex 1710 y @r{(}@code{vip-command-argument}@r{)}
-Yank the region determined by the motion command @var{motion-command}.
-@end table
-@noindent
-For example, @kbd{y $} will yank the text between point and the end of line
-into an anonymous register, while @kbd{"c y $} will yank the same text into
-register @kbd{c}.
-
-Use the following command to yank consecutive lines of text.
-
-@table @kbd
-@item y y
-@itemx Y
-@kindex 131 Y @r{(}@code{vip-yank-line}@r{)}
-@kindex 1712 y y @r{(}@code{vip-yank-line}@r{)}
-Yank a line.  Given @var{n}, yank @var{n} lines (@code{vip-yank-line}).
-@item y r
-@kindex 1712 y r
-Yank current region.
-@item y R
-@kindex 1711 y R
-Expand current region and yank it.
-@end table
-
-@node Put Back Commands
-@subsection Put Back Commands
-Deleted or yanked texts can be put back into the buffer by the command
-below.
-
-@table @kbd
-@item p
-@kindex 160 p @r{(}@code{vip-put-back}@r{)}
-Insert, after the character point is looking at, most recently
-deleted/yanked text from anonymous register.  Given a register name
-argument, the content of the named register will be put back.  Given a
-count, the command will be repeated that many times.  This command also
-checks if the text to put back ends with a new line character, and if so
-the text will be put below the current line (@code{vip-put-back}).
-@item P
-@kindex 120 P @r{(}@code{vip-Put-back}@r{)}
-Insert at point most recently deleted/yanked text from anonymous register.
-Given a register name argument, the content of the named register will
-be put back.  Given a count, the command will be repeated that many times.
-This command also checks if the text to put back ends with a new line
-character, and if so the text will be put above the current line rather
-than at point (@code{vip-Put-back}).
-@end table
-@noindent
-@cindex number register
-Thus, @kbd{" c p} will put back the content of the register @kbd{c} into the
-buffer.  It is also possible to specify @dfn{number register} which is a
-numeral between @kbd{1} and @kbd{9}.  If the number register @var{n} is
-specified, @var{n}-th previously deleted/yanked text will be put back.  It
-is an error to specify a number register for the delete/yank commands.
-
-@node Change Commands
-@subsection Change Commands
-
-Most commonly used change command takes the following form.
-
-@table @kbd
-@item c @var{motion-command}
-@kindex 1430 c @r{(}@code{vip-command-argument}@r{)}
-Replace the content of the region determined by the motion command
-@var{motion-command} by the text you type.  If the motion command is a
-point command then you will type the text into minibuffer, and if the
-motion command is a line command then the region will be deleted first and
-you can insert the text in @var{insert mode}.
-@end table
-@noindent
-For example, if point is at the beginning of a word @samp{foo} and you
-wish to change it to @samp{bar}, you can type @kbd{c w}.  Then, as @kbd{w}
-is a point command, you will get the prompt @samp{foo =>} in the
-minibuffer, for which you can type @kbd{b a r @key{RET}} to complete the change
-command.
-
-@table @kbd
-@item c c
-@kindex 1432 c c
-Change a line.  Given a count, that many lines are changed.
-@item c r
-@kindex 1432 c r
-Change current region.
-@item c R
-@kindex 1431 c R
-Expand current region and change it.
-@end table
-
-@node Repeating and Undoing Modifications
-@subsection Repeating and Undoing Modifications
-
-VIP records the previous modifying command, so that it is easy to repeat
-it.  It is also very easy to undo changes made by modifying commands.
-
-@table @kbd
-@item u
-@kindex 165 u @r{(}@code{vip-undo}@r{)}
-Undo the last change.  You can undo more by repeating undo by the repeat
-command @samp{.}.  For example, you can undo 5 previous changes by typing
-@samp{u....}.  If you type @samp{uu}, then the second @samp{u} undoes the
-first undo command (@code{vip-undo}).
-@item .
-@kindex 056 . @r{(}@code{vip-repeat}@r{)}
-Repeat the last modifying command.  Given count @var{n} it becomes the new
-count for the repeated command.  Otherwise, the count for the last
-modifying command is used again (@code{vip-repeat}).
-@end table
-
-@node Other Vi Commands
-@section Other Vi Commands
-
-Miscellaneous Vi commands are collected here.
-
-@table @kbd
-@item Z Z
-@kindex 132 Z Z @r{(}@code{save-buffers-kill-emacs}@r{)}
-Exit Emacs.  If modified buffers exist, you will be asked whether you wish
-to save them or not (@code{save-buffers-kill-emacs}).
-@item !@: @var{motion-command} @var{format-command}
-@itemx @var{n} !@: !@: @var{format-command}
-@kindex 041 ! @r{(}@code{vip-command-argument}@r{)}
-The region determined by the motion command @var{motion-command} will be
-given to the shell command @var{format-command} and the region will be
-replaced by its output.  If a count is given, it will be passed to
-@var{motion-command}.  For example, @samp{3!Gsort} will sort the region
-between point and the 3rd line.  If @kbd{!} is used instead of
-@var{motion-command} then @var{n} lines will be processed by
-@var{format-command} (@code{vip-command-argument}).
-@item J
-@kindex 112 J @r{(}@code{vip-join-lines}@r{)}
-Join two lines.  Given count, join that many lines.  A space will be
-inserted at each junction (@code{vip-join-lines}).
-@item < @var{motion-command}
-@itemx @var{n} < <
-@kindex 074 < @r{(}@code{vip-command-argument}@r{)}
-Shift region determined by the motion command @var{motion-command} to
-left by @var{shift-width} (default is 8).  If @kbd{<} is used instead of
-@var{motion-command} then shift @var{n} lines
-@*(@code{vip-command-argument}).
-@item > @var{motion-command}
-@itemx @var{n} > >
-@kindex 076 > @r{(}@code{vip-command-argument}@r{)}
-Shift region determined by the motion command @var{motion-command} to
-right by @var{shift-width} (default is 8).  If @kbd{<} is used instead of
-@var{motion-command} then shift @var{n} lines
-@*(@code{vip-command-argument}).
-@item = @var{motion-command}
-@kindex 075 = @r{(}@code{vip-command-argument}@r{)}
-Indent region determined by the motion command @var{motion-command}.  If
-@kbd{=} is used instead of @var{motion-command} then indent @var{n} lines
-(@code{vip-command-argument}).
-@item *
-@kindex 052 * @r{(}@code{vip-call-last-kbd-macro}@r{)}
-Call last remembered keyboard macro.
-@item #
-A new vi operator. @xref{New Commands}, for more details.
-@end table
-
-The following keys are reserved for future extensions, and currently
-assigned to a function that just beeps (@code{vip-nil}).
-
-@kindex 046 & @r{(}@code{vip-nil}@r{)}
-@kindex 100 @@ @r{(}@code{vip-nil}@r{)}
-@kindex 125 U @r{(}@code{vip-nil}@r{)}
-@kindex 133 [ @r{(}@code{vip-nil}@r{)}
-@kindex 135 ] @r{(}@code{vip-nil}@r{)}
-@kindex 137 _ @r{(}@code{vip-nil}@r{)}
-@kindex 161 q @r{(}@code{vip-nil}@r{)}
-@kindex 176 ~ @r{(}@code{vip-nil}@r{)}
-
-@example
-&, @@, U, [, ], _, q, ~
-@end example
-
-VIP uses a special local keymap to interpret key strokes you enter in vi
-mode.  The following keys are bound to @code{nil} in the keymap.  Therefore,
-these keys are interpreted by the global keymap of Emacs.  We give below a
-short description of the functions bound to these keys in the global
-keymap.  See GNU Emacs Manual for details.
-
-@table @kbd
-@item C-@@
-@kindex 000 C-@@ @r{(}@code{set-mark-command}@r{)}
-Set mark and push previous mark on mark ring (@code{set-mark-command}).
-@item @key{TAB}
-@kindex 011 TAB @r{(}@code{indent-for-tab-command}@r{)}
-Indent line for current major mode (@code{indent-for-tab-command}).
-@item C-j
-@kindex 012 C-j @r{(}@code{electric-newline-and-maybe-indent}@r{)}
-Insert a newline, and maybe indent according to mode.
-@item C-k
-@kindex 013 C-k @r{(}@code{kill-line}@r{)}
-Kill the rest of the current line; before a newline, kill the newline.
-With a numeric argument, kill that many lines from point.  Negative arguments
-kill lines backward (@code{kill-line}).
-@item C-l
-@kindex 014 C-l @r{(}@code{recenter}@r{)}
-Clear the screen and reprint everything (@code{recenter}).
-@item @var{n} C-p
-@kindex 020 C-p @r{(}@code{previous-line}@r{)}
-Move cursor vertically up @var{n} lines (@code{previous-line}).
-@item C-q
-@kindex 021 C-q @r{(}@code{quoted-insert}@r{)}
-Read next input character and insert it.  Useful for inserting control
-characters
-@*(@code{quoted-insert}).
-@item C-r
-@kindex 022 C-r @r{(}@code{isearch-backward}@r{)}
-Search backward incrementally (@code{isearch-backward}).
-@item C-s
-@kindex 023 C-s @r{(}@code{isearch-forward}@r{)}
-Search forward incrementally (@code{isearch-forward}).
-@item @var{n} C-t
-@kindex 024 C-t @r{(}@code{transpose-chars}@r{)}
-Interchange characters around point, moving forward one character.  With
-count @var{n}, take character before point and drag it forward past @var{n}
-other characters.  If no argument and at end of line, the previous two
-characters are exchanged (@code{transpose-chars}).
-@item @var{n} C-v
-@kindex 026 C-v @r{(}@code{scroll-up}@r{)}
-Scroll text upward @var{n} lines.  If @var{n} is not given, scroll near
-full screen (@code{scroll-up}).
-@item C-w
-@kindex 027 C-w @r{(}@code{kill-region}@r{)}
-Kill between point and mark.  The text is save in the kill ring.  The
-command @kbd{P} or @kbd{p} can retrieve it from kill ring
-(@code{kill-region}).
-@end table
-
-@node Commands in Insert Mode
-@section Insert Mode
-
-You can enter insert mode by one of the following commands.  In addition to
-these, you will enter insert mode if you give a change command with a line
-command as the motion command.  Insert commands are also modifying commands
-and you can repeat them by the repeat command @kbd{.} (@code{vip-repeat}).
-
-@table @kbd
-@item i
-@kindex 151 i @r{(}@code{vip-insert}@r{)}
-Enter insert mode at point (@code{vip-insert}).
-@item I
-@kindex 111 I @r{(}@code{vip-Insert}@r{)}
-Enter insert mode at the first non white character on the line
-(@code{vip-Insert}).
-@item a
-@kindex 141 a @r{(}@code{vip-append}@r{)}
-Move point forward by one character and then enter insert mode
-(@code{vip-append}).
-@item A
-@kindex 101 A @r{(}@code{vip-Append}@r{)}
-Enter insert mode at end of line (@code{vip-Append}).
-@item o
-@kindex 157 o @r{(}@code{vip-open-line}@r{)}
-Open a new line below the current line and enter insert mode
-(@code{vip-open-line}).
-@item O
-@kindex 117 O @r{(}@code{vip-Open-line}@r{)}
-Open a new line above the current line and enter insert mode
-(@code{vip-Open-line}).
-@item C-o
-@kindex 017 C-o @r{(}@code{vip-open-line-at-point}@r{)}
-Insert a newline and leave point before it, and then enter insert mode
-@*(@code{vip-open-line-at-point}).
-@end table
-
-Insert mode is almost like emacs mode.  Only the following 4 keys behave
-differently from emacs mode.
-
-@table @kbd
-@item @key{ESC}
-@kindex 033 ESC @r{(}@code{vip-change-mode-to-vi}@r{) (insert mode)}
-This key will take you back to vi mode (@code{vip-change-mode-to-vi}).
-@item C-h
-@kindex 010 C-h @r{(}@code{delete-backward-char}@r{) (insert mode)}
-Delete previous character (@code{delete-backward-char}).
-@item C-w
-@kindex 027 C-w @r{(}@code{vip-delete-backward-word}@r{) (insert mode)}
-Delete previous word (@code{vip-delete-backward-word}).
-@item C-z
-@kindex 032 C-z @r{(}@code{vip-ESC}@r{) (insert mode)}
-This key simulates @key{ESC} key in emacs mode.  For instance, typing
-@kbd{C-z x} in insert mode is the same as typing @kbd{ESC x} in emacs mode
-(@code{vip-ESC}).
-@end table
-@noindent
-You can also bind @kbd{C-h} to @code{help-command} if you like.
-(@xref{Customizing Key Bindings}, for details.)  Binding @kbd{C-h} to
-@code{help-command} has the effect of making the meaning of @kbd{C-h}
-uniform among emacs, vi and insert modes.
-
-When you enter insert mode, VIP records point as the start point of
-insertion, and when you leave insert mode the region between point and
-start point is saved for later use by repeat command etc.  Therefore, repeat
-command will not really repeat insertion if you move point by emacs
-commands while in insert mode.
-
-@node Ex Commands
-@chapter Ex Commands
-
-@kindex 072 : @r{(}@code{vip-ex}@r{)}
-
-In vi mode, you can execute an Ex command @var{ex-command} by typing:
-@example
-@kbd{:@: @var{ex-command} @key{RET}}
-@end example
-Every Ex command follows the following pattern:
-@example
-@var{address command} @kbd{!}@: @var{parameters count flags}
-@end example
-@noindent
-@cindex address
-where all parts are optional.  For the syntax of @dfn{address}, the reader
-is referred to the reference manual of Ex.
-
-@cindex magic
-@cindex regular expression
-
-In the current version of VIP, searching by Ex commands is always
-@dfn{magic}.  That is, search patterns are always treated as @dfn{regular
-expressions}.  For example, a typical forward search would be invoked by
-@kbd{:/@var{pat}/}.  If you wish to include @samp{/} as part of
-@var{pat} you must preceded it by @samp{\}.  VIP strips off these @kbd{\}'s
-before @kbd{/} and the resulting @var{pat} becomes the actual search
-pattern.  Emacs provides a different and richer class or regular
-expressions than Vi/Ex, and VIP uses Emacs's regular expressions.  See GNU
-Emacs Manual for details of regular expressions.
-
-Several Ex commands can be entered in a line by separating them by a pipe
-character @samp{|}.
-
-@menu
-* Ex Command Reference::        Explain all the Ex commands available in VIP.
-@end menu
-@node Ex Command Reference
-@section Ex Command Reference
-In this section we briefly explain all the Ex commands supported by VIP@.
-Most Ex commands expect @var{address} as their argument, and they use
-default addresses if they are not explicitly given.  In the following, such
-default addresses will be shown in parentheses.
-
-Most command names can and preferably be given in abbreviated forms.  In
-the following, optional parts of command names will be enclosed in
-brackets.  For example, @samp{co[py]} will mean that copy command can be
-give as @samp{co} or @samp{cop} or @samp{copy}.
-
-If @var{command} is empty, point will move to the beginning of the line
-specified by the @var{address}.  If @var{address} is also empty, point will
-move to the beginning of the current line.
-
-@cindex flag
-
-Some commands accept @dfn{flags} which are one of @kbd{p}, @kbd{l} and
-@kbd{#}.  If @var{flags} are given, the text affected by the commands will
-be displayed on a temporary window, and you will be asked to hit return to
-continue.  In this way, you can see the text affected by the commands
-before the commands will be executed.  If you hit @kbd{C-g} instead of
-@key{RET} then the commands will be aborted.  Note that the meaning of
-@var{flags} is different in VIP from that in Vi/Ex.
-
-@table @kbd
-@item (.,.@:) co[py] @var{addr} @var{flags}
-@itemx (.,.@:) t @var{addr} @var{flags}
-Place a copy of specified lines after @var{addr}.  If @var{addr} is
-@kbd{0}, it will be placed before the first line.
-@item (.,.@:) d[elete] @var{register} @var{count} @var{flags}
-Delete specified lines.  Text will be saved in a named @var{register} if a
-lower-case letter is given, and appended to a register if a capital letter is
-given.
-@item e[dit] !@: +@var{addr} @var{file}
-@itemx e[x] !@: +@var{addr} @var{file}
-@itemx vi[sual] !@: +@var{addr} @var{file}
-Edit a new file @var{file} in the current window.  The command will abort
-if current buffer is modified, which you can override by giving @kbd{!}.
-If @kbd{+}@var{addr} is given, @var{addr} becomes the current line.
-@item file
-Give information about the current file.
-@item (1,$) g[lobal] !@: /@var{pat}/ @var{cmds}
-@itemx (1,$) v /@var{pat}/ @var{cmds}
-Among specified lines first mark each line which matches the regular
-expression @var{pat}, and then execute @var{cmds} on each marked line.
-If @kbd{!}@: is given, @var{cmds} will be executed on each line not matching
-@var{pat}.  @kbd{v} is same as @kbd{g!}.
-@item (.,.+1) j[oin] !@: @var{count} @var{flags}
-Join specified lines into a line.  Without @kbd{!}, a space character will
-be inserted at each junction.
-@item (.@:) k @var{ch}
-@itemx (.@:) mar[k] @var{ch}
-Mark specified line by a lower-case character @var{ch}.  Then the
-addressing form @kbd{'}@var{ch} will refer to this line.  No white space is
-required between @kbd{k} and @var{ch}.  A white space is necessary between
-@kbd{mark} and @var{ch}, however.
-@item map @var{ch} @var{rhs}
-Define a macro for vi mode.  After this command, the character @var{ch}
-will be expanded to @var{rhs} in vi mode.
-@item (.,.@:) m[ove] @var{addr}
-Move specified lines after @var{addr}.
-@item (.@:) pu[t] @var{register}
-Put back previously deleted or yanked text.  If @var{register} is given,
-the text saved in the register will be put back; otherwise, last deleted or
-yanked text will be put back.
-@item q[uit] !
-Quit from Emacs.  If modified buffers with associated files exist, you will
-be asked whether you wish to save each of them.  At this point, you may
-choose not to quit, by hitting @kbd{C-g}.  If @kbd{!}@: is given, exit from
-Emacs without saving modified buffers.
-@item (.@:) r[ead] @var{file}
-Read in the content of the file @var{file} after the specified line.
-@item (.@:) r[ead] !@: @var{command}
-Read in the output of the shell command @var{command} after the specified
-line.
-@item se[t]
-Set a variable's value.  @xref{Customizing Constants}, for the list of 
variables
-you can set.
-@item sh[ell]
-Run a subshell in a window.
-@item (.,.@:) s[ubstitute] /@var{pat}/@var{repl}/ @var{options} @var{count} 
@var{flags}
-@itemx (.,.@:) & @var{options} @var{count} @var{flags}
-On each specified line, the first occurrence of string matching regular
-expression @var{pat} is replaced by replacement pattern @var{repl}.  Option
-characters are @kbd{g} and @kbd{c}.  If global option character @kbd{g}
-appears as part of @var{options}, all occurrences are substituted.  If
-confirm option character @kbd{c} appears, you will be asked to give
-confirmation before each substitution.  If @kbd{/@var{pat}/@var{repl}/} is
-missing, the last substitution is repeated.
-@item st[op]
-Suspend Emacs.
-@item ta[g] @var{tag}
-@cindex tag
-@cindex selected tags table
-Find first definition of @var{tag}.  If no @var{tag} is given, previously
-given @var{tag} is used and next alternate definition is find.  By default,
-the file @file{TAGS} in the current directory becomes the @dfn{selected tags
-table}.  You can select another tags table by @kbd{set} command.
-@xref{Customizing Constants}, for details.
-@item und[o]
-Undo the last change.
-@item unm[ap] @var{ch}
-The macro expansion associated with @var{ch} is removed.
-@item ve[rsion]
-Tell the version number of VIP.
-@item (1,$) w[rite] !@: @var{file}
-Write out specified lines into file @var{file}.  If no @var{file} is given,
-text will be written to the file associated to the current buffer.  Unless
-@kbd{!}@: is given, if @var{file} is different from the file associated to
-the current buffer and if the file @var{file} exists, the command will not
-be executed.  Unlike Ex, @var{file} becomes the file associated to the
-current buffer.
-@item (1,$) w[rite]>> @var{file}
-Write out specified lines at the end of file @var{file}.  @var{file}
-becomes the file associated to the current buffer.
-@item (1,$) wq !@: @var{file}
-Same as @kbd{write} and then @kbd{quit}.  If @kbd{!}@: is given, same as
-@kbd{write !}@: then @kbd{quit}.
-@item (.,.) y[ank] @var{register} @var{count}
-Save specified lines into register @var{register}.  If no register is
-specified, text will be saved in an anonymous register.
-@item @var{addr} !@: @var{command}
-Execute shell command @var{command}.  The output will be shown in a new
-window.  If @var{addr} is given, specified lines will be used as standard
-input to @var{command}.
-@item ($) =
-Print the line number of the addressed line.
-@item (.,.) > @var{count} @var{flags}
-Shift specified lines to the right.  The variable @code{vip-shift-width}
-(default value is 8) determines the amount of shift.
-@item (.,.) < @var{count} @var{flags}
-Shift specified lines to the left.  The variable @code{vip-shift-width}
-(default value is 8) determines the amount of shift.
-@item (.,.@:) ~ @var{options} @var{count} @var{flags}
-Repeat the previous @kbd{substitute} command using previous search pattern
-as @var{pat} for matching.
-@end table
-
-The following Ex commands are available in Vi, but not implemented in VIP.
-@example
-@kbd{abbreviate}, @kbd{list}, @kbd{next}, @kbd{print}, @kbd{preserve}, 
@kbd{recover}, @kbd{rewind}, @kbd{source},
-@kbd{unabbreviate}, @kbd{xit}, @kbd{z}
-@end example
-
-@node Customization
-@chapter Customization
-
-If you have a file called @file{~/.emacs.d/vip} (or @file{~/.vip}), then it
-will also be loaded when VIP is loaded.  This file is thus useful for
-customizing VIP.
-
-@menu
-* Customizing Constants::       How to change values of constants.
-* Customizing Key Bindings::    How to change key bindings.
-@end menu
-
-@node Customizing Constants
-@section Customizing Constants
-An easy way to customize VIP is to change the values of constants used
-in VIP@.  Here is the list of the constants used in VIP and their default
-values.
-
-@table @code
-@item vip-shift-width 8
-The number of columns shifted by @kbd{>} and @kbd{<} command.
-@item vip-re-replace nil
-If @code{t} then do regexp replace, if @code{nil} then do string replace.
-@item vip-search-wrap-around t
-If @code{t}, search wraps around the buffer.
-@item vip-re-search nil
-If @code{t} then search is reg-exp search, if @code{nil} then vanilla
-search.
-@item vip-case-fold-search nil
-If @code{t} search ignores cases.
-@item vip-re-query-replace nil
-If @code{t} then do reg-exp replace in query replace.
-@item vip-open-with-indent nil
-If @code{t} then indent to the previous current line when open a new line
-by @kbd{o} or @kbd{O} command.
-@item vip-tags-file-name "TAGS"
-The name of the file used as the tags table.
-@item vip-help-in-insert-mode nil
-If @code{t} then @kbd{C-h} is bound to @code{help-command} in insert mode,
-if @code{nil} then it sis bound to @code{delete-backward-char}.
-@end table
-@noindent
-You can reset these constants in VIP by the Ex command @kbd{set}.  Or you
-can include a line like this in your @file{~/.emacs.d/vip} file:
-@example
-(setq vip-case-fold-search t)
-@end example
-
-@node Customizing Key Bindings
-@section Customizing Key Bindings
-
-@cindex local keymap
-
-VIP uses @code{vip-command-mode-map} as the @dfn{local keymap} for vi mode.
-For example, in vi mode, @key{SPC} is bound to the function
-@code{vip-scroll}.  But, if you wish to make @key{SPC} and some other keys
- behave like Vi, you can include the following lines in your
-@file{~/.emacs.d/vip} file.
-
-@example
-(define-key vip-command-mode-map "\C-g" 'vip-info-on-file)
-(define-key vip-command-mode-map "\C-h" 'vip-backward-char)
-(define-key vip-command-mode-map "\C-m" 'vip-next-line-at-bol)
-(define-key vip-command-mode-map " " 'vip-forward-char)
-(define-key vip-command-mode-map "g" 'vip-keyboard-quit)
-(define-key vip-command-mode-map "s" 'vip-substitute)
-(define-key vip-command-mode-map "C" 'vip-change-to-eol)
-(define-key vip-command-mode-map "R" 'vip-change-to-eol)
-(define-key vip-command-mode-map "S" 'vip-substitute-line)
-(define-key vip-command-mode-map "X" 'vip-delete-backward-char)
-@end example
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-
-@unnumbered Key Index
-
-@printindex ky
-
-@unnumbered Concept Index
-@printindex cp
-
-@bye
diff --git a/etc/NEWS b/etc/NEWS
index c8a1e75d68f..37568ffdbea 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -478,6 +478,10 @@ All the characters that belong to the 'symbol' script 
(according to
 'char-script-table') now have the 'symbol' category, whose mnemonic is
 '5'.
 
+** Some libraries obsolete since Emacs 24.4 and 24.5 have been removed:
+cc-compat.el, info-edit.el, meese.el, otodo-mode.el, rcompile.el,
+sup-mouse.el, terminal.el, vi.el, vip.el, ws-mode.el, and yow.el.
+
 
 * Lisp Changes in Emacs 31.1
 
diff --git a/etc/refcards/Makefile b/etc/refcards/Makefile
index c80c55a60cf..ee85e5f3235 100644
--- a/etc/refcards/Makefile
+++ b/etc/refcards/Makefile
@@ -29,7 +29,6 @@ PDF_ENGLISH = \
        orgcard.pdf \
        refcard.pdf \
        survival.pdf \
-       vipcard.pdf \
        viperCard.pdf
 
 PDF_CZECH = \
@@ -296,12 +295,6 @@ survival.pdf: $(survival_deps)
 survival.dvi: $(survival_deps)
        $(ENVADD) tex survival.tex
 
-vipcard_deps = vipcard.tex emacsver.tex pdflayout.sty
-vipcard.pdf: $(vipcard_deps)
-       $(ENVADD) pdftex vipcard.tex
-vipcard.dvi: $(vipcard_deps)
-       $(ENVADD) tex vipcard.tex
-
 vipercard_deps = viperCard.tex emacsver.tex pdflayout.sty
 viperCard.pdf: $(vipercard_deps)
        $(ENVADD) pdftex viperCard.tex
diff --git a/etc/refcards/README b/etc/refcards/README
index 9521c9e0c2a..835aae4317f 100644
--- a/etc/refcards/README
+++ b/etc/refcards/README
@@ -32,7 +32,6 @@ List of generated cards:
     orgcard.pdf            Org-Mode Reference Card
     refcard.pdf            Emacs Reference Card
     survival.pdf           Emacs Survival Card
-    vipcard.pdf            VIP Quick Reference Card
     viperCard.pdf          ViperCard: Viper Reference Pal
 
 Brazilian Portuguese
diff --git a/etc/refcards/vipcard.tex b/etc/refcards/vipcard.tex
deleted file mode 100644
index 7e5e0bdcb74..00000000000
--- a/etc/refcards/vipcard.tex
+++ /dev/null
@@ -1,681 +0,0 @@
-% Quick Reference Card for VIP
-
-% Copyright (C) 1987, 2001--2024 Free Software Foundation, Inc.
-
-% Author: Masahiko Sato <ms@sail.stanford.edu>, 
<masahiko@sato.riec.tohoku.junet>
-
-% This document is free software: you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation, either version 3 of the License, or
-% (at your option) any later version.
-
-% As a special additional permission, you may distribute reference cards
-% printed, or formatted for printing, with the notice "Released under
-% the terms of the GNU General Public License version 3 or later"
-% instead of the usual distributed-under-the-GNU-GPL notice, and without
-% a copy of the GPL itself.
-
-% This document is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-% GNU General Public License for more details.
-
-% You should have received a copy of the GNU General Public License
-% along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-
-% This file is intended to be processed by plain TeX (TeX82).
-%
-% The final reference card has six columns, three on each side.
-% This file can be used to produce it in any of three ways:
-% 1 column per page
-%    produces six separate pages, each of which needs to be reduced to 80%.
-%    This gives the best resolution.
-% 2 columns per page
-%    produces three already-reduced pages.
-%    You will still need to cut and paste.
-% 3 columns per page
-%    produces two pages which must be printed sideways to make a
-%    ready-to-use 8.5 x 11 inch reference card.
-%    For this you need a dvi device driver that can print sideways.
-% Which mode to use is controlled by setting \columnsperpage.
-
-
-%**start of header
-\newcount\columnsperpage
-
-% This file can be printed with 1, 2, or 3 columns per page.
-% Specify how many you want here.
-\columnsperpage=1
-
-% PDF output layout.  0 for A4, 1 for letter (US), a `l' is added for
-% a landscape layout.
-\input pdflayout.sty
-\pdflayout=(1)
-
-\input emacsver.tex
-\def\versionemacs{18}           % version of Emacs this is for
-\def\versionvip{3.5}
-
-% Nothing else needs to be changed.
-
-\def\shortcopyrightnotice{\vskip 1ex plus 2 fill
-  \centerline{\small \copyright\ \year\ Free Software Foundation, Inc.
-  Permissions on back.}}
-
-\def\copyrightnotice{
-%\vskip 1ex plus 2 fill\begingroup\small
-\vskip 1ex \begingroup\small
-\centerline{Copyright \copyright\ \year\ Free Software Foundation, Inc.}
-\centerline{For VIP \versionvip\ with GNU Emacs version \versionemacs}
-\centerline{Written by Masahiko Sato,}
-\centerline{using refcard layout designed by Stephen Gildea.}
-
-Released under the terms of the GNU General Public License version 3 or later.
-
-For more Emacs documentation, and the \TeX{} source for this card,
-see the Emacs distribution, or {\tt https://www.gnu.org/software/emacs}
-\endgroup}
-
-% make \bye not \outer so that the \def\bye in the \else clause below
-% can be scanned without complaint.
-\def\bye{\par\vfill\supereject\end}
-
-\newdimen\intercolumnskip
-\newbox\columna
-\newbox\columnb
-
-\def\ncolumns{\the\columnsperpage}
-
-\message{[\ncolumns\space
-  column\if 1\ncolumns\else s\fi\space per page]}
-
-\def\scaledmag#1{ scaled \magstep #1}
-
-% This multi-way format was designed by Stephen Gildea
-% October 1986.
-% Slightly modified by Masahiko Sato, September 1987.
-\if 1\ncolumns
-  \hsize 4in
-  \vsize 10in
-  %\voffset -.7in
-  \voffset -.57in
-  \font\titlefont=\fontname\tenbf \scaledmag3
-  \font\headingfont=\fontname\tenbf \scaledmag2
-  \font\miniheadingfont=\fontname\tenbf \scaledmag1 % masahiko
-  \font\smallfont=\fontname\sevenrm
-  \font\smallsy=\fontname\sevensy
-
-  \footline{\hss\folio}
-  \def\makefootline{\baselineskip10pt\hsize6.5in\line{\the\footline}}
-\else
-  %\hsize 3.2in
-  %\vsize 7.95in
-  \hsize 3.41in % masahiko
-  \vsize 8in % masahiko
-  \hoffset -.75in
-  \voffset -.745in
-  \font\titlefont=cmbx10 \scaledmag2
-  \font\headingfont=cmbx10 \scaledmag1
-  \font\miniheadingfont=cmbx10 % masahiko
-  \font\smallfont=cmr6
-  \font\smallsy=cmsy6
-  \font\eightrm=cmr8
-  \font\eightbf=cmbx8
-  \font\eightit=cmti8
-  \font\eightsl=cmsl8
-  \font\eighttt=cmtt8
-  \font\eightsy=cmsy8
-  \textfont0=\eightrm
-  \textfont2=\eightsy
-  \def\rm{\eightrm}
-  \def\bf{\eightbf}
-  \def\it{\eightit}
-  \def\sl{\eightsl} % masahiko
-  \def\tt{\eighttt}
-  \normalbaselineskip=.8\normalbaselineskip
-  \normallineskip=.8\normallineskip
-  \normallineskiplimit=.8\normallineskiplimit
-  \normalbaselines\rm          %make definitions take effect
-
-  \if 2\ncolumns
-    \let\maxcolumn=b
-    \footline{\hss\rm\folio\hss}
-    \def\makefootline{\vskip 2in \hsize=6.86in\line{\the\footline}}
-  \else \if 3\ncolumns
-    \let\maxcolumn=c
-    \nopagenumbers
-  \else
-    \errhelp{You must set \columnsperpage equal to 1, 2, or 3.}
-    \errmessage{Illegal number of columns per page}
-  \fi\fi
-
-  %\intercolumnskip=.46in
-  \intercolumnskip=.19in % masahiko .19x4 + 3.41x3 = 10.99
-  \def\abc{a}
-  \output={%
-      % This next line is useful when designing the layout.
-      %\immediate\write16{Column \folio\abc\space starts with \firstmark}
-      \if \maxcolumn\abc \multicolumnformat \global\def\abc{a}
-      \else\if a\abc
-       \global\setbox\columna\columnbox \global\def\abc{b}
-        %% in case we never use \columnb (two-column mode)
-        \global\setbox\columnb\hbox to -\intercolumnskip{}
-      \else
-       \global\setbox\columnb\columnbox \global\def\abc{c}\fi\fi}
-  \def\multicolumnformat{\shipout\vbox{\makeheadline
-      \hbox{\box\columna\hskip\intercolumnskip
-        \box\columnb\hskip\intercolumnskip\columnbox}
-      \makefootline}\advancepageno}
-  \def\columnbox{\leftline{\pagebody}}
-
-  \def\bye{\par\vfill\supereject
-    \if a\abc \else\null\vfill\eject\fi
-    \if a\abc \else\null\vfill\eject\fi
-    \end}
-\fi
-
-% we won't be using math mode much, so redefine some of the characters
-% we might want to talk about
-\catcode`\^=12
-\catcode`\_=12
-
-\chardef\\=`\\
-\chardef\{=`\{
-\chardef\}=`\}
-
-\hyphenation{mini-buf-fer}
-
-\parindent 0pt
-\parskip 1ex plus .5ex minus .5ex
-
-\def\small{\smallfont\textfont2=\smallsy\baselineskip=.8\baselineskip}
-
-\outer\def\newcolumn{\vfill\eject}
-
-\outer\def\title#1{{\titlefont\centerline{#1}}\vskip 1ex plus .5ex}
-
-\outer\def\section#1{\par\filbreak
-  \vskip 3ex plus 2ex minus 2ex {\headingfont #1}\mark{#1}%
-  \vskip 2ex plus 1ex minus 1.5ex}
-
-% masahiko
-\outer\def\subsection#1{\par\filbreak
-  \vskip 2ex plus 2ex minus 2ex {\miniheadingfont #1}\mark{#1}%
-  \vskip 1ex plus 1ex minus 1.5ex}
-
-\newdimen\keyindent
-
-\def\beginindentedkeys{\keyindent=1em}
-\def\endindentedkeys{\keyindent=0em}
-\endindentedkeys
-
-\def\paralign{\vskip\parskip\halign}
-
-\def\<#1>{$\langle${\rm #1}$\rangle$}
-
-\def\kbd#1{{\tt#1}\null}       %\null so not an abbrev even if period follows
-
-\def\beginexample{\par\leavevmode\begingroup
-  \obeylines\obeyspaces\parskip0pt\tt}
-{\obeyspaces\global\let =\ }
-\def\endexample{\endgroup}
-
-\def\key#1#2{\leavevmode\hbox to \hsize{\vtop
-  {\hsize=.75\hsize\rightskip=1em
-  \hskip\keyindent\relax#1}\kbd{#2}\hfil}}
-
-\newbox\metaxbox
-\setbox\metaxbox\hbox{\kbd{M-x }}
-\newdimen\metaxwidth
-\metaxwidth=\wd\metaxbox
-
-\def\metax#1#2{\leavevmode\hbox to \hsize{\hbox to .75\hsize
-  {\hskip\keyindent\relax#1\hfil}%
-  \hskip -\metaxwidth minus 1fil
-  \kbd{#2}\hfil}}
-
-\def\fivecol#1#2#3#4#5{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad
-  &\kbd{#3}\quad&\kbd{#4}\quad&\kbd{#5}\cr}
-
-\def\fourcol#1#2#3#4{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad
-  &\kbd{#3}\quad&\kbd{#4}\quad\cr}
-
-\def\threecol#1#2#3{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad
-  &\kbd{#3}\quad\cr}
-
-\def\twocol#1#2{\hskip\keyindent\relax\kbd{#1}\hfil&\kbd{#2}\quad\cr}
-
-\def\twocolkey#1#2#3#4{\hskip\keyindent\relax#1\hfil&\kbd{#2}\quad&\relax#3\hfil&\kbd{#4}\quad\cr}
-
-%**end of header
-
-\beginindentedkeys
-
-\title{VIP Quick Reference Card}
-
-\centerline{(Based on VIP \versionvip\ in GNU Emacs \versionemacs)}
-
-%\copyrightnotice
-
-\section{Loading VIP}
-
-Just type \kbd{M-x vip-mode} followed by \kbd{RET}
-
-\section{VIP Modes}
-
-VIP has three modes: {\it emacs mode}, {\it vi mode} and {\it insert mode}.
-Mode line tells you which mode you are in.
-In emacs mode you can do all the normal GNU Emacs editing.
-This card explains only vi mode and insert mode.
-{\bf GNU Emacs Reference Card} explains emacs mode.
-You can switch modes as follows.
-
-\key{from emacs mode to vi mode}{C-z}
-\key{from vi mode to emacs mode}{C-z}
-\metax{from vi mode to insert mode}{i, I, a, A, o, O {\rm or} C-o}
-\key{from insert mode to vi mode}{ESC}
-
-If you wish to be in vi mode just after you startup Emacs,
-include the line:
-
-\hskip 5ex
-\kbd{(add-hook 'emacs-startup-hook 'vip-mode)}
-
-in your \kbd{.emacs} file.
-Or, you can put the following alias in your \kbd{.cshrc} file.
-
-\hskip 5ex
-\kbd{alias vip 'emacs \\!* -f vip-mode'}
-
-
-\section{Insert Mode}
-Insert mode is like emacs mode except for the following.
-
-\key{go back to vi mode}{ESC}
-\key{delete previous character}{C-h}
-\key{delete previous word}{C-w}
-\key{emulate \kbd{ESC} key in emacs mode}{C-z}
-
-The rest of this card explains commands in {\bf vi mode}.
-
-\section{Getting Information on VIP}
-
-Execute info command by typing \kbd{M-x info} and select menu item
-\kbd{vip}.  Also:
-
-\key{describe function attached to the key {\it x}}{C-h k {\it x}}
-
-\section{Leaving Emacs}
-
-\key{suspend Emacs}{X Z {\rm or} :st}
-\metax{exit Emacs permanently}{Z Z {\rm or} X C {\rm or} :q}
-
-\section{Error Recovery}
-
-\key{abort partially typed or executing command}{C-g}
-\key{redraw messed up screen}{C-l}
-\metax{{\bf recover} a file lost by a system crash}{M-x recover-file}
-\metax{restore a buffer to its original contents}{M-x revert-buffer}
-
-\shortcopyrightnotice
-
-\section{Counts}
-
-Most commands in vi mode accept a {\it count} which can be supplied as a
-prefix to the commands.  In most cases, if a count is given, the
-command is executed that many times.  E.g., \kbd{5 d d} deletes 5
-lines.
-
-%\shortcopyrightnotice
-\section{Registers}
-
-There are 26 registers (\kbd{a} to \kbd{z}) that can store texts
-and marks.
-You can append a text at the end of a register (say \kbd{x}) by
-specifying the register name in capital letter (say \kbd{X}).
-There are also 9 read only registers (\kbd{1} to \kbd{9}) that store
-up to 9 previous changes.
-We will use {\it x\/} to denote a register.
-\section{Entering Insert Mode}
-
-\key{{\bf insert} at point}{i}
-\key{{\bf append} after cursor}{a}
-\key{{\bf insert} before first non-white}{I}
-\key{{\bf append} at end of line}{A}
-\key{{\bf open} line below}{o}
-\key{{\bf open} line above}{O}
-\key{{\bf open} line at point}{C-o}
-
-\section{Buffers and Windows}
-
-\key{move cursor to {\bf next} window}{C-n}
-\key{delete current window}{X 0}
-\key{delete other windows}{X 1}
-\key{split current window into two windows}{X 2}
-\key{show current buffer in two windows}{X 3}
-\key{{\bf switch} to a buffer in the current window}{s {\sl buffer}}
-\key{{\bf switch} to a buffer in another window}{S {\sl buffer}}
-\key{{\bf kill} a buffer}{K}
-\key{list existing {\bf buffers}}{X B}
-
-\section{Files}
-
-\metax{{\bf visit} file in the current window}{v {\sl file} {\rm or} :e {\sl 
file}}
-\key{{\bf visit} file in another window}{V {\sl file}}
-\key{{\bf save} buffer to the associated file}{X S}
-\key{{\bf write} buffer to a specified file}{X W}
-\key{{\bf insert} a specified file at point}{X I}
-\key{{\bf get} information on the current {\bf file}}{g {\rm or} :f}
-\key{run the {\bf directory} editor}{X d}
-
-\section{Viewing the Buffer}
-
-\key{scroll to next screen}{SPC {\rm or} C-f}
-\key{scroll to previous screen}{RET {\rm or} C-b}
-\key{scroll {\bf down} half screen}{C-d}
-\key{scroll {\bf up} half screen}{C-u}
-\key{scroll down one line}{C-e}
-\key{scroll up one line}{C-y}
-
-\key{put current line on the {\bf home} line}{z H {\rm or} z RET}
-\key{put current line on the {\bf middle} line}{z M {\rm or} z .}
-\key{put current line on the {\bf last} line}{z L {\rm or} z -}
-
-\section{Marking and Returning}
-
-\key{{\bf mark} point in register {\it x}}{m {\it x}}
-\key{set mark at buffer beginning}{m <}
-\key{set mark at buffer end}{m >}
-\key{set mark at point}{m .}
-\key{jump to mark}{m ,}
-\key{exchange point and mark}{` `}
-\key{... and skip to first non-white on line}{' '}
-\key{go to mark {\it x}}{` {\it x}}
-\key{... and skip to first non-white on line}{' {\it x}}
-
-\section{Macros}
-
-\key{start remembering keyboard macro}{X (}
-\key{finish remembering keyboard macro}{X )}
-\key{call last keyboard macro}{*}
-\key{execute macro stored in register {\it x}}{@ {\it x}}
-
-\section{Motion Commands}
-
-\key{go backward one character}{h}
-\key{go forward one character}{l}
-\key{next line keeping the column}{j}
-\key{previous line keeping the column}{k}
-\key{next line at first non-white}{+}
-\key{previous line at first non-white}{-}
-
-\key{beginning of line}{0}
-\key{first non-white on line}{^}
-\key{end of line}{\$}
-\key{go to {\it n}-th column on line}{{\it n} |}
-
-\key{go to {\it n}-th line}{{\it n} G}
-\key{go to last line}{G}
-\key{find matching parenthesis for \kbd{()}, \kbd{\{\}} and \kbd{[]}}{\%}
-
-\key{go to {\bf home} window line}{H}
-\key{go to {\bf middle} window line}{M}
-\key{go to {\bf last} window line}{L}
-
-\subsection{Words, Sentences, Paragraphs}
-
-\key{forward {\bf word}}{w {\rm or} W}
-\key{{\bf backward} word}{b {\rm or} B}
-\key{{\bf end} of word}{e {\rm or} E}
-
-In the case of capital letter commands, a word is delimited by a
-non-white character.
-
-\key{forward sentence}{)}
-\key{backward sentence}{(}
-
-\key{forward paragraph}{\}}
-\key{backward paragraph}{\{}
-
-\subsection{Find Characters on the Line}
-
-\key{{\bf find} {\it c} forward on line}{f {\it c}}
-\key{{\bf find} {\it c} backward on line}{F {\it c}}
-\key{up {\bf to} {\it c} forward on line}{t {\it c}}
-\key{up {\bf to} {\it c} backward on line}{T {\it c}}
-\key{repeat previous \kbd{f}, \kbd{F}, \kbd{t} or \kbd{T}}{;}
-\key{... in the opposite direction}{,}
-
-\newcolumn
-\title{VIP Quick Reference Card}
-
-\section{Searching and Replacing}
-
-\key{search forward for {\sl pat}}{/ {\sl pat}}
-\key{search backward for {\sl pat}}{?\ {\sl pat}}
-\key{repeat previous search}{n}
-\key{... in the opposite direction}{N}
-
-\key{incremental {\bf search}}{C-s}
-\key{{\bf reverse} incremental search}{C-r}
-
-\key{{\bf replace}}{R}
-\key{{\bf query} replace}{Q}
-\key{{\bf replace} a character by another character {\it c}}{r {\it c}}
-
-\section{Modifying Commands}
-
-The delete (yank, change) commands explained below accept a motion command as
-their argument and delete (yank, change) the region determined by the motion
-command.  Motion commands are classified into {\it point commands} and
-{\it line commands}.  In the case of line commands, whole lines will
-be affected by the command.  Motion commands will be represented by
-{\it m} below.
-
-The point commands are as follows:
-
-\hskip 5ex
-\kbd{h l 0 ^ \$ w W b B e E ( ) / ?\ ` f F t T \% ; ,}
-
-The line commands are as follows:
-
-\hskip 5ex
-\kbd{j k + - H M L \{ \} G '}
-
-\subsection{Delete/Yank/Change Commands}
-
-\paralign to \hsize{#\tabskip=10pt plus 1 fil&#\tabskip=0pt&#\tabskip=0pt&#\cr
-\fourcol{}{{\bf delete}}{{\bf yank}}{{\bf change}}
-\fourcol{region determined by {\it m}}{d {\it m}}{y {\it m}}{c {\it m}}
-\fourcol{... into register {\it x}}{" {\it x\/} d {\it m}}{" {\it x\/} y {\it 
m}}{" {\it x\/} c {\it m}}
-\fourcol{a line}{d d}{Y {\rm or} y y}{c c}
-\fourcol{current {\bf region}}{d r}{y r}{c r}
-\fourcol{expanded {\bf region}}{d R}{y R}{c R}
-\fourcol{to end of line}{D}{y \$}{c \$}
-\fourcol{a character after point}{x}{y l}{c l}
-\fourcol{a character before point}{DEL}{y h}{c h}
-}
-
-\subsection{Put Back Commands}
-
-Deleted/yanked/changed text can be put back by the following commands.
-
-\key{{\bf Put} back at point/above line}{P}
-\key{... from register {\it x}}{" {\it x\/} P}
-\key{{\bf put} back after point/below line}{p}
-\key{... from register {\it x}}{" {\it x\/} p}
-
-\subsection{Repeating and Undoing Modifications}
-
-\key{{\bf undo} last change}{u {\rm or} :und}
-\key{repeat last change}{.\ {\rm (dot)}}
-
-Undo is undoable by \kbd{u} and repeatable by \kbd{.}.
-For example, \kbd{u...} will undo 4 previous changes.
-A \kbd{.} after \kbd{5dd} is equivalent to \kbd{5dd},
-while \kbd{3.} after \kbd{5dd} is equivalent to \kbd{3dd}.
-
-\section{Miscellaneous Commands}
-
-\endindentedkeys
-
-\paralign to \hsize{#\tabskip=5pt plus 1 
fil&#\tabskip=0pt&#\tabskip=0pt&#\tabskip=0pt&#\cr
-\fivecol{}{{\bf shift left}}{{\bf shift right}}{{\bf filter shell 
command}}{{\bf indent}}
-\fivecol{region}{< {\it m}}{> {\it m}}{!\ {\it m\/} {\sl shell-com}}{= {\it m}}
-\fivecol{line}{< <}{> >}{!\ !\ {\sl shell-com}}{= =}
-}
-
-\key{emulate \kbd{ESC}/\kbd{C-h} in emacs mode}{ESC{\rm /}C-h}
-\key{emulate \kbd{C-c}/\kbd{C-x} in emacs mode}{C{\rm /}X}
-
-\key{{\bf join} lines}{J}
-
-\key{lowercase region}{\# c {\it m}}
-\key{uppercase region}{\# C {\it m}}
-\key{execute last keyboard macro on each line in the region}{\# g {\it m}}
-
-\key{insert specified string for each line in the region}{\# q {\it m}}
-\key{check spelling of the words in the region}{\# s {\it m}}
-
-\section{Differences from Vi}
-
-\beginindentedkeys
-
-In VIP some keys behave rather differently from Vi.
-The table below lists such keys, and you can get the effect of typing
-these keys by typing the corresponding keys in the VIP column.
-
-\paralign to \hsize{#\tabskip=10pt plus 1 fil&#\tabskip=0pt&#\cr
-\threecol{}{{\bf Vi}}{{\bf VIP}}
-\threecol{forward character}{SPC}{l}
-\threecol{backward character}{C-h}{h}
-\threecol{next line at first non-white}{RET}{+}
-\threecol{delete previous character}{X}{DEL}
-\threecol{get information on file}{C-g}{g}
-\threecol{substitute characters}{s}{x i}
-\threecol{substitute line}{S}{c c}
-\threecol{change to end of line}{C {\rm or} R}{c \$}
-}
-
-(Strictly speaking, \kbd{C} and \kbd{R} behave slightly differently in Vi.)
-
-\section{Customization}
-
-By default, search is case sensitive.
-You can change this by including the following line in your \kbd{.vip} file.
-
-\hskip 5ex
-\kbd{(setq vip-case-fold-search t)}
-
-\beginindentedkeys
-
-\paralign to \hsize{#\tabskip=10pt plus 1 fil&#\tabskip=0pt&#\cr
-\twocol{{\bf variable}}{{\bf default value}}
-\twocol{vip-search-wrap-around}{t}
-\twocol{vip-case-fold-search}{nil}
-\twocol{vip-re-search}{nil}
-\twocol{vip-re-replace}{nil}
-\twocol{vip-re-query-replace}{nil}
-\twocol{vip-open-with-indent}{nil}
-\twocol{vip-help-in-insert-mode}{nil}
-\twocol{vip-shift-width}{8}
-\twocol{vip-tags-file-name}{"TAGS"}
-}
-
-%\subsection{Customizing Key Bindings}
-
-Include (some of) following lines in your \kbd{.vip} file
-to restore Vi key bindings.
-
-\beginexample
-(define-key vip-mode-map "\\C-g" 'vip-info-on-file)
-(define-key vip-mode-map "\\C-h" 'vip-backward-char)
-(define-key vip-mode-map "\\C-m" 'vip-next-line-at-bol)
-(define-key vip-mode-map " " 'vip-forward-char)
-(define-key vip-mode-map "g" 'vip-keyboard-quit)
-(define-key vip-mode-map "s" 'vip-substitute)
-(define-key vip-mode-map "C" 'vip-change-to-eol)
-(define-key vip-mode-map "R" 'vip-change-to-eol)
-(define-key vip-mode-map "S" 'vip-substitute-line)
-(define-key vip-mode-map "X" 'vip-delete-backward-char)
-\endexample
-
-\newcolumn
-
-\title{Ex Commands in VIP}
-
-In vi mode, an Ex command is entered by typing:
-
-\hskip 5ex
-\kbd{:\ {\sl ex-command} RET}
-
-\section{Ex Addresses}
-
-\paralign to \hsize{#\tabskip=5pt plus 1 fil&#\tabskip=2pt&#\tabskip=5pt plus 
1 fil&#\cr
-\twocolkey{current line}{.}{next line with {\sl pat}}{/ {\sl pat} /}
-\twocolkey{line {\it n}}{{\it n}}{previous line with {\sl pat}}{?\ {\sl pat} ?}
-\twocolkey{last line}{\$}{{\it n\/} line before {\it a}}{{\it a} - {\it n}}
-\twocolkey{next line}{+}{{\it a\/} through {\it b}}{{\it a\/} , {\it b}}
-\twocolkey{previous line}{-}{line marked with {\it x}}{' {\it x}}
-\twocolkey{entire buffer}{\%}{previous context}{' '}
-}
-
-Addresses can be specified in front of a command.
-For example,
-
-\hskip 5ex
-\kbd{:.,.+10m\$}
-
-moves 11 lines below current line to the end of buffer.
-
-\section{Ex Commands}
-
-\endindentedkeys
-
-\key{mark lines matching {\sl pat} and execute {\sl cmds} on these lines}{:g 
/{\sl pat}/ {\sl cmds}}
-
-\key{mark lines {\it not\/} matching {\sl pat} and execute {\sl cmds} on these 
lines}{:v /{\sl pat}/ {\sl cmds}}
-
-
-\key{{\bf move} specified lines after {\sl addr}}{:m {\sl addr}}
-\key{{\bf copy} specified lines after {\sl addr}}{:co\rm\ (or \kbd{:t})\ \sl 
addr}
-\key{{\bf delete} specified lines [into register {\it x\/}]}{:d {\rm [{\it 
x\/}]}}
-\key{{\bf yank} specified lines [into register {\it x\/}]}{:y {\rm [{\it 
x\/}]}}
-\key{{\bf put} back text [from register {\it x\/}]}{:pu {\rm [{\it x\/}]}}
-
-\key{{\bf substitute} {\sl repl} for first string on line matching {\sl 
pat}}{:s /{\sl pat}/{\sl repl}/}
-
-\key{repeat last substitution}{:\&}
-\key{repeat previous substitute with previous search pattern as {\sl 
pat}}{:\~{}}
-
-\key{{\bf read} in a file}{:r {\sl file}}
-\key{{\bf read} in the output of a shell command}{:r!\ {\sl command}}
-\key{write out specified lines into {\sl file}}{:w {\sl file}}
-\key{write out specified lines at the end of {\sl file}}{:w>> {\sl file}}
-\key{write out and then quit}{:wq {\sl file}}
-
-\key{define a macro {\it x} that expands to {\sl cmd}}{:map {\it x} {\sl cmd}}
-\key{remove macro expansion associated with {\it x}}{:unma {\it x}}
-
-\key{print line number}{:=}
-\key{print {\bf version} number of VIP}{:ve}
-
-\key{shift specified lines to the right}{:>}
-\key{shift specified lines to the left}{:<}
-
-\key{{\bf join} lines}{:j}
-\key{mark specified line to register {\it x}}{:k {\it x}}
-\key{{\bf set} a variable's value}{:se}
-\key{run a sub{\bf shell} in a window}{:sh}
-\key{execute shell command {\sl command}}{:!\ {\sl command}}
-\key{find first definition of {\bf tag} {\sl tag}}{:ta {\sl tag}}
-
-
-\copyrightnotice
-
-\bye
-
-% Local variables:
-% compile-command: "pdftex vipcard"
-% End:
diff --git a/lisp/info.el b/lisp/info.el
index e18772436e9..6e386207afe 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -223,7 +223,7 @@ These directories are searched after those in 
`Info-directory-list'."
       "org" "pcl-cvs" "pgg" "rcirc" "reftex" "remember" "sasl" "sc"
       "semantic" "ses" "sieve" "smtpmail" "speedbar" "srecode"
       "todo-mode" "tramp" "transient" "url" "use-package" "vhdl-mode"
-      "vip" "viper" "vtable" "widget" "wisent" "woman") .
+      "viper" "vtable" "widget" "wisent" "woman") .
      "https://www.gnu.org/software/emacs/manual/html_node/%m/%e";))
   "Alist telling `Info-mode' where manuals are accessible online.
 
@@ -4675,7 +4675,7 @@ Advanced commands:
 
 (defvar Info-file-list-for-emacs
   '("ediff" "eudc" "forms" "gnus" "info" ("Info" . "info") ("mh" . "mh-e")
-    "sc" "message" ("dired" . "dired-x") "viper" "vip" "idlwave"
+    "sc" "message" ("dired" . "dired-x") "viper" "idlwave"
     ("c" . "ccmode") ("c++" . "ccmode") ("objc" . "ccmode")
     ("java" . "ccmode") ("idl" . "ccmode") ("pike" . "ccmode")
     ("skeleton" . "autotype") ("auto-insert" . "autotype")
diff --git a/lisp/obsolete/cc-compat.el b/lisp/obsolete/cc-compat.el
deleted file mode 100644
index b3643f888e4..00000000000
--- a/lisp/obsolete/cc-compat.el
+++ /dev/null
@@ -1,165 +0,0 @@
-;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 1985, 1987, 1992-2024 Free Software Foundation, Inc.
-
-;; Authors:    1998- Martin Stjernholm
-;;            1994-1999 Barry A. Warsaw
-;; Maintainer: bug-cc-mode@gnu.org
-;; Created:    August 1994, split from cc-mode.el
-;; Keywords:   c languages
-;; Package:    cc-mode
-;; Obsolete-Since: 24.5
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Boring old c-mode.el (BOCM) is confusion and brain melt. cc-mode.el
-;; is clarity of thought and purity of chi. If you are still unwilling
-;; to accept enlightenment, this might help, or it may prolong your
-;; agony.
-;;
-;; To use, add the following to your c-mode-hook:
-;;
-;; (require 'cc-compat)
-;; (c-set-style "BOCM")
-;;
-;; This file is completely unsupported!  Although it has been patched
-;; superficially to keep pace with the rest of CC Mode, it hasn't been
-;; tested for a long time.
-
-;;; Code:
-
-(eval-when-compile
-  (let ((load-path
-        (if (and (boundp 'byte-compile-dest-file)
-                 (stringp byte-compile-dest-file))
-            (cons (file-name-directory byte-compile-dest-file) load-path)
-          load-path)))
-    (load "cc-bytecomp" nil t)))
-
-(cc-require 'cc-defs)
-(cc-require 'cc-vars)
-(cc-require 'cc-styles)
-(cc-require 'cc-engine)
-
-
-;; In case c-mode.el isn't loaded
-(defvar c-indent-level 2
-  "Indentation of C statements with respect to containing block.")
-;;;###autoload(put 'c-indent-level 'safe-local-variable 'integerp)
-
-(defvar c-brace-imaginary-offset 0
-  "Imagined indentation of a C open brace that actually follows a statement.")
-(defvar c-brace-offset 0
-  "Extra indentation for braces, compared with other text in same context.")
-(defvar c-argdecl-indent 5
-  "Indentation level of declarations of C function arguments.")
-(defvar c-label-offset -2
-  "Offset of C label lines and case statements relative to usual indentation.")
-(defvar c-continued-statement-offset 2
-  "Extra indent for lines not starting new statements.")
-(defvar c-continued-brace-offset 0
-  "Extra indent for substatements that start with open-braces.
-This is in addition to c-continued-statement-offset.")
-
-
-
-;; these offsets are taken by brute force testing c-mode.el, since
-;; there's no logic to what it does.
-(let* ((offsets        '((c-offsets-alist .
-                   ((defun-block-intro     . cc-block-intro-offset)
-                    (statement-block-intro . cc-block-intro-offset)
-                    (defun-open            . 0)
-                    (class-open            . 0)
-                    (inline-open           . c-brace-offset)
-                    (block-open            . c-brace-offset)
-                    (block-close           . cc-block-close-offset)
-                    (brace-list-open       . c-brace-offset)
-                    (substatement-open     . cc-substatement-open-offset)
-                    (substatement          . c-continued-statement-offset)
-                    (knr-argdecl-intro     . c-argdecl-indent)
-                    (case-label            . c-label-offset)
-                    (access-label          . c-label-offset)
-                    (label                 . c-label-offset)
-                    )))))
-  (c-add-style "BOCM" offsets))
-
-
-(defun cc-block-intro-offset (langelem)
-  ;; taken directly from calculate-c-indent confusion
-  (save-excursion
-    (c-backward-syntactic-ws)
-    (if (eq (char-before) ?{)
-       (forward-char -1)
-      (goto-char (cdr langelem)))
-    (let* ((curcol (save-excursion
-                    (goto-char (cdr langelem))
-                    (current-column)))
-         (bocm-lossage
-          ;; If no previous statement, indent it relative to line
-          ;; brace is on.  For open brace in column zero, don't let
-          ;; statement start there too.  If c-indent-level is zero,
-          ;; use c-brace-offset + c-continued-statement-offset
-          ;; instead.  For open-braces not the first thing in a line,
-          ;; add in c-brace-imaginary-offset.
-          (+ (if (and (bolp) (zerop c-indent-level))
-                 (+ c-brace-offset c-continued-statement-offset)
-               c-indent-level)
-             ;; Move back over whitespace before the openbrace.  If
-             ;; openbrace is not first nonwhite thing on the line,
-             ;; add the c-brace-imaginary-offset.
-             (progn (skip-chars-backward " \t")
-                    (if (bolp) 0 c-brace-imaginary-offset))
-             ;; If the openbrace is preceded by a parenthesized exp,
-             ;; move to the beginning of that; possibly a different
-             ;; line
-             (progn
-               (if (eq (char-before) ?\))
-                   (c-forward-sexp -1))
-               ;; Get initial indentation of the line we are on.
-               (current-indentation)))))
-      (- bocm-lossage curcol))))
-
-
-(defun cc-block-close-offset (langelem)
-  (save-excursion
-    (let* ((here (point))
-          bracep
-          (curcol (progn
-                    (goto-char (cdr langelem))
-                    (current-column)))
-          (bocm-lossage (progn
-                          (goto-char (cdr langelem))
-                          (if (eq (char-after) ?{)
-                              (setq bracep t)
-                            (goto-char here)
-                            (beginning-of-line)
-                            (backward-up-list 1)
-                            (forward-char 1)
-                            (c-forward-syntactic-ws))
-                          (current-column))))
-      (- bocm-lossage curcol
-        (if bracep 0 c-indent-level)))))
-
-
-(defun cc-substatement-open-offset (_langelem)
-  (+ c-continued-statement-offset c-continued-brace-offset))
-
-
-(cc-provide 'cc-compat)
-
-;;; cc-compat.el ends here
diff --git a/lisp/obsolete/info-edit.el b/lisp/obsolete/info-edit.el
deleted file mode 100644
index fb6de736590..00000000000
--- a/lisp/obsolete/info-edit.el
+++ /dev/null
@@ -1,89 +0,0 @@
-;;; info-edit.el --- Editing info files  -*- lexical-binding:t -*-
-
-;; Copyright (C) 1985-1986, 1992-2024 Free Software Foundation, Inc.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: help
-;; Obsolete-since: 24.4
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-(require 'info)
-
-(defvar Info-edit-mode-hook nil
-  "Hook run when `Info-edit-mode' is activated.")
-
-(make-obsolete-variable 'Info-edit-mode-hook
-                       "editing Info nodes by hand is not recommended." "24.4")
-
-(defvar Info-edit-mode-map (let ((map (make-sparse-keymap)))
-                             (set-keymap-parent map text-mode-map)
-                             (define-key map "\C-c\C-c" #'Info-cease-edit)
-                             map)
-  "Local keymap used within `e' command of Info.")
-
-(make-obsolete-variable 'Info-edit-mode-map
-                       "editing Info nodes by hand is not recommended."
-                       "24.4")
-
-;; Info-edit mode is suitable only for specially formatted data.
-(put 'Info-edit-mode 'mode-class 'special)
-
-(define-derived-mode Info-edit-mode text-mode "Info Edit"
-  "Major mode for editing the contents of an Info node.
-Like text mode with the addition of `Info-cease-edit'
-which returns to Info mode for browsing."
-  (setq buffer-read-only nil)
-  (force-mode-line-update)
-  (buffer-enable-undo (current-buffer)))
-
-(defun Info-edit ()
-  "Edit the contents of this Info node."
-  (interactive)
-  (Info-edit-mode)
-  (message "%s" (substitute-command-keys
-                "Editing: Type \\<Info-edit-mode-map>\\[Info-cease-edit] to 
return to info")))
-
-(put 'Info-edit 'disabled "Editing Info nodes by hand is not recommended.
-This feature will be removed in future.")
-
-(defun Info-cease-edit ()
-  "Finish editing Info node; switch back to Info proper."
-  (interactive)
-  ;; Do this first, so nothing has changed if user C-g's at query.
-  (and (buffer-modified-p)
-       (y-or-n-p "Save the file? ")
-       (save-buffer))
-  (Info-mode)
-  (force-mode-line-update)
-  (and (marker-position Info-tag-table-marker)
-       (buffer-modified-p)
-       (message "Tags may have changed.  Use Info-tagify if necessary")))
-
-(with-eval-after-load 'ibuffer
-  (defvar ibuffer-help-buffer-modes)
-  ;; Moved here from definition of ibuffer-help-buffer-modes to make
-  ;; that variable customizable even though this code is obsolete.  See
-  ;; also Bug#30990.
-  (add-to-list 'ibuffer-help-buffer-modes 'Info-edit-mode))
-
-(provide 'info-edit)
-
-;;; info-edit.el ends here
diff --git a/lisp/obsolete/meese.el b/lisp/obsolete/meese.el
deleted file mode 100644
index 7443bacc8b2..00000000000
--- a/lisp/obsolete/meese.el
+++ /dev/null
@@ -1,38 +0,0 @@
-;;; meese.el --- protect the impressionable young minds of America  -*- 
lexical-binding: t; -*-
-
-;; This is in the public domain on account of being distributed since
-;; 1985 or 1986 without a copyright notice.
-
-;; This file is part of GNU Emacs.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: games
-;; Obsolete-since: 24.4
-
-;;; Commentary:
-
-;; Adds a hook to protect the impressionable young minds of America
-;; from reading certain files in the Emacs distribution using Emacs.
-
-;; This file is named after Ed Meese, the US Attorney General
-;; under President Reagan, because of his support for censorship.
-
-;;; Code:
-
-(defun protect-innocence-hook ()
-  (let ((dir (file-name-directory buffer-file-name)))
-    (if (and (equal buffer-file-name (expand-file-name "sex.6" dir))
-            (file-exists-p buffer-file-name)
-            (not (y-or-n-p "Are you over 18? ")))
-       (progn
-         (clear-visited-file-modtime)
-         (setq buffer-file-name (expand-file-name "celibacy.1" dir))
-         (let ((inhibit-read-only t))  ; otherwise (erase-buffer) may bomb.
-           (erase-buffer)
-           (insert-file-contents buffer-file-name t))
-         (rename-buffer (file-name-nondirectory buffer-file-name))))))
-
-;;;(add-hook 'find-file-hook 'protect-innocence-hook)
-(provide 'meese)
-
-;;; meese.el ends here
diff --git a/lisp/obsolete/otodo-mode.el b/lisp/obsolete/otodo-mode.el
deleted file mode 100644
index deca885b44b..00000000000
--- a/lisp/obsolete/otodo-mode.el
+++ /dev/null
@@ -1,965 +0,0 @@
-;;; otodo-mode.el --- major mode for editing TODO list files  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 1997, 1999, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Oliver Seidel <privat@os10000.net>
-;; Maintainer: Stephen Berman <stephen.berman@gmx.net>
-;; Created: 2 Aug 1997
-;; Keywords: calendar, todo
-;; Obsolete-since: 24.4
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;; ---------------------------------------------------------------------------
-
-;;; Commentary:
-
-;;  Mode Description
-;;
-;;     TODO is a major mode for EMACS which offers functionality to
-;;     treat most lines in one buffer as a list of items one has to
-;;     do.  There are facilities to add new items, which are
-;;     categorized, to edit or even delete items from the buffer.
-;;     The buffer contents are currently compatible with the diary,
-;;     so that the list of todo-items will show up in the FANCY diary
-;;     mode.
-;;
-;;     Notice: Besides the major mode, this file also exports the
-;;     function `todo-show' which will change to the one specific
-;;     TODO file that has been specified in the todo-file-do
-;;     variable.  If this file does not conform to the TODO mode
-;;     conventions, the todo-show function will add the appropriate
-;;     header and footer.  I don't anticipate this to cause much
-;;     grief, but be warned, in case you attempt to read a plain text
-;;     file.
-;;
-;;  Preface, Quickstart Installation
-;;
-;;      To get this to work, make Emacs execute the line
-;;
-;;          (autoload 'todo-mode "todo-mode"
-;;                    "Major mode for editing TODO lists." t)
-;;          (autoload 'todo-show "todo-mode"
-;;                    "Show TODO items." t)
-;;          (autoload 'todo-insert-item "todo-mode"
-;;                    "Add TODO item." t)
-;;
-;;      You may now enter new items by typing "M-x todo-insert-item",
-;;      or enter your TODO list file by typing "M-x todo-show".
-;;
-;;      The TODO list file has a special format and some auxiliary
-;;      information, which will be added by the todo-show function if
-;;      it attempts to visit an un-initialized file.  Hence it is
-;;      recommended to use the todo-show function for the first time,
-;;      in order to initialize the file, but it is not necessary
-;;      afterwards.
-;;
-;;      As these commands are quite long to type, I would recommend
-;;      the addition of two bindings to your to your global keymap.  I
-;;      personally have the following in my initialization file:
-;;
-;;          (global-set-key "\C-ct" 'todo-show)  ; switch to TODO buffer
-;;         (global-set-key "\C-ci" 'todo-insert-item) ; insert new item
-;;
-;;      Note, however, that this recommendation has prompted some
-;;      criticism, since the keys C-c LETTER are reserved for user
-;;      functions.  I believe my recommendation is acceptable, since
-;;      the Emacs Lisp Manual *Tips* section also details that the
-;;      mode itself should not bind any functions to those keys.  The
-;;      express aim of the above two bindings is to work outside the
-;;      mode, which doesn't need the show function and offers a
-;;      different binding for the insert function.  They serve as
-;;      shortcuts and are not even needed (since the TODO mode will be
-;;      entered by visiting the TODO file, and later by switching to
-;;      its buffer).
-;;
-;;      If you are an advanced user of this package, please consult
-;;      the whole source code for autoloads, because there are several
-;;      extensions that are not explicitly listed in the above quick
-;;      installation.
-;;
-;;  Pre-Requisites
-;;
-;;      This package will require the following packages to be
-;;      available on the load-path:
-;;
-;;          time-stamp
-;;          easymenu
-;;
-;;  Operation
-;;
-;;     You will have the following facilities available:
-;;
-;;         M-x todo-show   will enter the todo list screen, here type
-;;
-;;         +  to go to next category
-;;          -  to go to previous category
-;;          d  to file the current entry, including a
-;;                                 comment and timestamp
-;;          e  to edit the current entry
-;;          E  to edit a multi-line entry
-;;          f  to file the current entry, including a
-;;                                 comment and timestamp
-;;          i  to insert a new entry, with prefix, omit category
-;;          I  to insert a new entry at current cursor position
-;;         j  jump to category
-;;          k  to kill the current entry
-;;          l  to lower the current entry's priority
-;;          n  for the next entry
-;;          p  for the previous entry
-;;         P  print
-;;          q  to save the list and exit the buffer
-;;          r  to raise the current entry's priority
-;;          s  to save the list
-;;          S  to save the list of top priorities
-;;         t  show top priority items for each category
-;;
-;;     When you add a new entry, you are asked for the text and then
-;;     for the category.  I for example have categories for things
-;;     that I want to do in the office (like mail my mum), that I
-;;     want to do in town (like buy cornflakes) and things I want to
-;;     do at home (move my suitcases).  The categories can be
-;;     selected with the cursor keys and if you type in the name of a
-;;     category which didn't exist before, an empty category of the
-;;     desired name will be added and filled with the new entry.
-;;
-;;  Configuration
-;;
-;;  Variable todo-prefix
-;;
-;;     I would like to recommend that you use the prefix "*/*" (by
-;;     leaving the variable 'todo-prefix' untouched) so that the
-;;     diary displays each entry every day.
-;;
-;;     To understand what I mean, please read the documentation that
-;;     goes with the calendar since that will tell you how you can
-;;     set up the fancy diary display and use the #include command to
-;;     include your todo list file as part of your diary.
-;;
-;;     If you have the diary package set up to usually display more
-;;     than one day's entries at once, consider using
-;;
-;;         "&%%(equal (calendar-current-date) date)"
-;;
-;;     as the value of `todo-prefix'.  Please note that this may slow
-;;     down the processing of your diary file some.
-;;
-;;      Carsten Dominik <dominik@strw.LeidenUniv.nl> suggested that
-;;
-;;          "&%%(todo-cp)"
-;;
-;;      might be nicer and to that effect a function has been declared
-;;      further down in the code.  You may wish to auto-load this.
-;;
-;;      Carsten also writes that *changing* the prefix after the
-;;      todo list is already established is not as simple as changing
-;;      the variable - the todo files have to be changed by hand.
-;;
-;;  Variable todo-file-do
-;;
-;;     This variable is fairly self-explanatory.  You have to store
-;;     your TODO list somewhere.  This variable tells the package
-;;     where to go and find this file.
-;;
-;;  Variable todo-file-done
-;;
-;;     Even when you're done, you may wish to retain the entries.
-;;     Given that they're timestamped and you are offered to add a
-;;     comment, this can make a useful diary of past events.  It will
-;;     even blend in with the EMACS diary package.  So anyway, this
-;;     variable holds the name of the file for the filed todo-items.
-;;
-;;  Variable todo-file-top
-;;
-;;      File storing the top priorities of your TODO list when
-;;      todo-save-top-priorities is non-nil.  Nice to include in your
-;;      diary instead of the complete TODO list.
-;;
-;;  Variable todo-mode-hook
-;;
-;;     Just like other modes, too, this mode offers to call your
-;;     functions before it goes about its business.  This variable
-;;     will be inspected for any functions you may wish to have
-;;     called once the other TODO mode preparations have been
-;;     completed.
-;;
-;;  Variable todo-insert-threshold
-;;
-;;             Another nifty feature is the insertion accuracy.  If you have
-;;             8 items in your TODO list, then you may get asked 4 questions
-;;             by the binary insertion algorithm.  However, you may not
-;;             really have a need for such accurate priorities amongst your
-;;             TODO items.  If you now think about the binary insertion
-;;             halving the size of the window each time, then the threshold
-;;             is the window size at which it will stop.  If you set the
-;;             threshold to zero, the upper and lower bound will coincide at
-;;             the end of the loop and you will insert your item just before
-;;             that point.  If you set the threshold to, e.g. 8, it will stop
-;;             as soon as the window size drops below that amount and will
-;;             insert the item in the approximate center of that window.  I
-;;             got the idea for this feature after reading a very helpful
-;;             e-mail reply from Trey Jackson <trey@cs.berkeley.edu> who
-;;             corrected some of my awful coding and pointed me towards some
-;;             good reading.  Thanks Trey!
-;;
-;;  Things to do
-;;
-;;      These originally were my ideas, but now also include all the
-;;      suggestions that I included before forgetting them:
-;;
-;;      o   Fancy fonts for todo/top-priority buffer
-;;      o   Remove todo-prefix option in todo-top-priorities
-;;      o   Rename category
-;;      o   Move entry from one category to another one
-;;      o   Entries which both have the generic */* prefix and a
-;;          "deadline" entry which are understood by diary, indicating
-;;          an event (unless marked by &)
-;;      o   The optional COUNT variable of todo-forward-item should be
-;;          applied to the other functions performing similar tasks
-;;      o   Modularization could be done for repeated elements of
-;;          the code, like the completing-read lines of code.
-;;     o   license / version function
-;;     o   export to diary file
-;;     o   todo-report-bug
-;;     o   GNATS support
-;;     o   elide multiline (as in bbdb, or, to a lesser degree, in
-;;          outline mode)
-;;     o   rewrite complete package to store data as Lisp objects
-;;          and have display modes for display, for diary export,
-;;          etc.  (Richard Stallman pointed out this is a bad idea)
-;;      o   so base todo-mode.el on generic-mode.el instead
-;;
-;;  History and Gossip
-;;
-;;     Many thanks to all the ones who have contributed to the
-;;     evolution of this package!  I hope I have listed all of you
-;;     somewhere in the documentation or at least in the RCS history!
-;;
-;;     Enjoy this package and express your gratitude by sending nice
-;;     things to my parents' address!
-;;
-;;     Oliver Seidel
-;;     (Lessingstr.  8, 65760 Eschborn, Federal Republic of Germany)
-
-;;; Code:
-
-(require 'time-stamp)
-
-
-;; User-configurable variables:
-
-(defgroup todo nil
-  "Maintain a list of todo items."
-  :link '(emacs-commentary-link "todo-mode")
-  :version "21.1"
-  :group 'calendar)
-
-(defcustom todo-prefix     "*/*"
-  "TODO mode prefix for entries.
-
-This is useful in conjunction with `calendar' and `diary' if you use
-
-#include \"~/.emacs.d/todo-do\"
-
-in your diary file to include your todo list file as part of your
-diary.  With the default value \"*/*\" the diary displays each entry
-every day and it may also be marked on every day of the calendar.
-Using \"&%%(equal (calendar-current-date) date)\" instead will only
-show and mark todo entries for today, but may slow down processing of
-the diary file somewhat."
-  :type 'string)
-(defcustom todo-file-do    (locate-user-emacs-file "todo-do" ".todo-do")
-  "TODO mode list file."
-  :version "24.4"                       ; added locate-user-emacs-file
-  :type 'file)
-(defcustom todo-file-done  (locate-user-emacs-file "todo-done" ".todo-done")
-  "TODO mode archive file."
-  :version "24.4"                       ; added locate-user-emacs-file
-  :type 'file)
-(defcustom todo-mode-hook  nil
-  "TODO mode hooks."
-  :type 'hook)
-(defcustom todo-edit-mode-hook nil
-  "TODO Edit mode hooks."
-  :type 'hook)
-(defcustom todo-insert-threshold 0
-  "TODO mode insertion accuracy.
-
-If you have 8 items in your TODO list, then you may get asked 4
-questions by the binary insertion algorithm.  However, you may not
-really have a need for such accurate priorities amongst your TODO
-items.  If you now think about the binary insertion halving the size
-of the window each time, then the threshold is the window size at
-which it will stop.  If you set the threshold to zero, the upper and
-lower bound will coincide at the end of the loop and you will insert
-your item just before that point.  If you set the threshold to,
-e.g. 8, it will stop as soon as the window size drops below that
-amount and will insert the item in the approximate center of that
-window."
-  :type 'integer)
-(defvar todo-edit-buffer " *TODO Edit*"
-  "TODO Edit buffer name.")
-(defcustom todo-file-top (locate-user-emacs-file "todo-top" ".todo-top")
-  "TODO mode top priorities file.
-
-Not in TODO format, but diary compatible.
-Automatically generated when `todo-save-top-priorities' is non-nil."
-  :version "24.4"                       ; added locate-user-emacs-file
-  :type 'string)
-
-(defcustom todo-print-function 'ps-print-buffer-with-faces
-  "Function to print the current buffer."
-  :type 'symbol)
-(defcustom todo-show-priorities 1
-  "Default number of priorities to show by \\[todo-top-priorities].
-0 means show all entries."
-  :type 'integer)
-(defcustom todo-print-priorities 0
-  "Default number of priorities to print by \\[todo-print].
-0 means print all entries."
-  :type 'integer)
-(defcustom todo-remove-separator t
-  "Non-nil to remove category separators in\
-\\[todo-top-priorities] and \\[todo-print]."
-  :type 'boolean)
-(defcustom todo-save-top-priorities-too t
-  "Non-nil makes `todo-save' automatically save top-priorities in 
`todo-file-top'."
-  :type 'boolean)
-
-;; Thanks for the ISO time stamp format go to Karl Eichwalder <ke@suse.de>
-;; My format string for the appt.el package is "%3b %2d, %y, %02I:%02M%p".
-;;
-(defcustom todo-time-string-format
-  "%:y-%02m-%02d %02H:%02M"
-  "TODO mode time string format for done entries.
-For details see the variable `time-stamp-format'."
-  :type 'string)
-
-(defcustom todo-entry-prefix-function 'todo-entry-timestamp-initials
-  "Function producing text to insert at start of todo entry."
-  :type 'symbol)
-(defcustom todo-initials (or (getenv "INITIALS") (user-login-name))
-  "Initials of todo item author."
-  :type 'string)
-
-(defun todo-entry-timestamp-initials ()
-  "Prepend timestamp and your initials to the head of a TODO entry."
-  (let ((time-stamp-format todo-time-string-format))
-    (concat (time-stamp-string) " " todo-initials ": ")))
-
-;; ---------------------------------------------------------------------------
-
-;; Set up some helpful context ...
-
-(defvar todo-categories nil
-  "TODO categories.")
-
-(defvar todo-cats nil
-  "Old variable for holding the TODO categories.
-Use `todo-categories' instead.")
-
-(defvar todo-previous-line 0
-  "Previous line asked about.")
-
-(defvar todo-previous-answer 0
-  "Previous answer got.")
-
-(defvar todo-mode-map
-  (let ((map (make-keymap)))
-    (suppress-keymap map t)
-    (define-key map "+" #'todo-forward-category)
-    (define-key map "-" #'todo-backward-category)
-    (define-key map "d" #'todo-file-item) ;done/delete
-    (define-key map "e" #'todo-edit-item)
-    (define-key map "E" #'todo-edit-multiline)
-    (define-key map "f" #'todo-file-item)
-    (define-key map "i" #'todo-insert-item)
-    (define-key map "I" #'todo-insert-item-here)
-    (define-key map "j" #'todo-jump-to-category)
-    (define-key map "k" #'todo-delete-item)
-    (define-key map "l" #'todo-lower-item)
-    (define-key map "n" #'todo-forward-item)
-    (define-key map "p" #'todo-backward-item)
-    (define-key map "P" #'todo-print)
-    (define-key map "q" #'todo-quit)
-    (define-key map "r" #'todo-raise-item)
-    (define-key map "s" #'todo-save)
-    (define-key map "S" #'todo-save-top-priorities)
-    (define-key map "t" #'todo-top-priorities)
-    map)
-  "TODO mode keymap.")
-
-(defvar todo-category-number 0 "TODO category number.")
-
-(defvar todo-tmp-buffer-name " *todo tmp*")
-
-(defvar todo-category-sep (make-string 75 ?-)
-  "Category separator.")
-
-(defvar todo-category-beg " --- "
-  "Category start separator to be prepended onto category name.")
-
-(defvar todo-category-end "--- End"
-  "Separator after a category.")
-
-(defvar todo-header "-*- mode: todo; "
-  "Header of todo files.")
-
-;; ---------------------------------------------------------------------------
-
-(defun todo-category-select ()
-  "Make TODO mode display the current category correctly."
-  (let ((name (nth todo-category-number todo-categories)))
-    (setq mode-line-buffer-identification
-;;          (concat "Category: " name))
-          (concat "Category: " (format "%18s" name)))
-    (widen)
-    (goto-char (point-min))
-    (search-forward-regexp
-     (concat "^"
-             (regexp-quote (concat todo-prefix todo-category-beg name))
-             "$"))
-    (let ((begin (1+ (line-end-position))))
-      (search-forward-regexp (concat "^" todo-category-end))
-      (narrow-to-region begin (line-beginning-position))
-      (goto-char (point-min)))))
-(defalias 'todo-cat-slct #'todo-category-select)
-
-(defun todo-forward-category ()
-  "Go forward to TODO list of next category."
-  (interactive)
-  (setq todo-category-number
-        (mod (1+ todo-category-number) (length todo-categories)))
-  (todo-category-select))
-(defalias 'todo-cmd-forw #'todo-forward-category)
-
-(defun todo-backward-category ()
-  "Go back to TODO list of previous category."
-  (interactive)
-  (setq todo-category-number
-        (mod (1- todo-category-number) (length todo-categories)))
-  (todo-category-select))
-(defalias 'todo-cmd-back #'todo-backward-category)
-
-(defun todo-backward-item ()
-  "Select previous entry of TODO list."
-  (interactive)
-  (search-backward-regexp (concat "^" (regexp-quote todo-prefix)) nil t)
-  (message ""))
-(defalias 'todo-cmd-prev #'todo-backward-item)
-
-(defun todo-forward-item (&optional count)
-  "Select COUNT-th next entry of TODO list."
-  (interactive "P")
-  (if (listp count) (setq count (car count)))
-  (end-of-line)
-  (search-forward-regexp (concat "^" (regexp-quote todo-prefix))
-                         nil 'goto-end count)
-  (beginning-of-line)
-  (message ""))
-(defalias 'todo-cmd-next #'todo-forward-item)
-
-(defun todo-save ()
-  "Save the TODO list."
-  (interactive)
-  (save-excursion
-    (save-restriction
-      (save-buffer)))
-  (if todo-save-top-priorities-too (todo-save-top-priorities)))
-(defalias 'todo-cmd-save #'todo-save)
-
-(defun todo-quit ()
-  "Done with TODO list for now."
-  (interactive)
-  (widen)
-  (todo-save)
-  (message "")
-  (bury-buffer))
-(defalias 'todo-cmd-done #'todo-quit)
-
-(defun todo-edit-item ()
-  "Edit current TODO list entry."
-  (interactive)
-  (if (< (point-min) (point-max))
-      (let ((item (todo-item-string)))
-       (if (todo-string-multiline-p item)
-           (todo-edit-multiline)
-         (let ((new (read-from-minibuffer "Edit: " item)))
-           (todo-remove-item)
-           (insert new "\n")
-           (todo-backward-item)
-           (message ""))))
-    (error "No TODO list entry to edit")))
-(defalias 'todo-cmd-edit #'todo-edit-item)
-
-(defun todo-edit-multiline ()
-  "Set up a buffer for editing a multiline TODO list entry."
-  (interactive)
-  (let ((buffer-name (generate-new-buffer-name todo-edit-buffer)))
-    (switch-to-buffer
-     (make-indirect-buffer
-      (file-name-nondirectory todo-file-do) buffer-name))
-    (message "To exit, simply kill this buffer and return to list.")
-    (todo-edit-mode)
-    (narrow-to-region (todo-item-start) (todo-item-end))))
-
-;;;###autoload
-(defun todo-add-category (&optional cat)
-  "Add new category CAT to the TODO list."
-  (interactive)
-  (let ((buf (find-file-noselect todo-file-do t))
-       (prompt "Category: "))
-    (unless (zerop (buffer-size buf))
-      (and (null todo-categories)
-          (null todo-cats)
-          (error "Error in %s: File is non-empty but contains no category"
-                 todo-file-do)))
-    (unless cat (setq cat (read-from-minibuffer prompt)))
-    (with-current-buffer buf
-      ;; reject names that could induce bugs and confusion
-      (while (and (cond ((string= "" cat)
-                        (setq prompt "Enter a non-empty category name: "))
-                       ((string-match "\\`\\s-+\\'" cat)
-                        (setq prompt "Enter a category name that is not only 
white space: "))
-                       ((member cat todo-categories)
-                        (setq prompt "Enter a non-existing category name: ")))
-                 (setq cat (read-from-minibuffer prompt))))
-      ;; initialize a newly created Todo buffer for Todo mode
-      (unless (file-exists-p todo-file-do) (todo-mode))
-      (setq todo-categories (cons cat todo-categories))
-      (widen)
-      (goto-char (point-min))
-      (if (search-forward "-*- mode: todo; " (+ (point-min) 16) t)
-         (kill-line)
-       (insert "-*- mode: todo; \n")
-       (forward-char -1))
-      (insert (format "todo-categories: %S; -*-" todo-categories))
-      (forward-char 1)
-      (insert (format "%s%s%s\n%s\n%s %s\n"
-                     todo-prefix todo-category-beg cat
-                     todo-category-end
-                     todo-prefix todo-category-sep))
-      (if (called-interactively-p 'interactive)
-         ;; properly display the newly added category
-         (progn (setq todo-category-number 0) (todo-show))
-       0))))
-
-;;;###autoload
-(defun todo-add-item-non-interactively (new-item category)
-  "Insert NEW-ITEM in TODO list as a new entry in CATEGORY."
-  (save-excursion
-    (todo-show))
-  (save-excursion
-    (if (string= "" category)
-        (setq category (nth todo-category-number todo-categories)))
-    (let ((cat-exists (member category todo-categories)))
-      (setq todo-category-number
-            (if cat-exists
-                (- (length todo-categories) (length cat-exists))
-              (todo-add-category category))))
-    (todo-show)
-    (setq todo-previous-line 0)
-    (let ((top 1)
-         (bottom (1+ (count-lines (point-min) (point-max)))))
-      (while (> (- bottom top) todo-insert-threshold)
-       (let* ((current (/ (+ top bottom) 2))
-              (answer (if (< current bottom)
-                          (todo-more-important-p current) nil)))
-         (if answer
-             (setq bottom current)
-           (setq top (1+ current)))))
-      (setq top (/ (+ top bottom) 2))
-      ;; goto-line doesn't have the desired behavior in a narrowed buffer.
-      (goto-char (point-min))
-      (forward-line (1- top)))
-    (insert new-item "\n")
-    (todo-backward-item)
-    (todo-save)
-    (message "")))
-
-;;;###autoload
-(defun todo-insert-item (arg)
-  "Insert new TODO list entry.
-With a prefix argument ARG solicit the category, otherwise use the current
-category."
-  (interactive "P")
-  (save-excursion
-    (if (not (derived-mode-p 'todo-mode)) (todo-show))
-    (let* ((new-item (concat todo-prefix " "
-                            (read-from-minibuffer
-                             "New TODO entry: "
-                             (if todo-entry-prefix-function
-                                 (funcall todo-entry-prefix-function)))))
-          (current-category (nth todo-category-number todo-categories))
-          (category (if arg (todo-completing-read) current-category)))
-      (todo-add-item-non-interactively new-item category))))
-
-(defalias 'todo-cmd-inst #'todo-insert-item)
-
-(defun todo-insert-item-here ()
-  "Insert a new TODO list entry directly above the entry at point.
-If point is on an empty line, insert the entry there."
-  (interactive)
-  (if (not (derived-mode-p 'todo-mode)) (todo-show))
-  (let ((new-item (concat todo-prefix " "
-                         (read-from-minibuffer
-                          "New TODO entry: "
-                          (if todo-entry-prefix-function
-                              (funcall todo-entry-prefix-function))))))
-    (unless (and (bolp) (eolp)) (todo-item-start))
-    (insert (concat new-item "\n"))
-    (backward-char)
-    ;; put point at start of new entry
-    (todo-item-start)))
-
-(defun todo-more-important-p (line)
-  "Ask whether entry is more important than the one at LINE."
-  (unless (equal todo-previous-line line)
-    (setq todo-previous-line line)
-    (goto-char (point-min))
-    (forward-line (1- todo-previous-line))
-    (let ((item (todo-item-string-start)))
-      (setq todo-previous-answer
-            (y-or-n-p (format-message "More important than `%s'? " item)))))
-  todo-previous-answer)
-(defalias 'todo-ask-p #'todo-more-important-p)
-
-(defun todo-delete-item ()
-  "Delete current TODO list entry."
-  (interactive)
-  (if (> (count-lines (point-min) (point-max)) 0)
-      (let* ((todo-entry (todo-item-string-start))
-             (todo-answer (y-or-n-p (concat "Permanently remove '"
-                                            todo-entry "'? "))))
-        (when todo-answer
-          (todo-remove-item)
-          (todo-backward-item))
-        (message ""))
-    (error "No TODO list entry to delete")))
-(defalias 'todo-cmd-kill #'todo-delete-item)
-
-(defun todo-raise-item ()
-  "Raise priority of current entry."
-  (interactive)
-  (if (> (count-lines (point-min) (point)) 0)
-      (let ((item (todo-item-string)))
-        (todo-remove-item)
-        (todo-backward-item)
-        (save-excursion
-          (insert item "\n"))
-        (message ""))
-    (error "No TODO list entry to raise")))
-(defalias 'todo-cmd-rais #'todo-raise-item)
-
-(defun todo-lower-item ()
-  "Lower priority of current entry."
-  (interactive)
-  (if (> (count-lines (point) (point-max)) 1)
-      ;; Assume there is a final newline
-      (let ((item (todo-item-string)))
-        (todo-remove-item)
-        (todo-forward-item)
-        (save-excursion
-          (insert item "\n"))
-        (message ""))
-    (error "No TODO list entry to lower")))
-(defalias 'todo-cmd-lowr #'todo-lower-item)
-
-(defun todo-file-item (&optional comment)
-  "File the current TODO list entry away, annotated with an optional COMMENT."
-  (interactive "sComment: ")
-  (or (> (count-lines (point-min) (point-max)) 0)
-      (error "No TODO list entry to file away"))
-  (let ((time-stamp-format todo-time-string-format))
-    (when (and comment (> (length comment) 0))
-      (goto-char (todo-item-end))
-      (insert
-       (if (save-excursion (beginning-of-line)
-                           (looking-at (regexp-quote todo-prefix)))
-           " "
-         "\n\t")
-       "(" comment ")"))
-    (goto-char (todo-item-end))
-    (insert " [" (nth todo-category-number todo-categories) "]")
-    (todo-item-start)
-    (let ((temp-point (point)))
-      (if (looking-at (regexp-quote todo-prefix))
-         (replace-match (time-stamp-string))
-       ;; Standard prefix -> timestamp
-       ;; Else prefix non-standard item start with timestamp
-       (insert (time-stamp-string)))
-      (append-to-file temp-point (todo-item-end 'include-sep) todo-file-done)
-      (delete-region temp-point (todo-item-end 'include-sep)))
-    (todo-backward-item)
-    (message "")))
-
-;; ---------------------------------------------------------------------------
-
-;; Utility functions:
-
-
-;;;###autoload
-(defun todo-top-priorities (&optional nof-priorities category-pr-page
-                                      interactive)
-  "List top priorities for each category.
-
-Number of entries for each category is given by NOF-PRIORITIES which
-defaults to `todo-show-priorities'.
-
-If CATEGORY-PR-PAGE is non-nil, a page separator `^L' is inserted
-between each category.
-INTERACTIVE should be non-nil if this function is called interactively."
-
-  (interactive "P\ni\nP")
-  (or nof-priorities (setq nof-priorities todo-show-priorities))
-  (if (listp nof-priorities)            ;universal argument
-      (setq nof-priorities (car nof-priorities)))
-  (let ((todo-print-buffer-name todo-tmp-buffer-name)
-        ;;(todo-print-category-number 0)
-        (todo-category-break (if category-pr-page "" ""))
-        (cat-end
-         (concat
-          (if todo-remove-separator
-              (concat todo-category-end "\n"
-                      (regexp-quote todo-prefix) " " todo-category-sep "\n")
-            (concat todo-category-end "\n"))))
-        beg end)
-    (save-excursion
-      (todo-show)
-      (save-restriction
-       (save-current-buffer
-         (widen)
-         (copy-to-buffer todo-print-buffer-name (point-min) (point-max))
-         (set-buffer todo-print-buffer-name)
-         (goto-char (point-min))
-         (when (re-search-forward (regexp-quote todo-header) nil t)
-           (beginning-of-line 1)
-           (delete-region (point) (line-end-position)))
-         (while (re-search-forward       ;Find category start
-                 (regexp-quote (concat todo-prefix todo-category-beg))
-                 nil t)
-           (setq beg (+ (line-end-position) 1)) ;Start of first entry.
-           (re-search-forward cat-end nil t)
-           (setq end (match-beginning 0))
-           (replace-match todo-category-break)
-           (narrow-to-region beg end)    ;In case we have too few entries.
-           (goto-char (point-min))
-           (if (zerop nof-priorities)      ;Traverse entries.
-               (goto-char end)            ;All entries
-             (todo-forward-item nof-priorities))
-           (setq beg (point))
-           (delete-region beg end)
-           (widen))
-         (and (looking-at "") (replace-match "")) ;Remove trailing form-feed.
-         (goto-char (point-min))         ;Due to display buffer
-         )))
-    (when interactive (display-buffer todo-print-buffer-name))
-    (message "Type C-x 1 to remove %s window.  M-C-v to scroll the help."
-             todo-print-buffer-name)))
-
-(defun todo-save-top-priorities (&optional nof-priorities)
-  "Save top priorities for each category in `todo-file-top'.
-
-Number of entries for each category is given by NOF-PRIORITIES which
-defaults to `todo-show-priorities'."
-  (interactive "P")
-  (save-window-excursion
-    (save-excursion
-      (save-restriction
-        (todo-top-priorities nof-priorities)
-        (set-buffer todo-tmp-buffer-name)
-        (write-file todo-file-top)
-        (kill-this-buffer)))))
-
-;;;###autoload
-(defun todo-print (&optional category-pr-page)
-  "Print todo summary using `todo-print-function'.
-If CATEGORY-PR-PAGE is non-nil, a page separator `^L' is inserted
-between each category.
-
-Number of entries for each category is given by `todo-print-priorities'."
-  (interactive "P")
-  (save-window-excursion
-    (save-excursion
-      (save-restriction
-       (todo-top-priorities todo-print-priorities
-                            category-pr-page)
-       (set-buffer todo-tmp-buffer-name)
-       (and (funcall todo-print-function)
-            (kill-this-buffer))
-       (message "Todo printing done.")))))
-
-(defun todo-jump-to-category ()
-  "Jump to a category.  Default is previous category."
-  (interactive)
-  (let ((category (todo-completing-read)))
-    (if (string= "" category)
-        (setq category (nth todo-category-number todo-categories)))
-    (setq todo-category-number
-          (if (member category todo-categories)
-              (- (length todo-categories)
-                 (length (member category todo-categories)))
-            (todo-add-category category)))
-    (todo-show)))
-
-(defun todo-line-string ()
-  "Return current line in buffer as a string."
-  (buffer-substring (line-beginning-position) (line-end-position)))
-
-(defun todo-item-string-start ()
-  "Return the start of this TODO list entry as a string."
-  ;; Suitable for putting in the minibuffer when asking the user
-  (let ((item (todo-item-string)))
-    (if (> (length item) 60)
-        (setq item (concat (substring item 0 56) "...")))
-    item))
-
-(defun todo-item-start ()
-  "Go to start of current TODO list item and return point."
-  (beginning-of-line)
-  (if (not (looking-at (regexp-quote todo-prefix)))
-      (search-backward-regexp
-       (concat "^" (regexp-quote todo-prefix)) nil t))
-  (point))
-
-(defun todo-item-end (&optional include-sep)
-  "Return point at end of current TODO list item.
-If INCLUDE-SEP is non-nil, return point after the separator."
-  (save-excursion
-    (end-of-line)
-    (if (search-forward-regexp
-         (concat "^" (regexp-quote todo-prefix)) nil 'goto-end)
-        (goto-char (match-beginning 0)))
-    (unless include-sep (skip-chars-backward "\n"))
-    (point)))
-
-(defun todo-remove-item ()
-  "Delete the current entry from the TODO list."
-  (delete-region (todo-item-start) (todo-item-end 'include-sep)))
-
-(defun todo-item-string ()
-  "Return current TODO list entry as a string."
-  (buffer-substring (todo-item-start) (todo-item-end)))
-
-(defun todo-string-count-lines (string)
-  "Return the number of lines STRING spans."
-  (length (split-string string "\n")))
-
-(defun todo-string-multiline-p (string)
-  "Return non-nil if STRING spans several lines."
-  (> (todo-string-count-lines string) 1))
-
-(defun todo-completing-read ()
-  "Return a category name, with completion, for use in Todo mode."
-  ;; make a copy of todo-categories in case history-delete-duplicates is
-  ;; non-nil, which makes completing-read alter todo-categories
-  (let* ((categories (copy-sequence todo-categories))
-        (history (cons 'todo-categories (1+ todo-category-number)))
-        (default (nth todo-category-number todo-categories))
-        (category (completing-read
-                   (concat "Category [" default "]: ")
-                   todo-categories nil nil nil history default)))
-    ;; restore the original value of todo-categories
-    (setq todo-categories categories)
-    category))
-
-;; ---------------------------------------------------------------------------
-
-(easy-menu-define todo-menu todo-mode-map "Todo Menu"
-                  '("Todo"
-                    ["Next category"        todo-forward-category t]
-                    ["Previous category"    todo-backward-category t]
-                    ["Jump to category"     todo-jump-to-category t]
-                    ["Show top priority items" todo-top-priorities t]
-                    ["Print categories"     todo-print t]
-                    "---"
-                    ["Edit item"            todo-edit-item t]
-                    ["File item"            todo-file-item t]
-                    ["Insert new item"      todo-insert-item t]
-                    ["Insert item here"     todo-insert-item-here t]
-                    ["Kill item"            todo-delete-item t]
-                    "---"
-                    ["Lower item priority"  todo-lower-item t]
-                    ["Raise item priority"  todo-raise-item t]
-                    "---"
-                    ["Next item"            todo-forward-item t]
-                    ["Previous item"        todo-backward-item t]
-                    "---"
-                    ["Save"                 todo-save t]
-                    ["Save Top Priorities"  todo-save-top-priorities t]
-                    "---"
-                    ["Quit"                 todo-quit t]
-                    ))
-
-;; As calendar reads todo-file-do before todo-mode is loaded.
-;;;###autoload
-(define-derived-mode todo-mode nil "TODO"
-  "Major mode for editing TODO lists."
-  nil)
-
-(with-suppressed-warnings ((lexical date entry))
-  (defvar date)
-  (defvar entry))
-
-;; t-c should be used from diary code, which requires calendar.
-(declare-function calendar-current-date "calendar" (&optional offset))
-
-;; Read about this function in the setup instructions above!
-;;;###autoload
-(defun todo-cp ()
-  "Make a diary entry appear only in the current date's diary."
-  (if (equal (calendar-current-date) date)
-      entry))
-
-(define-derived-mode todo-edit-mode text-mode "TODO Edit"
-  "Major mode for editing items in the TODO list.
-
-\\{todo-edit-mode-map}")
-
-;;;###autoload
-(defun todo-show ()
-  "Show TODO list."
-  (interactive)
-  ;; Call todo-initial-setup only if there is neither a Todo file nor
-  ;; a corresponding unsaved buffer.
-  (if (or (file-exists-p todo-file-do)
-         (let* ((buf (get-buffer (file-name-nondirectory todo-file-do)))
-                (bufname (buffer-file-name buf)))
-           (equal (expand-file-name todo-file-do) bufname)))
-      (find-file todo-file-do)
-    (todo-initial-setup))
-  (if (null todo-categories)
-      (if (null todo-cats)
-          (error "Error in %s: No categories in list `todo-categories'"
-                 todo-file-do)
-        (goto-char (point-min))
-        (and (search-forward "todo-cats:" nil t)
-             (replace-match "todo-categories:"))
-        (make-local-variable 'todo-categories)
-        (setq todo-categories todo-cats)))
-  (beginning-of-line)
-  (todo-category-select))
-
-(defun todo-initial-setup ()
-  "Set up things to work properly in TODO mode."
-  (find-file todo-file-do)
-  (erase-buffer)
-  (todo-mode)
-  (todo-add-category "Todo"))
-
-(provide 'todo-mode)
-
-;;; otodo-mode.el ends here
diff --git a/lisp/obsolete/rcompile.el b/lisp/obsolete/rcompile.el
deleted file mode 100644
index 258b2b519d9..00000000000
--- a/lisp/obsolete/rcompile.el
+++ /dev/null
@@ -1,180 +0,0 @@
-;;; rcompile.el --- run a compilation on a remote machine  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 1993-1994, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Alon Albert <alon@milcse.rtsg.mot.com>
-;; Maintainer: emacs-devel@gnu.org
-;; Created: 1993 Oct 6
-;; Keywords: tools, processes
-;; Obsolete-since: 24.4
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This package is for running a remote compilation and using emacs to parse
-;; the error messages. It works by rsh'ing the compilation to a remote host
-;; and parsing the output. If the file visited at the time remote-compile was
-;; called was loaded remotely (ange-ftp), the host and user name are obtained
-;; by the calling ange-ftp-ftp-name on the current directory. In this case the
-;; next-error command will also ange-ftp the files over. This is achieved
-;; automatically because the compilation-parse-errors function uses
-;; default-directory to build its file names. If however the file visited was
-;; loaded locally, remote-compile prompts for a host and user and assumes the
-;; files mounted locally (otherwise, how was the visited file loaded).
-
-;; See the user defined variables section for more info.
-
-;; I was contemplating redefining "compile" to "remote-compile" automatically
-;; if the file visited was ange-ftp'ed but decided against it for now. If you
-;; feel this is a good idea, let me know and I'll consider it again.
-
-;; Installation:
-
-;; To use rcompile, you also need to give yourself permission to connect to
-;; the remote host.  You do this by putting lines like:
-
-;; monopoly alon
-;; vme33
-;;
-;; in a file named .rhosts in the home directory (of the remote machine).
-;; Be careful what you put in this file. A line like:
-;;
-;; +
-;;
-;; Will allow anyone access to your account without a password. I suggest you
-;; read the rhosts(5) manual page before you edit this file (if you are not
-;; familiar with it already)
-
-;;; Code:
-
-(provide 'rcompile)
-(require 'compile)
-;;; The following should not be needed.
-;;; (eval-when-compile (require 'ange-ftp))
-
-;;;; user defined variables
-
-(defgroup remote-compile nil
-  "Run a compilation on a remote machine."
-  :group 'processes
-  :group 'tools)
-
-
-(defcustom remote-compile-host nil
-  "Host for remote compilations."
-  :type '(choice string (const nil)))
-
-(defcustom remote-compile-user nil
-  "User for remote compilations.
-nil means use the value returned by \\[user-login-name]."
-  :type '(choice string (const nil)))
-
-(defcustom remote-compile-run-before nil
-  "Command to run before compilation.
-This can be used for setting up environment variables,
-since rsh does not invoke the shell as a login shell and files like .login
-\(tcsh) and .bash_profile \(bash) are not run.
-nil means run no commands."
-  :type '(choice string (const nil)))
-
-(defcustom remote-compile-prompt-for-host nil
-  "Non-nil means prompt for host if not available from filename."
-  :type 'boolean)
-
-(defcustom remote-compile-prompt-for-user nil
-  "Non-nil means prompt for user if not available from filename."
-  :type 'boolean)
-
-;;;; internal variables
-
-;; History of remote compile hosts and users
-(defvar remote-compile-host-history nil)
-(defvar remote-compile-user-history nil)
-
-
-;;;; entry point
-
-;; We use the Tramp internal function `tramp-make-tramp-file-name'.
-;; It has changed its signature in Emacs 27.1, supporting still the
-;; old calling convention.  Let's assume rcompile.el has been removed
-;; once Tramp does not support it any longer.
-;; Better would be, if there are functions to provide user, host and
-;; localname of a remote filename, independent of Tramp's implementation.
-;; The function calls are wrapped by `funcall' in order to pacify the byte
-;; compiler.  ange-ftp check removed, because it is handled also by Tramp.
-;;;###autoload
-(defun remote-compile (host user command)
-  "Compile the current buffer's directory on HOST.  Log in as USER.
-See \\[compile]."
-  (interactive
-   (let (host user command prompt) ;; l l-host l-user
-     (setq prompt (if (stringp remote-compile-host)
-                      (format "Compile on host (default %s): "
-                              remote-compile-host)
-                    "Compile on host: ")
-           host (if (or remote-compile-prompt-for-host
-                        (null remote-compile-host))
-                    (read-from-minibuffer prompt
-                                          "" nil nil
-                                          'remote-compile-host-history)
-                  remote-compile-host)
-           user (if remote-compile-prompt-for-user
-                    (read-from-minibuffer (format
-                                           "Compile by user (default %s): "
-                                           (or remote-compile-user
-                                               (user-login-name)))
-                                          "" nil nil
-                                          'remote-compile-user-history)
-                  remote-compile-user))
-     (setq command (read-from-minibuffer "Compile command: "
-                                         compile-command nil nil
-                                         '(compile-history . 1)))
-     (list (if (string= host "") remote-compile-host host)
-           (if (string= user "") remote-compile-user user)
-           command)))
-  (setq compile-command command)
-  (cond (user
-         (setq remote-compile-user user))
-        ((null remote-compile-user)
-         (setq remote-compile-user (user-login-name))))
-  (let* (;; localname ;; Pacify byte-compiler.
-         (compile-command
-          (format "%s %s -l %s \"(%scd %s; %s)\""
-                 remote-shell-program
-                  host
-                  remote-compile-user
-                  (if remote-compile-run-before
-                      (concat remote-compile-run-before "; ")
-                    "")
-                  ""
-                  compile-command)))
-    (setq remote-compile-host host)
-    (save-some-buffers nil nil)
-    (compilation-start compile-command)
-    ;; Set comint-file-name-prefix in the compilation buffer so
-    ;; compilation-parse-errors will find referenced files by Tramp.
-    (with-current-buffer next-error-last-buffer
-      (when (fboundp 'tramp-make-tramp-file-name)
-        (setq-local comint-file-name-prefix
-                    (funcall
-                     #'tramp-make-tramp-file-name
-                     nil ;; method.
-                     remote-compile-user
-                     remote-compile-host
-                     ""))))))
-
-;;; rcompile.el ends here
diff --git a/lisp/obsolete/sup-mouse.el b/lisp/obsolete/sup-mouse.el
deleted file mode 100644
index e7bb58950a0..00000000000
--- a/lisp/obsolete/sup-mouse.el
+++ /dev/null
@@ -1,203 +0,0 @@
-;;; sup-mouse.el --- supdup mouse support for lisp machines  -*- 
lexical-binding: t; -*-
-
-;; Copyright (C) 1985-1986, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Wolfgang Rupprecht
-;; Maintainer: emacs-devel@gnu.org
-;; Created: 21 Nov 1986
-;; Keywords: hardware
-;; Obsolete-since: 24.4
-
-;;     (from code originally written by John Robinson@bbn for the bitgraph)
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;; Code:
-
-;;;  User customization option:
-
-(defcustom sup-mouse-fast-select-window nil
-  "Non-nil means mouse hits select new window, then execute.
-Otherwise just select."
-  :type 'boolean
-  :group 'mouse)
-
-(defconst mouse-left 0)
-(defconst mouse-center 1)
-(defconst mouse-right 2)
-
-(defconst mouse-2left 4)
-(defconst mouse-2center 5)
-(defconst mouse-2right 6)
-
-(defconst mouse-3left 8)
-(defconst mouse-3center 9)
-(defconst mouse-3right 10)
-
-;;;  Defuns:
-
-(defun sup-mouse-report ()
-  "This function is called directly by the mouse, it parses and
-executes the mouse commands.
-
- L move point          *  |---- These apply for mouse click in a window.
-2L delete word            |
-3L copy word             | If sup-mouse-fast-select-window is nil,
- C move point and yank *  | just selects that window.
-2C yank pop              |
- R set mark            *  |
-2R delete region         |
-3R copy region           |
-
-on mode line               on \"scroll bar\"   in minibuffer
- L scroll-up               line to top         execute-extended-command
- C proportional goto-char   line to middle     mouse-help
- R scroll-down             line to bottom      eval-expression"
-
-  (interactive)
-  (let*
-;; expect a string of <esc>:<buttons>;<x-pos>;<y-pos>c
-      ((buttons (sup-get-tty-num ?\;))
-       (x (sup-get-tty-num ?\;))
-       (y (sup-get-tty-num ?c))
-       (window (sup-pos-to-window x y))
-       (edges (window-edges window))
-       (old-window (selected-window))
-       (in-minibuf-p (eq y (1- (frame-height))))
-       (same-window-p (and (not in-minibuf-p) (eq window old-window)))
-       (in-mode-line-p (eq y (1- (nth 3 edges))))
-       (in-scrollbar-p (>= x (1- (nth 2 edges)))))
-    (setq x (- x (nth 0 edges)))
-    (setq y (- y (nth 1 edges)))
-
-;    (error "mouse-hit %d %d %d" buttons x y) ;;;; debug
-
-    (cond (in-mode-line-p
-          (select-window window)
-          (cond ((= buttons mouse-left)
-                 (scroll-up))
-                ((= buttons mouse-right)
-                 (scroll-down))
-                ((= buttons mouse-center)
-                 (goto-char (/ (* x
-                                  (- (point-max) (point-min)))
-                               (1- (window-width))))
-                 (beginning-of-line)
-                 (what-cursor-position)))
-          (select-window old-window))
-         (in-scrollbar-p
-          (select-window window)
-          (scroll-up
-           (cond ((= buttons mouse-left)
-                  y)
-                 ((= buttons mouse-right)
-                  (+ y (- 2 (window-height))))
-                 ((= buttons mouse-center)
-                  (/ (+ 2 y y (- (window-height))) 2))
-                 (t
-                  0)))
-          (select-window old-window))
-         (same-window-p
-          (cond ((= buttons mouse-left)
-                 (sup-move-point-to-x-y x y))
-                ((= buttons mouse-2left)
-                 (sup-move-point-to-x-y x y)
-                 (kill-word 1))
-                ((= buttons mouse-3left)
-                 (sup-move-point-to-x-y x y)
-                 (save-excursion
-                   (copy-region-as-kill
-                    (point) (progn (forward-word 1) (point))))
-                 (setq this-command 'yank)
-                 )
-                ((= buttons mouse-right)
-                 (push-mark)
-                 (sup-move-point-to-x-y x y)
-                 (exchange-point-and-mark))
-                ((= buttons mouse-2right)
-                 (push-mark)
-                 (sup-move-point-to-x-y x y)
-                 (kill-region (mark) (point)))
-                ((= buttons mouse-3right)
-                 (push-mark)
-                 (sup-move-point-to-x-y x y)
-                 (copy-region-as-kill (mark) (point))
-                 (setq this-command 'yank))
-                ((= buttons mouse-center)
-                 (sup-move-point-to-x-y x y)
-                 (setq this-command 'yank)
-                 (yank))
-                ((= buttons mouse-2center)
-                 (yank-pop 1))
-                )
-          )
-         (in-minibuf-p
-          (cond ((= buttons mouse-right)
-                 (call-interactively 'eval-expression))
-                ((= buttons mouse-left)
-                 (call-interactively 'execute-extended-command))
-                ((= buttons mouse-center)
-                 (describe-function 'sup-mouse-report)); silly self help
-                ))
-         (t                            ;in another window
-          (select-window window)
-          (cond ((not sup-mouse-fast-select-window))
-                ((= buttons mouse-left)
-                 (sup-move-point-to-x-y x y))
-                ((= buttons mouse-right)
-                 (push-mark)
-                 (sup-move-point-to-x-y x y)
-                 (exchange-point-and-mark))
-                ((= buttons mouse-center)
-                 (sup-move-point-to-x-y x y)
-                 (setq this-command 'yank)
-                 (yank))
-                ))
-         )))
-
-
-(defun sup-get-tty-num (term-char)
-  "Read from terminal until TERM-CHAR is read, and return intervening number.
-Upon non-numeric not matching TERM-CHAR signal an error."
-  (let
-      ((num 0)
-       (char (read-char)))
-    (while (and (>= char ?0)
-               (<= char ?9))
-      (setq num (+ (* num 10) (- char ?0)))
-      (setq char (read-char)))
-    (or (eq term-char char)
-       (error "Invalid data format in mouse command"))
-    num))
-
-(defun sup-move-point-to-x-y (x y)
-  "Position cursor in window coordinates.
-X and Y are 0-based character positions in the window."
-  (move-to-window-line y)
-  (move-to-column x)
-  )
-
-(defun sup-pos-to-window (x y)
-  "Find window corresponding to frame coordinates.
-X and Y are 0-based character positions on the frame."
-  (get-window-with-predicate (lambda (w)
-                              (coordinates-in-window-p (cons x y) w))))
-
-(provide 'sup-mouse)
-
-;;; sup-mouse.el ends here
diff --git a/lisp/obsolete/terminal.el b/lisp/obsolete/terminal.el
deleted file mode 100644
index 13667589c9e..00000000000
--- a/lisp/obsolete/terminal.el
+++ /dev/null
@@ -1,1333 +0,0 @@
-;;; terminal.el --- terminal emulator for GNU Emacs  -*- lexical-binding: t; 
-*-
-
-;; Copyright (C) 1986-1989, 1993-1994, 2001-2024 Free Software
-;; Foundation, Inc.
-
-;; Author: Richard Mlynarik <mly@eddie.mit.edu>
-;; Maintainer: emacs-devel@gnu.org
-;; Obsolete-since: 24.4
-;; Keywords: comm, terminals
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file has been censored by the Communications Decency Act.
-;; That law was passed under the guise of a ban on pornography, but
-;; it bans far more than that.  This file did not contain pornography,
-;; but it was censored nonetheless.
-
-;; For information on US government censorship of the Internet, and
-;; what you can do to bring back freedom of the press, see the web
-;; site https://www.eff.org/ [used to be vtw.org but that link is dead]
-
-;;; Code:
-
-;;>>TODO
-;;>> ** Nothing can be done about emacs' meta-lossage **
-;;>>  (without redoing keymaps `sanely' -- ask Mly for details)
-
-;;>> One probably wants to do setenv MORE -c when running with
-;;>>   more-processing enabled.
-
-(require 'ehelp)
-(require 'shell)
-
-(defgroup terminal nil
-  "Terminal emulator for Emacs."
-  :group 'terminals)
-
-
-(defcustom terminal-escape-char ?\C-^
-  "All characters except for this are passed verbatim through the
-terminal-emulator.  This character acts as a prefix for commands
-to the emulator program itself.  Type this character twice to send
-it through the emulator.  Type ? after typing it for a list of
-possible commands.
-This variable is local to each terminal-emulator buffer."
-  :type 'character)
-
-(defcustom terminal-scrolling t ;;>> Setting this to t sort-of defeats my 
whole aim in writing this package...
-  "If non-nil, the terminal-emulator will losingly `scroll' when output occurs
-past the bottom of the screen.  If nil, output will win and `wrap' to the top
-of the screen.
-This variable is local to each terminal-emulator buffer."
-  :type 'boolean)
-
-(defcustom terminal-more-processing t
-  "If non-nil, do more-processing.
-This variable is local to each terminal-emulator buffer."
-  :type 'boolean)
-
-;; If you are the sort of loser who uses scrolling without more breaks
-;; and expects to actually see anything, you should probably set this to
-;; around 400
-(defcustom terminal-redisplay-interval 5000
-  "Maximum number of characters which will be processed by the
-terminal-emulator before a screen redisplay is forced.
-Set this to a large value for greater throughput,
-set it smaller for more frequent updates but overall slower
-performance."
-  :type 'integer)
-
-(defvar terminal-more-break-insertion
-  "*** More break -- Press space to continue ***")
-
-(defvar terminal-meta-map nil)
-(if terminal-meta-map
-    nil
-  (let ((map (make-sparse-keymap)))
-    (define-key map [t] #'te-pass-through)
-    (setq terminal-meta-map map)))
-
-(defvar terminal-map nil)
-(if terminal-map
-    nil
-  (let ((map (make-sparse-keymap)))
-    ;; Prevent defining [menu-bar] as te-pass-through
-    ;; so we allow the global menu bar to be visible.
-    (define-key map [menu-bar] (make-sparse-keymap))
-    (define-key map [t] #'te-pass-through)
-    (define-key map [switch-frame] #'handle-switch-frame)
-    (define-key map "\e" terminal-meta-map)
-    ;;(define-key map "\C-l"
-    ;;  (lambda () (interactive) (te-pass-through) (redraw-display)))
-    (setq terminal-map map)))
-
-(defvar terminal-escape-map nil)
-(if terminal-escape-map
-    nil
-  (let ((map (make-sparse-keymap)))
-    (define-key map [t] #'undefined)
-    (dotimes (i 10)
-      (let ((s (make-string 1 (+ ?0 i))))
-       (define-key map s #'digit-argument)))
-    (define-key map "b" #'switch-to-buffer)
-    (define-key map "o" #'other-window)
-    (define-key map "e" #'te-set-escape-char)
-    (define-key map "\C-l" #'redraw-display)
-    (define-key map "\C-o" #'te-flush-pending-output)
-    (define-key map "m" #'te-toggle-more-processing)
-    (define-key map "x" #'te-escape-extended-command)
-    ;;>> What use is this?  Why is it in the default terminal-emulator map?
-    (define-key map "w" #'te-edit)
-    (define-key map "?" #'te-escape-help)
-    (define-key map (char-to-string help-char) #'te-escape-help)
-    (setq terminal-escape-map map)))
-
-(defvar te-escape-command-alist nil)
-(if te-escape-command-alist
-    nil
-  (setq te-escape-command-alist
-       '(("Set Escape Character" . te-set-escape-char)
-          ;;>> What use is this?  Why is it in the default terminal-emulator 
map?
-         ("Edit" . te-edit)
-         ("Refresh" . redraw-display)
-         ("Record Output" . te-set-output-log)
-         ("Photo" . te-set-output-log)
-         ("Tofu" . te-tofu) ;; confuse the uninitiated
-         ("Stuff Input" . te-stuff-string)
-         ("Flush Pending Output" . te-flush-pending-output)
-         ("Enable More Processing" . te-enable-more-processing)
-         ("Disable More Processing" . te-disable-more-processing)
-         ("Scroll at end of page" . te-do-scrolling)
-         ("Wrap at end of page" . te-do-wrapping)
-         ("Switch To Buffer" . switch-to-buffer)
-         ("Other Window" . other-window)
-         ("Kill Buffer" . kill-buffer)
-         ("Help" . te-escape-help)
-         ("Set Redisplay Interval" . te-set-redisplay-interval)
-         )))
-
-(defvar terminal-more-break-map nil)
-(if terminal-more-break-map
-    nil
-  (let ((map (make-sparse-keymap)))
-    (define-key map [t] #'te-more-break-unread)
-    (define-key map (char-to-string help-char) #'te-more-break-help)
-    (define-key map " " #'te-more-break-resume)
-    (define-key map "\C-l" #'redraw-display)
-    (define-key map "\C-o" #'te-more-break-flush-pending-output)
-    ;;>>> this isn't right
-    ;(define-key map "\^?" #'te-more-break-flush-pending-output) ;DEL
-    (define-key map "\r" #'te-more-break-advance-one-line)
-
-    (setq terminal-more-break-map map)))
-
-
-;;; Pacify the byte compiler
-(defvar te-process nil)
-(defvar te-log-buffer nil)
-(defvar te-height nil)
-(defvar te-width nil)
-(defvar te-more-count nil)
-(defvar te-redisplay-count nil)
-(defvar te-pending-output nil)
-(defvar te-saved-point)
-(defvar te-more-old-point nil)
-(defvar te-more-old-local-map nil)
-(defvar te-more-old-filter nil)
-(defvar te-more-old-mode-line-format nil)
-(defvar te-pending-output-info nil)
-
-;; Required to support terminfo systems
-(defconst te-terminal-name-prefix "emacs-em"
-  "Prefix used for terminal type names for Terminfo.")
-(defconst te-terminfo-directory
-  (file-name-as-directory
-   (expand-file-name "emacs-terminfo" temporary-file-directory))
-  "Directory used for run-time terminal definition files for Terminfo.")
-(defvar te-terminal-name nil)
-
-;;;;  escape map
-
-(defun te-escape ()
-  (interactive)
-  (let (s
-        (local (current-local-map))
-        (global (current-global-map)))
-    (unwind-protect
-        (progn
-          (use-global-map terminal-escape-map)
-          (use-local-map terminal-escape-map)
-          (setq s (read-key-sequence
-                    (if current-prefix-arg
-                        (format "Emacs Terminal escape[%s for help]> %d "
-                               (substitute-command-keys
-                                "\\<terminal-escape-map>\\[te-escape-help]")
-                                (prefix-numeric-value current-prefix-arg))
-                        (format "Emacs Terminal escape[%s for help]> "
-                               (substitute-command-keys
-                                
"\\<terminal-escape-map>\\[te-escape-help]"))))))
-      (use-global-map global)
-      (use-local-map local))
-
-    (message "")
-
-    (cond
-     ;;  Certain keys give vector notation, like [escape] when
-     ;;  you hit esc key...
-     ((and (stringp s)
-          (string= s (make-string 1 terminal-escape-char)))
-      (setq last-command-event terminal-escape-char)
-      (let ((terminal-escape-char -259))
-       (te-pass-through)))
-
-     ((setq s (lookup-key terminal-escape-map s))
-      (call-interactively s)))
-
-    ))
-
-
-(defun te-escape-help ()
-  "Provide help on commands available after terminal-escape-char is typed."
-  (interactive)
-  (message "Terminal emulator escape help...")
-  (let ((char (single-key-description terminal-escape-char)))
-    (with-electric-help
-      (function (lambda ()
-        (princ (format "Terminal-emulator escape, invoked by \"%s\"
-Type \"%s\" twice to send a single \"%s\" through.
-
-Other chars following \"%s\" are interpreted as follows:\n"
-                       char char char char))
-
-        (princ (substitute-command-keys "\\{terminal-escape-map}\n"))
-        (princ (format "\nSubcommands of \"%s\" (%s)\n"
-                       (where-is-internal 'te-escape-extended-command
-                                          terminal-escape-map t)
-                       'te-escape-extended-command))
-        (let ((l (sort (copy-sequence te-escape-command-alist)
-                       (function (lambda (a b)
-                                   (string< (car a) (car b)))))))
-          (while l
-            (let ((doc (or (documentation (cdr (car l)))
-                           "Not documented")))
-              (if (string-match "\n" doc)
-                  ;; just use first line of documentation
-                  (setq doc (substring doc 0 (match-beginning 0))))
-              (princ "  \"")
-              (princ (car (car l)))
-              (princ "\":\n     ")
-              (princ doc)
-              (write-char ?\n))
-            (setq l (cdr l))))
-        nil)))))
-
-
-
-(defun te-escape-extended-command ()
-  (interactive)
-  (let ((c (let ((completion-ignore-case t))
-            (completing-read "terminal command: "
-                             te-escape-command-alist
-                             nil t))))
-    (if c
-       (catch 'foo
-         (setq c (downcase c))
-         (let ((l te-escape-command-alist))
-           (while l
-             (if (string= c (downcase (car (car l))))
-                 (throw 'foo (call-interactively (cdr (car l))))
-               (setq l (cdr l)))))))))
-
-;; not used.
-(defun te-escape-extended-command-unread ()
-  (interactive)
-  (setq unread-command-events
-        (nconc (listify-key-sequence (this-command-keys))
-               unread-command-events))
-  (te-escape-extended-command))
-
-(defun te-set-escape-char (c)
-  "Change the terminal-emulator escape character."
-  (interactive "cSet escape character to: ")
-  (let ((o terminal-escape-char))
-    (message (if (= o c)
-                "\"%s\" is the escape char"
-                "\"%s\" is now the escape; \"%s\" passes through")
-            (single-key-description c)
-            (single-key-description o))
-    (setq terminal-escape-char c)))
-
-
-(defun te-stuff-string (string)
-  "Read a string to send to through the terminal emulator
-as though that string had been typed on the keyboard.
-
-Very poor man's file transfer protocol."
-  (interactive "sStuff string: ")
-  (process-send-string te-process string))
-
-(defun te-set-output-log (name)
-  "Record output from the terminal emulator in a buffer."
-  (interactive (list (if te-log-buffer
-                        nil
-                      (read-buffer "Record output in buffer: "
-                                   (format "%s output-log"
-                                           (buffer-name (current-buffer)))
-                                   nil))))
-  (if (or (null name) (equal name ""))
-      (progn (setq te-log-buffer nil)
-            (message "Output logging off."))
-    (if (get-buffer name)
-       nil
-      (with-current-buffer (get-buffer-create name)
-       (fundamental-mode)
-       (buffer-disable-undo (current-buffer))
-       (erase-buffer)))
-    (setq te-log-buffer (get-buffer name))
-    (message "Recording terminal emulator output into buffer \"%s\""
-            (buffer-name te-log-buffer))))
-
-(defun te-tofu ()
-  "Discontinue output log."
-  (interactive)
-  (te-set-output-log nil))
-
-
-(defun te-toggle (sym arg)
-  (set sym (cond ((not (numberp arg)) arg)
-                ((= arg 1) (not (symbol-value sym)))
-                ((< arg 0) nil)
-                (t t))))
-
-(defun te-toggle-more-processing (arg)
-  (interactive "p")
-  (message (if (te-toggle 'terminal-more-processing arg)
-              "More processing on" "More processing off"))
-  (if terminal-more-processing (setq te-more-count -1)))
-
-(defun te-toggle-scrolling (arg)
-  (interactive "p")
-  (message (if (te-toggle 'terminal-scrolling arg)
-              "Scroll at end of page" "Wrap at end of page")))
-
-(defun te-enable-more-processing ()
-  "Enable ** MORE ** processing"
-  (interactive)
-  (te-toggle-more-processing t))
-
-(defun te-disable-more-processing ()
-  "Disable ** MORE ** processing"
-  (interactive)
-  (te-toggle-more-processing nil))
-
-(defun te-do-scrolling ()
-  "Scroll at end of page (yuck)"
-  (interactive)
-  (te-toggle-scrolling t))
-
-(defun te-do-wrapping ()
-  "Wrap to top of window at end of page"
-  (interactive)
-  (te-toggle-scrolling nil))
-
-
-(defun te-set-redisplay-interval (arg)
-  "Set the maximum interval (in output characters) between screen updates.
-Set this number to large value for greater throughput,
-set it smaller for more frequent updates (but overall slower performance."
-  (interactive "NMax number of output chars between redisplay updates: ")
-  (setq arg (max arg 1))
-  (setq terminal-redisplay-interval arg
-       te-redisplay-count 0))
-
-;;;; more map
-
-;; every command -must- call te-more-break-unwind
-;; or grave lossage will result
-
-(put 'te-more-break-unread 'suppress-keymap t)
-(defun te-more-break-unread ()
-  (interactive)
-  (if (eq last-input-event terminal-escape-char)
-      (call-interactively 'te-escape)
-    (message "Continuing from more break (\"%s\" typed, %d chars output 
pending...)"
-            (single-key-description last-input-event)
-            (te-pending-output-length))
-    (setq te-more-count 259259)
-    (te-more-break-unwind)
-    (let ((terminal-more-processing nil))
-      (te-pass-through))))
-
-(defun te-more-break-resume ()
-  "Proceed past the **MORE** break,
-allowing the next page of output to appear"
-  (interactive)
-  (message "Continuing from more break")
-  (te-more-break-unwind))
-
-(defun te-more-break-help ()
-  "Provide help on commands available in a terminal-emulator **MORE** break"
-  (interactive)
-  (message "Terminal-emulator more break help...")
-  (sit-for 0)
-  (with-electric-help
-    (function (lambda ()
-      (princ "Terminal-emulator more break.\n\n")
-      (princ (format "Type \"%s\" (te-more-break-resume)\n%s\n"
-                    (where-is-internal 'te-more-break-resume
-                                       terminal-more-break-map t)
-                    (documentation 'te-more-break-resume)))
-      (princ (substitute-command-keys "\\{terminal-more-break-map}\n"))
-      (princ "Any other key is passed through to the program
-running under the terminal emulator and disables more processing until
-all pending output has been dealt with.")
-      nil))))
-
-
-(defun te-more-break-advance-one-line ()
-  "Allow one more line of text to be output before doing another more break."
-  (interactive)
-  (setq te-more-count 1)
-  (te-more-break-unwind))
-
-(defun te-more-break-flush-pending-output ()
-  "Discard any output which has been received by the terminal emulator but
-not yet processed and then proceed from the more break."
-  (interactive)
-  (te-more-break-unwind)
-  (te-flush-pending-output))
-
-(defun te-flush-pending-output ()
-  "Discard any as-yet-unprocessed output which has been received by
-the terminal emulator."
-  (interactive)
-  ;; this could conceivably be confusing in the presence of
-  ;; escape-sequences spanning process-output chunks
-  (if (null (cdr te-pending-output))
-      (message "(There is no output pending)")
-    (let ((length (te-pending-output-length)))
-      (message "Flushing %d chars of pending output" length)
-      (setq te-pending-output
-           (list 0 (format "\n*** %d chars of pending output flushed ***\n"
-                           length)))
-      (te-update-pending-output-display)
-      (te-process-output nil)
-      (sit-for 0))))
-
-
-(defun te-pass-through ()
-  "Character is passed to the program running under the terminal emulator.
-One characters is treated specially:
-the terminal escape character (normally C-^)
-lets you type a terminal emulator command."
-  (interactive)
-  (cond ((eq last-input-event terminal-escape-char)
-        (call-interactively 'te-escape))
-       (t
-        ;; Convert `return' to C-m, etc.
-        (if (and (symbolp last-input-event)
-                 (get last-input-event 'ascii-character))
-            (setq last-input-event (get last-input-event 'ascii-character)))
-        ;; Convert meta characters to 8-bit form for transmission.
-        (if (and (integerp last-input-event)
-                 (not (zerop (logand last-input-event ?\M-\^@))))
-            (setq last-input-event (+ 128 (logand last-input-event 127))))
-        ;; Now ignore all but actual characters.
-        ;; (It ought to be possible to send through function
-        ;; keys as character sequences if we add a description
-        ;; to our termcap entry of what they should look like.)
-        (if (integerp last-input-event)
-            (progn
-              (and terminal-more-processing (null (cdr te-pending-output))
-                   (te-set-more-count nil))
-              (process-send-string te-process (make-string 1 last-input-event))
-              (te-process-output t))
-          (message "Function key `%s' ignored"
-                   (single-key-description last-input-event))))))
-
-
-(defun te-set-window-start ()
-  (let* ((w (get-buffer-window (current-buffer)))
-        (h (if w (window-height w))))
-    (cond ((not w)) ; buffer not displayed
-         ((>= h (/ (- (point) (point-min)) (1+ te-width)))
-          ;; this is the normal case
-          (set-window-start w (point-min)))
-         ;; this happens if some vandal shrinks our window.
-         ((>= h (/ (- (point-max) (point)) (1+ te-width)))
-          (set-window-start w (- (point-max) (* h (1+ te-width)) -1)))
-         ;; I give up.
-         (t nil))))
-
-(defun te-pending-output-length ()
-  (let ((length (car te-pending-output))
-       (tem (cdr te-pending-output)))
-    (while tem
-      (setq length (+ length (length (car tem))) tem (cdr tem)))
-    length))
-
-;;>> What use is this terminal-edit stuff anyway?
-;;>>  If nothing else, it was written by somebody who didn't
-;;>>  competently understand the terminal-emulator...
-
-(defvar terminal-edit-map nil)
-(if terminal-edit-map
-    nil
-  (setq terminal-edit-map (make-sparse-keymap))
-  (define-key terminal-edit-map "\C-c\C-c" #'terminal-cease-edit))
-
-;; Terminal Edit mode is suitable only for specially formatted data.
-(put 'terminal-edit-mode 'mode-class 'special)
-
-(defun terminal-edit-mode ()
-  "Major mode for editing the contents of a terminal-emulator buffer.
-The editing commands are the same as in Fundamental mode,
-together with a command \\<terminal-edit-map>to return to terminal emulation: 
\\[terminal-cease-edit]."
-  (use-local-map terminal-edit-map)
-  (setq major-mode 'terminal-edit-mode)
-  (setq mode-name "Terminal Edit")
-  (setq mode-line-modified (default-value 'mode-line-modified))
-  (setq mode-line-process nil)
-  (run-mode-hooks 'terminal-edit-mode-hook))
-
-(defun te-edit ()
-  "Start editing the terminal emulator buffer with ordinary Emacs commands."
-  (interactive)
-  (terminal-edit-mode)
-  (force-mode-line-update)
-  ;; Make mode line update.
-  (if (eq (key-binding "\C-c\C-c") 'terminal-cease-edit)
-      (message "Editing: Type C-c C-c to return to Terminal")
-    (message "%s"
-            (substitute-command-keys
-              "Editing: Type \\[terminal-cease-edit] to return to Terminal"))))
-
-(defun terminal-cease-edit ()
-  "Finish editing message; switch back to Terminal proper."
-  (interactive)
-
-  ;;>> emulator will blow out if buffer isn't exactly te-width x te-height
-  (let ((buffer-read-only nil))
-    (widen)
-    (let ((opoint (point-marker))
-          (width te-width)
-          (h (1- te-height)))
-      (goto-char (point-min))
-      (while (>= h 0)
-        (let ((p (point)))
-          (cond ((search-forward "\n" (+ p width) 'move)
-                 (forward-char -1)
-                 (insert-char ?\s (- width (- (point) p)))
-                 (forward-char 1))
-                ((eobp)
-                 (insert-char ?\s (- width (- (point) p))))
-                ((= (following-char) ?\n)
-                 (forward-char 1))
-                (t
-                 (setq p (point))
-                 (if (search-forward "\n" nil t)
-                     (delete-region p (1- (point)))
-                     (delete-region p (point-max))))))
-        (if (= h 0)
-            (if (not (eobp)) (delete-region (point) (point-max)))
-            (if (eobp) (insert ?\n)))
-        (setq h (1- h)))
-      (goto-char opoint)
-      (set-marker opoint nil nil)
-      (setq te-saved-point (point))
-      (setq te-redisplay-count 0)
-      (setq te-more-count -1)))
-
-  (setq mode-line-modified (default-value 'mode-line-modified))
-  (use-local-map terminal-map)
-  (setq major-mode 'terminal-mode)
-  (setq mode-name "terminal")
-  (setq mode-line-process '(":%s")))
-
-;;;; more break hair
-
-(defun te-more-break ()
-  (te-set-more-count t)
-  (make-local-variable 'te-more-old-point)
-  (setq te-more-old-point (point))
-  (make-local-variable 'te-more-old-local-map)
-  (setq te-more-old-local-map (current-local-map))
-  (use-local-map terminal-more-break-map)
-  (make-local-variable 'te-more-old-filter)
-  (setq te-more-old-filter (process-filter te-process))
-  (make-local-variable 'te-more-old-mode-line-format)
-  (setq te-more-old-mode-line-format mode-line-format
-       mode-line-format (list "--   **MORE**  "
-                              mode-line-buffer-identification
-                              "%-"))
-  (set-process-filter te-process
-    (function (lambda (process string)
-               (with-current-buffer (process-buffer process)
-                 (setq te-pending-output (nconc te-pending-output
-                                                (list string))))
-                 (te-update-pending-output-display))))
-  (te-update-pending-output-display)
-  (if (eq (window-buffer (selected-window)) (current-buffer))
-      (message "More break "))
-  (or (eobp)
-      (null terminal-more-break-insertion)
-      (save-excursion
-       (forward-char 1)
-       (delete-region (point) (+ (point) te-width))
-       (insert terminal-more-break-insertion)))
-  (run-hooks 'terminal-more-break-hook)
-  (sit-for 0) ;get display to update
-  (throw 'te-process-output t))
-
-(defun te-more-break-unwind ()
-  (use-local-map te-more-old-local-map)
-  (set-process-filter te-process te-more-old-filter)
-  (goto-char te-more-old-point)
-  (setq mode-line-format te-more-old-mode-line-format)
-  (force-mode-line-update)
-  (let ((buffer-read-only nil))
-    (cond ((eobp))
-         (terminal-more-break-insertion
-          (forward-char 1)
-          (delete-region (point)
-                         (+ (point) (length terminal-more-break-insertion)))
-          (insert-char ?\s te-width)
-          (goto-char te-more-old-point)))
-    (setq te-more-old-point nil)
-    (let ((te-more-count 259259))
-      (te-newline)))
-  ;(sit-for 0)
-  (te-process-output t))
-
-(defun te-set-more-count (newline)
-  (let ((line (/ (- (point) (point-min)) (1+ te-width))))
-    (if newline (setq line (1+ line)))
-    (cond ((= line te-height)
-          (setq te-more-count te-height))
-         ;>>>> something is strange.  Investigate this!
-         ((= line (1- te-height))
-          (setq te-more-count te-height))
-         ((or (< line (/ te-height 2))
-              (> (- te-height line) 10))
-          ;; break at end of this page
-          (setq te-more-count (- te-height line)))
-         (t
-          ;; migrate back towards top (ie bottom) of screen.
-          (setq te-more-count (- te-height
-                                 (if (> te-height 10) 2 1)))))))
-
-
-;;;; More or less straight-forward terminal escapes
-
-;; ^j, meaning `newline' to non-display programs.
-;; (Who would think of ever writing a system which doesn't understand
-;;  display terminals natively?  Un*x:  The Operating System of the Future.)
-(defun te-newline ()
-  "Move down a line, optionally do more processing, perhaps wrap/scroll,
-move to start of new line, clear to end of line."
-  (end-of-line)
-  (cond ((not terminal-more-processing))
-       ((< (setq te-more-count (1- te-more-count)) 0)
-        (te-set-more-count t))
-       ((eq te-more-count 0)
-        ;; this doesn't return
-        (te-more-break)))
-  (if (eobp)
-      (progn
-       (delete-region (point-min) (+ (point-min) te-width))
-       (goto-char (point-min))
-       (if terminal-scrolling
-           (progn (delete-char 1)
-                  (goto-char (point-max))
-                  (insert ?\n))))
-    (forward-char 1)
-    (delete-region (point) (+ (point) te-width)))
-  (insert-char ?\s te-width)
-  (beginning-of-line)
-  (te-set-window-start))
-
-; ^p = x+32 y+32
-(defun te-move-to-position ()
-  ;; must offset by #o40 since cretinous unix won't send a 004 char through
-  (let ((y (- (te-get-char) 32))
-       (x (- (te-get-char) 32)))
-    (if (or (> x te-width)
-           (> y te-height))
-       ()
-      (goto-char (+ (point-min) x (* y (1+ te-width))))
-      ;(te-set-window-start?)
-      ))
-  (setq te-more-count -1))
-
-
-
-;; ^p c
-(defun te-clear-rest-of-line ()
-  (save-excursion
-    (let ((n (- (point) (progn (end-of-line) (point)))))
-      (delete-region (point) (+ (point) n))
-      (insert-char ?\s (- n)))))
-
-
-;; ^p C
-(defun te-clear-rest-of-screen ()
-  (save-excursion
-    (te-clear-rest-of-line)
-    (while (progn (end-of-line) (not (eobp)))
-      (forward-char 1) (end-of-line)
-      (delete-region (- (point) te-width) (point))
-      (insert-char ?\s te-width))))
-
-
-;; ^p ^l
-(defun te-clear-screen ()
-  ;; regenerate buffer to compensate for (nonexistent!!) bugs.
-  (erase-buffer)
-  (let ((i 0))
-    (while (< i te-height)
-      (setq i (1+ i))
-      (insert-char ?\s te-width)
-      (insert ?\n)))
-  (delete-region (1- (point-max)) (point-max))
-  (goto-char (point-min))
-  (setq te-more-count -1))
-
-
-;; ^p ^o count+32
-(defun te-insert-lines ()
-  (if (not (bolp))
-      ();(error "fooI")
-    (save-excursion
-      (let* ((line (- te-height (/ (- (point) (point-min)) (1+ te-width)) -1))
-            (n (min (- (te-get-char) ?\s) line))
-            (i 0))
-       (delete-region (- (point-max) (* n (1+ te-width))) (point-max))
-       (if (eq (point) (point-max)) (insert ?\n))
-       (while (< i n)
-         (setq i (1+ i))
-         (insert-char ?\s te-width)
-         (or (eq i line) (insert ?\n))))))
-  (setq te-more-count -1))
-
-
-;; ^p ^k count+32
-(defun te-delete-lines ()
-  (if (not (bolp))
-      ();(error "fooD")
-    (let* ((line (- te-height (/ (- (point) (point-min)) (1+ te-width)) -1))
-          (n (min (- (te-get-char) ?\s) line))
-          (i 0))
-      (delete-region (point)
-                    (min (+ (point) (* n (1+ te-width))) (point-max)))
-      (save-excursion
-       (goto-char (point-max))
-       (while (< i n)
-         (setq i (1+ i))
-         (insert-char ?\s te-width)
-         (or (eq i line) (insert ?\n))))))
-  (setq te-more-count -1))
-
-;; ^p ^a
-(defun te-beginning-of-line ()
-  (beginning-of-line))
-
-;; ^p ^b
-(defun te-backward-char ()
-  (if (not (bolp))
-      (backward-char 1)))
-
-;; ^p ^f
-(defun te-forward-char ()
-  (if (not (eolp))
-      (forward-char 1)))
-
-
-;; 0177
-(defun te-delete ()
-  (if (bolp)
-      ()
-    (delete-region (1- (point)) (point))
-    (insert ?\s)
-    (forward-char -1)))
-
-;; ^p ^g
-(defun te-beep ()
-  (beep))
-
-
-;; ^p _ count+32
-(defun te-insert-spaces ()
-  (let* ((p (point))
-        (n (min (- (te-get-char) 32)
-                (- (progn (end-of-line) (point)) p))))
-    (if (<= n 0)
-       nil
-      (delete-char (- n))
-      (goto-char p)
-      (insert-char ?\s n))
-    (goto-char p)))
-
-;; ^p d count+32  (should be ^p ^d but cretinous un*x won't send ^d chars!!!)
-(defun te-delete-char ()
-  (let* ((p (point))
-        (n (min (- (te-get-char) 32)
-                (- (progn (end-of-line) (point)) p))))
-    (if (<= n 0)
-       nil
-      (insert-char ?\s n)
-      (goto-char p)
-      (delete-char n))
-    (goto-char p)))
-
-
-
-;; disgusting unix-required excrement
-;;  Are we living twenty years in the past yet?
-
-(defun te-losing-unix ()
-  nil)
-
-;; ^i
-(defun te-output-tab ()
-  (let* ((p (point))
-        (x (- p (progn (beginning-of-line) (point))))
-        (l (min (- 8 (logand x 7))
-                (progn (end-of-line) (- (point) p)))))
-    (goto-char (+ p l))))
-
-;; ^p ^j
-;; Handle the `do' or `nl' termcap capability.
-;;>> I am not sure why this broken, obsolete, capability is here.
-;;>> Perhaps it is for VIle.  No comment was made about why it
-;;>> was added (in "Sun Dec  6 01:22:27 1987  Richard Stallman")
-(defun te-down-vertically-or-scroll ()
-  "Move down a line vertically, or scroll at bottom."
-  (let ((column (current-column)))
-    (end-of-line)
-    (if (eobp)
-       (progn
-         (delete-region (point-min) (+ (point-min) te-width))
-         (goto-char (point-min))
-         (delete-char 1)
-         (goto-char (point-max))
-         (insert ?\n)
-         (insert-char ?\s te-width)
-         (beginning-of-line))
-      (forward-line 1))
-    (move-to-column column))
-  (te-set-window-start))
-
-;; Also:
-;;  ^m => beginning-of-line (for which it -should- be using ^p ^a, right?!!)
-;;  ^g => te-beep (for which it should use ^p ^g)
-;;  ^h => te-backward-char (for which it should use ^p ^b)
-
-
-
-(defun te-filter (process string)
-  (with-current-buffer (process-buffer process)
-    (goto-char te-saved-point)
-    (and (bufferp te-log-buffer)
-         (if (null (buffer-name te-log-buffer))
-             ;; killed
-             (setq te-log-buffer nil)
-           (set-buffer te-log-buffer)
-           (goto-char (point-max))
-           (insert-before-markers string)
-           (set-buffer (process-buffer process))))
-    (setq te-pending-output (nconc te-pending-output (list string)))
-    (te-update-pending-output-display)
-    (te-process-output (eq (current-buffer)
-                           (window-buffer (selected-window))))
-    (set-buffer (process-buffer process))
-    (setq te-saved-point (point))))
-
-;; (A version of the following comment which might be distractingly offensive
-;; to some readers has been moved to term-nasty.el.)
-;; unix lacks ITS-style tty control...
-(defun te-process-output (preemptible)
-  ;;>> There seems no good reason to ever disallow preemption
-  (setq preemptible t)
-  (catch 'te-process-output
-    (let ((buffer-read-only nil)
-         (string nil) ostring start char (matchpos nil))
-      (while (cdr te-pending-output)
-       (setq ostring string
-             start (car te-pending-output)
-             string (car (cdr te-pending-output))
-             char (aref string start))
-       (if (eq (setq start (1+ start)) (length string))
-           (progn (setq te-pending-output
-                          (cons 0 (cdr (cdr te-pending-output)))
-                        start 0
-                        string (car (cdr te-pending-output)))
-                  (te-update-pending-output-display))
-           (setcar te-pending-output start))
-       (if (and (> char ?\037) (< char ?\377))
-           (cond ((eolp)
-                  ;; unread char
-                  (if (eq start 0)
-                      (setq te-pending-output
-                            (cons 0 (cons (make-string 1 char)
-                                          (cdr te-pending-output))))
-                      (setcar te-pending-output (1- start)))
-                  (te-newline))
-                 ((null string)
-                  (delete-char 1) (insert char)
-                  (te-redisplay-if-necessary 1))
-                 (t
-                  (let ((end (or (and (eq ostring string) matchpos)
-                                 (setq matchpos (string-match
-                                                  "[\000-\037\177-\377]"
-                                                  string start))
-                                 (length string))))
-                    (delete-char 1) (insert char)
-                    (setq char (point)) (end-of-line)
-                    (setq end (min end (+ start (- (point) char))))
-                    (goto-char char)
-                    (if (eq end matchpos) (setq matchpos nil))
-                    (delete-region (point) (+ (point) (- end start)))
-                    (insert (if (and (eq start 0)
-                                     (eq end (length string)))
-                                string
-                                (substring string start end)))
-                    (if (eq end (length string))
-                        (setq te-pending-output
-                              (cons 0 (cdr (cdr te-pending-output))))
-                        (setcar te-pending-output end))
-                    (te-redisplay-if-necessary (1+ (- end start))))))
-         ;; I suppose if I split the guts of this out into a separate
-         ;;  function we could trivially emulate different terminals
-         ;; Who cares in any case?  (Apart from stupid losers using rlogin)
-         (funcall
-           (if (eq char ?\^p)
-               (or (cdr (assq (te-get-char)
-                              '((?= . te-move-to-position)
-                                (?c . te-clear-rest-of-line)
-                                (?C . te-clear-rest-of-screen)
-                                (?\C-o . te-insert-lines)
-                                (?\C-k . te-delete-lines)
-                                ;; not necessary, but help sometimes.
-                                (?\C-a . te-beginning-of-line)
-                                (?\C-b . te-backward-char)
-                                ;; should be C-d, but un*x
-                                ;;  pty's won't send \004 through!
-                                 ;; Can you believe this?
-                                (?d . te-delete-char)
-                                (?_ . te-insert-spaces)
-                                ;; random
-                                (?\C-f . te-forward-char)
-                                (?\C-g . te-beep)
-                                (?\C-j . te-down-vertically-or-scroll)
-                                (?\C-l . te-clear-screen)
-                                )))
-                   'te-losing-unix)
-               (or (cdr (assq char
-                              '((?\C-j . te-newline)
-                                (?\177 . te-delete)
-                                ;; Did I ask to be sent these characters?
-                                ;; I don't remember doing so, either.
-                                ;; (Perhaps some operating system or
-                                ;; other is completely incompetent...)
-                                (?\C-m . te-beginning-of-line)
-                                (?\C-g . te-beep)
-                                (?\C-h . te-backward-char)
-                                (?\C-i . te-output-tab))))
-                   'te-losing-unix)))
-         (te-redisplay-if-necessary 1))
-       (and preemptible
-            (input-pending-p)
-            ;; preemptible output!  Oh my!!
-            (throw 'te-process-output t)))))
-  ;; We must update window-point in every window displaying our buffer
-  (walk-windows (lambda (w)
-                 (when (and (not (eq w (selected-window)))
-                            (eq (window-buffer w) (current-buffer)))
-                   (set-window-point w (point))))))
-
-(defun te-get-char ()
-  (if (cdr te-pending-output)
-      (let ((start (car te-pending-output))
-           (string (car (cdr te-pending-output))))
-       (prog1 (aref string start)
-         (if (eq (setq start (1+ start)) (length string))
-             (setq te-pending-output (cons 0 (cdr (cdr te-pending-output))))
-             (setcar te-pending-output start))))
-    (catch 'char
-      (let ((filter (process-filter te-process)))
-       (unwind-protect
-           (progn
-             (set-process-filter te-process
-                                 (function (lambda (_p s)
-                                    (or (eq (length s) 1)
-                                        (setq te-pending-output (list 1 s)))
-                                    (throw 'char (aref s 0)))))
-             (accept-process-output te-process))
-         (set-process-filter te-process filter))))))
-
-
-(defun te-redisplay-if-necessary (length)
-  (and (<= (setq te-redisplay-count (- te-redisplay-count length)) 0)
-       (eq (current-buffer) (window-buffer (selected-window)))
-       (waiting-for-user-input-p)
-       (progn (te-update-pending-output-display)
-             (sit-for 0)
-             (setq te-redisplay-count terminal-redisplay-interval))))
-
-(defun te-update-pending-output-display ()
-  (if (null (cdr te-pending-output))
-      (setq te-pending-output-info "")
-    (let ((length (te-pending-output-length)))
-      (if (< length 1500)
-         (setq te-pending-output-info "")
-       (setq te-pending-output-info (format "(%dK chars output pending) "
-                                            (/ (+ length 512) 1024))))))
-  (force-mode-line-update))
-
-
-(defun te-sentinel (process message)
-  (cond ((eq (process-status process) 'run))
-       ((null (buffer-name (process-buffer process)))) ;deleted
-       (t (let ((b (current-buffer)))
-            (with-current-buffer (process-buffer process)
-              (setq buffer-read-only nil)
-              (fundamental-mode)
-              (goto-char (point-max))
-              (delete-blank-lines)
-              (delete-horizontal-space)
-              (insert "\n*******\n" message "*******\n"))
-            (if (and (eq b (process-buffer process))
-                     (waiting-for-user-input-p))
-                (progn (goto-char (point-max))
-                       (recenter -1)))))))
-
-(defvar te-stty-string "stty -nl erase '^?' kill '^u' intr '^c' echo pass8"
-  "Shell command to set terminal modes for terminal emulator.")
-;; This used to have `new' in it, but that loses outside BSD
-;; and it's apparently not needed in BSD.
-
-;;;###autoload
-(defun terminal-emulator (buffer program args &optional width height)
-  "Under a display-terminal emulator in BUFFER, run PROGRAM on arguments ARGS.
-ARGS is a list of argument-strings.  Remaining arguments are WIDTH and HEIGHT.
-BUFFER's contents are made an image of the display generated by that program,
-and any input typed when BUFFER is the current Emacs buffer is sent to that
-program as keyboard input.
-
-Interactively, BUFFER defaults to \"*terminal*\" and PROGRAM and ARGS
-are parsed from an input-string using your usual shell.
-WIDTH and HEIGHT are determined from the size of the current window
--- WIDTH will be one less than the window's width, HEIGHT will be its height.
-
-To switch buffers and leave the emulator, or to give commands
-to the emulator itself (as opposed to the program running under it),
-type Control-^.  The following character is an emulator command.
-Type Control-^ twice to send it to the subprogram.
-This escape character may be changed using the variable `terminal-escape-char'.
-
-`Meta' characters may not currently be sent through the terminal emulator.
-
-Here is a list of some of the variables which control the behavior
-of the emulator -- see their documentation for more information:
-terminal-escape-char, terminal-scrolling, terminal-more-processing,
-terminal-redisplay-interval.
-
-This function calls the value of terminal-mode-hook if that exists
-and is non-nil after the terminal buffer has been set up and the
-subprocess started."
-  (interactive
-   (cons (with-current-buffer (get-buffer-create "*terminal*")
-           (buffer-name (if (or (not (boundp 'te-process))
-                                (null te-process)
-                                (not (eq (process-status te-process)
-                                         'run)))
-                            (current-buffer)
-                          (generate-new-buffer "*terminal*"))))
-         (append
-          (let* ((default-s
-                   ;; Default shell is same thing M-x shell uses.
-                   (or explicit-shell-file-name
-                       (getenv "ESHELL")
-                       (getenv "SHELL")
-                       (if (eq system-type 'android)
-                           "/system/bin/sh"
-                         "/bin/sh")))
-                 (s (read-string
-                     (format "Run program in emulator (default %s): "
-                             default-s))))
-            (if (equal s "")
-                (list default-s '())
-              (te-parse-program-and-args s))))))
-  (switch-to-buffer buffer)
-  (if (null width) (setq width (- (window-width (selected-window)) 1)))
-  (if (null height) (setq height (- (window-height (selected-window)) 1)))
-  (terminal-mode)
-  (setq te-width width te-height height)
-  (setq te-terminal-name (concat te-terminal-name-prefix
-                                (number-to-string te-width)
-                                (number-to-string te-height)))
-  (setq mode-line-buffer-identification
-       (list (format "Emacs terminal %dx%d: %%b  " te-width te-height)
-             'te-pending-output-info))
-  (let ((buffer-read-only nil))
-    (te-clear-screen))
-  (let (process)
-    (while (setq process (get-buffer-process (current-buffer)))
-      (if (y-or-n-p (format "Kill process %s? " (process-name process)))
-         (delete-process process)
-       (error "Process %s not killed" (process-name process)))))
-  (condition-case err
-      (let ((process-environment
-            (cons (concat "TERM=" te-terminal-name)
-                  (cons (concat "TERMCAP=" (te-create-termcap))
-                        (cons (concat "TERMINFO=" (te-create-terminfo))
-                              process-environment)))))
-       (setq te-process
-             (start-process "terminal-emulator" (current-buffer)
-                            "/bin/sh" "-c"
-                            ;; Yuck!!! Start a shell to set some terminal
-                            ;; control characteristics.  Then start the
-                            ;; "env" program to setup the terminal type
-                            ;; Then finally start the program we wanted.
-                            (format "%s; exec %s"
-                                    te-stty-string
-                                    (mapconcat #'te-quote-arg-for-sh
-                                               (cons program args) " "))))
-       (set-process-filter te-process #'te-filter)
-       (set-process-sentinel te-process #'te-sentinel))
-    (error (fundamental-mode)
-          (signal (car err) (cdr err))))
-  (setq inhibit-quit t)                        ;sport death
-  (use-local-map terminal-map)
-  (run-hooks 'terminal-mode-hook)
-  (message "Entering Emacs terminal-emulator...  Type %s %s for help"
-          (single-key-description terminal-escape-char)
-          (mapconcat #'single-key-description
-                     (where-is-internal #'te-escape-help terminal-escape-map t)
-                     " ")))
-
-
-(defun te-parse-program-and-args (s)
-  (cond ((string-match "\\`[-a-zA-Z0-9+=_.@/:][-a-zA-Z0-9+=_.@/: \t]*\\'" s)
-        (let ((l ()) (p 0))
-          (while p
-            (setq l (cons (if (string-match
-                               "\\([-a-zA-Z0-9+=_.@/:]+\\)[ \t]*"
-                               s p)
-                              (prog1 (substring s p (match-end 1))
-                                (setq p (match-end 0))
-                                (if (eq p (length s)) (setq p nil)))
-                              (prog1 (substring s p)
-                                (setq p nil)))
-                          l)))
-          (setq l (nreverse l))
-          (list (car l) (cdr l))))
-       ((and (string-match "[ \t]" s) (not (file-exists-p s)))
-        (list shell-file-name (list "-c" (concat "exec " s))))
-       (t (list s ()))))
-
-(put 'terminal-mode 'mode-class 'special)
-;; This is only separated out from function terminal-emulator
-;; to keep the latter a little more manageable.
-(defun terminal-mode ()
-  "Set up variables for use with the terminal-emulator.
-One should not call this -- it is an internal function
-of the terminal-emulator"
-  (kill-all-local-variables)
-  (buffer-disable-undo (current-buffer))
-  (setq major-mode 'terminal-mode)
-  (setq mode-name "terminal")
-; (make-local-variable 'Helper-return-blurb)
-; (setq Helper-return-blurb "return to terminal simulator")
-  (setq mode-line-process '(":%s"))
-  (setq buffer-read-only t)
-  (setq truncate-lines t)
-  (make-local-variable 'terminal-escape-char)
-  (setq terminal-escape-char (default-value 'terminal-escape-char))
-  (make-local-variable 'terminal-scrolling)
-  (setq terminal-scrolling (default-value 'terminal-scrolling))
-  (make-local-variable 'terminal-more-processing)
-  (setq terminal-more-processing (default-value 'terminal-more-processing))
-  (make-local-variable 'terminal-redisplay-interval)
-  (setq terminal-redisplay-interval (default-value 
'terminal-redisplay-interval))
-  (make-local-variable 'te-width)
-  (make-local-variable 'te-height)
-  (make-local-variable 'te-process)
-  (make-local-variable 'te-pending-output)
-  (setq te-pending-output (list 0))
-  (make-local-variable 'te-saved-point)
-  (setq te-saved-point (point-min))
-  (make-local-variable 'te-pending-output-info) ;for the mode line
-  (setq te-pending-output-info "")
-  (make-local-variable 'inhibit-quit)
-  ;(setq inhibit-quit t)
-  (make-local-variable 'te-log-buffer)
-  (setq te-log-buffer nil)
-  (make-local-variable 'te-more-count)
-  (setq te-more-count -1)
-  (make-local-variable 'te-redisplay-count)
-  (setq te-redisplay-count terminal-redisplay-interval)
-  ;(use-local-map terminal-mode-map)
-  ;; terminal-mode-hook is called above in function terminal-emulator
-  )
-
-;;;; what a complete loss
-
-(defun te-quote-arg-for-sh (string)
-  (cond ((string-match "\\`[-a-zA-Z0-9+=_.@/:]+\\'"
-                      string)
-        string)
-       ((not (string-search "$" string))
-        ;; "[\"\\]" are special to sh and the lisp reader in the same way
-        (prin1-to-string string))
-       (t
-        (let ((harder "")
-              (start 0)
-              (end 0))
-          (while (cond ((>= start (length string))
-                        nil)
-                       ;; this is the set of chars magic with "..." in `sh'
-                       ((setq end (string-match "[\"\\$]"
-                                                string start))
-                        t)
-                       (t (setq harder (concat harder
-                                               (substring string start)))
-                          nil))
-            (setq harder (concat harder (substring string start end)
-                                  ;; Can't use ?\\ since `concat'
-                                  ;; unfortunately does prin1-to-string
-                                  ;; on fixna.  Amazing.
-                                 "\\"
-                                 (substring string
-                                            end
-                                            (1+ end)))
-                  start (1+ end)))
-          (concat "\"" harder "\"")))))
-
-(defun te-create-terminfo ()
-  "Create and compile a terminfo entry for the virtual terminal. This is kept
-in the directory specified by `te-terminfo-directory'."
-  (when (and system-uses-terminfo
-            (not (file-exists-p (concat te-terminfo-directory
-                                        (substring te-terminal-name-prefix 0 1)
-                                        "/" te-terminal-name))))
-    (let ( (terminfo
-           (concat
-            ;; The first newline avoids trouble with ncurses.
-            (format "%s,\n\tmir, xon,cols#%d, lines#%d,"
-                    te-terminal-name te-width te-height)
-            "bel=^P^G, clear=^P\\f, cr=^P^A, cub1=^P^B, cud1=^P\\n,"
-            "cuf1=^P^F, cup=^P=%p1%'\\s'%+%c%p2%'\\s'%+%c,"
-            "dch=^Pd%p1%'\\s'%+%c, dch1=^Pd!, dl=^P^K%p1%'\\s'%+%c,"
-            "dl1=^P^K!, ed=^PC, el=^Pc, home=^P=\\s\\s,"
-            "ich=^P_%p1%'\\s'%+%c, ich1=^P_!, il=^P^O%p1%'\\s'%+%c,"
-            ;; The last newline avoids trouble with ncurses.
-            "il1=^P^O!, ind=^P\\n, nel=\\n,\n"))
-          ;; This is the desired name for the source file.
-          (file-name (concat te-terminfo-directory te-terminal-name ".tif")) )
-      (make-directory te-terminfo-directory t)
-      (let ((temp-file
-            (make-temp-file (expand-file-name "tif" te-terminfo-directory))))
-       ;; Store the source file under a random temp name.
-       (with-temp-file temp-file
-         (insert terminfo))
-       ;; Rename it to the desired name.
-       ;; We use this roundabout approach
-       ;; to avoid any risk of writing a name that
-       ;; was mischievously set up as a symlink.
-       (rename-file temp-file file-name))
-      ;; Now compile that source to make the binary that the
-      ;; programs actually use.
-      (let ((process-environment
-            (cons (concat "TERMINFO="
-                          (directory-file-name te-terminfo-directory))
-                  process-environment)))
-       (set-process-sentinel (start-process "tic" nil "tic" file-name)
-                             #'te-tic-sentinel))))
-    (directory-file-name te-terminfo-directory))
-
-(defun te-create-termcap ()
-  "Create a termcap entry for the virtual terminal"
-  ;; Because of Unix Brain Death(tm), we can't change
-  ;;  the terminal type of a running process, and so
-  ;;  terminal size and scrollability are wired-down
-  ;;  at this point.  ("Detach?  What's that?")
-  (concat (format "%s:co#%d:li#%d:%s"
-                 ;; Sigh.  These can't be dynamically changed.
-                 te-terminal-name te-width te-height (if terminal-scrolling
-                                        "" "ns:"))
-         ;;-- Basic things
-         ;; cursor-motion, bol, forward/backward char
-         "cm=^p=%+ %+ :cr=^p^a:le=^p^b:nd=^p^f:"
-         ;; newline, clear eof/eof, audible bell
-         "nw=^j:ce=^pc:cd=^pC:cl=^p^l:bl=^p^g:"
-         ;; insert/delete char/line
-         "IC=^p_%+ :DC=^pd%+ :AL=^p^o%+ :DL=^p^k%+ :"
-         ;;-- Not-widely-known (ie nonstandard) flags, which mean
-         ;; o writing in the last column of the last line
-         ;;   doesn't cause idiotic scrolling, and
-         ;; o don't use idiotische c-s/c-q sogenannte
-         ;;   ``flow control'' auf keinen Fall.
-         "LP:NF:"
-         ;;-- For stupid or obsolete programs
-         "ic=^p_!:dc=^pd!:al=^p^o!:dl=^p^k!:ho=^p=  :"
-         ;;-- For disgusting programs.
-         ;; (VI? What losers need these, I wonder?)
-         "im=:ei=:dm=:ed=:mi:do=^p^j:nl=^p^j:bs:")
-)
-
-(defun te-tic-sentinel (_proc state-change)
-  "If tic has finished, delete the .tif file"
-  (if (equal state-change "finished
-")
-      (delete-file (concat te-terminfo-directory te-terminal-name ".tif"))))
-
-(provide 'terminal)
-
-;;; terminal.el ends here
diff --git a/lisp/obsolete/vi.el b/lisp/obsolete/vi.el
deleted file mode 100644
index afc6284b348..00000000000
--- a/lisp/obsolete/vi.el
+++ /dev/null
@@ -1,1495 +0,0 @@
-;;; vi.el --- major mode for emulating "vi" editor under GNU Emacs  -*- 
lexical-binding: t; -*-
-
-;; This file is in the public domain because the authors distributed it
-;; without a copyright notice before the US signed the Bern Convention.
-
-;; This file is part of GNU Emacs.
-
-;; Author: Neal Ziring <nz@rsch.wisc.edu>
-;;     Felix S. T. Wu <wu@crys.wisc.edu>
-;; Keywords: emulations
-;; Obsolete-since: 24.5
-
-;;; Commentary:
-
-;; This file is obsolete.  Consider using viper instead.
-
-;; Originally written by : seismo!wucs!nz@rsch.wisc.edu (Neal Ziring)
-;; Extensively redesigned and rewritten by wu@crys.wisc.edu (Felix S.T. Wu)
-;; Last revision: 01/07/87 Wed (for GNU Emacs 18.33)
-
-;; INSTALLATION PROCEDURE:
-;; 1) Add a global key binding for command "vi-mode" (I use ESC ESC instead of
-;;    the single ESC used in real "vi", so I can access other ESC prefixed 
emacs
-;;    commands while I'm in "vi"), say, by putting the following line in your
-;;    ".emacs" file:
-;;    (define-key global-map "\e\e" 'vi-mode) ;quick switch into vi-mode
-;; 2) If you wish you can define "find-file-hook" to enter "vi" automatically
-;;    after a file is loaded into the buffer. For example, I defined it as:
-;;    (setq find-file-hook (list
-;;                           (function (lambda ()
-;;                               (if (not (or (eq major-mode 'Info-mode)
-;;                                          (eq major-mode 'vi-mode)))
-;;                                   (vi-mode))))))
-;; 3) In your init file you can define the command "vi-mode" to be "autoload"
-;;    or you can execute the "load" command to load "vi" directly.
-;; 4) Read the comments for command "vi-mode" before you start using it.
-
-;; COULD DO
-;; 1). A general 'define-operator' function to replace current hack
-;; 2). In operator handling, should allow other point moving Emacs commands
-;;     (such as ESC <, ESC >) to be used as arguments.
-
-;;; Code:
-
-(defvar vi-mode-old-major-mode)
-(defvar vi-mode-old-mode-name)
-(defvar vi-mode-old-local-map)
-(defvar vi-mode-old-case-fold)
-
-(if (null (where-is-internal 'vi-switch-mode (current-local-map)))
-    (define-key ctl-x-map "~" #'vi-switch-mode))
-
-(defvar vi-tilde-map nil
-  "Keymap used for \\[vi-switch-mode] prefix key.  Link to various major 
modes.")
-
-(if vi-tilde-map
-    nil
-  (setq vi-tilde-map (make-keymap))
-  (define-key vi-tilde-map "a" #'abbrev-mode)
-  (define-key vi-tilde-map "c" #'c-mode)
-  (define-key vi-tilde-map "d" #'vi-debugging)
-  (define-key vi-tilde-map "e" #'emacs-lisp-mode)
-  (define-key vi-tilde-map "f" #'auto-fill-mode)
-  (define-key vi-tilde-map "g" #'prolog-mode)
-  (define-key vi-tilde-map "h" #'hanoi)
-  ;; (define-key vi-tilde-map "i" #'info-mode)
-  (define-key vi-tilde-map "l" #'lisp-mode)
-  (define-key vi-tilde-map "n" #'nroff-mode)
-  (define-key vi-tilde-map "o" #'overwrite-mode)
-  (define-key vi-tilde-map "O" #'outline-mode)
-  (define-key vi-tilde-map "P" #'picture-mode)
-  (define-key vi-tilde-map "r" #'vi-readonly-mode)
-  (define-key vi-tilde-map "t" #'text-mode)
-  (define-key vi-tilde-map "v" #'vi-mode)
-  (define-key vi-tilde-map "x" #'tex-mode)
-  (define-key vi-tilde-map "~" #'vi-back-to-old-mode))
-
-(defun vi-switch-mode (arg mode-char)
-  "Switch the major mode of current buffer as specified by the following char 
\\{vi-tilde-map}"
-  (interactive "P\nc")
-  (let ((mode-cmd (lookup-key vi-tilde-map (char-to-string mode-char))))
-    (if (null mode-cmd)
-       (with-output-to-temp-buffer "*Help*"
-         (princ (substitute-command-keys "Possible major modes to switch to: 
\\{vi-tilde-map}"))
-         (with-current-buffer standard-output
-           (help-mode)))
-      (setq prefix-arg arg)            ; prefix arg will be passed down
-      (command-execute mode-cmd nil)   ; may need to save mode-line-format etc
-      (force-mode-line-update))))      ; just in case
-
-
-(defun vi-debugging (arg)
-  "Toggle debug-on-error flag.  If prefix arg is given, set t."
-  (interactive "P")
-  (if arg
-      (setq debug-on-error t)
-    (setq debug-on-error (not debug-on-error)))
-  (if debug-on-error
-      (message "Debug-on-error ...")
-    (message "NO more debug-on-error")))
-
-(defun vi-back-to-old-mode ()
-  "Go back to the previous mode without setting up for insertion."
-  (interactive)
-  (if vi-mode-old-major-mode
-      (progn
-       (setq mode-name vi-mode-old-mode-name)
-       (use-local-map vi-mode-old-local-map)
-       (setq major-mode vi-mode-old-major-mode)
-       (setq case-fold-search vi-mode-old-case-fold)
-       (force-mode-line-update))))
-
-(defun vi-readonly-mode ()
-  "Toggle current buffer's readonly flag."
-  (interactive)
-  (setq buffer-read-only (not buffer-read-only)))
-
-(defvar vi-com-map nil
-   "Keymap used in Evi's command state
-Command state includes most of the vi editing commands, with some Emacs
-command extensions.")
-
-(put 'vi-undefined 'suppress-keymap t)
-(if vi-com-map nil
-  (setq vi-com-map (make-keymap))
-;;(fillarray vi-com-map #'vi-undefined)
-  (define-key vi-com-map "\C-@" #'vi-mark-region) ; extension
-  (define-key vi-com-map "\C-a" #'vi-ask-for-info)  ; extension
-  (define-key vi-com-map "\C-b" #'vi-backward-windowful)
-  (define-key vi-com-map "\C-c" #'vi-do-old-mode-C-c-command) ; extension
-  (define-key vi-com-map "\C-d" #'vi-scroll-down-window)
-  (define-key vi-com-map "\C-e" #'vi-expose-line-below)
-  (define-key vi-com-map "\C-f" #'vi-forward-windowful)
-  (define-key vi-com-map "\C-g" #'keyboard-quit)
-  (define-key vi-com-map "\C-i" #'indent-relative-first-indent-point) ; TAB
-  (define-key vi-com-map "\C-j" #'vi-next-line) ; LFD
-  (define-key vi-com-map "\C-k" #'vi-kill-line) ; extension
-  (define-key vi-com-map "\C-l" #'recenter)
-  (define-key vi-com-map "\C-m" #'vi-next-line-first-nonwhite) ; RET
-  (define-key vi-com-map "\C-n" #'vi-next-line)
-  (define-key vi-com-map "\C-o" #'vi-split-open-line)
-  (define-key vi-com-map "\C-p" #'previous-line)
-  (define-key vi-com-map "\C-q" #'vi-query-replace) ; extension
-  (define-key vi-com-map "\C-r" #'vi-isearch-backward) ; modification
-  (define-key vi-com-map "\C-s" #'vi-isearch-forward)  ; extension
-  (define-key vi-com-map "\C-t" #'vi-transpose-objects) ; extension
-  (define-key vi-com-map "\C-u" #'vi-scroll-up-window)
-  (define-key vi-com-map "\C-v" #'scroll-up-command) ; extension
-  (define-key vi-com-map "\C-w" #'vi-kill-region)   ; extension
-  (define-key vi-com-map "\C-x" 'Control-X-prefix) ; extension
-  (define-key vi-com-map "\C-y" #'vi-expose-line-above)
-  (define-key vi-com-map "\C-z" #'suspend-emacs)
-
-  (define-key vi-com-map "\e"   'ESC-prefix); C-[ (ESC)
-  (define-key vi-com-map "\C-\\" #'vi-unimplemented)
-  (define-key vi-com-map "\C-]" #'xref-find-definitions)
-  (define-key vi-com-map "\C-^" #'vi-locate-def)  ; extension
-  (define-key vi-com-map "\C-_" #'vi-undefined)
-
-  (define-key vi-com-map " "  #'forward-char)
-  (define-key vi-com-map "!"  #'vi-operator)
-  (define-key vi-com-map "\"" #'vi-char-argument)
-  (define-key vi-com-map "#"  #'universal-argument) ; extension
-  (define-key vi-com-map "$"  #'end-of-line)
-  (define-key vi-com-map "%"  #'vi-find-matching-paren)
-  (define-key vi-com-map "&"  #'vi-unimplemented)
-  (define-key vi-com-map "'"  #'vi-goto-line-mark)
-  (define-key vi-com-map "("  #'backward-sexp)
-  (define-key vi-com-map ")"  #'forward-sexp)
-  (define-key vi-com-map "*"  #'vi-name-last-change-or-macro) ; extension
-  (define-key vi-com-map "+"  #'vi-next-line-first-nonwhite)
-  (define-key vi-com-map ","  #'vi-reverse-last-find-char)
-  (define-key vi-com-map "-"  #'vi-previous-line-first-nonwhite)
-  (define-key vi-com-map "."  #'vi-redo-last-change-command)
-  (define-key vi-com-map "/"  #'vi-search-forward)
-  (define-key vi-com-map "0"  #'beginning-of-line)
-
-  (define-key vi-com-map "1"  #'vi-digit-argument)
-  (define-key vi-com-map "2"  #'vi-digit-argument)
-  (define-key vi-com-map "3"  #'vi-digit-argument)
-  (define-key vi-com-map "4"  #'vi-digit-argument)
-  (define-key vi-com-map "5"  #'vi-digit-argument)
-  (define-key vi-com-map "6"  #'vi-digit-argument)
-  (define-key vi-com-map "7"  #'vi-digit-argument)
-  (define-key vi-com-map "8"  #'vi-digit-argument)
-  (define-key vi-com-map "9"  #'vi-digit-argument)
-
-  (define-key vi-com-map ":"  #'vi-ex-cmd)
-  (define-key vi-com-map ";"  #'vi-repeat-last-find-char)
-  (define-key vi-com-map "<"  #'vi-operator)
-  (define-key vi-com-map "="  #'vi-operator)
-  (define-key vi-com-map ">"  #'vi-operator)
-  (define-key vi-com-map "?"  #'vi-search-backward)
-  (define-key vi-com-map "@"  #'vi-call-named-change-or-macro) ; extension
-
-  (define-key vi-com-map "A"  #'vi-append-at-end-of-line)
-  (define-key vi-com-map "B"  #'vi-backward-blank-delimited-word)
-  (define-key vi-com-map "C"  #'vi-change-rest-of-line)
-  (define-key vi-com-map "D"  #'vi-kill-line)
-  (define-key vi-com-map "E"  #'vi-end-of-blank-delimited-word)
-  (define-key vi-com-map "F"  #'vi-backward-find-char)
-  (define-key vi-com-map "G"  #'vi-goto-line)
-  (define-key vi-com-map "H"  #'vi-home-window-line)
-  (define-key vi-com-map "I"  #'vi-insert-before-first-nonwhite)
-  (define-key vi-com-map "J"  #'vi-join-lines)
-  (define-key vi-com-map "K"  #'vi-undefined)
-  (define-key vi-com-map "L"  #'vi-last-window-line)
-  (define-key vi-com-map "M"  #'vi-middle-window-line)
-  (define-key vi-com-map "N"  #'vi-reverse-last-search)
-  (define-key vi-com-map "O"  #'vi-open-above)
-  (define-key vi-com-map "P"  #'vi-put-before)
-  (define-key vi-com-map "Q"  #'vi-quote-words) ; extension
-  (define-key vi-com-map "R"  #'vi-replace-chars)
-  (define-key vi-com-map "S"  #'vi-substitute-lines)
-  (define-key vi-com-map "T"  #'vi-backward-upto-char)
-  (define-key vi-com-map "U"  #'vi-unimplemented)
-  (define-key vi-com-map "V"  #'vi-undefined)
-  (define-key vi-com-map "W"  #'vi-forward-blank-delimited-word)
-  (define-key vi-com-map "X"  #'call-last-kbd-macro) ; modification/extension
-  (define-key vi-com-map "Y"  #'vi-yank-line)
-  (define-key vi-com-map "Z" (make-sparse-keymap)) ;allow below prefix command
-  (define-key vi-com-map "ZZ" #'vi-save-all-and-exit)
-
-  (define-key vi-com-map "["  #'vi-unimplemented)
-  (define-key vi-com-map "\\" #'vi-operator) ; extension for vi-narrow-op
-  (define-key vi-com-map "]"  #'vi-unimplemented)
-  (define-key vi-com-map "^"  #'back-to-indentation)
-  (define-key vi-com-map "_"  #'vi-undefined)
-  (define-key vi-com-map "`"  #'vi-goto-char-mark)
-
-  (define-key vi-com-map "a"  #'vi-insert-after)
-  (define-key vi-com-map "b"  #'backward-word)
-  (define-key vi-com-map "c"  #'vi-operator)
-  (define-key vi-com-map "d"  #'vi-operator)
-  (define-key vi-com-map "e"  #'vi-end-of-word)
-  (define-key vi-com-map "f"  #'vi-forward-find-char)
-  (define-key vi-com-map "g"  #'vi-beginning-of-buffer) ; extension
-  (define-key vi-com-map "h"  #'backward-char)
-  (define-key vi-com-map "i"  #'vi-insert-before)
-  (define-key vi-com-map "j"  #'vi-next-line)
-  (define-key vi-com-map "k"  #'previous-line)
-  (define-key vi-com-map "l"  #'forward-char)
-  (define-key vi-com-map "m"  #'vi-set-mark)
-  (define-key vi-com-map "n"  #'vi-repeat-last-search)
-  (define-key vi-com-map "o"  #'vi-open-below)
-  (define-key vi-com-map "p"  #'vi-put-after)
-  (define-key vi-com-map "q"  #'vi-replace)
-  (define-key vi-com-map "r"  #'vi-replace-1-char)
-  (define-key vi-com-map "s"  #'vi-substitute-chars)
-  (define-key vi-com-map "t"  #'vi-forward-upto-char)
-  (define-key vi-com-map "u"  #'undo)
-  (define-key vi-com-map "v"  #'vi-verify-spelling)
-  (define-key vi-com-map "w"  #'vi-forward-word)
-  (define-key vi-com-map "x"  #'vi-kill-char)
-  (define-key vi-com-map "y"  #'vi-operator)
-  (define-key vi-com-map "z"  #'vi-adjust-window)
-
-  (define-key vi-com-map "{"  #'backward-paragraph)
-  (define-key vi-com-map "|"  #'vi-goto-column)
-  (define-key vi-com-map "}"  #'forward-paragraph)
-  (define-key vi-com-map "~"  #'vi-change-case)
-  (define-key vi-com-map "\177" #'delete-backward-char))
-
-(put 'backward-char 'point-moving-unit 'char)
-(put 'vi-next-line 'point-moving-unit 'line)
-(put 'next-line 'point-moving-unit 'line)
-(put 'forward-line 'point-moving-unit 'line)
-(put 'previous-line 'point-moving-unit 'line)
-(put 'vi-isearch-backward 'point-moving-unit 'search)
-(put 'vi-search-backward 'point-moving-unit 'search)
-(put 'vi-isearch-forward 'point-moving-unit 'search)
-(put 'vi-search-forward 'point-moving-unit 'search)
-(put 'forward-char 'point-moving-unit 'char)
-(put 'end-of-line 'point-moving-unit 'char)
-(put 'vi-find-matching-paren 'point-moving-unit 'match)
-(put 'vi-goto-line-mark 'point-moving-unit 'line)
-(put 'backward-sexp 'point-moving-unit 'sexp)
-(put 'forward-sexp 'point-moving-unit 'sexp)
-(put 'vi-next-line-first-nonwhite 'point-moving-unit 'line)
-(put 'vi-previous-line-first-nonwhite 'point-moving-unit 'line)
-(put 'vi-reverse-last-find-char 'point-moving-unit 'rev-find)
-(put 'vi-re-search-forward 'point-moving-unit 'search)
-(put 'beginning-of-line 'point-moving-unit 'char)
-(put 'vi-beginning-of-buffer 'point-moving-unit 'char)
-(put 'vi-repeat-last-find-char 'point-moving-unit 'find)
-(put 'vi-re-search-backward 'point-moving-unit 'search)
-(put 'vi-backward-blank-delimited-word 'point-moving-unit 'WORD)
-(put 'vi-end-of-blank-delimited-word 'point-moving-unit 'match)
-(put 'vi-backward-find-char 'point-moving-unit 'find)
-(put 'vi-goto-line 'point-moving-unit 'line)
-(put 'vi-home-window-line 'point-moving-unit 'line)
-(put 'vi-last-window-line 'point-moving-unit 'line)
-(put 'vi-middle-window-line 'point-moving-unit 'line)
-(put 'vi-reverse-last-search 'point-moving-unit 'rev-search)
-(put 'vi-backward-upto-char 'point-moving-unit 'find)
-(put 'vi-forward-blank-delimited-word 'point-moving-unit 'WORD)
-(put 'back-to-indentation 'point-moving-unit 'char)
-(put 'vi-goto-char-mark 'point-moving-unit 'char)
-(put 'backward-word 'point-moving-unit 'word)
-(put 'vi-end-of-word 'point-moving-unit 'match)
-(put 'vi-forward-find-char 'point-moving-unit 'find)
-(put 'backward-char 'point-moving-unit 'char)
-(put 'vi-forward-char 'point-moving-unit 'char)
-(put 'vi-repeat-last-search 'point-moving-unit 'search)
-(put 'vi-forward-upto-char 'point-moving-unit 'find)
-(put 'vi-forward-word 'point-moving-unit 'word)
-(put 'vi-goto-column 'point-moving-unit 'match)
-(put 'forward-paragraph 'point-moving-unit 'paragraph)
-(put 'backward-paragraph 'point-moving-unit 'paragraph)
-
-;;; region mark commands
-(put 'mark-page 'point-moving-unit 'region)
-(put 'mark-paragraph 'point-moving-unit 'region)
-(put 'mark-word 'point-moving-unit 'region)
-(put 'mark-sexp 'point-moving-unit 'region)
-(put 'mark-defun 'point-moving-unit 'region)
-(put 'mark-whole-buffer 'point-moving-unit 'region)
-(put 'mark-end-of-sentence 'point-moving-unit 'region)
-(put 'c-mark-function 'point-moving-unit 'region)
-;;;
-
-(defvar vi-mark-alist nil
-  "Alist of (NAME . MARK), marks are local to each buffer.")
-
-(defvar vi-scroll-amount (/ (window-height) 2)
-  "Default amount of lines for scrolling (used by \"^D\"/\"^U\").")
-
-(defvar vi-shift-width 4
-  "Shift amount for \"<\"/\">\" operators.")
-
-(defvar vi-ins-point nil               ; integer
-  "Last insertion point.  Should use `mark' instead.")
-
-(defvar vi-ins-length nil              ; integer
-  "Length of last insertion.")
-
-(defvar vi-ins-repetition nil          ; integer
-  "The repetition required for last insertion.")
-
-(defvar vi-ins-overwrt-p nil           ; boolean
-  "T if last insertion was a replace actually.")
-
-(defvar vi-ins-prefix-code nil         ; ready-to-eval sexp
-  "Code to be eval'ed before (redo-)insertion begins.")
-
-(defvar vi-last-find-char nil          ; cons cell
-  "Save last direction, char and upto-flag used for char finding.")
-
-(defvar vi-last-change-command nil     ; cons cell
-  "Save commands for redoing last changes.  Each command is in (FUNC . ARGS)
-form that is ready to be `apply'ed.")
-
-(defvar vi-last-shell-command nil      ; last shell op command line
-  "Save last shell command given for \"!\" operator.")
-
-(defvar vi-insert-state nil             ; boolean
-  "Non-nil if it is in insert state.")
-
-; in "loaddefs.el"
-;(defvar search-last-string ""
-;  "Last string search for by a search command.")
-
-(defvar vi-search-last-command nil     ; (re-)search-forward(backward)
-  "Save last search command for possible redo.")
-
-(defvar vi-mode-old-local-map nil
-  "Save the local-map used before entering vi-mode.")
-
-(defvar vi-mode-old-mode-name nil
-  "Save the mode-name before entering vi-mode.")
-
-(defvar vi-mode-old-major-mode nil
-  "Save the major-mode before entering vi-mode.")
-
-(defvar vi-mode-old-case-fold nil)
-
-;(defconst vi-add-to-mode-line-1
-;  '(overwrite-mode nil " Insert"))
-
-;; Value is same as vi-add-to-mode-line-1 when in vi mode,
-;; but nil in other buffers.
-;(defvar vi-add-to-mode-line nil)
-
-(defun vi-mode-setup ()
-  "Setup a buffer for vi-mode by creating necessary buffer-local variables."
-;  (make-local-variable 'vi-add-to-mode-line)
-;  (setq vi-add-to-mode-line vi-add-to-mode-line-1)
-;  (or (memq vi-add-to-mode-line minor-mode-alist)
-;      (setq minor-mode-alist (cons vi-add-to-mode-line minor-mode-alist)))
-  (make-local-variable 'vi-scroll-amount)
-  (setq vi-scroll-amount (/ (window-height) 2))
-  (make-local-variable 'vi-shift-width)
-  (setq vi-shift-width 4)
-  (make-local-variable 'vi-ins-point)
-  (make-local-variable 'vi-ins-length)
-  (make-local-variable 'vi-ins-repetition)
-  (make-local-variable 'vi-ins-overwrt-p)
-  (make-local-variable 'vi-ins-prefix-code)
-  (make-local-variable 'vi-last-change-command)
-  (make-local-variable 'vi-last-shell-command)
-  (make-local-variable 'vi-last-find-char)
-  (make-local-variable 'vi-mark-alist)
-  (make-local-variable 'vi-insert-state)
-  (make-local-variable 'vi-mode-old-local-map)
-  (make-local-variable 'vi-mode-old-mode-name)
-  (make-local-variable 'vi-mode-old-major-mode)
-  (make-local-variable 'vi-mode-old-case-fold)
-  (run-mode-hooks 'vi-mode-hook))
-
-;;;###autoload
-(defun vi-mode ()
-  "Major mode that acts like the `vi' editor.
-The purpose of this mode is to provide you the combined power of vi (namely,
-the \"cross product\" effect of commands and repeat last changes) and Emacs.
-
-This command redefines nearly all keys to look like vi commands.
-It records the previous major mode, and any vi command for input
-\(`i', `a', `s', etc.) switches back to that mode.
-Thus, ordinary Emacs (in whatever major mode you had been using)
-is \"input\" mode as far as vi is concerned.
-
-To get back into vi from \"input\" mode, you must issue this command again.
-Therefore, it is recommended that you assign it to a key.
-
-Major differences between this mode and real vi :
-
-* Limitations and unsupported features
-  - Search patterns with line offset (e.g. /pat/+3 or /pat/z.) are
-    not supported.
-  - Ex commands are not implemented; try ':' to get some hints.
-  - No line undo (i.e. the `U' command), but multi-undo is a standard feature.
-
-* Modifications
-  - The stopping positions for some point motion commands (word boundary,
-    pattern search) are slightly different from standard `vi'.
-    Also, no automatic wrap around at end of buffer for pattern searching.
-  - Since changes are done in two steps (deletion then insertion), you need
-    to undo twice to completely undo a change command.  But this is not needed
-    for undoing a repeated change command.
-  - No need to set/unset `magic', to search for a string with regular expr
-    in it just put a prefix arg for the search commands.  Replace cmds too.
-  - ^R is bound to incremental backward search, so use ^L to redraw screen.
-
-* Extensions
-  - Some standard (or modified) Emacs commands were integrated, such as
-    incremental search, query replace, transpose objects, and keyboard macros.
-  - In command state, ^X links to the `ctl-x-map', and ESC can be linked to
-    esc-map or set undefined.  These can give you the full power of Emacs.
-  - See vi-com-map for those keys that are extensions to standard vi, e.g.
-    `vi-name-last-change-or-macro', `vi-verify-spelling', `vi-locate-def',
-    `vi-mark-region', and `vi-quote-words'.  Some of them are quite handy.
-  - Use \\[vi-switch-mode] to switch among different modes quickly.
-
-Syntax table and abbrevs while in vi mode remain as they were in Emacs."
-   (interactive)
-   (if (null vi-mode-old-major-mode)   ; very first call for current buffer
-       (vi-mode-setup))
-
-   (if (eq major-mode 'vi-mode)
-       (progn (ding) (message "Already in vi-mode."))
-     (setq vi-mode-old-local-map (current-local-map))
-     (setq vi-mode-old-mode-name mode-name)
-     (setq vi-mode-old-major-mode major-mode)
-     (setq vi-mode-old-case-fold case-fold-search) ; this is needed !!
-     (setq case-fold-search nil)       ; exact case match in searching
-     (use-local-map vi-com-map)
-     (setq major-mode 'vi-mode)
-     (setq mode-name "VI")
-     (force-mode-line-update)          ; force mode line update
-     (if vi-insert-state               ; this is a return from insertion
-         (vi-end-of-insert-state))))
-
-(defun vi-ding()
-  "Ding !"
-  (interactive)
-  (ding))
-
-(defun vi-save-all-and-exit ()
-  "Save all modified buffers without asking, then exits emacs."
-  (interactive)
-  (save-some-buffers t)
-  (kill-emacs))
-
-;; to be used by "ex" commands
-(defvar vi-replaced-string nil)
-(defvar vi-replacing-string nil)
-
-(defun vi-ex-cmd ()
-  "Ex commands are not implemented in Evi mode.  For some commonly used ex
-commands, you can use the following alternatives for similar effect :
-w            C-x C-s (save-buffer)
-wq           C-x C-c (save-buffers-kill-emacs)
-w fname      C-x C-w (write-file)
-e fname      C-x C-f (find-file)
-r fname      C-x i   (insert-file)
-s/old/new    use q (vi-replace) to do unconditional replace
-             use C-q (vi-query-replace) to do query replace
-set sw=n     M-x set-variable vi-shift-width n "
-  (interactive)
-;; (let ((cmd (read-string ":")) (lines 1))
-;;  (cond ((string-match "s"))))
-  (with-output-to-temp-buffer "*Help*"
-    (princ (documentation 'vi-ex-cmd))
-    (with-current-buffer standard-output
-      (help-mode))))
-
-(defun vi-undefined ()
-  (interactive)
-  (message "Command key \"%s\" is undefined in Evi."
-          (single-key-description last-command-event))
-  (ding))
-
-(defun vi-unimplemented ()
-  (interactive)
-  (message "Command key \"%s\" is not implemented in Evi."
-          (single-key-description last-command-event))
-  (ding))
-
-;;;;;
-(defun vi-goto-insert-state (repetition &optional prefix-code do-it-now-p)
-  "Go into insert state, the text entered will be repeated if REPETITION > 1.
-If PREFIX-CODE is given, do it before insertion begins if DO-IT-NOW-P is T.
-In any case, the prefix-code will be done before each `redo-insert'.
-This function expects `overwrite-mode' being set properly beforehand."
-  (if do-it-now-p (apply (car prefix-code) (cdr prefix-code)))
-  (setq vi-ins-point (point))
-  (setq vi-ins-repetition repetition)
-  (setq vi-ins-prefix-code prefix-code)
-  (setq mode-name vi-mode-old-mode-name)
-  (setq case-fold-search vi-mode-old-case-fold)
-  (use-local-map vi-mode-old-local-map)
-  (setq major-mode vi-mode-old-major-mode)
-  (force-mode-line-update)
-  (setq vi-insert-state t))
-
-(defun vi-end-of-insert-state ()
-  "Terminate insertion and set up last change command."
-  (if (or (< (point) vi-ins-point)    ;Check if there is any effective change
-         (and (= (point) vi-ins-point) (null vi-ins-prefix-code))
-         (<= vi-ins-repetition 0))
-      (vi-goto-command-state t)
-    (if (> vi-ins-repetition 1)
-       (progn
-         (let ((str (buffer-substring vi-ins-point (point))))
-           (while (> vi-ins-repetition 1)
-             (insert str)
-             (setq vi-ins-repetition (1- vi-ins-repetition))))))
-    (vi-set-last-change-command 'vi-first-redo-insertion vi-ins-point (point)
-                            overwrite-mode vi-ins-prefix-code)
-    (vi-goto-command-state t)))
-
-(defun vi-first-redo-insertion (begin end &optional overwrite-p prefix-code)
-  "Redo last insertion the first time.  Extract the string and save it for
-future redoes.  Do prefix-code if it's given, use overwrite mode if asked."
-  (let ((str (buffer-substring begin end)))
-    (if prefix-code (apply (car prefix-code) (cdr prefix-code)))
-    (if overwrite-p (delete-region (point) (+ (point) (length str))))
-    (insert str)
-    (vi-set-last-change-command 'vi-more-redo-insertion str overwrite-p 
prefix-code)))
-
-(defun vi-more-redo-insertion (str &optional overwrite-p prefix-code)
-  "Redo more insertion : copy string from STR to point, use overwrite mode
-if overwrite-p is T; apply prefix-code first if it's non-nil."
-  (if prefix-code (apply (car prefix-code) (cdr prefix-code)))
-  (if overwrite-p (delete-region (point) (+ (point) (length str))))
-  (insert str))
-
-(defun vi-goto-command-state (&optional from-insert-state-p)
-  "Go to vi-mode command state.  If optional arg exists, means return from
-insert state."
-  (use-local-map vi-com-map)
-  (setq vi-insert-state nil)
-  (if from-insert-state-p
-      (if overwrite-mode
-         (overwrite-mode 0)
-;      (set-minor-mode 'ins "Insert" nil)
-       )))
-
-(defun vi-kill-line (arg)
-   "kill specified number of lines (=d$), text saved in the kill ring."
-   (interactive "*P")
-   (kill-line arg)
-   (vi-set-last-change-command 'kill-line arg))
-
-(defun vi-kill-region (start end)
-  (interactive "*r")
-  (kill-region start end)
-  (vi-set-last-change-command 'kill-region))
-
-(defun vi-append-at-end-of-line (arg)
-   "go to end of line and then go into vi insert state."
-   (interactive "*p")
-   (vi-goto-insert-state arg '(end-of-line) t))
-
-(defun vi-change-rest-of-line (arg)
-  "Change the rest of (ARG) lines (= c$ in vi)."
-  (interactive "*P")
-  (vi-goto-insert-state 1 (list 'kill-line arg) t))
-
-(defun vi-insert-before-first-nonwhite (arg)
-  "(= ^i in vi)"
-  (interactive "*p")
-  (vi-goto-insert-state arg '(back-to-indentation) t))
-
-(defun vi-open-above (arg)
-  "open new line(s) above current line and enter insert state."
-  (interactive "*p")
-  (vi-goto-insert-state 1
-                       (list (function (lambda (x)
-                                         (or (beginning-of-line)
-                                             (open-line x)))) arg)
-                       t))
-
-(defun vi-open-below (arg)
-  "open new line(s) and go into insert mode on the last line."
-  (interactive "*p")
-  (vi-goto-insert-state 1
-                       (list (function (lambda (x)
-                                         (or (end-of-line)
-                                           (open-line x)
-                                           (forward-line x)))) arg)
-                       t))
-
-(defun vi-insert-after (arg)
-   "start vi insert state after cursor."
-   (interactive "*p")
-   (vi-goto-insert-state arg
-                        (list (function (lambda ()
-                                          (if (not (eolp)) (forward-char)))))
-                        t))
-
-(defun vi-insert-before (arg)
-  "enter insert state before the cursor."
-  (interactive "*p")
-  (vi-goto-insert-state arg))
-
-(defun vi-goto-line (arg)
-   "Go to ARGth line."
-   (interactive "P")
-   (if (null (vi-raw-numeric-prefix arg))
-       (with-no-warnings
-        (end-of-buffer))
-     (with-no-warnings (goto-line (vi-prefix-numeric-value arg)))))
-
-(defun vi-beginning-of-buffer ()
-  "Move point to the beginning of current buffer."
-  (interactive)
-  (goto-char (point-min)))
-
-;;;;; not used now
-;;(defvar regexp-search t              ; string
-;;  "*T if search string can contain regular expressions. (= set magic in vi)")
-;;;;;
-
-(defun vi-isearch-forward (arg)
-  "Incremental search forward.  Use regexp version if ARG is non-nil."
-  (interactive "P")
-  (let ((scmd (if arg 'isearch-forward-regexp 'isearch-forward))
-       (opoint (point)))
-    (call-interactively scmd)
-    (if (= opoint (point))
-       nil
-      (setq vi-search-last-command (if arg 're-search-forward 
'search-forward)))))
-
-(defun vi-isearch-backward (arg)
-  "Incremental search backward.  Use regexp version if ARG is non-nil."
-  (interactive "P")
-  (let ((scmd (if arg 'isearch-backward-regexp 'isearch-backward))
-       (opoint (point)))
-    (call-interactively scmd)
-    (if (= opoint (point))
-       nil
-      (setq vi-search-last-command (if arg 're-search-backward 
'search-backward)))))
-
-(defun vi-search-forward (arg string)
-   "Nonincremental search forward. Use regexp version if ARG is non-nil."
-   (interactive (if current-prefix-arg
-                   (list t (read-string "regexp/" nil))
-                 (list nil (read-string "/" nil))))
-   (setq vi-search-last-command (if arg 're-search-forward 'search-forward))
-   (if (> (length string) 0)
-       (isearch-update-ring string arg))
-   (funcall vi-search-last-command string nil nil 1))
-
-(defun vi-search-backward (arg string)
-   "Nonincremental search backward.  Use regexp version if ARG is non-nil."
-   (interactive (if current-prefix-arg
-                   (list t (read-string "regexp?" nil))
-                 (list nil (read-string "?" nil))))
-   (setq vi-search-last-command (if arg 're-search-backward 'search-backward))
-   (if (> (length string) 0)
-       (isearch-update-ring string arg))
-   (funcall vi-search-last-command string nil nil 1))
-
-(defun vi-repeat-last-search (arg &optional search-command search-string)
-  "Repeat last search command.
-If optional search-command/string are given,
-use those instead of the ones saved."
-  (interactive "p")
-  (if (null search-command) (setq search-command vi-search-last-command))
-  (if (null search-string)
-      (setq search-string
-           (car (if (memq search-command
-                          '(re-search-forward re-search-backward))
-                    regexp-search-ring
-                  search-ring))))
-  (if (null search-command)
-      (progn (ding) (message "No last search command to repeat."))
-    (funcall search-command search-string nil nil arg)))
-
-(defun vi-reverse-last-search (arg &optional search-command search-string)
-  "Redo last search command in reverse direction.
-If the optional search args are given, use those instead of the ones saved."
-  (interactive "p")
-  (if (null search-command) (setq search-command vi-search-last-command))
-  (if (null search-string)
-      (setq search-string
-           (car (if (memq search-command
-                          '(re-search-forward re-search-backward))
-                    regexp-search-ring
-                  search-ring))))
-  (if (null search-command)
-      (progn (ding) (message "No last search command to repeat."))
-    (funcall (cond ((eq search-command 're-search-forward) 're-search-backward)
-                  ((eq search-command 're-search-backward) 're-search-forward)
-                  ((eq search-command 'search-forward) 'search-backward)
-                  ((eq search-command 'search-backward) 'search-forward))
-            search-string nil nil arg)))
-
-(defun vi-join-lines (arg)
-   "join ARG lines from current line (default 2), cleaning up white space."
-   (interactive "P")
-   (if (null (vi-raw-numeric-prefix arg))
-       (delete-indentation t)
-     (let ((count (vi-prefix-numeric-value arg)))
-       (while (>= count 2)
-        (delete-indentation t)
-        (setq count (1- count)))))
-   (vi-set-last-change-command 'vi-join-lines arg))
-
-(defun vi-backward-kill-line ()
-   "kill the current line.  Only works in insert state."
-   (interactive)
-   (if (not vi-insert-state)
-       nil
-     (beginning-of-line 1)
-     (kill-line nil)))
-
-(defun vi-abort-ins ()
-  "abort insert state, kill inserted text and go back to command state."
-  (interactive)
-  (if (not vi-insert-state)
-      nil
-    (if (> (point) vi-ins-point)
-          (kill-region vi-ins-point (point)))
-    (vi-goto-command-state t)))
-
-(defun vi-backward-windowful (count)
-  "Backward COUNT windowfuls. Default is one."
-  (interactive "p")
-; (set-mark-command nil)
-  (while (> count 0)
-    (scroll-down nil)
-    (setq count (1- count))))
-
-(defun vi-scroll-down-window (count)
-  "Scrolls down window COUNT lines.
-If COUNT is nil (actually, non-integer), scrolls default amount.
-The given COUNT is remembered for future scrollings."
-  (interactive "P")
-  (if (integerp count)
-      (setq vi-scroll-amount count))
-  (scroll-up vi-scroll-amount))
-
-(defun vi-expose-line-below (count)
-  "Expose COUNT more lines below the current window.  Default COUNT is 1."
-  (interactive "p")
-  (scroll-up count))
-
-(defun vi-forward-windowful (count)
-  "Forward COUNT windowfuls. Default is one."
-  (interactive "p")
-; (set-mark-command nil)
-  (while (> count 0)
-    (scroll-up nil)
-    (setq count (1- count))))
-
-(defun vi-next-line (count)
-  "Go down count lines, try to keep at the same column."
-  (interactive "p")
-  (setq this-command 'next-line)       ; this is a needed trick
-  (if (= (point) (progn (line-move count) (point)))
-      (ding)                           ; no moving, already at end of buffer
-    (setq last-command 'next-line)))
-
-(defun vi-next-line-first-nonwhite (count)
-  "Go down COUNT lines.  Stop at first non-white."
-  (interactive "p")
-  (if (= (point) (progn (forward-line count) (back-to-indentation) (point)))
-      (ding)))                         ; no moving, already at end of buffer
-
-(defun vi-previous-line-first-nonwhite (count)
-  "Go up COUNT lines.  Stop at first non-white."
-  (interactive "p")
-  (forward-line (- count))
-  (back-to-indentation))
-
-(defun vi-scroll-up-window (count)
-  "Scrolls up window COUNT lines.
-If COUNT is nil (actually, non-integer), scrolls default amount.
-The given COUNT is remembered for future scrollings."
-  (interactive "P")
-  (if (integerp count)
-      (setq vi-scroll-amount count))
-  (scroll-down vi-scroll-amount))
-
-(defun vi-expose-line-above (count)
-  "Expose COUNT more lines above the current window.  Default COUNT is 1."
-  (interactive "p")
-  (scroll-down count))
-
-(defun vi-char-argument (arg)
-  "Get following character (could be any CHAR) as part of the prefix argument.
-Possible prefix-arg cases are nil, INTEGER, (nil . CHAR) or (INTEGER . CHAR)."
-  (interactive "P")
-  (let ((char (read-char)))
-    (cond ((null arg) (setq prefix-arg (cons nil char)))
-         ((integerp arg) (setq prefix-arg (cons arg char)))
-         ; This can happen only if the user changed his/her mind for CHAR,
-         ; Or there are some leading "universal-argument"s
-         (t (setq prefix-arg (cons (car arg) char))))))
-
-(defun vi-goto-mark (mark-char &optional line-flag)
-  "Go to marked position or line (if line-flag is given).
-Goto mark `@' means jump into and pop the top mark on the mark ring."
-  (cond ((char-equal mark-char last-command-event)     ; `` or ''
-        (exchange-point-and-mark) (if line-flag (back-to-indentation)))
-       ((char-equal mark-char ?@)      ; jump and pop mark
-        (set-mark-command t) (if line-flag (back-to-indentation)))
-       (t
-        (let ((mark (vi-get-mark mark-char)))
-          (if (null mark)
-              (progn (vi-ding) (message "Mark register undefined."))
-            (set-mark-command nil)
-            (goto-char mark)
-            (if line-flag (back-to-indentation)))))))
-
-(defun vi-goto-line-mark (char)
-  "Go to the line (at first non-white) marked by next char."
-  (interactive "c")
-  (vi-goto-mark char t))
-
-(defun vi-goto-char-mark (char)
-  "Go to the char position marked by next mark-char."
-  (interactive "c")
-  (vi-goto-mark char))
-
-(defun vi-digit-argument (arg)
-  "Set numeric prefix argument."
-  (interactive "P")
-  (cond ((null arg) (digit-argument arg))
-       ((integerp arg) (digit-argument nil)
-                        (setq prefix-arg (* prefix-arg arg)))
-       (t (digit-argument nil)         ; in (NIL . CHAR) or (NUM . CHAR) form
-          (setq prefix-arg (cons (* prefix-arg
-                                    (if (null (car arg)) 1 (car arg)))
-                                 (cdr arg))))))
-
-(defun vi-raw-numeric-prefix (arg)
-  "Return the raw value of numeric part prefix argument."
-  (if (consp arg) (car arg) arg))
-
-(defun vi-prefix-numeric-value (arg)
-  "Return numeric meaning of the raw prefix argument.  This is a modification
-to the standard one provided in `callint.c' to handle (_ . CHAR) cases."
-  (cond ((null arg) 1)
-       ((integerp arg) arg)
-       ((consp arg) (if (car arg) (car arg) 1))))
-
-(defun vi-reverse-last-find-char (count &optional find-arg)
-  "Reverse last f F t T operation COUNT times.  If the optional FIND-ARG
-is given, it is used instead of the saved one."
-  (interactive "p")
-  (if (null find-arg) (setq find-arg vi-last-find-char))
-  (if (null find-arg)
-      (progn (ding) (message "No last find char to repeat."))
-    (vi-find-char (cons (* (car find-arg) -1) (cdr find-arg)) count))) ;6/13/86
-
-(defun vi-find-char (arg count)
-  "Find in DIRECTION (1/-1) for CHAR of COUNT'th times on current line.
-If UPTO-FLAG is T, stop before the char. ARG = (DIRECTION.CHAR.UPTO-FLAG."
-  (let* ((direction (car arg)) (char (car (cdr arg)))
-        (upto-flag (cdr (cdr arg))) (pos (+ (point) direction)))
-    (if (catch 'exit-find-char
-         (while t
-           (cond ((null (char-after pos)) (throw 'exit-find-char nil))
-                 ((char-equal (char-after pos) ?\n) (throw 'exit-find-char 
nil))
-                 ((char-equal char (char-after pos)) (setq count (1- count))
-                  (if (= count 0)
-                      (throw 'exit-find-char
-                             (if upto-flag
-                                 (setq pos (- pos direction))
-                               pos)))))
-           (setq pos (+ pos direction))))
-      (goto-char pos)
-    (ding))))
-
-(defun vi-repeat-last-find-char (count &optional find-arg)
-  "Repeat last f F t T operation COUNT times.  If optional FIND-ARG is given,
-it is used instead of the saved one."
-  (interactive "p")
-  (if (null find-arg) (setq find-arg vi-last-find-char))
-  (if (null find-arg)
-      (progn (ding) (message "No last find char to repeat."))
-    (vi-find-char find-arg count)))
-
-(defun vi-backward-find-char (count char)
-  "Find the COUNT'th CHAR backward on current line."
-  (interactive "p\nc")
-  (setq vi-last-find-char (cons -1 (cons char nil)))
-  (vi-repeat-last-find-char count))
-
-(defun vi-forward-find-char (count char)
-  "Find the COUNT'th CHAR forward on current line."
-  (interactive "p\nc")
-  (setq vi-last-find-char (cons 1 (cons char nil)))
-  (vi-repeat-last-find-char count))
-
-(defun vi-backward-upto-char (count char)
-  "Find up to the COUNT'th CHAR backward on current line."
-  (interactive "p\nc")
-  (setq vi-last-find-char (cons -1 (cons char t)))
-  (vi-repeat-last-find-char count))
-
-(defun vi-forward-upto-char (count char)
-  "Find up to the COUNT'th CHAR forward on current line."
-  (interactive "p\nc")
-  (setq vi-last-find-char (cons 1 (cons char t)))
-  (vi-repeat-last-find-char count))
-
-(defun vi-end-of-word (count)
-  "Move forward until encountering the end of a word.
-With argument, do this that many times."
-  (interactive "p")
-  (if (not (eobp)) (forward-char))
-  (if (re-search-forward "\\W*\\w+\\>" nil t count)
-      (backward-char)))
-
-(defun vi-replace-1-char (count char)
-  "Replace char after point by CHAR.  Repeat COUNT times."
-  (interactive "p\nc")
-  (delete-char count nil)       ; don't save in kill ring
-  (setq last-command-event char)
-  (self-insert-command count)
-  (vi-set-last-change-command 'vi-replace-1-char count char))
-
-(defun vi-replace-chars (arg)
-  "Replace chars over old ones."
-  (interactive "*p")
-  (overwrite-mode 1)
-  (vi-goto-insert-state arg))
-
-(defun vi-substitute-chars (count)
-  "Substitute COUNT chars by the input chars, enter insert state."
-  (interactive "*p")
-  (vi-goto-insert-state 1 (list (function (lambda (c) ; this is a bit tricky
-                                           (delete-region (point)
-                                                          (+ (point) c))))
-                               count) t))
-
-(defun vi-substitute-lines (count)
-  "Substitute COUNT lines by the input chars. (=cc in vi)"
-  (interactive "*p")
-  (vi-goto-insert-state 1 (list 'vi-delete-op 'next-line (1- count)) t))
-
-(defun vi-prefix-char-value (arg)
-  "Get the char part of the current prefix argument."
-  (cond ((null arg) nil)
-       ((integerp arg) nil)
-       ((consp arg) (cdr arg))
-       (t nil)))
-
-(defun vi-operator (arg)
-  "Handling vi operators (d/c/</>/!/=/y).  Current implementation requires
-the key bindings of the operators being fixed."
-  (interactive "P")
-  (catch 'vi-exit-op
-    (let ((this-op-char last-command-event))
-      (setq last-command-event (read-char))
-      (setq this-command (lookup-key vi-com-map (char-to-string 
last-command-event)))
-      (if (not (eq this-command 'vi-digit-argument))
-         (setq prefix-arg arg)
-       (vi-digit-argument arg)
-       (setq last-command-event (read-char))
-       (setq this-command (lookup-key vi-com-map (char-to-string 
last-command-event))))
-      (cond ((char-equal this-op-char last-command-event) ; line op
-            (vi-execute-op this-op-char 'next-line
-                           (cons (1- (vi-prefix-numeric-value prefix-arg))
-                                 (vi-prefix-char-value prefix-arg))))
-           ;; We assume any command that has no property 'point-moving-unit'
-           ;; as having that property with the value 'CHAR'.  3/12/86
-           (t   ;;  (get this-command 'point-moving-unit)
-            (vi-execute-op this-op-char this-command prefix-arg))))))
-           ;;   (t (throw 'vi-exit-op (ding)))))))
-
-(defun vi-execute-op (op-char motion-command arg)
-  "Execute vi edit operator as specified by OP-CHAR, the operand is the region
-determined by the MOTION-COMMAND with ARG."
-  (cond ((= op-char ?d)
-        (if (vi-delete-op motion-command arg)
-            (vi-set-last-change-command 'vi-delete-op (vi-repeat-command-of 
motion-command) arg)))
-        ((= op-char ?c)
-         (if (vi-delete-op motion-command arg)
-             (vi-goto-insert-state 1 (list 'vi-delete-op
-                             (vi-repeat-command-of motion-command) arg) nil)))
-        ((= op-char ?y)
-         (if (vi-yank-op motion-command arg)
-             (vi-set-last-change-command 'vi-yank-op (vi-repeat-command-of 
motion-command) arg)))
-        ((= op-char ?!)
-         (if (vi-shell-op motion-command arg)
-             (vi-set-last-change-command 'vi-shell-op (vi-repeat-command-of 
motion-command) arg vi-last-shell-command)))
-        ((= op-char ?<)
-         (if (vi-shift-op motion-command arg (- vi-shift-width))
-             (vi-set-last-change-command 'vi-shift-op (vi-repeat-command-of 
motion-command) arg (- vi-shift-width))))
-        ((= op-char ?>)
-         (if (vi-shift-op motion-command arg vi-shift-width)
-             (vi-set-last-change-command 'vi-shift-op (vi-repeat-command-of 
motion-command) arg vi-shift-width)))
-        ((= op-char ?=)
-         (if (vi-indent-op motion-command arg)
-             (vi-set-last-change-command 'vi-indent-op (vi-repeat-command-of 
motion-command) arg)))
-        ((= op-char ?\\)
-         (vi-narrow-op motion-command arg))))
-
-(defun vi-repeat-command-of (command)
-  "Return the command for redo the given command."
-  (let ((cmd-type (get command 'point-moving-unit)))
-    (cond ((eq cmd-type 'search) 'vi-repeat-last-search)
-         ((eq cmd-type 'find) 'vi-repeat-last-find-char)
-         (t command))))
-
-(defun vi-effective-range (motion-command arg)
-  "Return (begin . end) of the range spanned by executing the given
-MOTION-COMMAND with ARG.
-   MOTION-COMMAND in ready-to-eval list form is not yet supported."
-  (save-excursion
-    (let ((begin (point)) end opoint
-         (moving-unit (get motion-command 'point-moving-unit)))
-      (setq prefix-arg arg)
-      (setq opoint (point))
-      (command-execute motion-command nil)
-;; Check if there is any effective motion. Note that for single line operation
-;; the motion-command causes no effective point movement (since it moves up or
-;; down zero lines), but it should be counted as effectively moved.
-      (if (and (= (point) opoint) (not (eq moving-unit 'line)))
-         (cons opoint opoint)          ; no effective motion
-       (if (eq moving-unit 'region)
-           (setq begin (or (mark) (point))))
-       (if (<= begin (point))
-           (setq end (point))
-         (setq end begin)
-         (setq begin (point)))
-       (cond ((or (eq moving-unit 'match) (eq moving-unit 'find))
-              (setq end (1+ end)))
-             ((eq moving-unit 'line)
-              (goto-char begin) (beginning-of-line) (setq begin (point))
-              (goto-char end) (forward-line 1) (beginning-of-line) (setq end 
(point))))
-       (if (> end (point-max)) (setq end (point-max))) ; force in buffer region
-       (cons begin end)))))
-
-(defun vi-delete-op (motion-command arg)
-  "Delete range specified by MOTION-COMMAND with ARG."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)) reg)
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (setq reg (vi-prefix-char-value arg))
-      (if (null reg)
-         (kill-region begin end)       ; kill ring as unnamed registers
-       (if (and (>= reg ?A) (<= reg ?Z))
-           (append-to-register (downcase reg) begin end t)
-         (copy-to-register reg begin end t)))
-      t)))
-
-(defun vi-yank-op (motion-command arg)
-  "Yank (in vi sense) range specified by MOTION-COMMAND with ARG."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)) reg)
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (setq reg (vi-prefix-char-value arg))
-      (if (null reg)
-         (copy-region-as-kill begin end); kill ring as unnamed registers
-       (if (and (>= reg ?A) (<= reg ?Z))
-           (append-to-register (downcase reg) begin end nil)
-         (copy-to-register reg begin end nil)))
-      t)))
-
-(defun vi-yank-line (arg)
-  "Yank (in vi sense) lines (= `yy' command)."
-  (interactive "*P")
-  (setq arg (cons (1- (vi-prefix-numeric-value arg)) (vi-prefix-char-value 
arg)))
-  (if (vi-yank-op 'next-line arg)
-      (vi-set-last-change-command 'vi-yank-op 'next-line arg)))
-
-(defun vi-string-end-with-nl-p (string)
-  "See if STRING ends with a newline char.
-Used in checking whether the yanked text should be put back as lines or not."
-  (= (aref string (1- (length string))) ?\n))
-
-(defun vi-put-before (arg &optional after-p)
-  "Put yanked (in vi sense) text back before/above cursor.
-If a numeric prefix value (currently it should be >1) is given, put back
-text as lines.  If the optional after-p is given, put after/below the cursor."
-  (interactive "P")
-  (let ((reg (vi-prefix-char-value arg)) put-text)
-    (if (and reg (or (< reg ?1) (> reg ?9)) (null (get-register reg)))
-       (error "Nothing in register %c" reg)
-      (if (null reg) (setq reg ?1))    ; the default is the last text killed
-      (setq put-text
-           (cond
-            ((and (>= reg ?1) (<= reg ?9))
-             (setq this-command 'yank) ; So we may yank-pop !!
-             (current-kill (- reg ?0 1) 'do-not-rotate))
-            ((stringp (get-register reg)) (get-register reg))
-            (t (error "Register %c is not containing text string" reg))))
-      (if (vi-string-end-with-nl-p put-text) ; put back text as lines
-         (if after-p
-             (progn (forward-line 1) (beginning-of-line))
-           (beginning-of-line))
-       (if after-p (forward-char 1)))
-      (push-mark)
-      (insert put-text)
-      (exchange-point-and-mark)
-;;    (back-to-indentation)      ; this is not allowed if we allow yank-pop
-      (vi-set-last-change-command 'vi-put-before arg after-p))))
-
-(defun vi-put-after (arg)
-  "Put yanked (in vi sense) text back after/below cursor."
-  (interactive "P")
-  (vi-put-before arg t))
-
-(defun vi-shell-op (motion-command arg &optional shell-command)
-  "Perform shell command (as filter).
-Performs command on range specified by MOTION-COMMAND
-with ARG. If SHELL-COMMAND is not given, ask for one from minibuffer.
-If char argument is given, it directs the output to a *temp* buffer."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)))
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (cond ((null shell-command)
-            (setq shell-command (read-string "!" nil))
-            (setq vi-last-shell-command shell-command)))
-      (shell-command-on-region begin end shell-command (not 
(vi-prefix-char-value arg))
-                                                      (not 
(vi-prefix-char-value arg)))
-      t)))
-
-(defun vi-shift-op (motion-command arg amount)
-  "Perform shift command on range specified by MOTION-COMMAND with ARG for
-AMOUNT on each line.  Negative amount means shift left.
-SPECIAL FEATURE: char argument can be used to specify shift amount(1-9)."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)))
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (if (vi-prefix-char-value arg)
-         (setq amount (if (> amount 0)
-                          (- (vi-prefix-char-value arg) ?0)
-                        (- ?0 (vi-prefix-char-value arg)))))
-      (indent-rigidly begin end amount)
-      t)))
-
-(defun vi-indent-op (motion-command arg)
-  "Perform indent command on range specified by MOTION-COMMAND with ARG."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)))
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (indent-region begin end nil)    ; insert TAB as indent command
-      t)))
-
-(defun vi-narrow-op (motion-command arg)
-  "Narrow to region specified by MOTION-COMMAND with ARG."
-  (let* ((range (vi-effective-range motion-command arg))
-        (begin (car range)) (end (cdr range)))
-    (if (= begin end)
-       nil                             ; point not moved, abort op
-      (narrow-to-region begin end))))
-
-(defun vi-get-mark (char)
-  "Return contents of vi mark register named CHAR, or nil if undefined."
-  (cdr (assq char vi-mark-alist)))
-
-(defun vi-set-mark (char)
-  "Set contents of vi mark register named CHAR to current point.
-'@' is the special anonymous mark register."
-  (interactive "c")
-  (if (char-equal char ?@)
-      (set-mark-command nil)
-    (let ((aelt (assq char vi-mark-alist)))
-      (if aelt
-         (move-marker (cdr aelt) (point)) ; fixed 6/12/86
-       (setq aelt (cons char (point-marker)))
-       (setq vi-mark-alist (cons aelt vi-mark-alist))))))
-
-(defun vi-find-matching-paren ()
-  "Locate the matching paren.  It's a hack right now."
-  (interactive)
-  (cond ((looking-at "[[({]") (forward-sexp 1) (backward-char 1))
-       ((looking-at "[])}]") (forward-char 1) (backward-sexp 1))
-        (t (ding))))
-
-(defun vi-backward-blank-delimited-word (count)
-  "Backward COUNT blank-delimited words."
-  (interactive "p")
-  (if (re-search-backward "[ \t\n`][^ \t\n`]+" nil t count)
-      (if (not (bobp)) (forward-char 1))))
-
-(defun vi-forward-blank-delimited-word (count)
-  "Forward COUNT blank-delimited words."
-  (interactive "p")
-  (if (re-search-forward "[^ \t\n]*[ \t\n]+[^ \t\n]" nil t count)
-      (if (not (eobp)) (backward-char 1))))
-
-(defun vi-end-of-blank-delimited-word (count)
-  "Forward to the end of the COUNT'th blank-delimited word."
-  (interactive "p")
-  (if (re-search-forward "[^ \t\n']+[ \t\n']" nil t count)
-      (if (not (eobp)) (backward-char 2))))
-
-(defun vi-home-window-line (arg)
-  "To window home or arg'th line from the top of the window."
-  (interactive "p")
-  (move-to-window-line (1- arg))
-  (back-to-indentation))
-
-(defun vi-last-window-line (arg)
-  "To window last line or arg'th line from the bottom of the window."
-  (interactive "p")
-  (move-to-window-line (- arg))
-  (back-to-indentation))
-
-(defun vi-middle-window-line ()
-  "To the middle line of the window."
-  (interactive)
-  (move-to-window-line nil)
-  (back-to-indentation))
-
-(defun vi-forward-word (count)
-  "Stop at the beginning of the COUNT'th words from point."
-  (interactive "p")
-  (if (re-search-forward "\\w*\\W+\\<" nil t count)
-      t
-    (vi-ding)))
-
-(defun vi-set-last-change-command (fun &rest args)
-  "Set (FUN . ARGS) as the `last-change-command'."
-  (setq vi-last-change-command (cons fun args)))
-
-(defun vi-redo-last-change-command (count &optional command)
-  "Redo last change command COUNT times.  If the optional COMMAND is given,
-it is used instead of the current `last-change-command'."
-  (interactive "p")
-  (if (null command)
-      (setq command vi-last-change-command))
-  (if (null command)
-      (message "No last change command available.")
-    (while (> count 0)
-      (apply (car command) (cdr command))
-      (setq count (1- count)))))
-
-(defun vi-kill-char (count)
-  "Kill COUNT chars from current point."
-  (interactive "*p")
-  (delete-char count t)                        ; save in kill ring
-  (vi-set-last-change-command 'delete-char count t))
-
-(defun vi-transpose-objects (arg unit)
-  "Transpose objects.
-The following char specifies unit of objects to be
-transposed -- \"c\" for chars, \"l\" for lines, \"w\" for words, \"s\" for
- sexp, \"p\" for paragraph.
-For the use of the prefix-arg, refer to individual functions called."
-  (interactive "*P\nc")
-  (if (char-equal unit ??)
-      (progn
-       (message "Transpose: c(har), l(ine), p(aragraph), s(-exp), w(ord),")
-       (setq unit (read-char))))
-  (vi-set-last-change-command 'vi-transpose-objects arg unit)
-  (cond ((char-equal unit ?c) (transpose-chars arg))
-       ((char-equal unit ?l) (transpose-lines (vi-prefix-numeric-value arg)))
-       ((char-equal unit ?p) (transpose-paragraphs (vi-prefix-numeric-value 
arg)))
-       ((char-equal unit ?s) (transpose-sexps (vi-prefix-numeric-value arg)))
-       ((char-equal unit ?w) (transpose-words (vi-prefix-numeric-value arg)))
-       (t (vi-transpose-objects arg ??))))
-
-(defun vi-query-replace (arg)
-  "Query replace, use regexp version if ARG is non-nil."
-  (interactive "*P")
-  (let ((rcmd (if arg 'query-replace-regexp 'query-replace)))
-    (call-interactively rcmd nil)))
-
-(defun vi-replace (arg)
-  "Replace strings, use regexp version if ARG is non-nil."
-  (interactive "*P")
-  (let ((rcmd (if arg 'replace-regexp 'replace-string)))
-    (call-interactively rcmd nil)))
-
-(defun vi-adjust-window (arg position)
-  "Move current line to the top/center/bottom of the window."
-  (interactive "p\nc")
-  (cond ((char-equal position ?\r) (recenter 0))
-       ((char-equal position ?-) (recenter -1))
-       ((char-equal position ?.) (recenter (/ (window-height) 2)))
-       (t (message "Move current line to: \\r(top) -(bottom) .(middle)")
-          (setq position (read-char))
-          (vi-adjust-window arg position))))
-
-(defun vi-goto-column (col)
-  "Go to given column of the current line."
-  (interactive "p")
-  (let ((opoint (point)))
-    (beginning-of-line)
-    (while (> col 1)
-      (if (eolp)
-         (setq col 0)
-       (forward-char 1)
-       (setq col (1- col))))
-    (if (= col 1)
-       t
-      (goto-char opoint)
-      (ding))))
-
-(defun vi-name-last-change-or-macro (arg char)
-  "Give name to the last change command or just defined kbd macro.
-If prefix ARG is given, name last macro, otherwise name last change command.
-The following CHAR will be the name for the command or macro."
-  (interactive "P\nc")
-  (if arg
-      (name-last-kbd-macro (intern (char-to-string char)))
-    (if (eq (car vi-last-change-command) 'vi-first-redo-insertion)
-       (let* ((args (cdr vi-last-change-command)) ; save the insertion text
-              (str (buffer-substring (nth 0 args) (nth 1 args)))
-              (overwrite-p (nth 2 args))
-              (prefix-code (nth 3 args)))
-         (vi-set-last-change-command 'vi-more-redo-insertion str
-                                  overwrite-p prefix-code)))
-    (fset (intern (char-to-string char)) vi-last-change-command)))
-
-(defun vi-call-named-change-or-macro (count char)
-  "Execute COUNT times the keyboard macro definition named by the following 
CHAR."
-  (interactive "p\nc")
-  (if (stringp (symbol-function (intern (char-to-string char))))
-      (execute-kbd-macro (intern (char-to-string char)) count)
-    (vi-redo-last-change-command count (symbol-function (intern 
(char-to-string char))))))
-
-(defun vi-change-case (arg)            ; could be made as an operator ?
-  "Change the case of the char after point."
-  (interactive "*p")
-  (catch 'exit
-    (if (looking-at "[a-z]")
-       (upcase-region (point) (+ (point) arg))
-      (if (looking-at "[A-Z]")
-         (downcase-region (point) (+ (point) arg))
-       (ding)
-       (throw 'exit nil)))
-    (vi-set-last-change-command 'vi-change-case arg) ;should avoid redundant 
save
-    (forward-char arg)))
-
-(defun vi-ask-for-info (char)
-  "Inquire status info. The next CHAR will specify the particular info 
requested."
-  (interactive "c")
-  (cond ((char-equal char ?l) (what-line))
-       ((char-equal char ?c) (what-cursor-position))
-       ((char-equal char ?p) (what-page))
-       (t (message "Ask for: l(ine number), c(ursor position), p(age number)")
-          (setq char (read-char))
-          (vi-ask-for-info char))))
-
-(declare-function c-mark-function "cc-cmds" ())
-
-(defun vi-mark-region (arg region)
-  "Mark region appropriately.  The next char REGION is 
d(efun),s(-exp),b(uffer),
-p(aragraph), P(age), f(unction in C/Pascal etc.), w(ord), e(nd of sentence),
-l(ines)."
-  (interactive "p\nc")
-  (cond ((char-equal region ?d) (mark-defun))
-       ((char-equal region ?s) (mark-sexp arg))
-       ((char-equal region ?b) (with-no-warnings (mark-whole-buffer)))
-       ((char-equal region ?p) (mark-paragraph))
-       ((char-equal region ?P) (mark-page arg))
-       ((char-equal region ?f) (c-mark-function))
-       ((char-equal region ?w) (mark-word arg))
-       ((char-equal region ?e) (mark-end-of-sentence arg))
-       ((char-equal region ?l) (vi-mark-lines arg))
-       (t (message "Mark: 
d(efun),s(-exp),b(uf),p(arag),P(age),f(unct),w(ord),e(os),l(ines)")
-          (setq region (read-char))
-          (vi-mark-region arg region))))
-
-(defun vi-mark-lines (num)
-  "Mark NUM of lines from current line as current region."
-  (beginning-of-line 1)
-  (push-mark)
-  (end-of-line num))
-
-(defun vi-verify-spelling (arg unit)
-  "Verify spelling for the objects specified by char UNIT : [b(uffer),
-r(egion), s(tring), w(ord) ]."
-  (interactive "P\nc")
-  (setq prefix-arg arg)                        ; seems not needed
-  (cond ((char-equal unit ?b) (call-interactively 'spell-buffer))
-       ((char-equal unit ?r) (call-interactively 'spell-region))
-       ((char-equal unit ?s) (call-interactively 'spell-string))
-       ((char-equal unit ?w) (call-interactively 'spell-word))
-       (t (message "Spell check: b(uffer), r(egion), s(tring), w(ord)")
-          (setq unit (read-char))
-          (vi-verify-spelling arg unit))))
-
-(defun vi-do-old-mode-C-c-command (arg)
-  "This is a hack for accessing mode specific C-c commands in vi-mode."
-  (interactive "P")
-  (let ((cmd (lookup-key vi-mode-old-local-map
-                        (concat "\C-c" (char-to-string (read-char))))))
-    (if (catch 'exit-vi-mode   ; kludge hack due to dynamic binding
-                               ; of case-fold-search
-         (if (null cmd)
-             (progn (ding) nil)
-           (let ((case-fold-search vi-mode-old-case-fold)) ; a hack
-             (setq prefix-arg arg)
-             (command-execute cmd nil)
-             nil)))
-       (progn
-         (vi-back-to-old-mode)
-         (setq prefix-arg arg)
-         (command-execute cmd nil)))))
-
-(defun vi-quote-words (arg char)
-  "Quote ARG words from the word point is on with pattern specified by CHAR.
-Currently, CHAR could be [,{,(,\",',`,<,*, etc."
-  (interactive "*p\nc")
-  (while (not (string-match "[[({<\"'`*]" (char-to-string char)))
-    (message "Enter any of [,{,(,<,\",',`,* as quoting character.")
-    (setq char (read-char)))
-  (vi-set-last-change-command 'vi-quote-words arg char)
-  (if (not (looking-at "\\<")) (forward-word -1))
-  (insert char)
-  (cond ((char-equal char ?\[) (setq char ?\]))
-       ((char-equal char ?{) (setq char ?}))
-       ((char-equal char ?<) (setq char ?>))
-       ((char-equal char ?\() (setq char ?\)))
-       ((char-equal char ?`) (setq char ?')))
-  (vi-end-of-word arg)
-  (forward-char 1)
-  (insert char))
-
-(defun vi-locate-def ()
-  "Locate definition in current file for the name before the point.
-It assumes a `(def..' always starts at the beginning of a line."
-  (interactive)
-  (let (name)
-    (save-excursion
-      (setq name (buffer-substring (progn (vi-backward-blank-delimited-word 1)
-                                         (skip-chars-forward "^a-zA-Z")
-                                         (point))
-                                  (progn (vi-end-of-blank-delimited-word 1)
-                                         (forward-char)
-                                         (skip-chars-backward "^a-zA-Z")
-                                         (point)))))
-    (set-mark-command nil)
-    (goto-char (point-min))
-    (if (re-search-forward (concat "^(def[unvarconst ]*" name) nil t)
-       nil
-      (ding)
-      (message "No definition for \"%s\" in current file." name)
-      (set-mark-command t))))
-
-(defun vi-split-open-line (arg)
-  "Insert a newline and leave point before it.
-With ARG, inserts that many newlines."
-  (interactive "*p")
-  (vi-goto-insert-state 1
-    (list (function (lambda (arg)
-                     (let ((flag (and (bolp) (not (bobp)))))
-                       (if flag (forward-char -1))
-                       (while (> arg 0)
-                         (save-excursion
-                           (insert ?\n)
-                           (if fill-prefix (insert fill-prefix)))
-                         (setq arg (1- arg)))
-                       (if flag (forward-char 1))))) arg)
-    t))
-
-(provide 'vi)
-
-;;; vi.el ends here
diff --git a/lisp/obsolete/vip.el b/lisp/obsolete/vip.el
deleted file mode 100644
index eecedbd5e74..00000000000
--- a/lisp/obsolete/vip.el
+++ /dev/null
@@ -1,3050 +0,0 @@
-;;; vip.el --- a VI Package for GNU Emacs  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1986-1988, 1992-1993, 1998, 2001-2024 Free Software
-;; Foundation, Inc.
-
-;; Author: Masahiko Sato <ms@sail.stanford.edu>
-;; Keywords: emulations
-;; Obsolete-since: 24.5
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This file is obsolete.  Consider using viper instead.
-
-;; A full-featured vi(1) emulator.
-;;
-;; In Japan, the author's address is: masahiko@sato.riec.tohoku.junet
-;;
-;; Send suggestions and bug reports to one of the above addresses.
-;; When you report a bug, be sure to include the version number of VIP and
-;; Emacs you are using.
-
-;; Execute info command by typing "M-x info" to get information on VIP.
-
-;;; Code:
-
-(defgroup vip nil
-  "A VI Package for GNU Emacs."
-  :prefix "vip-"
-  :group 'emulations)
-
-;; external variables
-
-(defvar vip-emacs-local-map nil
-  "Local map used in Emacs mode.  (Buffer-specific.)")
-
-(defvar vip-insert-local-map nil
-  "Local map used in insert command mode.  (Buffer-specific.)")
-
-(make-variable-buffer-local 'vip-emacs-local-map)
-(make-variable-buffer-local 'vip-insert-local-map)
-
-(defvar vip-insert-point nil
-  "Remember insert point as a marker.  (Buffer-specific.)")
-
-(set-default 'vip-insert-point (make-marker))
-(make-variable-buffer-local 'vip-insert-point)
-
-(defvar vip-com-point nil
-  "Remember com point as a marker.  (Buffer-specific.)")
-
-(set-default 'vip-com-point (make-marker))
-(make-variable-buffer-local 'vip-com-point)
-
-(defvar vip-current-mode nil
-  "Current mode.  One of `emacs-mode', `vi-mode', `insert-mode'.")
-
-(make-variable-buffer-local 'vip-current-mode)
-(setq-default vip-current-mode 'emacs-mode)
-
-(defvar vip-emacs-mode-line-buffer-identification nil
-  "Value of mode-line-buffer-identification in Emacs mode within vip.")
-(make-variable-buffer-local 'vip-emacs-mode-line-buffer-identification)
-(setq-default vip-emacs-mode-line-buffer-identification
-             '("Emacs: %17b"))
-
-(defvar vip-current-major-mode nil
-  "vip-current-major-mode is the major-mode vi considers it is now.
-\(buffer specific)")
-
-(make-variable-buffer-local 'vip-current-major-mode)
-
-(defvar vip-last-shell-com nil
-  "Last shell command executed by ! command.")
-
-(defvar vip-use-register nil
-  "Name of register to store deleted or yanked strings.")
-
-(defvar vip-d-com nil
-  "How to reexecute last destructive command.  Value is list (M-COM VAL COM).")
-
-(defcustom vip-shift-width 8
-  "The number of columns shifted by > and < command."
-  :type 'integer)
-
-(defcustom vip-re-replace nil
-  "If t then do regexp replace, if nil then do string replace."
-  :type 'boolean)
-
-(defvar vip-d-char nil
-  "The character remembered by the vi \"r\" command.")
-
-(defvar vip-f-char nil
-  "For use by \";\" command.")
-
-(defvar vip-F-char nil
-  "For use by \".\" command.")
-
-(defvar vip-f-forward nil
-  "For use by \";\" command.")
-
-(defvar vip-f-offset nil
-  "For use by \";\" command.")
-
-(defcustom vip-search-wrap-around t
-  "If t, search wraps around."
-  :type 'boolean)
-
-(defcustom vip-re-search nil
-  "If t, search is reg-exp search, otherwise vanilla search."
-  :type 'boolean)
-
-(defvar vip-s-string nil
-  "Last vip search string.")
-
-(defvar vip-s-forward nil
-  "If t, search is forward.")
-
-(defcustom vip-case-fold-search nil
-  "If t, search ignores cases."
-  :type 'boolean)
-
-(defcustom vip-re-query-replace nil
-  "If t then do regexp replace, if nil then do string replace."
-  :type 'boolean)
-
-(defcustom vip-open-with-indent nil
-  "If t, indent when open a new line."
-  :type 'boolean)
-
-(defcustom vip-help-in-insert-mode nil
-  "If t then C-h is bound to help-command in insert mode.
-If nil then it is bound to `delete-backward-char'."
-  :type 'boolean)
-
-(defvar vip-quote-string "> "
-  "String inserted at the beginning of region.")
-
-(defvar vip-tags-file-name "TAGS")
-
-(defvar vip-inhibit-startup-message nil)
-
-(defvar vip-startup-file (locate-user-emacs-file "vip" ".vip")
-  "Filename used as startup file for vip.")
-
-;; key bindings
-
-(defvar vip-mode-map
-  (let ((map (make-keymap)))
-    (define-key map "\C-a" #'beginning-of-line)
-    (define-key map "\C-b" #'vip-scroll-back)
-    (define-key map "\C-c" #'vip-ctl-c)
-    (define-key map "\C-d" #'vip-scroll-up)
-    (define-key map "\C-e" #'vip-scroll-up-one)
-    (define-key map "\C-f" #'vip-scroll)
-    (define-key map "\C-g" #'vip-keyboard-quit)
-    (define-key map "\C-h" #'help-command)
-    (define-key map "\C-m" #'vip-scroll-back)
-    (define-key map "\C-n" #'vip-other-window)
-    (define-key map "\C-o" #'vip-open-line-at-point)
-    (define-key map "\C-u" #'vip-scroll-down)
-    (define-key map "\C-x" #'vip-ctl-x)
-    (define-key map "\C-y" #'vip-scroll-down-one)
-    (define-key map "\C-z" #'vip-change-mode-to-emacs)
-    (define-key map "\e" #'vip-ESC)
-
-    (define-key map [?\S-\ ] #'vip-scroll-back)
-    (define-key map " " #'vip-scroll)
-    (define-key map "!" #'vip-command-argument)
-    (define-key map "\"" #'vip-command-argument)
-    (define-key map "#" #'vip-command-argument)
-    (define-key map "$" #'vip-goto-eol)
-    (define-key map "%" #'vip-paren-match)
-    (define-key map "&" #'vip-nil)
-    (define-key map "'" #'vip-goto-mark-and-skip-white)
-    (define-key map "(" #'vip-backward-sentence)
-    (define-key map ")" #'vip-forward-sentence)
-    (define-key map "*" #'call-last-kbd-macro)
-    (define-key map "+" #'vip-next-line-at-bol)
-    (define-key map "," #'vip-repeat-find-opposite)
-    (define-key map "-" #'vip-previous-line-at-bol)
-    (define-key map "." #'vip-repeat)
-    (define-key map "/" #'vip-search-forward)
-
-    (define-key map "0" #'vip-beginning-of-line)
-    (define-key map "1" #'vip-digit-argument)
-    (define-key map "2" #'vip-digit-argument)
-    (define-key map "3" #'vip-digit-argument)
-    (define-key map "4" #'vip-digit-argument)
-    (define-key map "5" #'vip-digit-argument)
-    (define-key map "6" #'vip-digit-argument)
-    (define-key map "7" #'vip-digit-argument)
-    (define-key map "8" #'vip-digit-argument)
-    (define-key map "9" #'vip-digit-argument)
-
-    (define-key map ":" #'vip-ex)
-    (define-key map ";" #'vip-repeat-find)
-    (define-key map "<" #'vip-command-argument)
-    (define-key map "=" #'vip-command-argument)
-    (define-key map ">" #'vip-command-argument)
-    (define-key map "?" #'vip-search-backward)
-    (define-key map "@" #'vip-nil)
-
-    (define-key map "A" #'vip-Append)
-    (define-key map "B" #'vip-backward-Word)
-    (define-key map "C" #'vip-ctl-c-equivalent)
-    (define-key map "D" #'vip-kill-line)
-    (define-key map "E" #'vip-end-of-Word)
-    (define-key map "F" #'vip-find-char-backward)
-    (define-key map "G" #'vip-goto-line)
-    (define-key map "H" #'vip-window-top)
-    (define-key map "I" #'vip-Insert)
-    (define-key map "J" #'vip-join-lines)
-    (define-key map "K" #'vip-kill-buffer)
-    (define-key map "L" #'vip-window-bottom)
-    (define-key map "M" #'vip-window-middle)
-    (define-key map "N" #'vip-search-Next)
-    (define-key map "O" #'vip-Open-line)
-    (define-key map "P" #'vip-Put-back)
-    (define-key map "Q" #'vip-query-replace)
-    (define-key map "R" #'vip-replace-string)
-    (define-key map "S" #'vip-switch-to-buffer-other-window)
-    (define-key map "T" #'vip-goto-char-backward)
-    (define-key map "U" #'vip-nil)
-    (define-key map "V" #'vip-find-file-other-window)
-    (define-key map "W" #'vip-forward-Word)
-    (define-key map "X" #'vip-ctl-x-equivalent)
-    (define-key map "Y" #'vip-yank-line)
-    (define-key map "ZZ" #'save-buffers-kill-emacs)
-
-    (define-key map "[" #'vip-nil)
-    (define-key map "\\" #'vip-escape-to-emacs)
-    (define-key map "]" #'vip-nil)
-    (define-key map "^" #'vip-bol-and-skip-white)
-    (define-key map "_" #'vip-nil)
-    (define-key map "`" #'vip-goto-mark)
-
-    (define-key map "a" #'vip-append)
-    (define-key map "b" #'vip-backward-word)
-    (define-key map "c" #'vip-command-argument)
-    (define-key map "d" #'vip-command-argument)
-    (define-key map "e" #'vip-end-of-word)
-    (define-key map "f" #'vip-find-char-forward)
-    (define-key map "g" #'vip-info-on-file)
-    (define-key map "h" #'vip-backward-char)
-    (define-key map "i" #'vip-insert)
-    (define-key map "j" #'vip-next-line)
-    (define-key map "k" #'vip-previous-line)
-    (define-key map "l" #'vip-forward-char)
-    (define-key map "m" #'vip-mark-point)
-    (define-key map "n" #'vip-search-next)
-    (define-key map "o" #'vip-open-line)
-    (define-key map "p" #'vip-put-back)
-    (define-key map "q" #'vip-nil)
-    (define-key map "r" #'vip-replace-char)
-    (define-key map "s" #'vip-switch-to-buffer)
-    (define-key map "t" #'vip-goto-char-forward)
-    (define-key map "u" #'vip-undo)
-    (define-key map "v" #'vip-find-file)
-    (define-key map "w" #'vip-forward-word)
-    (define-key map "x" #'vip-delete-char)
-    (define-key map "y" #'vip-command-argument)
-    (define-key map "zH" #'vip-line-to-top)
-    (define-key map "zM" #'vip-line-to-middle)
-    (define-key map "zL" #'vip-line-to-bottom)
-    (define-key map "z\C-m" #'vip-line-to-top)
-    (define-key map "z." #'vip-line-to-middle)
-    (define-key map "z-" #'vip-line-to-bottom)
-
-    (define-key map "{" #'vip-backward-paragraph)
-    (define-key map "|" #'vip-goto-col)
-    (define-key map "}" #'vip-forward-paragraph)
-    (define-key map "~" #'vip-nil)
-    (define-key map "\177" #'vip-delete-backward-char)
-    map))
-
-(defun vip-version ()
-  (interactive)
-  (message "VIP version 3.5 of September 15, 1987"))
-
-
-;; basic set up
-
-;;;###autoload
-(defun vip-setup ()
-  "Set up bindings for C-x 7 and C-z that are useful for VIP users."
-  (define-key ctl-x-map "7" #'vip-buffer-in-two-windows)
-  (global-set-key "\C-z" #'vip-change-mode-to-vi))
-
-(defmacro vip-loop (count body)
-  "(COUNT BODY) Execute BODY COUNT times."
-  `(let ((count ,count))
-     (while (> count 0)
-       ,body
-       (setq count (1- count)))))
-
-(defun vip-push-mark-silent (&optional location)
-  "Set mark at LOCATION (point, by default) and push old mark on mark ring.
-No message."
-  (if (null (mark t))
-      nil
-    (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
-    (if (> (length mark-ring) mark-ring-max)
-       (progn
-         (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
-         (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
-  (set-mark (or location (point))))
-
-(defun vip-goto-col (arg)
-  "Go to ARG's column."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (save-excursion
-      (end-of-line)
-      (if (> val (1+ (current-column))) (error "")))
-    (if com (move-marker vip-com-point (point)))
-    (beginning-of-line)
-    (forward-char (1- val))
-    (if com (vip-execute-com 'vip-goto-col val com))))
-
-(defun vip-copy-keymap (map)
-  (if (null map) (make-sparse-keymap) (copy-keymap map)))
-
-
-;; changing mode
-
-(defun vip-change-mode (new-mode)
-  "Change mode to NEW-MODE---either emacs-mode, vi-mode, or insert-mode."
-  (or (eq new-mode vip-current-mode)
-      (progn
-       (cond ((eq new-mode 'vi-mode)
-              (if (eq vip-current-mode 'insert-mode)
-                  (progn
-                    (vip-copy-region-as-kill (point) vip-insert-point)
-                    (vip-repeat-insert-command))
-                (setq vip-emacs-local-map (current-local-map)
-                      vip-emacs-mode-line-buffer-identification
-                      mode-line-buffer-identification
-                      vip-insert-local-map (vip-copy-keymap
-                                            (current-local-map))))
-              (vip-change-mode-line "Vi:   ")
-              (use-local-map vip-mode-map))
-             ((eq new-mode 'insert-mode)
-              (move-marker vip-insert-point (point))
-              (if (eq vip-current-mode 'emacs-mode)
-                  (setq vip-emacs-local-map (current-local-map)
-                        vip-emacs-mode-line-buffer-identification
-                        mode-line-buffer-identification
-                        vip-insert-local-map (vip-copy-keymap
-                                              (current-local-map)))
-                (setq vip-insert-local-map (vip-copy-keymap
-                                            vip-emacs-local-map)))
-              (vip-change-mode-line "Insert")
-              (use-local-map vip-insert-local-map)
-              (define-key vip-insert-local-map "\e" #'vip-change-mode-to-vi)
-              (define-key vip-insert-local-map "\C-z" #'vip-ESC)
-              (define-key vip-insert-local-map "\C-h"
-                (if vip-help-in-insert-mode #'help-command
-                  #'delete-backward-char))
-              (define-key vip-insert-local-map "\C-w"
-                #'vip-delete-backward-word))
-             ((eq new-mode 'emacs-mode)
-              (vip-change-mode-line "Emacs:")
-              (use-local-map vip-emacs-local-map)))
-       (setq vip-current-mode new-mode)
-       (force-mode-line-update))))
-
-(defun vip-copy-region-as-kill (beg end)
-  "If BEG and END do not belong to the same buffer, it copies empty region."
-  (condition-case nil
-      (copy-region-as-kill beg end)
-    (error (copy-region-as-kill beg beg))))
-
-(defun vip-change-mode-line (string)
-  "Assuming that the mode line format contains the string \"Emacs:\", this
-function replaces the string by \"Vi:   \" etc."
-  (setq mode-line-buffer-identification
-       (if (string= string "Emacs:")
-           vip-emacs-mode-line-buffer-identification
-         (list (concat string " %17b")))))
-
-;;;###autoload
-(defun vip-mode ()
-  "Turn on VIP emulation of VI."
-  (interactive)
-  (if (not vip-inhibit-startup-message)
-      (progn
-       (switch-to-buffer "VIP Startup Message")
-       (erase-buffer)
-       (insert
-        "VIP is a Vi emulation package for GNU Emacs.  VIP provides most Vi 
commands
-including Ex commands.  VIP is however different from Vi in several points.
-You can get more information on VIP by:
-    1.  Typing `M-x info' and selecting menu item \"vip\".
-    2.  Typing `C-h k' followed by a key whose description you want.
-    3.  Printing VIP manual which can be found as GNU/man/vip.texinfo
-    4.  Printing VIP Reference Card which can be found as GNU/etc/vipcard.tex
-
-This startup message appears whenever you load VIP unless you type `y' now.
-Type `n' to quit this window for now.\n")
-       (goto-char (point-min))
-       (if (y-or-n-p "Inhibit VIP startup message? ")
-           (progn
-             (with-current-buffer
-                  (find-file-noselect
-                   (substitute-in-file-name vip-startup-file))
-               (goto-char (point-max))
-               (insert "\n(setq vip-inhibit-startup-message t)\n")
-               (save-buffer)
-               (kill-buffer (current-buffer)))
-             (message "VIP startup message inhibited.")
-             (sit-for 2)))
-       (kill-buffer (current-buffer))
-       (message "")
-       (setq vip-inhibit-startup-message t)))
-  (vip-change-mode-to-vi))
-
-(defun vip-change-mode-to-vi ()
-  "Change mode to vi mode."
-  (interactive)
-  (vip-change-mode 'vi-mode))
-
-(defun vip-change-mode-to-insert ()
-  "Change mode to insert mode."
-  (interactive)
-  (vip-change-mode 'insert-mode))
-
-(defun vip-change-mode-to-emacs ()
-  "Change mode to Emacs mode."
-  (interactive)
-  (vip-change-mode 'emacs-mode))
-
-
-;; escape to emacs mode temporarily
-
-(defun vip-escape-to-emacs (arg &optional events)
-  "Escape to Emacs mode for one Emacs command.
-ARG is used as the prefix value for the executed command.  If
-EVENTS is a list of events, which become the beginning of the command."
-  (interactive "P")
-  (let (com (old-map (current-local-map)))
-    (if events (setq unread-command-events
-                     (append events unread-command-events)))
-    (setq prefix-arg arg)
-    (use-local-map vip-emacs-local-map)
-    (unwind-protect
-       (setq com (key-binding (read-key-sequence nil)))
-      (use-local-map old-map))
-    (command-execute com prefix-arg)
-    (setq prefix-arg nil)  ;; reset prefix arg
-    ))
-
-(defun vip-message-conditions (conditions)
-  "Print CONDITIONS as a message."
-  (let ((case (car conditions)) (msg (cdr conditions)))
-    (if (null msg)
-       (message "%s" case)
-      (message "%s %s" case (prin1-to-string msg)))
-    (ding)))
-
-(defun vip-ESC (arg)
-  "Emulate ESC key in Emacs mode."
-  (interactive "P")
-  (vip-escape-to-emacs arg '(?\e)))
-
-(defun vip-ctl-c (arg)
-  "Emulate C-c key in Emacs mode."
-  (interactive "P")
-  (vip-escape-to-emacs arg '(?\C-c)))
-
-(defun vip-ctl-x (arg)
-  "Emulate C-x key in Emacs mode."
-  (interactive "P")
-  (vip-escape-to-emacs arg '(?\C-x)))
-
-(defun vip-ctl-h (arg)
-  "Emulate C-h key in Emacs mode."
-  (interactive "P")
-  (vip-escape-to-emacs arg '(?\C-h)))
-
-
-;; prefix argument for vi mode
-
-;; In vi mode, prefix argument is a dotted pair (NUM . COM) where NUM
-;; represents the numeric value of the prefix argument and COM represents
-;; command prefix such as "c", "d", "m" and "y".
-
-(defun vip-prefix-arg-value (char value com)
-  "Compute numeric prefix arg value.  Invoked by CHAR.  VALUE is the value
-obtained so far, and COM is the command part obtained so far."
-  (while (and (>= char ?0) (<= char ?9))
-    (setq value (+ (* (if (numberp value) value 0) 10) (- char ?0)))
-    (setq char (read-char)))
-  (setq prefix-arg value)
-  (if com (setq prefix-arg (cons prefix-arg com)))
-  (while (= char ?U)
-    (vip-describe-arg prefix-arg)
-    (setq char (read-char)))
-  (push char unread-command-events))
-
-(defun vip-prefix-arg-com (char value com)
-  "Vi operator as prefix argument."
-  (let ((cont t))
-    (while (and cont
-               (or (= char ?c) (= char ?d) (= char ?y)
-                   (= char ?!) (= char ?<) (= char ?>) (= char ?=)
-                   (= char ?#) (= char ?r) (= char ?R) (= char ?\")))
-      (if com
-         ;; this means that we already have a command character, so we
-         ;; construct a com list and exit while.  however, if char is "
-         ;; it is an error.
-         (progn
-           ;; new com is (CHAR . OLDCOM)
-           (if (or (= char ?#) (= char ?\")) (error ""))
-           (setq com (cons char com))
-           (setq cont nil))
-       ;; if com is nil we set com as char, and read more.  again, if char
-       ;; is ", we read the name of register and store it in vip-use-register.
-       ;; if char is !, =, or #, a complete com is formed so we exit while.
-       (cond ((or (= char ?!) (= char ?=))
-              (setq com char)
-              (setq char (read-char))
-              (setq cont nil))
-             ((= char ?#)
-              ;; read a char and encode it as com
-              (setq com (+ 128 (read-char)))
-              (setq char (read-char))
-              (setq cont nil))
-             ((or (= char ?<) (= char ?>))
-              (setq com char)
-              (setq char (read-char))
-              (if (= com char) (setq com (cons char com)))
-              (setq cont nil))
-             ((= char ?\")
-              (let ((reg (read-char)))
-                (if (or (and (<= ?A reg) (<= reg ?z))
-                        (and (<= ?1 reg) (<= reg ?9)))
-                    (setq vip-use-register reg)
-                  (error ""))
-                (setq char (read-char))))
-             (t
-              (setq com char)
-              (setq char (read-char)))))))
-  (if (atom com)
-      ;; com is a single char, so we construct prefix-arg
-      ;; and if char is ?, describe prefix arg, otherwise exit by
-      ;; pushing the char back
-      (progn
-       (setq prefix-arg (cons value com))
-       (while (= char ?U)
-         (vip-describe-arg prefix-arg)
-         (setq char (read-char)))
-       (push char unread-command-events))
-    ;; as com is non-nil, this means that we have a command to execute
-    (if (or (= (car com) ?r) (= (car com) ?R))
-       ;; execute appropriate region command.
-       (let ((char (car com)) (com (cdr com)))
-         (setq prefix-arg (cons value com))
-         (if (= char ?r) (vip-region prefix-arg)
-           (vip-Region prefix-arg))
-         ;; reset prefix-arg
-         (setq prefix-arg nil))
-      ;; otherwise, reset prefix arg and call appropriate command
-      (setq value (if (null value) 1 value))
-      (setq prefix-arg nil)
-      (cond ((equal com '(?c . ?c)) (vip-line (cons value ?C)))
-           ((equal com '(?d . ?d)) (vip-line (cons value ?D)))
-           ((equal com '(?d . ?y)) (vip-yank-defun))
-           ((equal com '(?y . ?y)) (vip-line (cons value ?Y)))
-           ((equal com '(?< . ?<)) (vip-line (cons value ?<)))
-           ((equal com '(?> . ?>)) (vip-line (cons value ?>)))
-           ((equal com '(?! . ?!)) (vip-line (cons value ?!)))
-           ((equal com '(?= . ?=)) (vip-line (cons value ?=)))
-           (t (error ""))))))
-
-(defun vip-describe-arg (arg)
-  (let (val com)
-    (setq val (vip-P-val arg)
-         com (vip-getcom arg))
-    (if (null val)
-       (if (null com)
-           (message "Value is nil, and command is nil.")
-         (message "Value is nil, and command is %c." com))
-      (if (null com)
-         (message "Value is %d, and command is nil." val)
-       (message "Value is %d, and command is %c." val com)))))
-
-(defun vip-digit-argument (arg)
-  "Begin numeric argument for the next command."
-  (interactive "P")
-  (vip-prefix-arg-value last-command-event nil
-                       (if (consp arg) (cdr arg) nil)))
-
-(defun vip-command-argument (arg)
-  "Accept a motion command as an argument."
-  (interactive "P")
-  (condition-case nil
-      (vip-prefix-arg-com
-       last-command-event
-       (cond ((null arg) nil)
-            ((consp arg) (car arg))
-            ((numberp arg) arg)
-             (t (error "Strange arg")))
-       (cond ((null arg) nil)
-            ((consp arg) (cdr arg))
-            ((numberp arg) nil)
-             (t (error "Strange arg"))))
-    (quit
-     (setq vip-use-register nil)
-     (signal 'quit nil))))
-
-(defun vip-p-val (arg)
-  "Get value part of prefix-argument ARG."
-  (cond ((null arg) 1)
-       ((consp arg) (if (null (car arg)) 1 (car arg)))
-       (t arg)))
-
-(defun vip-P-val (arg)
-  "Get value part of prefix-argument ARG."
-  (cond ((consp arg) (car arg))
-       (t arg)))
-
-(defun vip-getcom (arg)
-  "Get com part of prefix-argument ARG."
-  (cond ((null arg) nil)
-       ((consp arg) (cdr arg))
-       (t nil)))
-
-(defun vip-getCom (arg)
-  "Get com part of prefix-argument ARG and modify it."
-  (let ((com (vip-getcom arg)))
-    (cond ((equal com ?c) ?C)
-         ((equal com ?d) ?D)
-         ((equal com ?y) ?Y)
-         (t com))))
-
-
-;; repeat last destructive command
-
-(defun vip-append-to-register (reg start end)
-  "Append region to text in register REG.
-START and END are buffer positions indicating what to append."
-  (set-register reg (concat (or (get-register reg) "")
-                           (buffer-substring start end))))
-
-(defun vip-execute-com (m-com val com)
-  "(M-COM VAL COM)  Execute command COM. The list (M-COM VAL COM) is set
-to vip-d-com for later use by vip-repeat"
-  (let ((reg vip-use-register))
-    (if com
-       (cond ((= com ?c) (vip-change vip-com-point (point)))
-             ((= com (- ?c)) (vip-change-subr vip-com-point (point)))
-             ((or (= com ?C) (= com (- ?C)))
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (if vip-use-register
-                    (progn
-                      (cond ((and (<= ?a vip-use-register)
-                                  (<= vip-use-register ?z))
-                             (copy-to-register
-                              vip-use-register (mark) (point) nil))
-                            ((and (<= ?A vip-use-register)
-                                  (<= vip-use-register ?Z))
-                             (vip-append-to-register
-                              (+ vip-use-register 32) (mark) (point)))
-                            (t (setq vip-use-register nil)
-                               (error "")))
-                      (setq vip-use-register nil)))
-                (delete-region (mark) (point)))
-              (open-line 1)
-              (if (= com ?C) (vip-change-mode-to-insert) (yank)))
-             ((= com ?d)
-              (if vip-use-register
-                  (progn
-                    (cond ((and (<= ?a vip-use-register)
-                                (<= vip-use-register ?z))
-                           (copy-to-register
-                            vip-use-register vip-com-point (point) nil))
-                          ((and (<= ?A vip-use-register)
-                                (<= vip-use-register ?Z))
-                           (vip-append-to-register
-                            (+ vip-use-register 32) vip-com-point (point)))
-                          (t (setq vip-use-register nil)
-                             (error "")))
-                    (setq vip-use-register nil)))
-              (setq last-command
-                    (if (eq last-command 'd-command) 'kill-region nil))
-              (kill-region vip-com-point (point))
-              (setq this-command 'd-command))
-             ((= com ?D)
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (if vip-use-register
-                    (progn
-                      (cond ((and (<= ?a vip-use-register)
-                                  (<= vip-use-register ?z))
-                             (copy-to-register
-                              vip-use-register (mark) (point) nil))
-                            ((and (<= ?A vip-use-register)
-                                  (<= vip-use-register ?Z))
-                             (vip-append-to-register
-                              (+ vip-use-register 32) (mark) (point)))
-                            (t (setq vip-use-register nil)
-                               (error "")))
-                      (setq vip-use-register nil)))
-                (setq last-command
-                      (if (eq last-command 'D-command) 'kill-region nil))
-                (kill-region (mark) (point))
-                (if (eq m-com 'vip-line) (setq this-command 'D-command)))
-              (back-to-indentation))
-             ((= com ?y)
-              (if vip-use-register
-                  (progn
-                    (cond ((and (<= ?a vip-use-register)
-                                (<= vip-use-register ?z))
-                           (copy-to-register
-                            vip-use-register vip-com-point (point) nil))
-                          ((and (<= ?A vip-use-register)
-                                (<= vip-use-register ?Z))
-                           (vip-append-to-register
-                            (+ vip-use-register 32) vip-com-point (point)))
-                          (t (setq vip-use-register nil)
-                             (error "")))
-                    (setq vip-use-register nil)))
-              (setq last-command nil)
-              (copy-region-as-kill vip-com-point (point))
-              (goto-char vip-com-point))
-             ((= com ?Y)
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (if vip-use-register
-                    (progn
-                      (cond ((and (<= ?a vip-use-register)
-                                  (<= vip-use-register ?z))
-                             (copy-to-register
-                              vip-use-register (mark) (point) nil))
-                            ((and (<= ?A vip-use-register)
-                                  (<= vip-use-register ?Z))
-                             (vip-append-to-register
-                              (+ vip-use-register 32) (mark) (point)))
-                            (t (setq vip-use-register nil)
-                               (error "")))
-                      (setq vip-use-register nil)))
-                (setq last-command nil)
-                (copy-region-as-kill (mark) (point)))
-              (goto-char vip-com-point))
-             ((or (= com ?!) (= com (- ?!)))
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (shell-command-on-region
-                 (mark) (point)
-                 (if (= com ?!)
-                     (setq vip-last-shell-com (vip-read-string "!"))
-                   vip-last-shell-com)
-                 t t)))
-             ((= com ?=)
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (if (> (mark) (point)) (exchange-point-and-mark))
-                (indent-region (mark) (point) nil)))
-             ((= com ?<)
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (indent-rigidly (mark) (point) (- vip-shift-width)))
-              (goto-char vip-com-point))
-             ((= com ?>)
-              (save-excursion
-                (set-mark vip-com-point)
-                (vip-enlarge-region (mark) (point))
-                (indent-rigidly (mark) (point) vip-shift-width))
-              (goto-char vip-com-point))
-             ((>= com 128)
-              ;; this is special command #
-              (vip-special-prefix-com (- com 128)))))
-    (setq vip-d-com (list m-com val (if (or (= com ?c) (= com ?C) (= com ?!))
-                                       (- com) com)
-                         reg))))
-
-(defun vip-repeat (arg)
-  "(ARG)  Re-execute last destructive command.  vip-d-com has the form
-\(COM ARG CH REG), where COM is the command to be re-executed, ARG is the
-argument for COM, CH is a flag for repeat, and REG is optional and if exists
-is the name of the register for COM."
-  (interactive "P")
-  (if (eq last-command 'vip-undo)
-      ;; if the last command was vip-undo, then undo-more
-      (vip-undo-more)
-    ;; otherwise execute the command stored in vip-d-com.  if arg is non-nil
-    ;; its prefix value is used as new prefix value for the command.
-    (let ((m-com (car vip-d-com))
-         (val (vip-P-val arg))
-         (com (car (cdr (cdr vip-d-com))))
-         (reg (nth 3 vip-d-com)))
-      (if (null val) (setq val (car (cdr vip-d-com))))
-      (if (null m-com) (error "No previous command to repeat"))
-      (setq vip-use-register reg)
-      (funcall m-com (cons val com)))))
-
-(defun vip-special-prefix-com (char)
-  "This command is invoked interactively by the key sequence #<char>"
-  (cond ((= char ?c)
-        (downcase-region (min vip-com-point (point))
-                         (max vip-com-point (point))))
-       ((= char ?C)
-        (upcase-region (min vip-com-point (point))
-                       (max vip-com-point (point))))
-       ((= char ?g)
-        (set-mark vip-com-point)
-        (vip-global-execute))
-       ((= char ?q)
-        (set-mark vip-com-point)
-        (vip-quote-region))
-       ((= char ?s) (ispell-region vip-com-point (point)))))
-
-
-;; undoing
-
-(defun vip-undo ()
-  "Undo previous change."
-  (interactive)
-  (message "undo!")
-  (undo-start)
-  (undo-more 2)
-  (setq this-command 'vip-undo))
-
-(defun vip-undo-more ()
-  "Continue undoing previous changes."
-  (message "undo more!")
-  (undo-more 1)
-  (setq this-command 'vip-undo))
-
-
-;; utilities
-
-(defun vip-string-tail (str)
-  (if (or (null str) (string= str "")) nil
-    (substring str 1)))
-
-(defun vip-yank-defun ()
-  (mark-defun)
-  (copy-region-as-kill (point) (mark)))
-
-(defun vip-enlarge-region (beg end)
-  "Enlarge region between BEG and END."
-  (if (< beg end)
-      (progn (goto-char beg) (set-mark end))
-    (goto-char end)
-    (set-mark beg))
-  (beginning-of-line)
-  (exchange-point-and-mark)
-  (if (or (not (eobp)) (not (bolp))) (with-no-warnings (next-line 1)))
-  (beginning-of-line)
-  (if (> beg end) (exchange-point-and-mark)))
-
-(defun vip-global-execute ()
-  "Call last keyboard macro for each line in the region."
-  (if (> (point) (mark)) (exchange-point-and-mark))
-  (beginning-of-line)
-  (call-last-kbd-macro)
-  (while (< (point) (mark))
-    (forward-line 1)
-    (beginning-of-line)
-    (call-last-kbd-macro)))
-
-(defun vip-quote-region ()
-  "Quote region by inserting the user supplied string at the beginning of
-each line in the region."
-  (setq vip-quote-string
-       (let ((str
-              (vip-read-string (format "quote string (default %s): "
-                                       vip-quote-string))))
-         (if (string= str "") vip-quote-string str)))
-  (vip-enlarge-region (point) (mark))
-  (if (> (point) (mark)) (exchange-point-and-mark))
-  (insert vip-quote-string)
-  (beginning-of-line)
-  (forward-line 1)
-  (while (and (< (point) (mark)) (bolp))
-    (insert vip-quote-string)
-    (beginning-of-line)
-    (forward-line 1)))
-
-(defun vip-end-with-a-newline-p (string)
-  "Check if the string ends with a newline."
-  (or (string= string "")
-      (= (aref string (1- (length string))) ?\n)))
-
-(defvar vip-save-minibuffer-local-map)
-
-(defun vip-read-string (prompt &optional init)
-  (setq vip-save-minibuffer-local-map (copy-keymap minibuffer-local-map))
-  (define-key minibuffer-local-map "\C-h" #'backward-char)
-  (define-key minibuffer-local-map "\C-w" #'backward-word)
-  (define-key minibuffer-local-map "\e" #'exit-minibuffer)
-  (let (str)
-    (condition-case nil
-       (setq str (read-string prompt init))
-      (quit
-       (setq minibuffer-local-map vip-save-minibuffer-local-map)
-       (signal 'quit nil)))
-    (setq minibuffer-local-map vip-save-minibuffer-local-map)
-    str))
-
-
-;; insertion commands
-
-(defun vip-repeat-insert-command ()
-  "This function is called when mode changes from insertion mode to
-vi command mode.  It will repeat the insertion command if original insertion
-command was invoked with argument > 1."
-  (let ((i-com (car vip-d-com)) (val (car (cdr vip-d-com))))
-    (if (and val (> val 1)) ;; first check that val is non-nil
-       (progn
-         (setq vip-d-com (list i-com (1- val) ?r))
-         (vip-repeat nil)
-         (setq vip-d-com (list i-com val ?r))))))
-
-(defun vip-insert (arg) ""
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-insert val ?r))
-    (if com (vip-loop val (yank))
-      (vip-change-mode-to-insert))))
-
-(defun vip-append (arg)
-  "Append after point."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-append val ?r))
-    (if (not (eolp)) (forward-char))
-    (if (equal com ?r)
-       (vip-loop val (yank))
-      (vip-change-mode-to-insert))))
-
-(defun vip-Append (arg)
-  "Append at end of line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-Append val ?r))
-    (end-of-line)
-    (if (equal com ?r)
-       (vip-loop val (yank))
-      (vip-change-mode-to-insert))))
-
-(defun vip-Insert (arg)
-  "Insert before first non-white."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-Insert val ?r))
-    (back-to-indentation)
-    (if (equal com ?r)
-       (vip-loop val (yank))
-      (vip-change-mode-to-insert))))
-
-(defun vip-open-line (arg)
-  "Open line below."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-open-line val ?r))
-    (let ((col (current-indentation)))
-      (if (equal com ?r)
-         (vip-loop val
-               (progn
-                 (end-of-line)
-                 (newline 1)
-                 (if vip-open-with-indent (indent-to col))
-                 (yank)))
-       (end-of-line)
-       (newline 1)
-       (if vip-open-with-indent (indent-to col))
-       (vip-change-mode-to-insert)))))
-
-(defun vip-Open-line (arg)
-  "Open line above."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-  (setq vip-d-com (list 'vip-Open-line val ?r))
-  (let ((col (current-indentation)))
-    (if (equal com ?r)
-       (vip-loop val
-             (progn
-               (beginning-of-line)
-               (open-line 1)
-               (if vip-open-with-indent (indent-to col))
-               (yank)))
-      (beginning-of-line)
-      (open-line 1)
-      (if vip-open-with-indent (indent-to col))
-      (vip-change-mode-to-insert)))))
-
-(defun vip-open-line-at-point (arg)
-  "Open line at point."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-open-line-at-point val ?r))
-    (if (equal com ?r)
-       (vip-loop val
-             (progn
-               (open-line 1)
-               (yank)))
-      (open-line 1)
-      (vip-change-mode-to-insert))))
-
-(defun vip-substitute (arg)
-  "Substitute characters."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (save-excursion
-      (set-mark (point))
-      (forward-char val)
-      (if (equal com ?r)
-         (vip-change-subr (mark) (point))
-       (vip-change (mark) (point))))
-    (setq vip-d-com (list 'vip-substitute val ?r))))
-
-(defun vip-substitute-line (arg)
-  "Substitute lines."
-  (interactive "p")
-  (vip-line (cons arg ?C)))
-
-
-;; line command
-
-(defun vip-line (arg)
-  (let ((val (car arg)) (com (cdr arg)))
-    (move-marker vip-com-point (point))
-    (with-no-warnings (next-line (1- val)))
-    (vip-execute-com 'vip-line val com)))
-
-(defun vip-yank-line (arg)
-  "Yank ARG lines (in vi's sense)"
-  (interactive "P")
-  (let ((val (vip-p-val arg)))
-    (vip-line (cons val ?Y))))
-
-
-;; region command
-
-(defun vip-region (arg)
-  (interactive "P")
-  (let ((val (vip-P-val arg))
-       (com (vip-getcom arg)))
-    (move-marker vip-com-point (point))
-    (exchange-point-and-mark)
-    (vip-execute-com 'vip-region val com)))
-
-(defun vip-Region (arg)
-  (interactive "P")
-  (let ((val (vip-P-val arg))
-       (com (vip-getCom arg)))
-    (move-marker vip-com-point (point))
-    (exchange-point-and-mark)
-    (vip-execute-com 'vip-Region val com)))
-
-(defun vip-replace-char (arg)
-  "Replace the following ARG chars by the character read."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (setq vip-d-com (list 'vip-replace-char val ?r))
-    (vip-replace-char-subr (if (equal com ?r) vip-d-char (read-char)) val)))
-
-(defun vip-replace-char-subr (char arg)
-  (delete-char arg t)
-  (setq vip-d-char char)
-  (vip-loop (if (> arg 0) arg (- arg)) (insert char))
-  (backward-char arg))
-
-(defun vip-replace-string ()
-  "Replace string.  If you supply null string as the string to be replaced,
-the query replace mode will toggle between string replace and regexp replace."
-  (interactive)
-  (let (str)
-    (setq str (vip-read-string
-              (if vip-re-replace "Replace regexp: " "Replace string: ")))
-    (if (string= str "")
-       (progn
-         (setq vip-re-replace (not vip-re-replace))
-         (message "Replace mode changed to %s."
-                  (if vip-re-replace "regexp replace"
-                    "string replace")))
-      (if vip-re-replace
-         ;; (replace-regexp
-         ;;  str
-         ;;  (vip-read-string (format "Replace regexp \"%s\" with: " str)))
-         (while (re-search-forward str nil t)
-           (replace-match (vip-read-string
-                           (format "Replace regexp \"%s\" with: " str))
-                          nil nil))
-       (with-no-warnings
-         (replace-string
-          str
-          (vip-read-string (format "Replace \"%s\" with: " str))))))))
-
-
-;; basic cursor movement.  j, k, l, m commands.
-
-(defun vip-forward-char (arg)
-  "Move point right ARG characters (left if ARG negative).On reaching end
-of buffer, stop and signal error."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-char val)
-    (if com (vip-execute-com 'vip-forward-char val com))))
-
-(defun vip-backward-char (arg)
-  "Move point left ARG characters (right if ARG negative).  On reaching
-beginning of buffer, stop and signal error."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (backward-char val)
-    (if com (vip-execute-com 'vip-backward-char val com))))
-
-
-;; word command
-
-(defun vip-forward-word (arg)
-  "Forward word."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-word val)
-    (skip-chars-forward " \t\n")
-    (if com
-       (progn
-         (if (or (= com ?c) (= com (- ?c)))
-             (progn (backward-word 1) (forward-word 1)))
-         (if (or (= com ?d) (= com ?y))
-             (progn
-               (backward-word 1)
-               (forward-word 1)
-               (skip-chars-forward " \t")))
-         (vip-execute-com 'vip-forward-word val com)))))
-
-(defun vip-end-of-word (arg)
-  "Move point to end of current word."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-char)
-    (forward-word val)
-    (backward-char)
-    (if com
-       (progn
-         (forward-char)
-         (vip-execute-com 'vip-end-of-word val com)))))
-
-(defun vip-backward-word (arg)
-  "Backward word."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (backward-word val)
-    (if com (vip-execute-com 'vip-backward-word val com))))
-
-(defun vip-forward-Word (arg)
-  "Forward word delimited by white character."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (re-search-forward "[^ \t\n]*[ \t\n]+" nil t val)
-    (if com
-       (progn
-         (if (or (= com ?c) (= com (- ?c)))
-             (progn (backward-word 1) (forward-word 1)))
-         (if (or (= com ?d) (= com ?y))
-             (progn
-               (backward-word 1)
-               (forward-word 1)
-               (skip-chars-forward " \t")))
-         (vip-execute-com 'vip-forward-Word val com)))))
-
-(defun vip-end-of-Word (arg)
-  "Move forward to end of word delimited by white character."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-char)
-    (if (re-search-forward "[^ \t\n]+" nil t val) (backward-char))
-    (if com
-       (progn
-         (forward-char)
-         (vip-execute-com 'vip-end-of-Word val com)))))
-
-(defun vip-backward-Word (arg)
-  "Backward word delimited by white character."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (if (re-search-backward "[ \t\n]+[^ \t\n]+" nil t val)
-       (forward-char)
-      (goto-char (point-min)))
-    (if com (vip-execute-com 'vip-backward-Word val com))))
-
-(defun vip-beginning-of-line (arg)
-  "Go to beginning of line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (beginning-of-line val)
-    (if com (vip-execute-com 'vip-beginning-of-line val com))))
-
-(defun vip-bol-and-skip-white (arg)
-  "Beginning of line at first non-white character."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (back-to-indentation)
-    (if com (vip-execute-com 'vip-bol-and-skip-white val com))))
-
-(defun vip-goto-eol (arg)
-  "Go to end of line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (end-of-line val)
-    (if com (vip-execute-com 'vip-goto-eol val com))))
-
-(defun vip-next-line (arg)
-  "Go to next line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (line-move val)
-    (setq this-command 'next-line)
-    (if com (vip-execute-com 'vip-next-line val com))))
-
-(defun vip-next-line-at-bol (arg)
-  "Next line at beginning of line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (with-no-warnings (next-line val))
-    (back-to-indentation)
-    (if com (vip-execute-com 'vip-next-line-at-bol val com))))
-
-(defun vip-previous-line (arg)
-  "Go to previous line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (with-no-warnings (next-line (- val)))
-    (setq this-command 'previous-line)
-    (if com (vip-execute-com 'vip-previous-line val com))))
-
-(defun vip-previous-line-at-bol (arg)
-  "Previous line at beginning of line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (with-no-warnings (next-line (- val)))
-    (back-to-indentation)
-    (if com (vip-execute-com 'vip-previous-line val com))))
-
-(defun vip-change-to-eol (arg)
-  "Change to end of line."
-  (interactive "P")
-  (vip-goto-eol (cons arg ?c)))
-
-(defun vip-kill-line (arg)
-  "Delete line."
-  (interactive "P")
-  (vip-goto-eol (cons arg ?d)))
-
-
-;; moving around
-
-(defun vip-goto-line (arg)
-  "Go to ARG's line.  Without ARG go to end of buffer."
-  (interactive "P")
-  (let ((val (vip-P-val arg)) (com (vip-getCom arg)))
-    (move-marker vip-com-point (point))
-    (set-mark (point))
-    (if (null val)
-       (goto-char (point-max))
-      (goto-char (point-min))
-      (forward-line (1- val)))
-    (back-to-indentation)
-    (if com (vip-execute-com 'vip-goto-line val com))))
-
-(defun vip-find-char (arg char forward offset)
-  "Find ARG's occurrence of CHAR on the current line.  If FORWARD then
-search is forward, otherwise backward.  OFFSET is used to adjust point
-after search."
-  (let ((arg (if forward arg (- arg))) point)
-    (save-excursion
-      (save-restriction
-       (if (> arg 0)
-           (narrow-to-region
-            ;; forward search begins here
-            (if (eolp) (error "") (point))
-            ;; forward search ends here
-            (progn (with-no-warnings (next-line 1)) (beginning-of-line) 
(point)))
-         (narrow-to-region
-          ;; backward search begins from here
-          (if (bolp) (error "") (point))
-          ;; backward search ends here
-          (progn (beginning-of-line) (point))))
-       ;; if arg > 0, point is forwarded before search.
-       (if (> arg 0) (goto-char (1+ (point-min)))
-         (goto-char (point-max)))
-       (let ((case-fold-search nil))
-         (search-forward (char-to-string char) nil 0 arg))
-       (setq point (point))
-       (if (or (and (> arg 0) (= point (point-max)))
-               (and (< arg 0) (= point (point-min))))
-           (error ""))))
-    (goto-char (+ point (if (> arg 0) (if offset -2 -1) (if offset 1 0))))))
-
-(defun vip-find-char-forward (arg)
-  "Find char on the line.  If called interactively read the char to find
-from the terminal, and if called from vip-repeat, the char last used is
-used.  This behavior is controlled by the sign of prefix numeric value."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (> val 0)
-       ;; this means that the function was called interactively
-       (setq vip-f-char (read-char)
-             vip-f-forward t
-             vip-f-offset nil)
-      (setq val (- val)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t nil)
-    (setq val (- val))
-    (if com
-       (progn
-         (setq vip-F-char vip-f-char);; set new vip-F-char
-         (forward-char)
-         (vip-execute-com 'vip-find-char-forward val com)))))
-
-(defun vip-goto-char-forward (arg)
-  "Go up to char ARG forward on line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (> val 0)
-       ;; this means that the function was called interactively
-       (setq vip-f-char (read-char)
-             vip-f-forward t
-             vip-f-offset t)
-      (setq val (- val)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t t)
-    (setq val (- val))
-    (if com
-       (progn
-         (setq vip-F-char vip-f-char);; set new vip-F-char
-         (forward-char)
-         (vip-execute-com 'vip-goto-char-forward val com)))))
-
-(defun vip-find-char-backward (arg)
-  "Find char ARG on line backward."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (> val 0)
-       ;; this means that the function was called interactively
-       (setq vip-f-char (read-char)
-             vip-f-forward nil
-             vip-f-offset nil)
-      (setq val (- val)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char
-     val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil nil)
-    (setq val (- val))
-    (if com
-       (progn
-         (setq vip-F-char vip-f-char);; set new vip-F-char
-         (vip-execute-com 'vip-find-char-backward val com)))))
-
-(defun vip-goto-char-backward (arg)
-  "Go up to char ARG backward on line."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (> val 0)
-       ;; this means that the function was called interactively
-       (setq vip-f-char (read-char)
-             vip-f-forward nil
-             vip-f-offset t)
-      (setq val (- val)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil t)
-    (setq val (- val))
-    (if com
-       (progn
-         (setq vip-F-char vip-f-char);; set new vip-F-char
-         (vip-execute-com 'vip-goto-char-backward val com)))))
-
-(defun vip-repeat-find (arg)
-  "Repeat previous find command."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char val vip-f-char vip-f-forward vip-f-offset)
-    (if com
-       (progn
-         (if vip-f-forward (forward-char))
-         (vip-execute-com 'vip-repeat-find val com)))))
-
-(defun vip-repeat-find-opposite (arg)
-  "Repeat previous find command in the opposite direction."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (vip-find-char val vip-f-char (not vip-f-forward) vip-f-offset)
-    (if com
-       (progn
-         (if vip-f-forward (forward-char))
-         (vip-execute-com 'vip-repeat-find-opposite val com)))))
-
-
-;; window scrolling etc.
-
-(defun vip-other-window (arg)
-  "Switch to other window."
-  (interactive "p")
-  (other-window arg)
-  (or (not (eq vip-current-mode 'emacs-mode))
-      (string= (buffer-name (current-buffer)) " *Minibuf-1*")
-      (vip-change-mode-to-vi)))
-
-(defun vip-window-top (arg)
-  "Go to home window line."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (move-to-window-line (1- val))
-    (if com (vip-execute-com 'vip-window-top val com))))
-
-(defun vip-window-middle (arg)
-  "Go to middle window line."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (move-to-window-line (+ (/ (1- (window-height)) 2) (1- val)))
-    (if com (vip-execute-com 'vip-window-middle val com))))
-
-(defun vip-window-bottom (arg)
-  "Go to last window line."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (move-to-window-line (- val))
-    (if com (vip-execute-com 'vip-window-bottom val com))))
-
-(defun vip-line-to-top (arg)
-  "Put current line on the home line."
-  (interactive "p")
-  (recenter (1- arg)))
-
-(defun vip-line-to-middle (arg)
-  "Put current line on the middle line."
-  (interactive "p")
-  (recenter (+ (1- arg) (/ (1- (window-height)) 2))))
-
-(defun vip-line-to-bottom (arg)
-  "Put current line on the last line."
-  (interactive "p")
-  (recenter (- (window-height) (1+ arg))))
-
-
-;; paren match
-
-(defun vip-paren-match (arg)
-  "Go to the matching parenthesis."
-  (interactive "P")
-  (let ((com (vip-getcom arg)))
-    (if (numberp arg)
-       (if (or (> arg 99) (< arg 1))
-           (error "Prefix must be between 1 and 99")
-         (goto-char
-          (if (> (point-max) 80000)
-              (* (/ (point-max) 100) arg)
-            (/ (* (point-max) arg) 100)))
-         (back-to-indentation))
-    (cond ((looking-at "[([{]")
-          (if com (move-marker vip-com-point (point)))
-          (forward-sexp 1)
-          (if com
-              (vip-execute-com 'vip-paren-match nil com)
-            (backward-char)))
-         ((looking-at "[])}]")
-          (forward-char)
-          (if com (move-marker vip-com-point (point)))
-          (backward-sexp 1)
-          (if com (vip-execute-com 'vip-paren-match nil com)))
-         (t (error ""))))))
-
-
-;; sentence and paragraph
-
-(defun vip-forward-sentence (arg)
-  "Forward sentence."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-sentence val)
-    (if com (vip-execute-com 'vip-forward-sentence nil com))))
-
-(defun vip-backward-sentence (arg)
-  "Backward sentence."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getcom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (backward-sentence val)
-    (if com (vip-execute-com 'vip-backward-sentence nil com))))
-
-(defun vip-forward-paragraph (arg)
-  "Forward paragraph."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (forward-paragraph val)
-    (if com (vip-execute-com 'vip-forward-paragraph nil com))))
-
-(defun vip-backward-paragraph (arg)
-  "Backward paragraph."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (com (vip-getCom arg)))
-    (if com (move-marker vip-com-point (point)))
-    (backward-paragraph val)
-    (if com (vip-execute-com 'vip-backward-paragraph nil com))))
-
-
-;; scrolling
-
-(defun vip-scroll (arg)
-  "Scroll to next screen."
-  (interactive "p")
-  (if (> arg 0)
-      (while (> arg 0)
-       (scroll-up)
-       (setq arg (1- arg)))
-    (while (> 0 arg)
-      (scroll-down)
-      (setq arg (1+ arg)))))
-
-(defun vip-scroll-back (arg)
-  "Scroll to previous screen."
-  (interactive "p")
-  (vip-scroll (- arg)))
-
-(defun vip-scroll-down (arg)
-  "Scroll up half screen."
-  (interactive "P")
-  (if (null arg) (scroll-down (/ (window-height) 2))
-    (scroll-down arg)))
-
-(defun vip-scroll-down-one (arg)
-  "Scroll up one line."
-  (interactive "p")
-  (scroll-down arg))
-
-(defun vip-scroll-up (arg)
-  "Scroll down half screen."
-  (interactive "P")
-  (if (null arg) (scroll-up (/ (window-height) 2))
-    (scroll-up arg)))
-
-(defun vip-scroll-up-one (arg)
-  "Scroll down one line."
-  (interactive "p")
-  (scroll-up arg))
-
-
-;; splitting window
-
-(defun vip-buffer-in-two-windows ()
-  "Show current buffer in two windows."
-  (interactive)
-  (delete-other-windows)
-  (split-window-below))
-
-
-;; searching
-
-(defun vip-search-forward (arg)
-  "Search a string forward.  ARG is used to find the ARG's occurrence
-of the string.  Default is vanilla search.  Search mode can be toggled by
-giving null search string."
-  (interactive "P")
-  (let ((val (vip-P-val arg)) (com (vip-getcom arg)))
-    (setq vip-s-forward t
-         vip-s-string (vip-read-string (if vip-re-search "RE-/" "/")))
-    (if (string= vip-s-string "")
-       (progn
-         (setq vip-re-search (not vip-re-search))
-         (message "Search mode changed to %s search."
-                  (if vip-re-search "regular expression"
-                    "vanilla")))
-      (vip-search vip-s-string t val)
-      (if com
-         (progn
-           (move-marker vip-com-point (mark))
-           (vip-execute-com 'vip-search-next val com))))))
-
-(defun vip-search-backward (arg)
-  "Search a string backward.  ARG is used to find the ARG's occurrence
-of the string.  Default is vanilla search.  Search mode can be toggled by
-giving null search string."
-  (interactive "P")
-  (let ((val (vip-P-val arg)) (com (vip-getcom arg)))
-    (setq vip-s-forward nil
-         vip-s-string (vip-read-string (if vip-re-search "RE-?" "?")))
-    (if (string= vip-s-string "")
-       (progn
-         (setq vip-re-search (not vip-re-search))
-         (message "Search mode changed to %s search."
-                  (if vip-re-search "regular expression"
-                    "vanilla")))
-      (vip-search vip-s-string nil val)
-      (if com
-         (progn
-           (move-marker vip-com-point (mark))
-           (vip-execute-com 'vip-search-next val com))))))
-
-(defun vip-search (string forward arg &optional no-offset init-point)
-  "(STRING FORWARD COUNT &optional NO-OFFSET) Search COUNT's occurrence of
-STRING.  Search will be forward if FORWARD, otherwise backward."
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg))
-       (null-arg (null (vip-P-val arg))) (offset (not no-offset))
-       (case-fold-search vip-case-fold-search)
-       (start-point (or init-point (point))))
-    (if forward
-       (condition-case conditions
-           (progn
-             (if (and offset (not (eobp))) (forward-char))
-             (if vip-re-search
-                 (progn
-                   (re-search-forward string nil nil val)
-                   (re-search-backward string))
-               (search-forward string nil nil val)
-               (search-backward string))
-             (push-mark start-point))
-         (search-failed
-          (if (and null-arg vip-search-wrap-around)
-              (progn
-                (goto-char (point-min))
-                (vip-search string forward (cons 1 com) t start-point))
-            (goto-char start-point)
-            (signal 'search-failed (cdr conditions)))))
-      (condition-case conditions
-           (progn
-             (if vip-re-search
-                   (re-search-backward string nil nil val)
-               (search-backward string nil nil val))
-             (push-mark start-point))
-         (search-failed
-          (if (and null-arg vip-search-wrap-around)
-              (progn
-                (goto-char (point-max))
-                (vip-search string forward (cons 1 com) t start-point))
-            (goto-char start-point)
-            (signal 'search-failed (cdr conditions))))))))
-
-(defun vip-search-next (arg)
-  "Repeat previous search."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (null vip-s-string) (error "No previous search string"))
-    (vip-search vip-s-string vip-s-forward arg)
-    (if com (vip-execute-com 'vip-search-next val com))))
-
-(defun vip-search-Next (arg)
-  "Repeat previous search in the reverse direction."
-  (interactive "P")
-  (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
-    (if (null vip-s-string) (error "No previous search string"))
-    (vip-search vip-s-string (not vip-s-forward) arg)
-    (if com (vip-execute-com 'vip-search-Next val com))))
-
-
-;; visiting and killing files, buffers
-
-(defun vip-switch-to-buffer ()
-  "Switch to buffer in the current window."
-  (interactive)
-  (let (buffer)
-    (setq buffer
-         (read-buffer
-          (format "switch to buffer (%s): "
-                  (buffer-name (other-buffer (current-buffer))))))
-    (switch-to-buffer buffer)
-    (vip-change-mode-to-vi)))
-
-(defun vip-switch-to-buffer-other-window ()
-  "Switch to buffer in another window."
-  (interactive)
-  (let (buffer)
-    (setq buffer
-         (read-buffer
-          (format "Switch to buffer (%s): "
-                  (buffer-name (other-buffer (current-buffer))))))
-    (switch-to-buffer-other-window buffer)
-    (vip-change-mode-to-vi)))
-
-(defun vip-kill-buffer ()
-  "Kill a buffer."
-  (interactive)
-  (let (buffer buffer-name)
-    (setq buffer-name
-         (read-buffer
-          (format "Kill buffer (%s): "
-                  (buffer-name (current-buffer)))))
-    (setq buffer
-         (if (null buffer-name)
-             (current-buffer)
-           (get-buffer buffer-name)))
-    (if (null buffer) (error "Buffer %s nonexistent" buffer-name))
-    (if (or (not (buffer-modified-p buffer))
-           (y-or-n-p "Buffer is modified, are you sure? "))
-       (kill-buffer buffer)
-      (error "Buffer not killed"))))
-
-(defun vip-find-file ()
-  "Visit file in the current window."
-  (interactive)
-  (let (file)
-    (setq file (read-file-name "visit file: "))
-    (switch-to-buffer (find-file-noselect file))
-    (vip-change-mode-to-vi)))
-
-(defun vip-find-file-other-window ()
-  "Visit file in another window."
-  (interactive)
-  (let (file)
-    (setq file (read-file-name "Visit file: "))
-    (switch-to-buffer-other-window (find-file-noselect file))
-    (vip-change-mode-to-vi)))
-
-(defun vip-info-on-file ()
-  "Give information of the file associated to the current buffer."
-  (interactive)
-  (message "\"%s\" line %d of %d"
-          (if (buffer-file-name) (buffer-file-name) "")
-          (1+ (count-lines (point-min) (point)))
-          (1+ (count-lines (point-min) (point-max)))))
-
-
-;; yank and pop
-
-(defun vip-yank (text)
-  "yank TEXT silently."
-  (save-excursion
-    (vip-push-mark-silent (point))
-    (insert text)
-    (exchange-point-and-mark))
-  (skip-chars-forward " \t"))
-
-(defun vip-put-back (arg)
-  "Put back after point/below line."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (text (if vip-use-register
-                 (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9))
-                     (current-kill (- vip-use-register ?1) 'do-not-rotate)
-                   (get-register vip-use-register))
-               (current-kill 0))))
-    (if (null text)
-       (if vip-use-register
-           (let ((reg vip-use-register))
-             (setq vip-use-register nil)
-             (error "Nothing in register %c" reg))
-         (error "")))
-    (setq vip-use-register nil)
-    (if (vip-end-with-a-newline-p text)
-       (progn
-         (with-no-warnings (next-line 1))
-         (beginning-of-line))
-      (if (and (not (eolp)) (not (eobp))) (forward-char)))
-    (setq vip-d-com (list 'vip-put-back val nil vip-use-register))
-    (vip-loop val (vip-yank text))))
-
-(defun vip-Put-back (arg)
-  "Put back at point/above line."
-  (interactive "P")
-  (let ((val (vip-p-val arg))
-       (text (if vip-use-register
-                 (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9))
-                     (current-kill (- vip-use-register ?1) 'do-not-rotate)
-                   (get-register vip-use-register))
-               (current-kill 0))))
-    (if (null text)
-       (if vip-use-register
-           (let ((reg vip-use-register))
-             (setq vip-use-register nil)
-             (error "Nothing in register %c" reg))
-         (error "")))
-    (setq vip-use-register nil)
-    (if (vip-end-with-a-newline-p text) (beginning-of-line))
-    (setq vip-d-com (list 'vip-Put-back val nil vip-use-register))
-    (vip-loop val (vip-yank text))))
-
-(defun vip-delete-char (arg)
-  "Delete character."
-  (interactive "P")
-  (let ((val (vip-p-val arg)))
-    (setq vip-d-com (list 'vip-delete-char val nil))
-    (if vip-use-register
-       (progn
-         (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z))
-             (vip-append-to-register
-              (+ vip-use-register 32) (point) (- (point) val))
-           (copy-to-register vip-use-register (point) (- (point) val) nil))
-         (setq vip-use-register nil)))
-    (delete-char val t)))
-
-(defun vip-delete-backward-char (arg)
-  "Delete previous character."
-  (interactive "P")
-  (let ((val (vip-p-val arg)))
-    (setq vip-d-com (list 'vip-delete-backward-char val nil))
-    (if vip-use-register
-       (progn
-         (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z))
-             (vip-append-to-register
-              (+ vip-use-register 32) (point) (+ (point) val))
-           (copy-to-register vip-use-register (point) (+ (point) val) nil))
-         (setq vip-use-register nil)))
-    (with-no-warnings (delete-backward-char val t))))
-
-
-;; join lines.
-
-(defun vip-join-lines (arg)
-  "Join this line to next, if ARG is nil.  Otherwise, join ARG lines"
-  (interactive "*P")
-  (let ((val (vip-P-val arg)))
-    (setq vip-d-com (list 'vip-join-lines val nil))
-    (vip-loop (if (null val) 1 (1- val))
-         (progn
-           (end-of-line)
-           (if (not (eobp))
-               (progn
-                 (forward-line 1)
-                 (delete-region (point) (1- (point)))
-                 (fixup-whitespace)))))))
-
-
-;; making small changes
-
-(defvar vip-c-string)
-
-(defun vip-change (beg end)
-  (setq vip-c-string
-       (vip-read-string (format "%s => " (buffer-substring beg end))))
-  (vip-change-subr beg end))
-
-(defun vip-change-subr (beg end)
-  (if vip-use-register
-      (progn
-       (copy-to-register vip-use-register beg end nil)
-       (setq vip-use-register nil)))
-  (kill-region beg end)
-  (setq this-command 'vip-change)
-  (insert vip-c-string))
-
-
-;; query replace
-
-(defun vip-query-replace ()
-  "Query replace.  If you supply null string as the string to be replaced,
-the query replace mode will toggle between string replace and regexp replace."
-  (interactive)
-  (let (str)
-    (setq str (vip-read-string
-              (if vip-re-query-replace "Query replace regexp: "
-                "Query replace: ")))
-    (if (string= str "")
-       (progn
-         (setq vip-re-query-replace (not vip-re-query-replace))
-         (message "Query replace mode changed to %s."
-                  (if vip-re-query-replace "regexp replace"
-                    "string replace")))
-      (if vip-re-query-replace
-         (query-replace-regexp
-          str
-          (vip-read-string (format "Query replace regexp \"%s\" with: " str)))
-       (query-replace
-        str
-        (vip-read-string (format "Query replace \"%s\" with: " str)))))))
-
-
-;; marking
-
-(defun vip-mark-beginning-of-buffer ()
-  (interactive)
-  (set-mark (point))
-  (goto-char (point-min))
-  (exchange-point-and-mark)
-  (message "mark set at the beginning of buffer"))
-
-(defun vip-mark-end-of-buffer ()
-  (interactive)
-  (set-mark (point))
-  (goto-char (point-max))
-  (exchange-point-and-mark)
-  (message "mark set at the end of buffer"))
-
-(defun vip-mark-point (char)
-  (interactive "c")
-  (cond ((and (<= ?a char) (<= char ?z))
-        (point-to-register (- char (- ?a ?\C-a)) nil))
-       ((= char ?<) (vip-mark-beginning-of-buffer))
-       ((= char ?>) (vip-mark-end-of-buffer))
-       ((= char ?.) (push-mark))
-       ((= char ?,) (set-mark-command 1))
-       ((= char ?D) (mark-defun))
-       (t (error ""))))
-
-(defun vip-goto-mark (arg)
-  "Go to mark."
-  (interactive "P")
-  (let ((char (read-char)) (com (vip-getcom arg)))
-    (vip-goto-mark-subr char com nil)))
-
-(defun vip-goto-mark-and-skip-white (arg)
-  "Go to mark and skip to first non-white on line."
-  (interactive "P")
-  (let ((char (read-char)) (com (vip-getCom arg)))
-    (vip-goto-mark-subr char com t)))
-
-(defun vip-goto-mark-subr (char com skip-white)
-  (cond ((and (<= ?a char) (<= char ?z))
-        (let ((buff (current-buffer)))
-          (if com (move-marker vip-com-point (point)))
-          (goto-char (register-to-point (- char (- ?a ?\C-a))))
-          (if skip-white (back-to-indentation))
-          (vip-change-mode-to-vi)
-          (if com
-              (if (equal buff (current-buffer))
-                  (vip-execute-com (if skip-white
-                                       'vip-goto-mark-and-skip-white
-                                     'vip-goto-mark)
-                                   nil com)
-                (switch-to-buffer buff)
-                (goto-char vip-com-point)
-                (vip-change-mode-to-vi)
-                (error "")))))
-       ((and (not skip-white) (= char ?`))
-        (if com (move-marker vip-com-point (point)))
-        (exchange-point-and-mark)
-        (if com (vip-execute-com 'vip-goto-mark nil com)))
-       ((and skip-white (= char ?'))
-        (if com (move-marker vip-com-point (point)))
-        (exchange-point-and-mark)
-        (back-to-indentation)
-        (if com (vip-execute-com 'vip-goto-mark-and-skip-white nil com)))
-       (t (error ""))))
-
-(defun vip-exchange-point-and-mark ()
-  (interactive)
-  (exchange-point-and-mark)
-  (back-to-indentation))
-
-(defun vip-keyboard-quit ()
-  "Abort partially formed or running command."
-  (interactive)
-  (setq vip-use-register nil)
-  (keyboard-quit))
-
-(defun vip-ctl-c-equivalent (arg)
-  "Emulate C-c in Emacs mode."
-  (interactive "P")
-  (vip-ctl-key-equivalent "\C-c" arg))
-
-(defun vip-ctl-x-equivalent (arg)
-  "Emulate C-x in Emacs mode."
-  (interactive "P")
-  (vip-ctl-key-equivalent "\C-x" arg))
-
-(defun vip-ctl-key-equivalent (key arg)
-  (let ((char (read-char)))
-    (if (and (<= ?A char) (<= char ?Z))
-       (setq char (- char (- ?A ?\C-a))))
-    (vip-escape-to-emacs arg (list (aref key 0) char))))
-
-;; commands in insertion mode
-
-(defun vip-delete-backward-word (arg)
-  "Delete previous word."
-  (interactive "p")
-  (save-excursion
-    (set-mark (point))
-    (backward-word arg)
-    (delete-region (point) (mark))))
-
-
-;; implement ex commands
-
-(defvar ex-token-type nil
-  "type of token.  if non-nil, gives type of address.  if nil, it
-is a command.")
-
-(defvar ex-token nil
-  "value of token.")
-
-(defvar ex-addresses nil
-  "list of ex addresses")
-
-(defvar ex-flag nil
-  "flag for ex flag")
-
-(defvar ex-buffer nil
-  "name of ex buffer")
-
-(defvar ex-count nil
-  "value of ex count")
-
-(defvar ex-g-flag nil
-  "flag for global command")
-
-(defvar ex-g-variant nil
-  "if t global command is executed on lines not matching ex-g-pat")
-
-(defvar ex-reg-exp nil
-  "save reg-exp used in substitute")
-
-(defvar ex-repl nil
-  "replace pattern for substitute")
-
-(defvar ex-g-pat nil
-  "pattern for global command")
-
-(defvar ex-map (make-sparse-keymap)
-  "save commands for mapped keys")
-
-(defvar ex-tag nil
-  "save ex tag")
-
-(defvar ex-file nil)
-
-(defvar ex-variant nil)
-
-(defvar ex-offset nil)
-
-(defvar ex-append nil)
-
-(defun vip-nil ()
-  (interactive)
-  (error ""))
-
-(defun vip-looking-back (str)
-  "returns t if looking back reg-exp STR before point."
-  (and (save-excursion (re-search-backward str nil t))
-       (= (point) (match-end 0))))
-
-(defun vip-check-sub (str)
-  "check if ex-token is an initial segment of STR"
-  (let ((length (length ex-token)))
-    (if (and (<= length (length str))
-            (string= ex-token (substring str 0 length)))
-       (setq ex-token str)
-      (setq ex-token-type "non-command"))))
-
-(defun vip-get-ex-com-subr ()
-  "get a complete ex command"
-  (set-mark (point))
-  (re-search-forward "[a-z][a-z]*")
-  (setq ex-token-type "command")
-  (setq ex-token (buffer-substring (point) (mark)))
-  (exchange-point-and-mark)
-  (cond ((looking-at "a")
-        (cond ((looking-at "ab") (vip-check-sub "abbreviate"))
-              ((looking-at "ar") (vip-check-sub "args"))
-              (t (vip-check-sub "append"))))
-       ((looking-at "[bh]") (setq ex-token-type "non-command"))
-       ((looking-at "c")
-        (if (looking-at "co") (vip-check-sub "copy")
-          (vip-check-sub "change")))
-       ((looking-at "d") (vip-check-sub "delete"))
-       ((looking-at "e")
-        (if (looking-at "ex") (vip-check-sub "ex")
-          (vip-check-sub "edit")))
-       ((looking-at "f") (vip-check-sub "file"))
-       ((looking-at "g") (vip-check-sub "global"))
-       ((looking-at "i") (vip-check-sub "insert"))
-       ((looking-at "j") (vip-check-sub "join"))
-       ((looking-at "l") (vip-check-sub "list"))
-       ((looking-at "m")
-        (cond ((looking-at "map") (vip-check-sub "map"))
-              ((looking-at "mar") (vip-check-sub "mark"))
-              (t (vip-check-sub "move"))))
-       ((looking-at "n")
-        (if (looking-at "nu") (vip-check-sub "number")
-          (vip-check-sub "next")))
-       ((looking-at "o") (vip-check-sub "open"))
-       ((looking-at "p")
-        (cond ((looking-at "pre") (vip-check-sub "preserve"))
-              ((looking-at "pu") (vip-check-sub "put"))
-              (t (vip-check-sub "print"))))
-       ((looking-at "q") (vip-check-sub "quit"))
-       ((looking-at "r")
-        (cond ((looking-at "rec") (vip-check-sub "recover"))
-              ((looking-at "rew") (vip-check-sub "rewind"))
-              (t (vip-check-sub "read"))))
-       ((looking-at "s")
-        (cond ((looking-at "se") (vip-check-sub "set"))
-              ((looking-at "sh") (vip-check-sub "shell"))
-              ((looking-at "so") (vip-check-sub "source"))
-              ((looking-at "st") (vip-check-sub "stop"))
-              (t (vip-check-sub "substitute"))))
-       ((looking-at "t")
-        (if (looking-at "ta") (vip-check-sub "tag")
-          (vip-check-sub "t")))
-       ((looking-at "u")
-        (cond ((looking-at "una") (vip-check-sub "unabbreviate"))
-              ((looking-at "unm") (vip-check-sub "unmap"))
-              (t (vip-check-sub "undo"))))
-       ((looking-at "v")
-        (cond ((looking-at "ve") (vip-check-sub "version"))
-              ((looking-at "vi") (vip-check-sub "visual"))
-              (t (vip-check-sub "v"))))
-       ((looking-at "w")
-        (if (looking-at "wq") (vip-check-sub "wq")
-          (vip-check-sub "write")))
-       ((looking-at "x") (vip-check-sub "xit"))
-       ((looking-at "y") (vip-check-sub "yank"))
-       ((looking-at "z") (vip-check-sub "z")))
-  (exchange-point-and-mark))
-
-(defun vip-get-ex-token ()
-  "get an ex-token which is either an address or a command.
-a token has type \(command, address, end-mark) and value."
-  (with-current-buffer " *ex-working-space*"
-    (skip-chars-forward " \t")
-    (cond ((looking-at "[k#]")
-          (setq ex-token-type "command")
-          (setq ex-token (char-to-string (following-char)))
-          (forward-char 1))
-         ((looking-at "[a-z]") (vip-get-ex-com-subr))
-         ((looking-at "\\.")
-          (forward-char 1)
-          (setq ex-token-type "dot"))
-         ((looking-at "[0-9]")
-          (set-mark (point))
-          (re-search-forward "[0-9]*")
-          (setq ex-token-type
-                (cond ((string= ex-token-type "plus") "add-number")
-                      ((string= ex-token-type "minus") "sub-number")
-                      (t "abs-number")))
-          (setq ex-token (string-to-number (buffer-substring (point) (mark)))))
-         ((looking-at "\\$")
-          (forward-char 1)
-          (setq ex-token-type "end"))
-         ((looking-at "%")
-          (forward-char 1)
-          (setq ex-token-type "whole"))
-         ((looking-at "\\+")
-          (cond ((looking-at "\\+[-+\n|]")
-                 (forward-char 1)
-                 (insert "1")
-                 (backward-char 1)
-                 (setq ex-token-type "plus"))
-                ((looking-at "\\+[0-9]")
-                 (forward-char 1)
-                 (setq ex-token-type "plus"))
-                (t
-                 (error "Badly formed address"))))
-         ((looking-at "-")
-          (cond ((looking-at "-[-+\n|]")
-                 (forward-char 1)
-                 (insert "1")
-                 (backward-char 1)
-                 (setq ex-token-type "minus"))
-                ((looking-at "-[0-9]")
-                 (forward-char 1)
-                 (setq ex-token-type "minus"))
-                (t
-                 (error "Badly formed address"))))
-         ((looking-at "/")
-          (forward-char 1)
-          (set-mark (point))
-          (let ((cont t))
-            (while (and (not (eolp)) cont)
-              ;;(re-search-forward "[^/]*/")
-              (re-search-forward "[^/]*\\(/\\|\n\\)")
-              (if (not (vip-looking-back "[^\\]\\(\\\\\\\\\\)*\\\\/"))
-                  (setq cont nil))))
-          (backward-char 1)
-          (setq ex-token (buffer-substring (point) (mark)))
-          (if (looking-at "/") (forward-char 1))
-          (setq ex-token-type "search-forward"))
-         ((looking-at "\\?")
-          (forward-char 1)
-          (set-mark (point))
-          (let ((cont t))
-            (while (and (not (eolp)) cont)
-              ;;(re-search-forward "[^\\?]*\\?")
-              (re-search-forward "[^\\?]*\\(\\?\\|\n\\)")
-              (if (not (vip-looking-back "[^\\]\\(\\\\\\\\\\)*\\\\\\?"))
-                  (setq cont nil))
-              (backward-char 1)
-              (if (not (looking-at "\n")) (forward-char 1))))
-          (setq ex-token-type "search-backward")
-          (setq ex-token (buffer-substring (1- (point)) (mark))))
-         ((looking-at ",")
-          (forward-char 1)
-          (setq ex-token-type "comma"))
-         ((looking-at ";")
-          (forward-char 1)
-          (setq ex-token-type "semi-colon"))
-         ((looking-at "[!=><&~]")
-          (setq ex-token-type "command")
-          (setq ex-token (char-to-string (following-char)))
-          (forward-char 1))
-         ((looking-at "'")
-          (setq ex-token-type "goto-mark")
-          (forward-char 1)
-          (cond ((looking-at "'") (setq ex-token nil))
-                ((looking-at "[a-z]") (setq ex-token (following-char)))
-                (t (error "%s" "Marks are ' and a-z")))
-          (forward-char 1))
-         ((looking-at "\n")
-          (setq ex-token-type "end-mark")
-          (setq ex-token "goto"))
-         (t
-           (error "Invalid token")))))
-
-(defun vip-ex (&optional string)
-  "ex commands within VIP."
-  (interactive)
-  (or string
-      (setq ex-g-flag nil
-           ex-g-variant nil))
-  (let ((com-str (or string (vip-read-string ":")))
-       (address nil) (cont t) (dot (point)))
-    (with-current-buffer (get-buffer-create " *ex-working-space*")
-      (delete-region (point-min) (point-max))
-      (insert com-str "\n")
-      (goto-char (point-min)))
-    (setq ex-token-type "")
-    (setq ex-addresses nil)
-    (while cont
-      (vip-get-ex-token)
-      (cond ((or (string= ex-token-type "command")
-                (string= ex-token-type "end-mark"))
-            (if address (setq ex-addresses (cons address ex-addresses)))
-            (cond ((string= ex-token "global")
-                   (ex-global nil)
-                   (setq cont nil))
-                  ((string= ex-token "v")
-                   (ex-global t)
-                   (setq cont nil))
-                  (t
-                   (vip-execute-ex-command)
-                   (with-current-buffer " *ex-working-space*"
-                     (skip-chars-forward " \t")
-                     (cond ((looking-at "|")
-                            (forward-char 1))
-                           ((looking-at "\n")
-                            (setq cont nil))
-                           (t (error "Extra character at end of a 
command")))))))
-           ((string= ex-token-type "non-command")
-            (error "%s: Not an editor command" ex-token))
-           ((string= ex-token-type "whole")
-            (setq ex-addresses
-                  (cons (point-max) (cons (point-min) ex-addresses))))
-           ((string= ex-token-type "comma")
-            (setq ex-addresses
-                  (cons (if (null address) (point) address) ex-addresses)))
-           ((string= ex-token-type "semi-colon")
-            (if address (setq dot address))
-            (setq ex-addresses
-                  (cons (if (null address) (point) address) ex-addresses)))
-           (t (let ((ans (vip-get-ex-address-subr address dot)))
-                (if ans (setq address ans))))))))
-
-(defun vip-get-ex-pat ()
-  "get a regular expression and set ex-variant if found"
-  (with-current-buffer " *ex-working-space*"
-    (skip-chars-forward " \t")
-    (if (looking-at "!")
-       (progn
-         (setq ex-g-variant (not ex-g-variant)
-               ex-g-flag (not ex-g-flag))
-         (forward-char 1)
-         (skip-chars-forward " \t")))
-    (if (looking-at "/")
-       (progn
-         (forward-char 1)
-         (set-mark (point))
-         (let ((cont t))
-           (while (and (not (eolp)) cont)
-             (re-search-forward "[^/]*\\(/\\|\n\\)")
-             ;;(re-search-forward "[^/]*/")
-             (if (not (vip-looking-back "[^\\]\\(\\\\\\\\\\)*\\\\/"))
-                 (setq cont nil))))
-         (setq ex-token
-               (if (= (mark) (point)) ""
-                 (buffer-substring (1- (point)) (mark))))
-         (backward-char 1))
-      (setq ex-token nil))))
-
-(defun vip-get-ex-command ()
-  "get an ex command"
-  (with-current-buffer " *ex-working-space*"
-    (if (looking-at "/") (forward-char 1))
-    (skip-chars-forward " \t")
-    (cond ((looking-at "[a-z]")
-          (vip-get-ex-com-subr)
-          (if (string= ex-token-type "non-command")
-               (error "%s: Not an editor command" ex-token)))
-         ((looking-at "[!=><&~]")
-          (setq ex-token (char-to-string (following-char)))
-          (forward-char 1))
-         (t (error "Could not find an ex command")))))
-
-(defun vip-get-ex-opt-gc ()
-  "get an ex option g or c"
-  (with-current-buffer " *ex-working-space*"
-    (if (looking-at "/") (forward-char 1))
-    (skip-chars-forward " \t")
-    (cond ((looking-at "g")
-          (setq ex-token "g")
-          (forward-char 1)
-          t)
-         ((looking-at "c")
-          (setq ex-token "c")
-          (forward-char 1)
-          t)
-         (t nil))))
-
-(defun vip-default-ex-addresses (&optional whole-flag)
-  "compute default addresses.  whole-flag means whole buffer."
-  (cond ((null ex-addresses)
-        (setq ex-addresses
-              (if whole-flag
-                  (cons (point-max) (cons (point-min) nil))
-                (cons (point) (cons (point) nil)))))
-       ((null (cdr ex-addresses))
-        (setq ex-addresses
-              (cons (car ex-addresses) ex-addresses)))))
-
-(defun vip-get-ex-address ()
-  "get an ex-address as a marker and set ex-flag if a flag is found"
-  (let ((address (point-marker)) (cont t))
-    (setq ex-token "")
-    (setq ex-flag nil)
-    (while cont
-      (vip-get-ex-token)
-      (cond ((string= ex-token-type "command")
-            (if (or (string= ex-token "print") (string= ex-token "list")
-                    (string= ex-token "#"))
-                (progn
-                  (setq ex-flag t)
-                  (setq cont nil))
-             (error "Address expected")))
-           ((string= ex-token-type "end-mark")
-            (setq cont nil))
-           ((string= ex-token-type "whole")
-            (error "a trailing address is expected"))
-           ((string= ex-token-type "comma")
-            (error "Extra characters after an address"))
-           (t (let ((ans (vip-get-ex-address-subr address (point-marker))))
-                (if ans (setq address ans))))))
-    address))
-
-(defun vip-get-ex-address-subr (old-address dot)
-  "returns an address as a point"
-  (let ((address nil))
-    (if (null old-address) (setq old-address dot))
-    (cond ((string= ex-token-type "dot")
-          (setq address dot))
-         ((string= ex-token-type "add-number")
-          (save-excursion
-            (goto-char old-address)
-            (forward-line (if (= old-address 0) (1- ex-token) ex-token))
-            (setq address (point-marker))))
-         ((string= ex-token-type "sub-number")
-          (save-excursion
-            (goto-char old-address)
-            (forward-line (- ex-token))
-            (setq address (point-marker))))
-         ((string= ex-token-type "abs-number")
-          (save-excursion
-            (goto-char (point-min))
-            (if (= ex-token 0) (setq address 0)
-              (forward-line (1- ex-token))
-              (setq address (point-marker)))))
-         ((string= ex-token-type "end")
-          (setq address (point-max-marker)))
-         ((string= ex-token-type "plus") t);; do nothing
-         ((string= ex-token-type "minus") t);; do nothing
-         ((string= ex-token-type "search-forward")
-          (save-excursion
-            (ex-search-address t)
-            (setq address (point-marker))))
-         ((string= ex-token-type "search-backward")
-          (save-excursion
-            (ex-search-address nil)
-            (setq address (point-marker))))
-         ((string= ex-token-type "goto-mark")
-          (save-excursion
-            (if (null ex-token)
-                (exchange-point-and-mark)
-              (goto-char (register-to-point (- ex-token (- ?a ?\C-a)))))
-            (setq address (point-marker)))))
-    address))
-
-(defun ex-search-address (forward)
-  "search pattern and set address"
-  (if (string= ex-token "")
-      (if (null vip-s-string) (error "No previous search string")
-       (setq ex-token vip-s-string))
-    (setq vip-s-string ex-token))
-  (if forward
-      (progn
-       (forward-line 1)
-       (re-search-forward ex-token))
-    (forward-line -1)
-    (re-search-backward ex-token)))
-
-(defun vip-get-ex-buffer ()
-  "get a buffer name and set ex-count and ex-flag if found"
-  (setq ex-buffer nil)
-  (setq ex-count nil)
-  (setq ex-flag nil)
-  (with-current-buffer " *ex-working-space*"
-    (skip-chars-forward " \t")
-    (if (looking-at "[a-zA-Z]")
-       (progn
-         (setq ex-buffer (following-char))
-         (forward-char 1)
-         (skip-chars-forward " \t")))
-    (if (looking-at "[0-9]")
-       (progn
-         (set-mark (point))
-         (re-search-forward "[0-9][0-9]*")
-         (setq ex-count (string-to-number (buffer-substring (point) (mark))))
-         (skip-chars-forward " \t")))
-    (if (looking-at "[pl#]")
-       (progn
-         (setq ex-flag t)
-         (forward-char 1)))
-    (if (not (looking-at "[\n|]"))
-       (error "Invalid extra characters"))))
-
-(defun vip-get-ex-count ()
-  (setq ex-variant nil
-       ex-count nil
-       ex-flag nil)
-  (with-current-buffer " *ex-working-space*"
-    (skip-chars-forward " \t")
-    (if (looking-at "!")
-       (progn
-         (setq ex-variant t)
-         (forward-char 1)))
-    (skip-chars-forward " \t")
-    (if (looking-at "[0-9]")
-       (progn
-         (set-mark (point))
-         (re-search-forward "[0-9][0-9]*")
-         (setq ex-count (string-to-number (buffer-substring (point) (mark))))
-         (skip-chars-forward " \t")))
-    (if (looking-at "[pl#]")
-       (progn
-         (setq ex-flag t)
-         (forward-char 1)))
-    (if (not (looking-at "[\n|]"))
-       (error "Invalid extra characters"))))
-
-(defun vip-get-ex-file ()
-  "get a file name and set ex-variant, ex-append and ex-offset if found"
-  (setq ex-file nil
-       ex-variant nil
-       ex-append nil
-       ex-offset nil)
-  (with-current-buffer " *ex-working-space*"
-    (skip-chars-forward " \t")
-    (if (looking-at "!")
-       (progn
-         (setq ex-variant t)
-         (forward-char 1)
-         (skip-chars-forward " \t")))
-    (if (looking-at ">>")
-       (progn
-         (setq ex-append t
-               ex-variant t)
-         (forward-char 2)
-         (skip-chars-forward " \t")))
-    (if (looking-at "\\+")
-       (progn
-         (forward-char 1)
-         (set-mark (point))
-         (re-search-forward "[ \t\n]")
-         (backward-char 1)
-         (setq ex-offset (buffer-substring (point) (mark)))
-         (forward-char 1)
-         (skip-chars-forward " \t")))
-    (set-mark (point))
-    (re-search-forward "[ \t\n]")
-    (backward-char 1)
-    (setq ex-file (buffer-substring (point) (mark)))))
-
-(defun vip-execute-ex-command ()
-  "execute ex command using the value of addresses."
-  (cond ((string= ex-token "goto") (ex-goto))
-       ((string= ex-token "copy") (ex-copy nil))
-       ((string= ex-token "delete") (ex-delete))
-       ((string= ex-token "edit") (ex-edit))
-       ((string= ex-token "file") (vip-info-on-file))
-       ;((string= ex-token "global") (ex-global nil))
-       ((string= ex-token "join") (ex-line "join"))
-       ((string= ex-token "k") (ex-mark))
-       ((string= ex-token "mark") (ex-mark))
-       ((string= ex-token "map") (ex-map))
-       ((string= ex-token "move") (ex-copy t))
-       ((string= ex-token "put") (ex-put))
-       ((string= ex-token "quit") (ex-quit))
-       ((string= ex-token "read") (ex-read))
-       ((string= ex-token "set") (ex-set))
-       ((string= ex-token "shell") (ex-shell))
-       ((string= ex-token "substitute") (ex-substitute))
-       ((string= ex-token "stop") (suspend-emacs))
-       ((string= ex-token "t") (ex-copy nil))
-       ((string= ex-token "tag") (ex-tag))
-       ((string= ex-token "undo") (vip-undo))
-       ((string= ex-token "unmap") (ex-unmap))
-       ;((string= ex-token "v") (ex-global t))
-       ((string= ex-token "version") (vip-version))
-       ((string= ex-token "visual") (ex-edit))
-       ((string= ex-token "write") (ex-write nil))
-       ((string= ex-token "wq") (ex-write t))
-       ((string= ex-token "yank") (ex-yank))
-       ((string= ex-token "!") (ex-command))
-       ((string= ex-token "=") (ex-line-no))
-       ((string= ex-token ">") (ex-line "right"))
-       ((string= ex-token "<") (ex-line "left"))
-       ((string= ex-token "&") (ex-substitute t))
-       ((string= ex-token "~") (ex-substitute t t))
-       ((or (string= ex-token "append")
-            (string= ex-token "args")
-            (string= ex-token "change")
-            (string= ex-token "insert")
-            (string= ex-token "open")
-            )
-         (error "%s: No such command from VIP" ex-token))
-       ((or (string= ex-token "abbreviate")
-            (string= ex-token "list")
-            (string= ex-token "next")
-            (string= ex-token "print")
-            (string= ex-token "preserve")
-            (string= ex-token "recover")
-            (string= ex-token "rewind")
-            (string= ex-token "source")
-            (string= ex-token "unabbreviate")
-            (string= ex-token "xit")
-            (string= ex-token "z")
-            )
-         (error "%s: Not implemented in VIP" ex-token))
-       (t (error "%s: Not an editor command" ex-token))))
-
-(defun ex-goto ()
-  "ex goto command"
-  (if (null ex-addresses)
-      (setq ex-addresses (cons (point) nil)))
-  (push-mark)
-  (goto-char (car ex-addresses))
-  (beginning-of-line))
-
-(defun ex-copy (del-flag)
-  "ex copy and move command.  DEL-FLAG means delete."
-  (vip-default-ex-addresses)
-  (let ((address (vip-get-ex-address))
-       (end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-    (goto-char end)
-    (save-excursion
-      (set-mark beg)
-      (vip-enlarge-region (mark) (point))
-      (if del-flag (kill-region (point) (mark))
-       (copy-region-as-kill (point) (mark)))
-      (if ex-flag
-         (progn
-           (with-output-to-temp-buffer "*copy text*"
-             (princ
-              (if (or del-flag ex-g-flag ex-g-variant)
-                  (current-kill 0)
-                (buffer-substring (point) (mark)))))
-           (condition-case nil
-               (progn
-                 (vip-read-string "[Hit return to continue] ")
-                 (save-excursion (kill-buffer "*copy text*")))
-             (quit
-              (save-excursion (kill-buffer "*copy text*"))
-              (signal 'quit nil))))))
-      (if (= address 0)
-         (goto-char (point-min))
-       (goto-char address)
-       (forward-line 1))
-      (insert (current-kill 0))))
-
-(defun ex-delete ()
-  "ex delete"
-  (vip-default-ex-addresses)
-  (vip-get-ex-buffer)
-  (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-    (if (> beg end) (error "First address exceeds second"))
-    (save-excursion
-      (vip-enlarge-region beg end)
-      (exchange-point-and-mark)
-      (if ex-count
-         (progn
-           (set-mark (point))
-           (forward-line (1- ex-count)))
-       (set-mark end))
-      (vip-enlarge-region (point) (mark))
-      (if ex-flag
-         ;; show text to be deleted and ask for confirmation
-         (progn
-           (with-output-to-temp-buffer " *delete text*"
-             (princ (buffer-substring (point) (mark))))
-           (condition-case nil
-               (vip-read-string "[Hit return to continue] ")
-             (quit
-              (save-excursion (kill-buffer " *delete text*"))
-              (error "")))
-           (save-excursion (kill-buffer " *delete text*")))
-       (if ex-buffer
-           (if (and (<= ?A ex-buffer) (<= ex-buffer ?Z))
-               (vip-append-to-register
-                (+ ex-buffer 32) (point) (mark))
-             (copy-to-register ex-buffer (point) (mark) nil)))
-       (delete-region (point) (mark))))))
-
-(defun ex-edit ()
-  "ex-edit"
-  (vip-get-ex-file)
-  (if (and (not ex-variant) (buffer-modified-p) buffer-file-name)
-      (error "No write since last change (:e! overrides)"))
-  (vip-change-mode-to-emacs)
-  (set-buffer
-   (find-file-noselect (concat default-directory ex-file)))
-  (vip-change-mode-to-vi)
-  (goto-char (point-min))
-  (if ex-offset
-      (progn
-       (with-current-buffer " *ex-working-space*"
-         (delete-region (point-min) (point-max))
-         (insert ex-offset "\n")
-         (goto-char (point-min)))
-       (goto-char (vip-get-ex-address))
-       (beginning-of-line))))
-
-(defun ex-global (variant)
-  "ex global command"
-  (if (or ex-g-flag ex-g-variant)
-      (error "Global within global not allowed")
-    (if variant
-       (setq ex-g-flag nil
-             ex-g-variant t)
-      (setq ex-g-flag t
-           ex-g-variant nil)))
-  (vip-get-ex-pat)
-  (if (null ex-token)
-      (error "Missing regular expression for global command"))
-  (if (string= ex-token "")
-      (if (null vip-s-string) (error "No previous search string")
-       (setq ex-g-pat vip-s-string))
-    (setq ex-g-pat ex-token
-         vip-s-string ex-token))
-  (if (null ex-addresses)
-      (setq ex-addresses (list (point-max) (point-min))))
-  (let ((marks nil) (mark-count 0)
-       com-str (end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-    (if (> beg end) (error "First address exceeds second"))
-    (save-excursion
-      (vip-enlarge-region beg end)
-      (exchange-point-and-mark)
-      (let ((cont t) (limit (point-marker)))
-       (exchange-point-and-mark)
-       ;; skip the last line if empty
-       (beginning-of-line)
-       (if (and (eobp) (not (bobp))) (backward-char 1))
-       (while (and cont (not (bobp)) (>= (point) limit))
-         (beginning-of-line)
-         (set-mark (point))
-         (end-of-line)
-         (let ((found (re-search-backward ex-g-pat (mark) t)))
-           (if (or (and ex-g-flag found)
-                   (and ex-g-variant (not found)))
-               (progn
-                 (end-of-line)
-                 (setq mark-count (1+ mark-count))
-                 (setq marks (cons (point-marker) marks)))))
-         (beginning-of-line)
-         (if (bobp) (setq cont nil)
-           (forward-line -1)
-           (end-of-line)))))
-    (with-current-buffer " *ex-working-space*"
-      (setq com-str (buffer-substring (1+ (point)) (1- (point-max)))))
-    (while marks
-      (goto-char (car marks))
-      ;; report progress of execution on a slow machine.
-      ;;(message "Executing global command...")
-      ;;(if (zerop (% mark-count 10))
-      ;;    (message "Executing global command...%d" mark-count))
-      (vip-ex com-str)
-      (setq mark-count (1- mark-count))
-      (setq marks (cdr marks)))))
-;;(message "Executing global command...done")))
-
-(defun ex-line (com)
-  "ex line commands.  COM is join, shift-right or shift-left."
-  (vip-default-ex-addresses)
-  (vip-get-ex-count)
-  (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) point)
-    (if (> beg end) (error "First address exceeds second"))
-    (save-excursion
-      (vip-enlarge-region beg end)
-      (exchange-point-and-mark)
-      (if ex-count
-         (progn
-           (set-mark (point))
-           (forward-line ex-count)))
-      (if ex-flag
-         ;; show text to be joined and ask for confirmation
-         (progn
-           (with-output-to-temp-buffer " *text*"
-             (princ (buffer-substring (point) (mark))))
-           (condition-case nil
-               (progn
-                 (vip-read-string "[Hit return to continue] ")
-                 (ex-line-subr com (point) (mark)))
-             (quit
-              (ding)))
-           (save-excursion (kill-buffer " *text*")))
-       (ex-line-subr com (point) (mark)))
-      (setq point (point)))
-    (goto-char (1- point))
-    (beginning-of-line)))
-
-(defun ex-line-subr (com beg end)
-  (cond ((string= com "join")
-        (goto-char (min beg end))
-        (while (and (not (eobp)) (< (point) (max beg end)))
-          (end-of-line)
-          (if (and (<= (point) (max beg end)) (not (eobp)))
-              (progn
-                (forward-line 1)
-                (delete-region (point) (1- (point)))
-                (if (not ex-variant) (fixup-whitespace))))))
-       ((or (string= com "right") (string= com "left"))
-        (indent-rigidly
-         (min beg end) (max beg end)
-         (if (string= com "right") vip-shift-width (- vip-shift-width)))
-        (goto-char (max beg end))
-        (end-of-line)
-        (forward-char 1))))
-
-(defun ex-mark ()
-  "ex mark"
-  (let (char)
-    (if (null ex-addresses)
-       (setq ex-addresses
-             (cons (point) nil)))
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (if (looking-at "[a-z]")
-         (progn
-           (setq char (following-char))
-           (forward-char 1)
-           (skip-chars-forward " \t")
-           (if (not (looking-at "[\n|]"))
-               (error "Extra characters at end of \"k\" command")))
-       (if (looking-at "[\n|]")
-           (error "\"k\" requires a following letter")
-         (error "Mark must specify a letter"))))
-    (save-excursion
-      (goto-char (car ex-addresses))
-      (point-to-register (- char (- ?a ?\C-a)) nil))))
-
-(defun ex-map ()
-  "ex map"
-  (let (char string)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (setq char (char-to-string (following-char)))
-      (forward-char 1)
-      (skip-chars-forward " \t")
-      (if (looking-at "[\n|]") (error "Missing rhs"))
-      (set-mark (point))
-      (with-no-warnings
-       (end-of-buffer))
-      (backward-char 1)
-      (setq string (buffer-substring (mark) (point))))
-    (if (not (lookup-key ex-map char))
-       (define-key ex-map char
-         (or (lookup-key vip-mode-map char) 'vip-nil)))
-    (define-key vip-mode-map char
-      (lambda (count)
-       (interactive "p")
-       (execute-kbd-macro string count)))))
-
-(defun ex-unmap ()
-  "ex unmap"
-  (let (char)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (setq char (char-to-string (following-char)))
-      (forward-char 1)
-      (skip-chars-forward " \t")
-      (if (not (looking-at "[\n|]")) (error "Macro must be a character")))
-    (if (not (lookup-key ex-map char))
-       (error "That macro wasn't mapped"))
-    (define-key vip-mode-map char (lookup-key ex-map char))
-    (define-key ex-map char nil)))
-
-(defun ex-put ()
-  "ex put"
-  (let ((point (if (null ex-addresses) (point) (car ex-addresses))))
-    (vip-get-ex-buffer)
-    (setq vip-use-register ex-buffer)
-    (goto-char point)
-    (if (= point 0) (vip-Put-back 1) (vip-put-back 1))))
-
-(defun ex-quit ()
-  "ex quit"
-  (let (char)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (setq char (following-char)))
-    (if (= char ?!) (kill-emacs t) (save-buffers-kill-emacs))))
-
-(defun ex-read ()
-  "ex read"
-  (let ((point (if (null ex-addresses) (point) (car ex-addresses)))
-       (variant nil) command file)
-    (goto-char point)
-    (if (not (= point 0)) (with-no-warnings (next-line 1)))
-    (beginning-of-line)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (if (looking-at "!")
-         (progn
-           (setq variant t)
-           (forward-char 1)
-           (skip-chars-forward " \t")
-           (set-mark (point))
-           (end-of-line)
-           (setq command (buffer-substring (mark) (point))))
-       (set-mark (point))
-       (re-search-forward "[ \t\n]")
-       (backward-char 1)
-       (setq file (buffer-substring (point) (mark)))))
-      (if variant
-         (shell-command command t)
-       (with-no-warnings
-         (insert-file file)))))
-
-(defalias 'ex-set #'set-variable)
-
-(defun ex-shell ()
-  "ex shell"
-  (vip-change-mode-to-emacs)
-  (shell))
-
-(defun ex-substitute (&optional repeat r-flag)
-  "ex substitute.
-If REPEAT use previous reg-exp which is ex-reg-exp or
-vip-s-string"
-  (let (pat repl (opt-g nil) (opt-c nil) (matched-pos nil))
-    (if repeat (setq ex-token nil) (vip-get-ex-pat))
-    (if (null ex-token)
-       (setq pat (if r-flag vip-s-string ex-reg-exp)
-             repl ex-repl)
-      (setq pat (if (string= ex-token "") vip-s-string ex-token))
-      (setq vip-s-string pat
-           ex-reg-exp pat)
-      (vip-get-ex-pat)
-      (if (null ex-token)
-         (setq ex-token ""
-               ex-repl "")
-       (setq repl ex-token
-             ex-repl ex-token)))
-    (while (vip-get-ex-opt-gc)
-      (if (string= ex-token "g") (setq opt-g t) (setq opt-c t)))
-    (vip-get-ex-count)
-    (if ex-count
-       (save-excursion
-         (if ex-addresses (goto-char (car ex-addresses)))
-         (set-mark (point))
-         (forward-line (1- ex-count))
-         (setq ex-addresses (cons (point) (cons (mark) nil))))
-      (if (null ex-addresses)
-         (setq ex-addresses (cons (point) (cons (point) nil)))
-       (if (null (cdr ex-addresses))
-           (setq ex-addresses (cons (car ex-addresses) ex-addresses)))))
-    ;(setq G opt-g)
-    (let ((beg (car ex-addresses)) (end (car (cdr ex-addresses)))
-         eol-mark) ;;(cont t)
-      (save-excursion
-       (vip-enlarge-region beg end)
-       (let ((limit (save-excursion
-                      (goto-char (max (point) (mark)))
-                      (point-marker))))
-         (goto-char (min (point) (mark)))
-         (while (< (point) limit)
-           (end-of-line)
-           (setq eol-mark (point-marker))
-           (beginning-of-line)
-           (if opt-g
-               (progn
-                 (while (and (not (eolp))
-                             (re-search-forward pat eol-mark t))
-                   (if (or (not opt-c) (y-or-n-p "Replace? "))
-                       (progn
-                         (setq matched-pos (point))
-                         (replace-match repl))))
-                 (end-of-line)
-                 (forward-char))
-             (if (and (re-search-forward pat eol-mark t)
-                      (or (not opt-c) (y-or-n-p "Replace? ")))
-                 (progn
-                   (setq matched-pos (point))
-                   (replace-match repl)))
-             (end-of-line)
-             (forward-char))))))
-    (if matched-pos (goto-char matched-pos))
-    (beginning-of-line)
-    (if opt-c (message "done"))))
-
-(defun ex-tag ()
-  "ex tag"
-  (let (tag)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (set-mark (point))
-      (skip-chars-forward "^ |\t\n")
-      (setq tag (buffer-substring (mark) (point))))
-    (if (not (string= tag "")) (setq ex-tag tag))
-    (vip-change-mode-to-emacs)
-    (condition-case conditions
-       (progn
-          (with-suppressed-warnings ((obsolete find-tag find-tag-other-window))
-           (if (string= tag "")
-               (find-tag ex-tag t)
-             (find-tag-other-window ex-tag)))
-         (vip-change-mode-to-vi))
-      (error
-       (vip-change-mode-to-vi)
-       (vip-message-conditions conditions)))))
-
-(defun ex-write (q-flag)
-  "ex write"
-  (vip-default-ex-addresses t)
-  (vip-get-ex-file)
-  (if (string= ex-file "")
-      (progn
-       (if (null buffer-file-name)
-           (error "No file associated with this buffer"))
-       (setq ex-file buffer-file-name))
-    (setq ex-file (expand-file-name ex-file)))
-  (if (and (not (string= ex-file (buffer-file-name)))
-          (file-exists-p ex-file)
-          (not ex-variant))
-      (error "\"%s\" File exists - use w! to override" ex-file))
-  (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-    (if (> beg end) (error "First address exceeds second"))
-    (save-excursion
-      (vip-enlarge-region beg end)
-      (write-region (point) (mark) ex-file ex-append t)))
-  (if (null buffer-file-name) (setq buffer-file-name ex-file))
-  (if q-flag (save-buffers-kill-emacs)))
-
-(defun ex-yank ()
-  "ex yank"
-  (vip-default-ex-addresses)
-  (vip-get-ex-buffer)
-  (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-    (if (> beg end) (error "First address exceeds second"))
-    (save-excursion
-      (vip-enlarge-region beg end)
-      (exchange-point-and-mark)
-      (if (or ex-g-flag ex-g-variant) (error "Can't yank within global"))
-      (if ex-count
-         (progn
-           (set-mark (point))
-           (forward-line (1- ex-count)))
-       (set-mark end))
-      (vip-enlarge-region (point) (mark))
-      (if ex-flag (error "Extra characters at end of command"))
-      (if ex-buffer
-         (copy-to-register ex-buffer (point) (mark) nil))
-      (copy-region-as-kill (point) (mark)))))
-
-(defun ex-command ()
-  "execute shell command"
-  (let (command)
-    (with-current-buffer " *ex-working-space*"
-      (skip-chars-forward " \t")
-      (set-mark (point))
-      (end-of-line)
-      (setq command (buffer-substring (mark) (point))))
-    (if (null ex-addresses)
-       (shell-command command)
-      (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
-       (if (null beg) (setq beg end))
-       (save-excursion
-         (goto-char beg)
-         (set-mark end)
-         (vip-enlarge-region (point) (mark))
-         (shell-command-on-region (point) (mark) command t t))
-       (goto-char beg)))))
-
-(defun ex-line-no ()
-  "print line number"
-  (message "%d"
-          (1+ (count-lines
-               (point-min)
-               (if (null ex-addresses) (point-max) (car ex-addresses))))))
-
-(if (file-exists-p vip-startup-file) (load vip-startup-file))
-
-(provide 'vip)
-
-;;; vip.el ends here
diff --git a/lisp/obsolete/ws-mode.el b/lisp/obsolete/ws-mode.el
deleted file mode 100644
index d8ee63c8a01..00000000000
--- a/lisp/obsolete/ws-mode.el
+++ /dev/null
@@ -1,539 +0,0 @@
-;;; ws-mode.el --- WordStar emulation mode for GNU Emacs -*- lexical-binding: 
t -*-
-
-;; Copyright (C) 1991, 2001-2024 Free Software Foundation, Inc.
-
-;; Author: Juergen Nickelsen <nickel@cs.tu-berlin.de>
-;; Version: 0.7
-;; Keywords: emulations
-;; Obsolete-since: 24.5
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; This provides emulation of WordStar with a minor mode.
-
-;;; Code:
-
-(defgroup wordstar nil
-  "WordStar emulation within Emacs."
-  :prefix "wordstar-"
-  :prefix "ws-"
-  :group 'emulations)
-
-(defcustom wordstar-mode-lighter " WordStar"
-  "Lighter shown in the modeline for `wordstar' mode."
-  :type 'string)
-
-(defvar wordstar-C-k-map
-  (let ((map (make-keymap)))
-    (define-key map " " ())
-    (define-key map "0" #'ws-set-marker-0)
-    (define-key map "1" #'ws-set-marker-1)
-    (define-key map "2" #'ws-set-marker-2)
-    (define-key map "3" #'ws-set-marker-3)
-    (define-key map "4" #'ws-set-marker-4)
-    (define-key map "5" #'ws-set-marker-5)
-    (define-key map "6" #'ws-set-marker-6)
-    (define-key map "7" #'ws-set-marker-7)
-    (define-key map "8" #'ws-set-marker-8)
-    (define-key map "9" #'ws-set-marker-9)
-    (define-key map "b" #'ws-begin-block)
-    (define-key map "\C-b" #'ws-begin-block)
-    (define-key map "c" #'ws-copy-block)
-    (define-key map "\C-c" #'ws-copy-block)
-    (define-key map "d" #'save-buffers-kill-emacs)
-    (define-key map "\C-d" #'save-buffers-kill-emacs)
-    (define-key map "f" #'find-file)
-    (define-key map "\C-f" #'find-file)
-    (define-key map "h" #'ws-show-markers)
-    (define-key map "\C-h" #'ws-show-markers)
-    (define-key map "i" #'ws-indent-block)
-    (define-key map "\C-i" #'ws-indent-block)
-    (define-key map "k" #'ws-end-block)
-    (define-key map "\C-k" #'ws-end-block)
-    (define-key map "p" #'ws-print-block)
-    (define-key map "\C-p" #'ws-print-block)
-    (define-key map "q" #'kill-emacs)
-    (define-key map "\C-q" #'kill-emacs)
-    (define-key map "r" #'insert-file)
-    (define-key map "\C-r" #'insert-file)
-    (define-key map "s" #'save-some-buffers)
-    (define-key map "\C-s" #'save-some-buffers)
-    (define-key map "t" #'ws-mark-word)
-    (define-key map "\C-t" #'ws-mark-word)
-    (define-key map "u" #'ws-exdent-block)
-    (define-key map "\C-u" #'keyboard-quit)
-    (define-key map "v" #'ws-move-block)
-    (define-key map "\C-v" #'ws-move-block)
-    (define-key map "w" #'ws-write-block)
-    (define-key map "\C-w" #'ws-write-block)
-    (define-key map "x" #'save-buffers-kill-emacs)
-    (define-key map "\C-x" #'save-buffers-kill-emacs)
-    (define-key map "y" #'ws-delete-block)
-    (define-key map "\C-y" #'ws-delete-block)
-    map))
-
-(defvar wordstar-C-o-map
-  (let ((map (make-keymap)))
-    (define-key map " " ())
-    (define-key map "c" #'wordstar-center-line)
-    (define-key map "\C-c" #'wordstar-center-line)
-    (define-key map "b" #'switch-to-buffer)
-    (define-key map "\C-b" #'switch-to-buffer)
-    (define-key map "j" #'justify-current-line)
-    (define-key map "\C-j" #'justify-current-line)
-    (define-key map "k" #'kill-buffer)
-    (define-key map "\C-k" #'kill-buffer)
-    (define-key map "l" #'list-buffers)
-    (define-key map "\C-l" #'list-buffers)
-    (define-key map "m" #'auto-fill-mode)
-    (define-key map "\C-m" #'auto-fill-mode)
-    (define-key map "r" #'set-fill-column)
-    (define-key map "\C-r" #'set-fill-column)
-    (define-key map "\C-u" #'keyboard-quit)
-    (define-key map "wd" #'delete-other-windows)
-    (define-key map "wh" #'split-window-right)
-    (define-key map "wo" #'other-window)
-    (define-key map "wv" #'split-window-below)
-    map))
-
-(defvar wordstar-C-q-map
-  (let ((map (make-keymap)))
-    (define-key map " " ())
-    (define-key map "0" #'ws-find-marker-0)
-    (define-key map "1" #'ws-find-marker-1)
-    (define-key map "2" #'ws-find-marker-2)
-    (define-key map "3" #'ws-find-marker-3)
-    (define-key map "4" #'ws-find-marker-4)
-    (define-key map "5" #'ws-find-marker-5)
-    (define-key map "6" #'ws-find-marker-6)
-    (define-key map "7" #'ws-find-marker-7)
-    (define-key map "8" #'ws-find-marker-8)
-    (define-key map "9" #'ws-find-marker-9)
-    (define-key map "a" #'ws-query-replace)
-    (define-key map "\C-a" #'ws-query-replace)
-    (define-key map "b" #'ws-goto-block-begin)
-    (define-key map "\C-b" #'ws-goto-block-begin)
-    (define-key map "c" #'end-of-buffer)
-    (define-key map "\C-c" #'end-of-buffer)
-    (define-key map "d" #'end-of-line)
-    (define-key map "\C-d" #'end-of-line)
-    (define-key map "f" #'ws-search)
-    (define-key map "\C-f" #'ws-search)
-    (define-key map "k" #'ws-goto-block-end)
-    (define-key map "\C-k" #'ws-goto-block-end)
-    (define-key map "l" #'ws-undo)
-    (define-key map "\C-l" #'ws-undo)
-    ;; (define-key map "p" #'ws-last-cursorp)
-    ;; (define-key map "\C-p" #'ws-last-cursorp)
-    (define-key map "r" #'beginning-of-buffer)
-    (define-key map "\C-r" #'beginning-of-buffer)
-    (define-key map "s" #'beginning-of-line)
-    (define-key map "\C-s" #'beginning-of-line)
-    (define-key map "\C-u" #'keyboard-quit)
-    (define-key map "w" #'ws-last-error)
-    (define-key map "\C-w" #'ws-last-error)
-    (define-key map "y" #'ws-kill-eol)
-    (define-key map "\C-y" #'ws-kill-eol)
-    (define-key map "\177" #'ws-kill-bol)
-    map))
-
-(defvar wordstar-mode-map
-  (let ((map (make-keymap)))
-    (define-key map "\C-a" #'backward-word)
-    (define-key map "\C-b" #'fill-paragraph)
-    (define-key map "\C-c" #'scroll-up-command)
-    (define-key map "\C-d" #'forward-char)
-    (define-key map "\C-e" #'previous-line)
-    (define-key map "\C-f" #'forward-word)
-    (define-key map "\C-g" #'delete-char)
-    (define-key map "\C-h" #'backward-char)
-    (define-key map "\C-i" #'indent-for-tab-command)
-    (define-key map "\C-j" #'help-for-help)
-    (define-key map "\C-k" wordstar-C-k-map)
-    (define-key map "\C-l" #'ws-repeat-search)
-    (define-key map "\C-n" #'open-line)
-    (define-key map "\C-o" wordstar-C-o-map)
-    (define-key map "\C-p" #'quoted-insert)
-    (define-key map "\C-q" wordstar-C-q-map)
-    (define-key map "\C-r" #'scroll-down-command)
-    (define-key map "\C-s" #'backward-char)
-    (define-key map "\C-t" #'kill-word)
-    (define-key map "\C-u" #'keyboard-quit)
-    (define-key map "\C-v" #'overwrite-mode)
-    (define-key map "\C-w" #'scroll-down-line)
-    (define-key map "\C-x" #'next-line)
-    (define-key map "\C-y" #'kill-complete-line)
-    (define-key map "\C-z" #'scroll-up-line)
-    map))
-
-;; wordstar-C-j-map not yet implemented
-(defvar wordstar-C-j-map nil)
-
-;;;###autoload
-(define-minor-mode wordstar-mode
-  "Minor mode with WordStar-like key bindings.
-
-BUGS:
- - Help menus with WordStar commands (C-j just calls help-for-help)
-   are not implemented
- - Options for search and replace
- - Show markers (C-k h) is somewhat strange
- - Search and replace (C-q a) is only available in forward direction
-
-No key bindings beginning with ESC are installed, they will work
-Emacs-like."
-  :group 'wordstar
-  :lighter wordstar-mode-lighter
-  :keymap wordstar-mode-map)
-
-(defun turn-on-wordstar-mode ()
-  (when (and (not (minibufferp))
-             (not wordstar-mode))
-    (wordstar-mode 1)))
-
-(define-globalized-minor-mode global-wordstar-mode wordstar-mode
-  turn-on-wordstar-mode)
-
-(defun wordstar-center-paragraph ()
-  "Center each line in the paragraph at or after point.
-See `wordstar-center-line' for more info."
-  (interactive)
-  (save-excursion
-    (forward-paragraph)
-    (or (bolp) (newline 1))
-    (let ((end (point)))
-      (backward-paragraph)
-      (wordstar-center-region (point) end))))
-
-(defun wordstar-center-region (from to)
-  "Center each line starting in the region.
-See `wordstar-center-line' for more info."
-  (interactive "r")
-  (if (> from to)
-      (let ((tem to))
-       (setq to from from tem)))
-  (save-excursion
-    (save-restriction
-      (narrow-to-region from to)
-      (goto-char from)
-      (while (not (eobp))
-       (wordstar-center-line)
-       (forward-line 1)))))
-
-(defun wordstar-center-line ()
-  "Center the line point is on, within the width specified by `fill-column'.
-This means adjusting the indentation to match
-the distance between the end of the text and `fill-column'."
-  (interactive)
-  (save-excursion
-    (let (line-length)
-      (beginning-of-line)
-      (delete-horizontal-space)
-      (end-of-line)
-      (delete-horizontal-space)
-      (setq line-length (current-column))
-      (beginning-of-line)
-      (indent-to
-       (+ left-margin
-         (/ (- fill-column left-margin line-length) 2))))))
-
-;;;;;;;;;;;
-;; wordstar special variables:
-
-(defvar ws-marker-0 nil "Position marker 0 in WordStar mode.")
-(defvar ws-marker-1 nil "Position marker 1 in WordStar mode.")
-(defvar ws-marker-2 nil "Position marker 2 in WordStar mode.")
-(defvar ws-marker-3 nil "Position marker 3 in WordStar mode.")
-(defvar ws-marker-4 nil "Position marker 4 in WordStar mode.")
-(defvar ws-marker-5 nil "Position marker 5 in WordStar mode.")
-(defvar ws-marker-6 nil "Position marker 6 in WordStar mode.")
-(defvar ws-marker-7 nil "Position marker 7 in WordStar mode.")
-(defvar ws-marker-8 nil "Position marker 8 in WordStar mode.")
-(defvar ws-marker-9 nil "Position marker 9 in WordStar mode.")
-
-(defvar ws-block-begin-marker nil "Beginning of \"Block\" in WordStar mode.")
-(defvar ws-block-end-marker nil "End of \"Block\" in WordStar mode.")
-
-(defvar ws-search-string nil "String of last search in WordStar mode.")
-(defvar ws-search-direction t
-  "Direction of last search in WordStar mode.  t if forward, nil if backward.")
-
-(defvar ws-last-cursorposition nil
-  "Position before last search etc. in WordStar mode.")
-
-(defvar ws-last-errormessage nil
-  "Last error message issued by a WordStar mode function.")
-
-;;;;;;;;;;;
-;; wordstar special functions:
-
-(defun ws-error (string)
-  "Report error of a WordStar special function.
-Error message is saved in `ws-last-errormessage' for recovery
-with C-q w."
-  (setq ws-last-errormessage string)
-  (error string))
-
-(defun ws-begin-block ()
-  "In WordStar mode: Set block begin marker to current cursor position."
-  (interactive)
-  (setq ws-block-begin-marker (point-marker))
-  (message "Block begin marker set"))
-
-(defun ws-show-markers ()
-  "In WordStar mode: Show block markers."
-  (interactive)
-  (if (or ws-block-begin-marker ws-block-end-marker)
-      (save-excursion
-       (if ws-block-begin-marker
-           (progn
-             (goto-char ws-block-begin-marker)
-             (message "Block begin marker")
-             (sit-for 2))
-         (message "Block begin marker not set")
-         (sit-for 2))
-       (if ws-block-end-marker
-           (progn
-             (goto-char ws-block-end-marker)
-             (message "Block end marker")
-             (sit-for 2))
-         (message "Block end marker not set"))
-       (message ""))
-    (message "Block markers not set")))
-
-(defun ws-indent-block ()
-  "In WordStar mode: Indent block (not yet implemented)."
-  (interactive)
-  (ws-error "Indent block not yet implemented"))
-
-(defun ws-end-block ()
-  "In WordStar mode: Set block end marker to current cursor position."
-  (interactive)
-  (setq ws-block-end-marker (point-marker))
-  (message "Block end marker set"))
-
-(defun ws-print-block ()
-  "In WordStar mode: Print block."
-  (interactive)
-  (message "Don't do this. Write block to a file (C-k w) and print this file"))
-
-(defun ws-mark-word ()
-  "In WordStar mode: Mark current word as block."
-  (interactive)
-  (save-excursion
-    (forward-word 1)
-    (sit-for 1)
-    (ws-end-block)
-    (forward-word -1)
-    (sit-for 1)
-    (ws-begin-block)))
-
-(defun ws-exdent-block ()
-  "I don't know what this (C-k u) should do."
-  (interactive)
-  (ws-error "This won't be done -- not yet implemented"))
-
-(defun ws-move-block ()
-  "In WordStar mode: Move block to current cursor position."
-  (interactive)
-  (if (and ws-block-begin-marker ws-block-end-marker)
-      (progn
-       (kill-region ws-block-begin-marker ws-block-end-marker)
-       (yank)
-       (save-excursion
-         (goto-char (region-beginning))
-         (setq ws-block-begin-marker (point-marker))
-         (goto-char (region-end))
-         (setq ws-block-end-marker (point-marker))))
-    (ws-error (cond (ws-block-begin-marker "Block end marker not set")
-                   (ws-block-end-marker "Block begin marker not set")
-                   (t "Block markers not set")))))
-
-(defun ws-write-block ()
-  "In WordStar mode: Write block to file."
-  (interactive)
-  (if (and ws-block-begin-marker ws-block-end-marker)
-      (let ((filename (read-file-name "Write block to file: ")))
-       (write-region ws-block-begin-marker ws-block-end-marker filename))
-    (ws-error (cond (ws-block-begin-marker "Block end marker not set")
-                   (ws-block-end-marker "Block begin marker not set")
-                   (t "Block markers not set")))))
-
-
-(defun ws-delete-block ()
-  "In WordStar mode: Delete block."
-  (interactive)
-  (if (and ws-block-begin-marker ws-block-end-marker)
-      (progn
-       (kill-region ws-block-begin-marker ws-block-end-marker)
-       (setq ws-block-end-marker nil)
-       (setq ws-block-begin-marker nil))
-    (ws-error (cond (ws-block-begin-marker "Block end marker not set")
-                   (ws-block-end-marker "Block begin marker not set")
-                   (t "Block markers not set")))))
-
-(defun ws-goto-block-begin ()
-  "In WordStar mode: Go to block begin marker."
-  (interactive)
-  (if ws-block-begin-marker
-      (progn
-       (setq ws-last-cursorposition (point-marker))
-       (goto-char ws-block-begin-marker))
-    (ws-error "Block begin marker not set")))
-
-(defun ws-search (string)
-  "In WordStar mode: Search string, remember string for repetition."
-  (interactive "sSearch for: ")
-  (message "Forward (f) or backward (b)")
-  (let ((direction
-        (read-char)))
-    (cond ((equal (upcase direction) ?F)
-          (setq ws-search-string string)
-          (setq ws-search-direction t)
-          (setq ws-last-cursorposition (point-marker))
-          (search-forward string))
-         ((equal (upcase direction) ?B)
-          (setq ws-search-string string)
-          (setq ws-search-direction nil)
-          (setq ws-last-cursorposition (point-marker))
-          (search-backward string))
-         (t (keyboard-quit)))))
-
-(defun ws-goto-block-end ()
-  "In WordStar mode: Go to block end marker."
-  (interactive)
-  (if ws-block-end-marker
-      (progn
-       (setq ws-last-cursorposition (point-marker))
-       (goto-char ws-block-end-marker))
-    (ws-error "Block end marker not set")))
-
-(defun ws-undo ()
-  "In WordStar mode: Undo and give message about undoing more changes."
-  (interactive)
-  (undo)
-  (message "Repeat C-q l to undo more changes"))
-
-(defun ws-goto-last-cursorposition ()
-  "In WordStar mode: Go to position before last search."
-  (interactive)
-  (if ws-last-cursorposition
-      (progn
-       (setq ws-last-cursorposition (point-marker))
-       (goto-char ws-last-cursorposition))
-    (ws-error "No last cursor position available")))
-
-(defun ws-last-error ()
-  "In WordStar mode: repeat last error message.
-This will only work for errors raised by WordStar mode functions."
-  (interactive)
-  (if ws-last-errormessage
-      (message "%s" ws-last-errormessage)
-    (message "No WordStar error yet")))
-
-(defun ws-kill-eol ()
-  "In WordStar mode: Kill to end of line (like WordStar, not like Emacs)."
-  (interactive)
-  (let ((p (point)))
-    (end-of-line)
-    (kill-region p (point))))
-
-(defun ws-kill-bol ()
-  "In WordStar mode: Kill to beginning of line (like WordStar, not like 
Emacs)."
-  (interactive)
-  (let ((p (point)))
-    (beginning-of-line)
-    (kill-region (point) p)))
-
-(defun kill-complete-line ()
-  "Kill the complete line."
-  (interactive)
-  (beginning-of-line)
-  (if (eobp) (error "End of buffer"))
-  (let ((beg (point)))
-    (forward-line 1)
-    (kill-region beg (point))))
-
-(defun ws-repeat-search ()
-  "In WordStar mode: Repeat last search."
-  (interactive)
-  (setq ws-last-cursorposition (point-marker))
-  (if ws-search-string
-      (if ws-search-direction
-         (search-forward ws-search-string)
-       (search-backward ws-search-string))
-    (ws-error "No search to repeat")))
-
-(defun ws-query-replace (from to)
-  "In WordStar mode: Search string, remember string for repetition."
-  (interactive "sReplace: \n\
-sWith: " )
-  (setq ws-search-string from)
-  (setq ws-search-direction t)
-  (setq ws-last-cursorposition (point-marker))
-  (query-replace from to))
-
-(defun ws-copy-block ()
-  "In WordStar mode: Copy block to current cursor position."
-  (interactive)
-  (if (and ws-block-begin-marker ws-block-end-marker)
-      (progn
-       (copy-region-as-kill ws-block-begin-marker ws-block-end-marker)
-       (yank)
-       (save-excursion
-         (goto-char (region-beginning))
-         (setq ws-block-begin-marker (point-marker))
-         (goto-char (region-end))
-         (setq ws-block-end-marker (point-marker))))
-    (ws-error (cond (ws-block-begin-marker "Block end marker not set")
-                   (ws-block-end-marker "Block begin marker not set")
-                   (t "Block markers not set")))))
-
-(defmacro ws-set-marker (&rest indices)
-  (let (n forms)
-    (while indices
-      (setq n (pop indices))
-      (push `(defun ,(intern (format "ws-set-marker-%d" n)) ()
-               ,(format "In WordStar mode: Set marker %d to current cursor 
position" n)
-               (interactive)
-               (setq ,(intern (format "ws-marker-%d" n)) (point-marker))
-               (message ,(format "Marker %d set" n)))
-            forms))
-    `(progn ,@(nreverse forms))))
-
-(ws-set-marker 0 1 2 3 4 5 6 7 8 9)
-
-(defmacro ws-find-marker (&rest indices)
-  (let (n forms)
-    (while indices
-      (setq n (pop indices))
-      (push `(defun ,(intern (format "ws-find-marker-%d" n)) ()
-               ,(format "In WordStar mode: Go to marker %d." n)
-               (interactive)
-               (if ,(intern (format "ws-marker-%d" n))
-                   (progn (setq ws-last-cursorposition (point-marker))
-                          (goto-char ,(intern (format "ws-marker-%d" n))))
-                 (ws-error ,(format "Marker %d not set" n))))
-            forms))
-    `(progn ,@(nreverse forms))))
-
-(ws-find-marker 0 1 2 3 4 5 6 7 8 9)
-
-(provide 'ws-mode)
-
-;;; ws-mode.el ends here
diff --git a/lisp/obsolete/yow.el b/lisp/obsolete/yow.el
deleted file mode 100644
index eb4c65c4084..00000000000
--- a/lisp/obsolete/yow.el
+++ /dev/null
@@ -1,94 +0,0 @@
-;;; yow.el --- quote random zippyisms  -*- lexical-binding: t; -*-
-
-;; Copyright (C) 1993-1995, 2000-2024 Free Software Foundation, Inc.
-
-;; Author: Richard Mlynarik
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: games
-;; Obsolete-since: 24.4
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software: you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Important pinheadery for GNU Emacs.
-;; This file is obsolete.  For similar functionality, see
-;; fortune.el and cookie1.el.
-
-;;; Code:
-
-(require 'cookie1)
-
-(defgroup yow nil
-  "Quote random zippyisms."
-  :prefix "yow-"
-  :group 'games)
-
-(defcustom yow-file (expand-file-name "yow.lines" data-directory)
-   "File containing pertinent pinhead phrases."
-  :type 'file)
-
-(defconst yow-load-message "Am I CONSING yet?...")
-(defconst yow-after-load-message "I have SEEN the CONSING!!")
-
-;;;###autoload
-(defun yow (&optional insert display)
-  "Return or display a random Zippy quotation.  With prefix arg, insert it."
-  (interactive "P\np")
-  (let ((yow (cookie yow-file yow-load-message yow-after-load-message)))
-    (cond (insert
-          (insert yow))
-         ((not display)
-          yow)
-         (t
-          (message "%s" yow)))))
-
-(defsubst read-zippyism (prompt &optional require-match)
-  "Read a Zippyism from the minibuffer with completion, prompting with PROMPT.
-If optional second arg is non-nil, require input to match a completion."
-  (cookie-read prompt yow-file yow-load-message yow-after-load-message
-              require-match))
-
-;;;###autoload
-(defun insert-zippyism (&optional zippyism)
-  "Prompt with completion for a known Zippy quotation, and insert it at point."
-  (interactive (list (read-zippyism "Pinhead wisdom: " t)))
-  (insert zippyism))
-
-;;;###autoload
-(defun apropos-zippy (regexp)
-  "Return a list of all Zippy quotes matching REGEXP.
-If called interactively, display a list of matches."
-  (interactive "sApropos Zippy (regexp): ")
-  (cookie-apropos regexp yow-file (called-interactively-p 'interactive)))
-
-
-;; Yowza!! Feed zippy quotes to the doctor. Watch results.
-;; fun, fun, fun. Entertainment for hours...
-;;
-;; written by Kayvan Aghaiepour
-
-(declare-function doctor-ret-or-read "doctor" (arg))
-
-;;;###autoload
-(defun psychoanalyze-pinhead ()
-  "Zippy goes to the analyst."
-  (interactive)
-  (cookie-doctor yow-file))
-
-(provide 'yow)
-
-;;; yow.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]