unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* [PATCH] gnu: Add most debian patches to nvi.
@ 2015-01-20 18:20 Marek Benc
  2015-01-21  9:35 ` Andreas Enge
  0 siblings, 1 reply; 11+ messages in thread
From: Marek Benc @ 2015-01-20 18:20 UTC (permalink / raw)
  To: guix-devel

[-- Attachment #1: Type: text/plain, Size: 111 bytes --]

Nvi has some bugs, and the Debian people have some patches... so, I 
decided to import most of them into Guix.

[-- Attachment #2: nvi-debian-patches.patch --]
[-- Type: text/x-patch, Size: 236811 bytes --]

From 802ffa3c75be0ce04e84aadbefc146802650e4be Mon Sep 17 00:00:00 2001
From: Marek Benc <merkur32@gmail.com>
Date: Tue, 20 Jan 2015 18:49:54 +0100
Subject: [PATCH] gnu: Add most debian patches to nvi.

* gnu/packages/patches/nvi-additional-upstream-data.patch: New file.
* gnu/packages/patches/nvi-casting.patch: New file.
* gnu/packages/patches/nvi-db4.patch: New file.
* gnu/packages/patches/nvi-dbpagesize-binpower.patch: New file.
* gnu/packages/patches/nvi-exrc-writability-check.patch: New file.
* gnu/packages/patches/nvi-fallback-to-dumb-term.patch: New file.
* gnu/packages/patches/nvi-file-backup.patch: New file.
* gnu/packages/patches/nvi-glibc-has-grantpt.patch: New file.
* gnu/packages/patches/nvi-include-term-h.patch: New file.
* gnu/packages/patches/nvi-lfs.patch: New file.
* gnu/packages/patches/nvi-manpage-errors.patch: New file.
* gnu/packages/patches/nvi-manpage-note-dropped-F.patch: New file.
* gnu/packages/patches/nvi-no-one-line-visual.patch: New file.
* gnu/packages/patches/nvi-private-regex-fixes.patch: New file.
* gnu/packages/patches/nvi-safe-printf.patch: New file.
* gnu/packages/patches/nvi-search-word.patch: New file.
* gnu/packages/patches/nvi-support-C-locale.patch: New file.
* gnu/packages/patches/nvi-trailing-tab-segv.patch: New file.
* gnu/packages/patches/nvi-tutorial-typos.patch: New file.
* gnu/packages/patches/nvi-widechar-horrors.patch: New file.
* gnu/packages/nvi.scm (nvi): Make use of them.
* gnu-system.am (dist_patch_DATA): Add them.

---
 gnu-system.am                                      |   20 +
 gnu/packages/nvi.scm                               |   23 +-
 .../patches/nvi-additional-upstream-data.patch     | 3485 ++++++++++++++++++++
 gnu/packages/patches/nvi-casting.patch             |   28 +
 gnu/packages/patches/nvi-db4.patch                 |   29 +
 gnu/packages/patches/nvi-dbpagesize-binpower.patch |   25 +
 .../patches/nvi-exrc-writability-check.patch       |   62 +
 .../patches/nvi-fallback-to-dumb-term.patch        |   30 +
 gnu/packages/patches/nvi-file-backup.patch         |   36 +
 gnu/packages/patches/nvi-glibc-has-grantpt.patch   |   29 +
 gnu/packages/patches/nvi-include-term-h.patch      |   29 +
 gnu/packages/patches/nvi-lfs.patch                 |   29 +
 gnu/packages/patches/nvi-manpage-errors.patch      |  771 +++++
 .../patches/nvi-manpage-note-dropped-F.patch       |   59 +
 gnu/packages/patches/nvi-no-one-line-visual.patch  |   25 +
 gnu/packages/patches/nvi-private-regex-fixes.patch |   32 +
 gnu/packages/patches/nvi-safe-printf.patch         |   19 +
 gnu/packages/patches/nvi-search-word.patch         |   30 +
 gnu/packages/patches/nvi-support-C-locale.patch    |   31 +
 gnu/packages/patches/nvi-trailing-tab-segv.patch   |   19 +
 gnu/packages/patches/nvi-tutorial-typos.patch      |   64 +
 gnu/packages/patches/nvi-widechar-horrors.patch    |   69 +
 22 files changed, 4943 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/nvi-additional-upstream-data.patch
 create mode 100644 gnu/packages/patches/nvi-casting.patch
 create mode 100644 gnu/packages/patches/nvi-db4.patch
 create mode 100644 gnu/packages/patches/nvi-dbpagesize-binpower.patch
 create mode 100644 gnu/packages/patches/nvi-exrc-writability-check.patch
 create mode 100644 gnu/packages/patches/nvi-fallback-to-dumb-term.patch
 create mode 100644 gnu/packages/patches/nvi-file-backup.patch
 create mode 100644 gnu/packages/patches/nvi-glibc-has-grantpt.patch
 create mode 100644 gnu/packages/patches/nvi-include-term-h.patch
 create mode 100644 gnu/packages/patches/nvi-lfs.patch
 create mode 100644 gnu/packages/patches/nvi-manpage-errors.patch
 create mode 100644 gnu/packages/patches/nvi-manpage-note-dropped-F.patch
 create mode 100644 gnu/packages/patches/nvi-no-one-line-visual.patch
 create mode 100644 gnu/packages/patches/nvi-private-regex-fixes.patch
 create mode 100644 gnu/packages/patches/nvi-safe-printf.patch
 create mode 100644 gnu/packages/patches/nvi-search-word.patch
 create mode 100644 gnu/packages/patches/nvi-support-C-locale.patch
 create mode 100644 gnu/packages/patches/nvi-trailing-tab-segv.patch
 create mode 100644 gnu/packages/patches/nvi-tutorial-typos.patch
 create mode 100644 gnu/packages/patches/nvi-widechar-horrors.patch

diff --git a/gnu-system.am b/gnu-system.am
index f29b452..1806e79 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -433,7 +433,27 @@ dist_patch_DATA =						\
   gnu/packages/patches/net-tools-bitrot.patch			\
   gnu/packages/patches/ninja-tests.patch			\
   gnu/packages/patches/nss-pkgconfig.patch			\
+  gnu/packages/patches/nvi-additional-upstream-data.patch	\
   gnu/packages/patches/nvi-assume-preserve-path.patch           \
+  gnu/packages/patches/nvi-casting.patch			\
+  gnu/packages/patches/nvi-db4.patch				\
+  gnu/packages/patches/nvi-dbpagesize-binpower.patch		\
+  gnu/packages/patches/nvi-exrc-writability-check.patch		\
+  gnu/packages/patches/nvi-fallback-to-dumb-term.patch		\
+  gnu/packages/patches/nvi-file-backup.patch			\
+  gnu/packages/patches/nvi-glibc-has-grantpt.patch		\
+  gnu/packages/patches/nvi-include-term-h.patch			\
+  gnu/packages/patches/nvi-lfs.patch				\
+  gnu/packages/patches/nvi-manpage-errors.patch			\
+  gnu/packages/patches/nvi-manpage-note-dropped-F.patch		\
+  gnu/packages/patches/nvi-no-one-line-visual.patch		\
+  gnu/packages/patches/nvi-private-regex-fixes.patch		\
+  gnu/packages/patches/nvi-safe-printf.patch			\
+  gnu/packages/patches/nvi-search-word.patch			\
+  gnu/packages/patches/nvi-support-C-locale.patch		\
+  gnu/packages/patches/nvi-trailing-tab-segv.patch		\
+  gnu/packages/patches/nvi-tutorial-typos.patch			\
+  gnu/packages/patches/nvi-widechar-horrors.patch		\
   gnu/packages/patches/orpheus-cast-errors-and-includes.patch	\
   gnu/packages/patches/ots-no-include-missing-file.patch	\
   gnu/packages/patches/patchelf-page-size.patch			\
diff --git a/gnu/packages/nvi.scm b/gnu/packages/nvi.scm
index 8fd736d..a0a36b7 100644
--- a/gnu/packages/nvi.scm
+++ b/gnu/packages/nvi.scm
@@ -37,7 +37,28 @@
                          ".tar.bz2"))
         (sha256
           (base32 "0nbbs1inyrqds0ywn3ln5slv54v5zraq7lszkg8nsavv4kivhh9l"))
-        (patches (list (search-patch "nvi-assume-preserve-path.patch")))
+        (patches (list
+                   (search-patch "nvi-assume-preserve-path.patch")
+                   (search-patch "nvi-additional-upstream-data.patch")
+                   (search-patch "nvi-db4.patch")
+                   (search-patch "nvi-lfs.patch")
+                   (search-patch "nvi-safe-printf.patch")
+                   (search-patch "nvi-casting.patch")
+                   (search-patch "nvi-no-one-line-visual.patch")
+                   (search-patch "nvi-private-regex-fixes.patch")
+                   (search-patch "nvi-search-word.patch")
+                   (search-patch "nvi-widechar-horrors.patch")
+                   (search-patch "nvi-manpage-errors.patch")
+                   (search-patch "nvi-tutorial-typos.patch")
+                   (search-patch "nvi-dbpagesize-binpower.patch")
+                   (search-patch "nvi-include-term-h.patch")
+                   (search-patch "nvi-glibc-has-grantpt.patch")
+                   (search-patch "nvi-exrc-writability-check.patch")
+                   (search-patch "nvi-fallback-to-dumb-term.patch")
+                   (search-patch "nvi-manpage-note-dropped-F.patch")
+                   (search-patch "nvi-trailing-tab-segv.patch")
+                   (search-patch "nvi-support-C-locale.patch")
+                   (search-patch "nvi-file-backup.patch")))
         (snippet
           ;; Create a wrapper for the configure script, make it executable.
           '(let ((conf-wrap (open-output-file "configure")))
diff --git a/gnu/packages/patches/nvi-additional-upstream-data.patch b/gnu/packages/patches/nvi-additional-upstream-data.patch
new file mode 100644
index 0000000..839d44b
--- /dev/null
+++ b/gnu/packages/patches/nvi-additional-upstream-data.patch
@@ -0,0 +1,3485 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+01additional_upstream_data.dpatch by <hesso@pool.math.tu-berlin.de>
+
+
+A few documentation files cherry-picked from the last stable release tarball,
+because they are missing in later development branch releases.
+
+diff -Naur nvi-1.81.6.orig/nvi-1.79/FAQ nvi-1.81.6/nvi-1.79/FAQ
+--- nvi-1.81.6.orig/nvi-1.79/FAQ	1970-01-01 01:00:00.000000000 +0100
++++ nvi-1.81.6/nvi-1.79/FAQ	1996-10-14 15:52:46.000000000 +0200
+@@ -0,0 +1,160 @@
++@(#)FAQ	8.13 (Berkeley) 10/14/96
++
++Q: How can I get vi to display my character set?
++A: Vi uses the C library routine isprint(3) to determine if a character
++   is printable, or should be displayed as an octal or hexadecimal value
++   on the screen.  Generally, if vi is displaying printable characters
++   in octal/hexadecimal forms, your environment is not configured correctly.
++   Try looking at the man pages that allow you to configure your locale.
++   For example, to configure an ISO 8859-1 locale under Solaris using csh,
++   you would do:
++
++	setenv LANG C
++	setenv LC_CTYPE iso_8859_1
++
++   Other LC_CTYPE systems/values that I'm told work:
++
++   System	Value
++   ======	=====
++   FreeBSD	lt_LN.ISO_8859-1
++   HP-UX  9.X	american.iso88591
++   HP-UX 10.X	en_US.iso88591
++   SunOS  4.X	iso_8859_1
++   SunOS  5.X	iso_8859_1
++
++   If there's no other solution, you can use the print and noprint edit
++   options of vi to specify that a specific character is printable or not
++   printable.
++	
++Q: My map won't work!
++A: One thing that you should immediately check if a vi map doesn't work
++   is if depends on the final cursor position after a P or p command.
++   Historic vi's were inconsistent as to the final position of the cursor,
++   and, to make matter worse, the final cursor position also depended on
++   whether the put text came from a named or unnamed buffer!  Vi follows
++   the POSIX 1003.2 standard on this one, and makes this consistent, always
++   placing the cursor on the first character.
++
++Q: I'm using ksh or csh as my vi edit option shell value, and file
++   expansions don't work right!
++A: The problem may be in your ksh or csh startup files, e.g., .cshrc.  Vi
++   executes the shell to do name expansion, and the shell generally reads
++   its startup files.  If the startup files are not correctly configured
++   for non-interactive use, e.g., they always echo a prompt to the screen,
++   vi will be unable to parse the output and things will not work
++   correctly.
++
++Q: How does the iclower edit option differ from the ignorecase (i.e. ic)
++   edit option?
++A: The difference is that the ignorecase edit option always ignores the
++   case of letters in the Regular Expression (RE), and the iclower edit
++   option only ignores the case if there are no upper-case letters in the
++   RE.  If any upper-case letters appear in the Regular Expression, then
++   it will be treated case-sensitively, as if the ignorecase edit option
++   was not set.
++
++Q: When I edit binary files, vi appends a <newline> to the last line!
++A: This is historic practice for vi, and further, it's required by the
++   POSIX 1003.2 standard.  My intent is to provide a command line and/or
++   edit option to turn this behavior off when I switch to version 2.0 of
++   the Berkeley DB package.
++
++Q: My cursor keys don't work when I'm in text input mode!
++A: A common problem over slow links is that the set of characters sent by
++   the cursor keys don't arrive close enough together for vi to understand
++   that they are a single keystroke, and not separate keystrokes.  Try
++   increasing the value of the escapetime edit option, which will cause
++   vi to wait longer before deciding that the <escape> character that
++   starts cursor key sequences doesn't have any characters following it.
++
++Q: When I edit some files, vi seems to hang forever, and I have to kill it.
++A: Vi uses flock(2) and fcntl(2) to do file locking.  When it attempts to
++   acquired a lock for a file on an NFS mounted filesystem, it can hang
++   for a very long (perhaps infinite) period of time.  Turning off the
++   "lock" edit option will keep vi from attempting to acquire any locks
++   on the files you edit.
++
++Q: When I compile vi I get lots of warnings about pointer assignments
++   being incompatible!
++A: Vi is partially written to support wide characters.  When this code
++   interfaces with the code that doesn't yet support wide characters,
++   the pointer types clash.  This will hopefully be fixed in the near
++   future, but I've been saying that for awhile, now.
++
++Q: I get jumpy scrolling behavior in the screen!
++A: This is almost certainly a problem with the system's terminfo or
++   termcap information for your terminal.  If the terminfo/termcap entry
++   doesn't have the settable scrolling region capabilities, or the more
++   powerful scrolling commands, these behaviors can result.  Historic
++   implementations of vi, and some of the vi clones, don't suffer from
++   this problem because they wrote their own screen support instead of
++   using the curses library.
++
++   The solution is to find a good terminfo or termcap entry for your
++   terminal, which will fix the problem for all of the applications on
++   your system, not just vi.  Eric Raymond maintains the freely
++   redistributable termcap/terminfo entries.  They can be downloaded
++   from http://www.ccil.org/~esr/ncurses.html, or you can contact him
++   at esr@snark.thyrsus.com.
++
++Q: The entire screen repaints on every keystroke!
++A: Your system's curses implementation is broken.  You should use the
++   curses implementation provided with vi or a curses replacement such
++   as ncurses.  Eric Raymond is one of the maintainers of the freely
++   redistributable ncurses package.  You can download ncurses from
++   http://www.ccil.org/~esr/ncurses.html, or you can contact him at
++   esr@snark.thyrsus.com.
++
++Q: When I use vi on a Sun console (terminal type sun-34) the screen
++   is occasionally trashed, usually when exiting vi!
++A: The Sun console can't handle the 'al' capability of the termcap
++   entry (the il1 capability of terminfo entries).  If you delete that
++   entry from your terminfo/termcap information everything should work
++   correctly.
++
++Q: I don't have a version of ctags (or I have ctags, but it doesn't tag
++   nearly enough things)!
++A: There's a version of ctags available on the 4.4BSD-Lite distributions,
++   as well as the FreeBSD, NetBSD, Linux and GNU distributions.  Or, you
++   might want to try Exuberant Ctags:
++
++	Title:		Exuberant Ctags
++	Version:	1.3
++	Entered-date:	16JUN96
++	Description:
++	    A better ctags which generates tags for all possible tag types:
++	    macro definitions, enumerated values (values inside enum{...}),
++	    function and method definitions, enum/struct/union tags, external
++	    function prototypes (optional), typedefs, and variable
++	    declarations. It is far less easily fooled by code containing #if
++	    preprocessor conditional constructs, using a conditional path
++	    selection algorithm to resolve complicated choices, and a
++	    fall-back algorithm when this one fails. Can also be used to print
++	    out a list of selected objects found in source files.
++	Keywords:	ctags, tags, exuberant
++	Author:		darren@sirsi.com (Darren Hiebert)
++			darren@hiwaay.net (Darren Hiebert)
++	Maintained-by:	darren@sirsi.com (Darren Hiebert)
++			darren@hiwaay.net (Darren Hiebert)
++	Primary-site:	sunsite.unc.edu /pub/Linux/devel/lang/c
++			27kB ctags-1.3.tar.gz
++	Alternate-site:	ftp.halcyon.com /local/gvr
++			27kB ctags-1.3.tar.gz
++	Original-site:
++	Platforms:	UNIX, MSDOS, WindowsNT, Windows95, OS/2, Amiga
++	Copying-policy:	Public domain
++
++Q: When I update a file I already have open, and use :e to reread it, I
++   get nul's for the rest of the file!
++A: Your system's implementation of mmap(2) has a bug; you will have to
++   exit vi and re-execute it.
++
++Q: Where can I get cscope?
++A: Cscope is available on UNIXWare System V Release 4.0 variants such as
++   Sun Solaris 2.x (/opt/SUNWspro/bin) and UNIXWare System V Release 4.1.
++
++   You can buy version 13.3 source with an unrestricted license for $400
++   from AT&T Software Solutions by calling +1-800-462-8146.  Binary
++   redistribution of cscope is an additional $1500, one-time flat fee.
++
++   For more information, see http://www.unipress.com/att/new/cscope.html.
+diff -Naur nvi-1.81.6.orig/docs/changelog nvi-1.81.6/docs/changelog
+--- nvi-1.81.6.orig/nvi-1.79/docs/changelog	1970-01-01 01:00:00.000000000 +0100
++++ nvi-1.81.6/nvi-1.79/docs/changelog	1996-10-23 15:39:08.000000000 +0200
+@@ -0,0 +1,1102 @@
++1.78 -> 1.79 (10/23/96)
++	+ Rename delete() to del(), for C++.
++	+ Add Spanish to the list of translations.
++	+ Update to Perl 5.003_06, and other Perl interpreter updates.
++	+ Update the set-edit-option interface for the scripting languages.
++	+ Rework ex command parsing to match historic practice for backslash
++	  escaped <newline> characters inside of global commands.
++	+ Enhance the comment edit option to skip C++ comments.
++	+ Change installation to configure the recovery shell script to match
++	  the system pathnames and to install it into the vi data directory.
++	  Move the recover script into the build directory, and delete the
++	  recover directory.
++	+ Enhance LynxOS support.
++1.76 -> 1.78 (10/01/96)
++	+ Fix bugs when both the leftright scrolling and number edit options
++	  were on.
++	+ Fix bug where splitting in the middle of the screen could repaint
++	  incorrectly.
++	+ Fix first-nul in input bug, where random garbage was inserted.
++	+ Correct search and mark-as-motion-command bug, it's a line mode
++	  action if the search starts at or before the first non<blank>.
++	+ Fix bug autoindent bug, where ^D could shift too far in the line.
++	+ Fix core dump where ! command called from the .exrc file.
++	+ Add the -S command-line option, which initializes vi to have the
++	  secure edit option preset.
++1.75 -> 1.76 (09/15/96)
++	+ Fix bug where ^V didn't keep input mapping from happening.
++	+ Fix a core dump bug in the R command.
++	+ Give up on licensing: no more shareware, adware, whatever.
++	+ Fix cursor positioning bug for C, S and c$ in an empty file.
++1.74 -> 1.75 (08/22/96)
++	+ Add French to the error message translations.
++	+ Move the UNLICENSED message to the end of the message line.
++	+ Fix bug where wide characters in a file name weren't calculated
++	  correctly in the status message.
++	+ Fix bug where cl_rename was called directly, by the ex shell code.
++	+ Fix bug where splitting a screen resulting in a new screen at the
++	  top of the display resulted in badly displayed status messages.
++1.73 -> 1.74 (08/18/96)
++	+ Fix bug where the status line wasn't redisplayed if the user ran
++	  an ex command that trashed the screen.
++	+ Fix bug where the long version of the status line wasn't displayed
++	  when switching screens.
++	+ Rework fast-path filename completion code to sort the entries, and
++	  strip out . and .. by default.
++	+ Fix bug where ex went to the first line instead of the last one when
++	  reading in a file.
++1.72 -> 1.73 (08/12/96)
++	+ Do filename completion and some file expansion internally for speed.
++	+ Fix CSCOPE_DIRS environmental variable support.
++	+ Ex parser fix for global commands in script files.
++	+ Add the O_PATH option, so you can specify a directory search path
++	  for files.
++	+ Make it possible to specify the database file to cscope, allowing
++	  multiple databases in a single directory.
++	+ Fix incremental search to overwrite erased characters so the user
++	  can tell where they are on the colon-command line.
++	+ Fix incremental search to restart the search if the user enters an
++	  unescaped shell meta character.
++1.71 -> 1.72 (07/12/96)
++	+ Cscope fix: test for files newer than the database was reversed.
++	+ Display "files to edit" message for rewind, next and initial screen.
++	+ Fix a bug in the R command where it could fail if the user extended
++	  the file.
++	+ Fix a bug where text abbreviations could corrupt the line.
++	+ Fix a bug where the windowname edit option couldn't be set before a
++	  file was loaded into the edit buffer.
++	+ Fix a bug where the system .exrc values weren't being overridden by
++	  the user's $HOME .exrc values.
++	+ Fix a bug in the filename completion code, where garbage characters
++	  could be added to the colon command line.
++	+ Fix bug where multiple edit sessions on a non-existent file could
++	  all write the file without warning.
++	+ Fix bug where screen update was incorrect if a character triggered
++	  both a wrapmargin and showmatch condition.
++	+ Fix bug in leftright scrolling where <CR> during text input didn't
++	  return the cursor to the left margin.
++	+ Rev the Perl interpreter code, new version from Sven Verdoolaege,
++	  based on Perl 5.003.01.
++	+ Fix bug in tags file pattern search introduced in 1.71.
++1.70 -> 1.71 (07/01/96)
++	+ Don't include <term.h> -- neither HPUX or Solaris can cope with it.
++	+ Fix bug where ^M's in the original pattern were converted into new
++	  lines in the file during substitution commands.
++	+ Make window resize events separate from interrupts -- too many users
++	  complained.
++	+ Fix bug in first-character-is-null text input semantic.
++	+ Rework search routines to take a length instead of a nul-terminated
++	  string for a pattern.  This fixes a couple of bugs in searching, but
++	  probably introduces new ones.
++	+ Fix prompting the user after a write filter command, the way I did
++	  it in 1.70 broke the display.
++	+ Don't switch to the alternate xterm screen when entering the ex
++	  text input commands from vi mode.
++	+ Implement the Fg command, so can foreground a background screen into
++	  a split screen.
++	+ Change the fg command to match screen names using the last component
++	  of the filename the full filename fails.
++1.69 -> 1.70 (06/28/96)
++	+ Change the ex read command to support named pipes.
++	+ Copy the EXINIT/NEXINIT strings before executing their commands so
++	  we don't step on the process environment.
++	+ Don't do "line modification" reports for intermediate commands
++	  executed from the vi colon command line, it screws up filter
++	  reads, causing nvi to prompt for the user to continue.
++	+ Add "smd" as an abbreviation for showmode: HP, ICL and SCO have it.
++	+ Change nvi to always prompt the user after a write filter command.
++	  This matches historic practice.
++	+ Fix recovery information mailed to the user to reflect the program's
++	  installed name.
++	+ Change configuration script to not cache option information, e.g.,
++	  --disable-curses.
++	+ Fix a bug where the second character of the vi [[, ]] and ZZ
++	  commands could start a command mapped sequence.
++	+ Fix 3 write bugs: partial writes (3,$write), were clearing the
++	  modified flag, full writes using line numbers (1,$write) were
++	  not, and append historically never cleared the modified flag, and
++	  we didn't get that right.
++	+ Shorten the "more files to edit" message so it can gang on a single
++	  line, lots of people have complained.  Add the number of files that
++	  are left to edit, it's historic practice.
++	+ Fix core dump where message catalogs collided with truncating the
++	  write path.  Add a new write message so the string "appended" is
++	  taken from a message catalog.
++	+ Fix bug where an undo followed by '.' to repeat it wouldn't work
++	  if no other repeatable commands had been entered.
++	+ Fix core dump when resolution of input lines' autoindent characters
++	  invalidated cached display information.
++	+ Set the name of the X11 xterm icon/window to "xterm" when exiting,
++	  if modified based on the windowname option.
++	+ Include <term.h> if it exists, fixes portability problems on IRIX
++	  systems.
++1.68 -> 1.69 (06/17/96)
++	+ Add the windowname edit option and code to change the icon/window
++	  name for xterm's.
++	+ Enhance the comment edit option to skip shell comments.
++	+ Add conditional prototypes to replacement C library functions.
++	+ Minor enhancements/reworking to Makefile.in, other build files.
++	+ Fix bug in vi text input ^D processing, could result in cursor
++	  warp to the beginning of the line.
++	+ Fix leftright screen bug where the screen wasn't repainted when
++	  being repainted from scratch.
++	+ Update the Swedish and Dutch catalogs.
++	+ Truncate paths in write commands if they don't fit on one line.
++	+ Fix alternate screen bug where the screen flashed and output lost
++	  when switching to/from the X11 xterm alternate screen.  Fix bug
++	  where nvi switched into the alternate screen during filter-read
++	  commands, which doesn't match historic practice.
++	+ Minor relative cursor positioning change, make cursor position
++	  changes from ex real and permanent.
++1.67 -> 1.68 (06/09/96)
++	+ Fix core dump when tagging out of a modified file.
++1.66 -> 1.67 (06/09/96)
++	+ Convert the license to adware.
++	+ Leftright scrolling tweak, don't repaint the screen as often.
++	+ Change so that search warning/error messages don't appear during an
++	  incremental search.
++	+ Cscope fix: test for files newer than the database was reversed.
++	+ Don't display ex `welcome message' if in ex batch mode.
++	+ Test for vsnprintf and snprintf separately, HP 10.10 has snprintf
++	  but not vsnprintf.
++	+ Reverse lookup order between LC_MESSAGES and LANG.
++	+ Fix Tcl/Perl core dumps in common API code to get/set options.
++	+ Fix R command -- it used a DB pinned page after discarding it.
++	+ Minor fixes in multiple edit buffer message handling code.
++	+ Fix yk command moving to shorter line core dump.
++	+ Rework message handling to try and gang more messages onto a single
++	  line.
++1.65 -> 1.66 (05/18/96)
++	+ Convert vi man page to historic -man macro package, and install it.
++	+ Fix bug were !! on an empty line with a nonexistent command left the
++	  cursor on the second character, not the first.
++	+ Fix bug where line redisplay was wrong when a <tab> replaced a
++	  previous <tab> in the line.
++	+ Fix bug where D (d$) didn't reset the relative cursor position.
++	+ Fix bug where yG incorrectly reset the relative cursor position.
++	+ Fix bug where the window size couldn't be grown once it was shrunk.
++	+ Fix bug where the extended edit option caused tag searches to fail.
++	+ If multiple lines in the tags file with the same leading tag, build
++	  a tags stack like the Cscope stack.  This is the obvious extension,
++	  and the way that Larry McVoy's ctags program works.
++	+ Send the appropriate TI/TE sequence in the curses screen whenever
++	  entering ex/vi mode.  This means that :shell now shows the correct
++	  screen when using xterm alternate screens.
++	+ Rework the options display code to get five columns in an 80 column
++	  screen.
++	+ Interactive Unix V3.0 port -- mostly file name shortening, other
++	  minor changes.  Only preliminary, more work will be necessary.
++	+ Add debugging option to not read EXINIT/.exrc information.
++	+ Fix bug where re_compile printed an error message to the screen
++	  when the user entered [ to an incremental search.
++	+ Turn off screen beeps when incremental search is failing.
++	+ Fix bug where the iclower option didn't trigger an RE recompilation.
++	+ Fix bug where -t into an already locked file forced the user to wait
++	  as if a startup command had failed.
++	+ LynxOS port -- mostly adding <sys/types.h> even though <sys/param.h>
++	  was already included.
++	+ Fix ex output bug, where it appeared as if an ex command was skipped
++	  due to flags not being cleared in the vs_msg() routine.
++	+ Fix core dump when global command tried to switch screens.
++1.64 -> 1.65 (05/13/96)
++	+ Fix cscope <blank>-matching pattern to use extended RE's, and bug
++	  that kept cscope from finding patterns containing <blank>s.
++	+ Fix core dumps in both leftright and folded screens when tabstops
++	  edit option value was large, and tab characters occurred as the last
++	  character in the logical screen.
++	+ Fix core dump where the second screen of a folded line wasn't
++	  displayed correctly.
++	+ Fix incremental search to match the current location for strings
++	  starting with \< patterns.
++	+ Fix bug where margins were ignored during replay of text input.
++	+ Fix bug where motion components to shorter lines could lose because
++	  the relative motion flags weren't ever set.  This has been broken
++	  forever, but the change almost certainly breaks something else -- I
++	  have no idea what.
++	+ Tags display: don't print the current entry separately, display
++	  them all and add a trailing asterisk for the current one.
++	+ Change the cscope add command to put the directory name through
++	  standard file name expansion.
++	+ Fix cscope use of buffers -- search commands weren't nul-terminated.
++1.63 -> 1.64 (05/08/96)
++	+ Add installation target to the Makefile.
++	+ Add documentation on the new tags commands to the Vi Reference
++	  Manual.
++	+ Make the sidescroll edit option work again.
++	+ Fix bug where messages output during startup by ex could be lost.
++	+ Change ex/vi commands errors into beeps, unless the verbose edit
++	  option is set -- there are too many macros that are expected to
++	  eventually fail.  This matches historic practice.
++	+ Truncate paths in initial vi screen if they won't fit on one line.
++	+ Make cursor position after filter write match historic practice.
++	+ Force the user to wait if there is output and the user is leaving
++	  the screen for any reason -- don't permit further ex commands.
++	+ Don't use a <newline> character to scroll the screen when exiting,
++	  scroll in the vi screen before endwin() is called.
++	+ Fix bug where the column number could be incorrect because the old
++	  screen wasn't updated after a screen split.
++	+ Fix ex print routine to correctly specify print flags.
++	+ Make -g/-O a separate make/configuration option.
++	+ Fix bug where ex/vi messages weren't being joined.
++	+ Fix bug where termcap strings were free'd twice.
++	+ Fix bug where TI/TE still weren't working -- I didn't put in the
++	  translation strings for BSD style curses.
++	+ Fix bug where I misspelled the iclower edit option as icloser.
++1.62 -> 1.63 (04/29/96)
++	+ Robustness and type/lint fixes for the Tcl interface code.
++	+ Fix core dump if TERM wasn't set or terminal type was unknown.
++	+ Fix bug where combining ex commands that did/did not require an
++	  ex screen would overwrite the command with the want-to-continue
++	  messsage.
++	+ Fix bug where the screen was never resolved if the user continued
++	  entering ex commands using the : character, but then backspaced
++	  over the prompt to quit or tried to edit their colon command-line
++	  history.
++	+ Fix bug where cursor wasn't placed over the ^ placeholder character
++	  when quoting using the literal-next character.
++	+ Fix bug where nvi under BSD style curses wasn't sending TI/TE termcap
++	  strings when suspending the process.
++	+ Rename mic again, to iclower.
++	+ Fix bug where 'z' commands trailing / or ? commands weren't being
++	  executed.
++	+ Change incremental search to leave the cursor at its last position
++	  when searching for something that was never found.
++	+ Fix bug where search-with-confirmation from vi mode didn't position
++	  the cursor correctly after displaying the confirm message.
++	+ Fix bug where the "search wrapped" message was dependent on the
++	  verbose edit option, which doesn't match historic practice.  Change
++	  search messages to be in inverse video.
++	+ Fix bug where matched showmatch character wasn't being displayed
++	  before the matching character was displayed.
++	+ Another cursor update bug required a change to vs_paint().
++	+ Fix bug were initial line offset was wrong for the first split screen
++	  (symptom is very strange column numbers and blank first line).
++	+ Create filename "argument" lists when creating new screens.
++	+ Fix bug where globals with associated commands that included both
++	  buffer execution and other commands could fail to execute the latter.
++1.61 -> 1.62 (04/22/96)
++	+ Rename the "searchci" edit option to be "mic".
++	+ Fix memory corruption in global commands ending in searches.
++	+ Fix text resolution bug, corrected the cursor based on the
++	  first line input, not the last.
++	+ Rework the readonly edit option to match historic practice.
++	+ Fix several minor incremental search bugs; make incremental
++	  searches work in maps.
++	+ Fix long-line core dump, where an incorrect screen map could be
++	  used.
++1.60 -> 1.61 (04/12/96)
++	+ The cursor now ends up on the FIRST character of the put text for
++	  all versions of the vi put commands, regardless of the source
++	  of the text.  This matches System III/V behavior and POSIX 1003.2.
++	+ Fixed bug where showmatch messages were getting discarded.
++	+ Minor Perl integration fixes.
++	+ Integrate Cscope into the tags stack code -- major change.
++	+ Fixed bug where ^T would drop core if returning to a temporary file.
++	+ Changed vs_ routine to display ex output to replace tab characters
++	  with spaces.
++	+ Fix autoindent code to not back up past beginning of line when ^T
++	  inserted into the middle of a line, i.e. offset != 0.
++	+ Fix "notimeout" option, was being ignored, by a coding error.
++	+ Fix showmatch code to never flash on a match if keys are waiting.
++	+ Change the vi 'D' command to ignore any supplied count, matching
++	  historic practice.
++	+ Fix viusage for D, S, C and Y (the aliased vi commands).
++	+ Fix the Perl5 configuration bug in the configuration script.
++	+ Make file completion commands in empty lines work.
++	+ Fix where the change to let vi use the default ex command structure
++	  broke the ex specification of the script or source file name.
++	+ Fix to free saved RE structures when screens exit.  This is a major
++	  RE change, which fixed several bugs in the handling of saved/subst
++	  RE's.  It's likely to have added new bugs, however.
++	+ Add case-independent searching (the searchci edit option).
++	+ Add incremental search (the searchincr edit option).
++	+ Home the cursor when executing ex commands from vi.
++1.59 -> 1.60 (03/29/96)
++	+ Fix ":w >>" core dump, make that command match historic practice.
++	+ Fix autoindent bug where the length of the line was incorrectly
++	  calculated.
++	+ Fix cursor bug where cursor could end up at the wrong place if the
++	  movement keys were entered quickly enough.
++	+ Change the read/write whirling indicator to appear only every 1/4
++	  second, clean up the appearance.
++	+ Don't change the options real values until underlying functions
++	  have returned OK -- fix "set tabstop=0" core dump.
++	+ Fix resizing on Sun's: use SA_INTERRUPT to interrupt read calls.
++	+ Fix two forward mark command bugs: one where it wasn't setting the
++	  "favorite cursor" position because of the refresh optimization,
++	  and one where it didn't have VM_RCM_SET set in the command flags
++	  for some reason.
++	+ Fix a bug were the 's' command on top of a <tab> didn't correctly
++	  copy the buffer.
++	+ Make :exusage command work for commands having optional leading
++	  capital letters, e.g. Next.
++	+ Previous changes broke the inital-matching-prefix code in the key
++	  mapping part of v_event_get -- fix it, and fix the infinite macro
++	  interrupt code at the same time.
++	+ Add "cedit" edit option, so colon command-line editing is optional.
++	  Change filec/cedit so that you can set them to the same character,
++	  and they do cedit if in column 1, and filec otherwise.
++	+ Fix "source of non-existent file" core dump.
++	+ Fix bug where functions keys specified in startup information were
++	  never resolved/activated.
++	+ Fix v_txt bug where could infinitely loop if <escape> triggered an
++	  abbreviation expansion.
++	+ Move version string into VERSION file, out of ex_version.c
++1.58 -> 1.59
++	+ Configuration changes, several minor bug fixes, including a few
++	  core dumps.  No functional changes.
++1.57 -> 1.58
++	+ Fix the problem where colon command-line temporary files were
++	  getting left in /tmp.
++	+ Fix the configuration scripts to quit immediately if the Perl
++	  or Tk/Tcl libraries are specified but not found.
++	+ Several screen fixes -- the changes in 1.57 weren't as safe as
++	  I thought.  More specifically, the refresh-only-if-waiting change
++	  caused a lot of problems.  In general, fixing them should provide
++	  even more speedup, but I'm nervous.
++	+ Lots of changes in the configuration scripts, hopefully this is
++	  just a first-round ordeal.
++	+ Several other minor bug fixes.
++1.56 -> 1.57
++	+ Add <esc> hook to colon commands, so you can edit colon commands.
++	+ Add Perl5 interpreter.
++	+ Change shell expansion code to fail if it doesn't read at least
++	  one non-blank character from the shell.  If the shell expansion
++	  process fails, or if not at least one non-blank character, it
++	  now displays an error message to the user.
++	+ Rework the screen display so that it matches the historic vi screen
++	  refreshes.
++	+ Rework options processing: print/noprint are no longer cumulative,
++	  provide more information to underlying edit options modules, move
++	  O_MESG information into the screen specific code.
++	+ Make file completion character settable.
++	+ Rework terminal restart -- you can now use ":set term" to switch
++	  terminal types.  This cleaned up screen resizing considerably.
++	+ Character display fix, display \177 as ^?, not in hex/octal.
++	+ Tag search bug fix, don't repeat search if successful.
++	+ Replace sys_siglist[] use with private sigmsg() routine.
++	+ Fix core dump if illegal screenId specified to Tcl routine.
++	+ Add get/set mark interface to Tcl Interpreter interface.
++	+ Fix core dump if file expansion code stressed (re: filec edit option)
++	+ Fix bug where filter commands in empty files couldn't find line 0.
++	+ Switch to GNU autoconf 2.7 for configuration, delete nvi/PORT.
++	  Many random portability fixes.
++1.55 -> 1.56 (11/26/95)
++	+ Bug fix release -- generally available beta release.
++1.54 -> 1.55 (11/18/95)
++	+ Bug fix release.
++	+ Integrate Tcl interpreter.
++1.53 -> 1.54 (11/11/95)
++	+ Bug fix release.  A major change in reworking the ex commands, when
++	  called from the colon command line, to match historic practice, and
++	  permit them to be entered repeatedly after ex has trashed the screen.
++	+ Use restartable endwin() from System V curses to implement screen
++	+ suspend.
++1.52 -> 1.53 (10/29/95)
++	+ Switch to using vendor's curses library for all ports.
++	+ Back out the event driven version, leaving screen separation.
++	+ User configuration of <escape> timeout (the escapetime edit option).
++	+ Add Tcl/Tk screen support.
++	+ Add file name completion (the filec edit option).
++	+ Disallow access to outside applications (the secure edit option).
++1.51 -> 1.52 (7/26/95)
++	+ Minor cleanups, snapshotted for SMI.
++1.50 -> 1.51 (7/05/95)
++	+ Lots and lots of changes for event driven model, largely in moving
++	  the boundary between the screen code and the editor up and down.
++	  Private release for Rob Zimmermann @ Tartan and Bill Shannon @ SMI.
++1.49 -> 1.50 Fri Jun  9 13:56:17 1995
++	+ Minor bug fixes for stability.
++	+ Convert to an event driven model, with the usual Nachos Supreme
++	  layering that results.  This is a completely new version, nothing
++	  done previously matters any more.
++1.48 -> 1.49 Wed Mar  8 10:42:17 1995
++	+ Changes in 1.46 broke ^A processing.
++	+ Add :previous to split screen commands.
++	+ Lots o' random bug fixes -- passes purify testing again.
++1.47 -> 1.48 Thu Feb  9 18:13:29 1995
++	+ Random bug fixes for 1.47.
++	+ Move the FREF (file structure) list out of the screen and into
++	  the global area.
++	+ Change semantics to :E to more closely match :e -- ":E" joins
++	  the current file, so ":E /tmp" is now the command to match the
++	  historic ":split".
++1.46 -> 1.47 Wed Feb  8 19:43:41 1995
++	+ All ex commands (including visual and excluding global and v)
++	  are now supported inside ex global commands.
++	+ Rework the append/change/insert commands to match historic
++	  practice for text appended to the ex command line, and inside
++	  of ex global commands.
++	+ Restructure to make single-line screens work.
++	+ Restructure to create curses independent screen routines.
++	+ Restructure to permit Edit, Next, and Tag routines to create new
++	  screens on the fly.
++	+ Change hexadecimal output to be \x## instead of 0x##.
++	+ Change ex commands run from vi to stay in vi mode for as long as
++	  possible, i.e. until ex modifies the screen outside of the editor.
++1.45 -> 1.46 Tue Jan 24 10:22:27 1995
++	+ Restructure to build as a library.
++1.44 -> 1.45 Thu Jan 12 21:33:06 1995
++	+ Fix relative cursor motion to handle folded lines.
++	+ Recompile the search pattern if applicable edit options change.
++	+ Change +/-c command ordering to match historic practice.
++	+ Rework autoindent code to always resolve preceeding <blank>
++	  characters when a ^T or ^D are entered.
++	+ Add the print/noprint edit options, so can now specify if
++	  a character is printable.
++	+ Change ex to run in canonical mode.
++	+ Fix ex text input to support the number edit option.
++	+ Vi text input fix for the R command to correctly restore
++	  characters entered and then backspaced over.
++	+ Several vi increment command fixes.
++1.43 -> 1.44
++	+ Bug fix, vi was printing the last line number on the status line
++	  at startup.  Change to execute commands at first line set, i.e.
++	  "vi -t tag -c cmd" executes cmd at the tag line, not EOF.
++1.42 -> 1.43 Sat Dec  3 13:11:32 1994
++	+ Marks, SunOS signed comparison fix for 1.42.
++1.41 -> 1.42 Fri Dec  2 20:08:16 1994
++	+ Make autowrite require the file not be read-only.
++	+ Make the ex insert command work in empty files.
++	+ Tab expansion is no longer limited to values < 20 (which matches
++	  historical practice).
++	+ Simplify (and fix limit detection for) the # command.  It's no
++	  longer possible to use the # command itself to repeat or modify
++	  a previous # command, '.' is the only possibility.
++	+ Lots more reworking of the ex addresses, putting ? and / into
++	  the ex addressing code broke the world.
++	+ Make the Put, Preserve and Print commands work (don't ask).
++	+ Split stdout/stderr from shell expansions; stdout is expansion
++	  text, stderr is entered on the message queue.
++1.40 -> 1.41 Fri Nov 18 16:13:52 1994
++	+ Addition of a port for AUX 3.1
++	+ Addition of a message catalog for Russian.
++	+ Make vi ? and / commands be true ex addresses (historic practice).
++	+ Display the date first in vi -r recovery list.
++1.39 -> 1.40 Mon Nov 14 10:46:56 1994
++	+ Two bug fixes for 1.39; -r option and v_change core dump.
++1.38 -> 1.39 Sun Nov 13 18:04:08 1994
++	+ Ex substitution with confirmation now matches historic practice
++	  (except that it still runs in raw mode, not cooked).
++	+ Nvi now clears the screen before painting, if repainting the
++	  entire screen.
++	+ Fix final cursor position for put command entering text in a
++	  single line.
++	+ Change to break error message lines on the last <blank> in the
++	  line.
++	+ Always center the current line when returning to a previously
++	  edited file or moving to a tag line that's not visible on the
++	  screen.
++	+ Change write of the current file using an explicit name or % to
++	  match the semantics of :w<CR>, not :w file<CR>.
++	+ Add command aliases to vi, and remap 6 historic commands to their
++	  historic counterparts: D->d$, Y->y_, S->c_, C->c$, A->$a, I->^i.
++	+ Match option display to historic practice; if boolean or numeric
++	  options changed to default values, not displayed by default.
++	  Nvi treats string options the same way, vi always displayed any
++	  string option that was changed.
++	+ Added lock edit option, if not set, no file locking is done.
++	+ Rework ex to permit any ex command in the EXINIT variable or
++	  exrc startup files.  This fixes the bug were `vi +100 file'
++	  painted the screen and then moved to line 100 and repainted.
++	  (Yanked to SCCS ID 9.1.)
++	+ Bug fix: could report file modified more recently than it was
++	  written, incorrectly.
++	+ Search fix: historically, motions with deltas were not corrected
++	  to the previous/next line based on the starting/stopping column.
++	+ Addressing fixes: make trailing non-existent addresses work, change
++	  % to be text substitution, not a unique address (to follow future
++	  POSIX).
++1.37 -> 1.38 Mon Oct 24 12:51:58 1994
++	+ Scrolling fix; ^B can move to nonexistent lines.
++	+ Fix to vi mapped commands; <escape> characters while already in
++	  command mode did not historically cause the mapped characters to
++	  be flushed.
++	+ Add the backup edit option, automatically version edit files.
++	+ Make it possible to edit files that db can't read, i.e. edit a
++	  temporary file, with the correct file name.
++	+ Only anchor the last line of the file to the bottom line of the
++	  screen if there's half or less of a screen between the target
++	  line and the end of the file.
++	+ Fix wrapmargin text allocation bug.
++	+ Fix ex put command to work in any empty file.
++	+ Fix global command to handle move's to line 0 correctly.
++	+ Regularize the yank cursor motions, several bug fixes for historic
++	  practice.
++	+ Fix N and n, when used as a motion command for the ! command,
++	  repeat the last bang command instead of prompting for a new
++	  one.
++	+ Timeout maps beginning with <escape> quickly, instead of based
++	  on the keytime option.
++	+ Bug fix for wraplen option, wasn't triggered for input commands.
++1.36 -> 1.37 Sun Oct  9 19:02:53 1994
++	+ Change PORT directories to install patches before distribution.
++	+ Fix ^A to set search direction and pattern for consistency.
++	+ Fold the showdirty option into the showmode option.
++	+ Ex addressing fix: change search offset and line arguments (e.g.
++	  the copy command) to be ex addressing offsets, matching historic
++	  practice.
++	+ Ex addressing fix: support ^ as an offset/flag equivalent to -.
++	+ Ex addressing fix: historically, any missing address defaulted to
++	  dot, e.g. "4,,," was the same as ".,.".
++	+ Ex addressing fix: historically, <blank> separated numbers were
++	  additive, e.g. "3 5p" displayed line 8.
++	+ Ex addressing fix: make ';' as a range delimiter match historic
++	  practice.
++	+ Change nvi to exit immediately if stdout isn't a terminal.
++	+ Change alternate file name behavior to match historic practice,
++	  make the :write command set the current file name.
++	+ Text input fix; input keys from a map, with an associated count,
++	  weren't historically affected by the wrapmargin value.
++	+ Add wraplen option, same as wrapmargin, but from the left-hand
++	  column, not the right.
++	+ Make ex address .<number> be equivalent to .+<number>, i.e. the
++	  '+' is understood; matches historic practice, and it's widely
++	  documented for ed(1).
++	+ Input mode ^V^J historically mapped into a single ^J.
++	+ Minor catalog changes, fixes; don't use 's' to pluralize words.
++1.35 -> 1.36 Thu Sep  8 08:40:25 1994
++	+ Don't overwrite user's maps with standard (termcap) mappings.
++	+ Make \ escape kill and erase characters in vi text input mode.
++	+ Fix ^D autoindent bug by resolving leading <blank>s at ^D.
++	+ Rework abbreviation tests (again!) to match historic practice.
++	+ Change ^D/^U default scrolling value to be based on window option
++	  value, not screen lines, correct scrolling option value, both to
++	  match historic practice.  NOTE: System V does this differently!
++1.34 -> 1.35 Wed Aug 31 19:20:15 1994
++	+ Add the historic -l option.
++	+ Message catalogs.
++	+ Display global messages at each flush, just in case some are there.
++	+ Fix global substitute code, `\\' wasn't handled correctly.
++	+ Fix abbreviation code to use <blank>s as the preceding character.
++	+ Fix ruler to display logical column, not physical column.
++	+ Block signals when user issues :preserve command, so no race caused
++	  by SIGHUP/SIGTERM.
++1.33 -> 1.34 Wed Aug 17 14:37:32 1994 (PUBLICLY AVAILABLE VERSION)
++	+ Back out sccsid string fix, it won't work on SunOS 4.1.
++1.32 -> 1.33 Wed Aug 17 09:31:41 1994 (PUBLICLY AVAILABLE VERSION)
++	+ Get back 5K of data space for the sccsid strings.
++	+ Fix bug where cG fix in version 1.31 broke cw cursor positioning
++	  when the change command extended the line.
++	+ Fix core dump in map/seq code if character larger than 7 bits.
++	+ Block signals when manipulating the SCR chains.
++	+ Fix memory allocation for machines with multiple pointer sizes.
++1.31 -> 1.32 Mon Aug 15 14:27:49 1994
++	+ Turn off recno mmap call for Solaris 2.4/SunOS 5.4.
++1.30 -> 1.31 Sun Aug 14 13:13:35 1994
++	+ Fix bug were cG on the last line of a file wasn't done in line mode,
++	  and where the cursor wasn't positioned correctly after exiting text
++	  insert mode.
++	+ Add termcap workaround to make function keys greater than 9 work
++	  correctly (or fail if old-style termcap support).
++	+ Change ex/vi to not flush mapped keys on error -- this is historic
++	  practice, and people depended on it.
++	+ Rework vi parser so that no command including a mapped key ever
++	  becomes the '.' command, matching historic practice.
++	+ Make <escape> cancellation in the vi parser match POSIX 1003.2.
++	+ Fix curses bug where standout string was written for each standout
++	  character, and where standout mode was never exited explicitly.
++	  Fix bugs in curses SF/sf and SR/sr scrolling, as seen on Sun and
++	  x86 consoles.
++	+ The v/global commands execute the print command by default.
++	+ The number option historically applies to ex as well as vi.
++1.29 -> 1.30 Mon Aug  8 10:30:42 1994
++	+ Make first read into a temporary set the file's name.
++	+ Permit any key to continue scrolling or ex commands -- this
++	  allows stacked colon commands, and matches historic practice.
++	+ Don't output normal ! command commentary in ex silent mode.
++	+ Allow +/- flags after substitute commands, make line (flag)
++	  offsets from vi mode match historic practice.
++	+ Return <eof> to ex immediately, even if preceded by spaces.  Rework
++	  ex parser to do erase the prompt instead of depending on the print
++	  routines to do it.  Minor fixes to the ex parser for display of
++	  default and scrolling commands.  MORE EX PARSER CHANGES.
++1.28 -> 1.29 Fri Aug  5 10:18:07 1994
++	+ Make the abbreviated ex delete command work (:dele---###lll for
++	  example, is historically legal.
++	+ When autoprint fires, multiple flags may be set, use ex_print
++	  directly instead of the stub routines.
++	+ Change v/global commands to turn off autoprint while running.
++	+ Minor changes to make the ! command display match historic output.
++	+ Rework the ex parser to permit multiple command separators without
++	  commands -- MAJOR CHANGE, likely to introduce all sorts of new bugs.
++	+ Fix cd command to expand argument in the context of each element
++	  of the cdpath option, make relative paths always relative to the
++	  current directory.
++	+ Rework write/quit cases for temporary files, so that user's don't
++	  discard them accidentally.
++	+ Check for window size changes when continuing after a suspend.
++	+ Fix memory problem in svi_screen, used free'd memory.
++	+ Change the ex change, insert, append commands to match historic
++	  cursor positions if no data entered by the user.
++	+ Change ex format flags (#, l, p) to affect future commands, not
++	  just the current one, to match historic practice.
++	+ Make the user's EOF character an additional scroll character in ex.
++	+ Fix ex ^D scrolling to be the value of the scroll option, not half
++	  the screen.
++	+ Fix buffer execution to match historic practice -- bugs where the
++	  '*' command didn't work, and @<carriage-return> didn't work.
++	+ Fix doubled reporting of deleted lines in filters.
++	+ Rework the % ` / ? ( ) N n { and ^A commands to always cut into
++	  numeric buffers regardless of the location or length of the cut.
++	  This matches historic practice.
++	+ Fix the { command to check the current line if the cursor doesn't
++	  start on the first character of the line.
++	+ Do '!' expansion in the ex read command arguments, it's historic
++	  practice.  In addition, it sets the last '!' command.
++1.27 -> 1.28 Wed Jul 27 21:29:18 1994
++	+ Add support for scrolling using the CS and SF/sf/SR/sr termcap
++	  strings to the 4BSD curses.
++	+ Rework of getkey() introduced a bug where command interrupt put
++	  nvi into an infinite loop.
++	+ Piping through a filter historically cut the replaced lines into
++	  the default buffer, although not the numeric ones.
++	+ Read of a filter and !! historically moved to the first nonblank
++	  of the resulting cursor line (most of the time).
++	+ Rework cursor motion flags, to support '!' as a motion command.
++1.26 -> 1.27 Tue Jul 26 10:27:58 1994
++	+ Add the meta option, to specify characters the shell will expand.
++	+ Fix the read command to match historic practice, the white space
++	  and bang characters weren't getting parsed correctly.
++	+ Change SIGALRM handler to save and restore errno.
++	+ Change SunOS include/compat.h to include <vfork.h> so that the
++	  ex/filter.c code works again.
++	+ Don't put lines deleted by the ex delete command into the numeric
++	  buffers, matching historic practice.
++	+ Fix; if appending to a buffer, default buffer historically only
++	  references the appended text, not the resulting text.
++	+ Support multiple, semi-colon separated search strings, and 'z'
++	  commands after search strings.
++	+ Make previous context mark setting match historic practice (see
++	  docs/internals/context).
++	+ Fix the set command to permit whitespace between the option and
++	  the question mark, fix question marks in general.
++	+ Fix bug where ex error messages could be accidentally preceded
++	  by a single space.
++	+ Fix bug where curses reorganization could lose screen specific
++	  mappings as soon as any screen exited.
++	+ Fix bug in paragraph code where invalid macros could be matched.
++	  Make paragraph motions stop at formfeed (^L) characters.
++	+ Change 'c' to match historic practice, it cut text into numeric
++	  buffers.
++1.25 -> 1.26 Tue Jul 19 17:46:24 1994
++	+ Ignore SIGWINCH if the screen size is unchanged; SunOS systems
++	  deliver one when a screen is uncovered.
++	+ Fix: don't permit a command with a motion component to wrap due
++	  to wrapscan and return to the original cursor position.
++	+ Fix: ^E wasn't beeping when reaching the bottom of the file.
++	+ Fix bg/fg bug where tmp file exiting caused a NULL dereference.
++	+ Rework file locking code to use fcntl(2) explicitly.
++	+ Fix bug in section code where invalid macros could be matched.
++	+ Fix bug where line number reset by vi's Q command.
++	+ Add explicit character mode designation to character mode buffers.
++	+ Add <sys/ioctl.h> include to sex/sex_window.c, needed by NET/2
++	  vintage systems.
++	+ Change to always flush a character during suspend, 4BSD curses
++	  has the optimization where it doesn't flush after a standend().
++	+ Fix bug on OSF1 where <curses.h> changes the values of VERASE,
++	  VKILL and VWERASE to incorrect ones.
++	+ Fix bug where optarg used incorrectly in main.c.
++	+ Block all signals when acting on a signal delivery.
++	+ Fix recovery bug where RCV_EMAIL could fire even if there wasn't
++	  a backing file; format recovery message.
++1.24 -> 1.25 Sun Jul 17 14:33:38 1994
++	+ Stop allowing keyboard suspends (^Z) in insert mode, it's hard
++	  to get autowrite correct, and it's not historic practice.
++	+ Fix z^, z+ to match historic practice.
++	+ Bug in message handling, "vi +35 non-existent_file" lost the
++	  status message because the "+35" pushed onto the stack erased
++	  it.  For now, change so that messages aren't displayed if there
++	  are keys waiting -- may need to add a "don't-erase" bit to the
++	  character in the stack instead.
++	+ Bug in svi_msgflush(), where error messages could come out in
++	  normal video.
++1.23 -> 1.24 Sat Jul 16 18:30:18 1994
++	+ Fix core dump in exf.c, where editing a non-existent file and
++	  exiting could cause already free'd memory to be free'd.
++	+ Clean up numerous memory errors, courtesy of Purify.
++	+ Change process wait code to fail if wait fails, and not attempt
++	  to interpret the wait return information.
++	+ Open recovery and DB files for writing as well as reading, System
++	  V (fcntl) won't let you acquire LOCK_EX locks otherwise.
++	+ Fix substitute bug where could malloc 0 bytes (AIX breaks).
++	+ Permit the mapping of <carriage-return>, it's historic practice.
++	+ Historic vi didn't eat <blank> characters before the force
++	  flag, match historic practice.
++	+ Bug in ex argument parsing, corrected for literal characters
++	  twice.
++	+ Delete screen specific maps when the screen closes.
++	+ Move to the first non-<blank> in the line on startup; historic
++	  practice.
++	+ Change the ex visual command to move directly to a line if no
++	  trailing 'z' command.
++	+ Fix "[[" and "]]" to match historic practice (yet again...).
++	+ Fix "yb" and "y{" commands to update the cursor correctly.
++	+ Change "~<motion>" to match the yank cursor movement semantics
++	  exactly.
++	+ Move all of the curses related code into sex/svi -- major rework,
++	  but should help in future ports.
++	+ Fix bug in split code caused by new file naming code, where would
++	  drop core when a split screen exited.
++	+ Change svi_ex_write to do character display translation, so that
++	  messages with file names in them are displayed correctly.
++	+ Display the file name on split screens instead of a divider line.
++	+ Fix move bug, wasn't copying lines before putting them.
++	+ Fix bug were :n dropped core if no arguments supplied.
++	+ Don't quote characters in executed buffer: "ifoo<esc>" should leave
++	  insert mode after the buffer is executed.
++	+ Tagpop and tagpush should set the absolute mark in case only moving
++	  within a file.
++	+ Skip leading whitespace characters before tags and cursor word
++	  searches.
++	+ Fix bug in ex_global where re_conv() was allocating the temporary
++	  buffer and not freeing it.
++1.22 -> 1.23: Wed Jun 29 19:22:33 1994
++	+ New <sys/cdefs.h> required "inline" to change to "__inline"
++	+ Fix System V curses code for new ^Z support.
++	+ Fix off-by-one in the move code, avoid ":1,$mo$" with only one
++	  line in the buffer.
++	+ Line orientation of motion commands was remembered too long,
++	  i.e.  '.' command could be incorrectly marked as line oriented.
++	+ Move file modification time into EXF, so it's shared across
++	  split screens.
++	+ Put the prev[ious] command back in, people complained.
++	+ Random fixes to next/prev semantics changed in 1.22.
++	+ Historically vi doesn't only move to the last address if there's
++	  ANYTHING after the addresses, e.g. ":3" moves to line 3, ":3|"
++	  prints line 3.
++1.21 -> 1.22: Mon Jun 27 11:01:41 1994
++	+ Make the line between split screens inverse video again.
++	+ Delete the prev[ious] command, it's not useful enough to keep.
++	+ Rework :args/file name handling from scratch -- MAJOR CHANGE,
++	  likely to introduce all sorts of new bugs.
++	+ Fix RE bug where no subexpressions in the pattern but there were
++	  subexpressions referenced in the replacement, e.g. "s/XXX/\1/g".
++	+ Change recovery to not leave unmodified files around after a
++	  crash, by using the owner 'x' bit on unmodified backup files.
++	  MAJOR CHANGE, the system recovery script has to change!
++	+ Change -r option to delete recovery.* files that reference non-
++	  existent vi.* files.
++	+ Rework recovery locking so that fcntl(2) locking will work.
++	+ Fix append (upper-case) buffers, broken by cut fixes.
++	+ Fix | to not set the absolute motion mark.
++	+ Read $HOME/.exrc file on startup if the effective user ID is
++	  root.  This makes running vi while su(1)'d work correctly.
++	+ Use the full pathname of the file as the recovery name, not
++	  just the last component.  Matches historic practice.
++	+ Keep marks in empty files from being destroyed.
++	+ Block all caught signals before calling the DB routines.
++	+ Make the line change report match historic practice (yanked
++	  lines were different than everything else).
++	+ Add section on multiple screens to the reference manual.
++	+ Display all messages at once, combine onto a single line if
++	  possible.  Delete the trailing period from all messages.
++1.20 -> 1.21: Thu May 19 12:21:58 1994
++	+ Delete the -l flag from the recover mail.
++	+ Send the user email if ex command :preserve executed, this matches
++	  historic practice.  Lots of changes to the preserve and recovery
++	  code, change preserve to snapshot files (again, historic practice).
++	+ Make buffers match historic practice: "add logically stores text
++	  into buffer a, buffer 1, and the unnamed buffer.
++	+ Print <tab> characters as ^I on the colon command line if the
++	  list option set.
++	+ Adjust ^F and ^B scroll values in the presence of split screens
++	  and small windows.
++	+ Break msg* routines out from util.c into msg.c, start thinking
++	  about message catalogs.
++	+ Add tildeop set option, based on stevie's option of the same name.
++	  Changes  the ~ command into "[count] ~ motion", i.e. ~ takes a
++	  trailing motion.
++	+ Chose NOT to match historic practice on cursor positioning after
++	  consecutive undo commands on a single line; see vi/v_undo.c for
++	  the comment.
++	+ Add a one line cache so that multiple changes to the same line
++	  are only counted once (e.g. "dl35p" changes one line, not 35).
++	+ Rework signals some more.  Block file sync signals in vi routines
++	  that interface to DB, so can sync the files at interrupt time.
++	  Write up all of the signal handling arguments, see signal.c.
++1.19 -> 1.20: Thu May  5 19:24:57 1994
++	+ Return ^Z to synchronous handling.  See the dicussion in signal.c
++	  and svi_screen.c:svi_curses_init().
++	+ Fix bug where line change report was wrong in util.c:msg_rpt().
++1.18 -> 1.19: Thu May  5 12:59:51 1994
++	+ Block DSUSP so that ^Y isn't delivered at SIGTSTP.
++	+ Fix bug -- put into an empty file leaves the cursor at 1,0,
++	  not the first nonblank.
++	+ Fix bug were number of lines reported for the 'P' command was
++	  off-by-one.
++	+ Fix bug were 0^D wasn't being handled correctly.
++	+ Delete remnants of ^Z as a raw character.
++	+ Fix bug where if a map was an entire colon command, it may never
++	  have been displayed.
++	+ Final cursor position fixes for the vi T and t commands.
++	+ The ex :next command took an optional ex command as it's first
++	  argument similar to the :edit commands.  Match historic practice.
++1.17 -> 1.18: Wed May  4 13:57:10 1994
++	+ Rework curses information in the PORT/Makefile's.
++	+ Minor fixes to ^Z asynchronous code.
++1.16 -> 1.17: Wed May  4 11:15:56 1994
++	+ Make ex comment handling match historic practice.
++	+ Make ^Z work asynchronously, we can no longer use the SIGTSTP
++	  handler in the curses library.
++1.15 -> 1.16: Mon May  2 19:42:07 1994
++	+ Make the 'p' and 'P' commands support counts, i.e. "Y10p" works.
++	+ Make characters that map to themselves as the first part of the
++	  mapping work, it's historic practice.
++	+ Fix bug where "s/./\& /" discarded the space in the replacement
++	  string.
++	+ Add support for up/down cursor arrows in text input mode, rework
++	  left/right support to match industry practice.
++	+ Fix bug were enough character remapping could corrupt memory.
++	+ Delete O_REMAPMAX in favor of setting interrupts after N mapped
++	  characters without a read, delete the map counter per character.
++	  MAJOR CHANGE.  All of the interrupt signal handling has been
++	  reworked so that interrupts are always turned on instead of
++	  being turned on periodically, when an interruptible operation is
++	  pending.
++	+ Fix bug where vi wait() was interrupted by the recovery alarm.
++	+ Make +cmd's and initial commands execute with the current line
++	  set to the last line of the file.  This is historic practice.
++	+ Change "lock failed" error message to a file status message.
++	  It always fails over NFS, and making all NFS files readonly
++	  isn't going to fly.
++	+ Use the historic line number format, but check for overflow.
++	+ Fix bug where vi command parser ignored buffers specified as
++	  part of the motion command.
++	+ Make [@*]buffer commands on character mode buffers match historic
++	  practice.
++	+ Fix bug where the cmap/chf entries of the tty structure weren't
++	  being cleared when new characters were read.
++	+ Fix bug where the default command motion flags were being set
++	  when the command was a motion component.
++	+ Fix wrapmargin bug; if appending characters, and wrapmargin breaks
++	  the line, an additional space is eaten.
++1.14 -> 1.15: Fri Apr 29 07:44:57 1994
++	+ Make the ex delete command work in any empty file.
++	+ Fix bug where 't' command placed the cursor on the character
++	  instead of to its left.
++	+ ^D and ^U didn't set the scroll option value historically.
++	  Note, this change means that any user set value (e.g. 15^D)
++	  will be lost when splitting the screen, since the split code
++	  now resets the scroll value regardless.
++	+ Fix the ( command to set the absolute movement mark.
++	+ Only use TIOCGWINSZ for window information if SIGWINCH signal
++	  caught.
++	+ Delete the -l flag, and make -r work for multiple arguments.
++	  Add the ex "recover[!] file" command.
++	+ Switch into ex terminal mode and use the sex routines when
++	  append/change/insert called from vi mode.
++	+ Make ^F and ^B match historic practice.  This required a fairly
++	  extensive rework of the svi scrolling code.
++	+ Cursor positioning in H, M, L, G (first non-blank for 1G) wasn't
++	  being done correctly.  Delete the SETLFNB flag.  H, M, and L stay
++	  logical movements (SETNNB) and G always moves to the first nonblank.
++	+ System V uses "lines" and "cols", not "li" and "co", change as
++	  necessary.  Check termcap function returns for errors.
++	+ Fix `<character> command to do start/end of line correction,
++	  and to set line mode if starting and stopping at column 0.
++	+ Fix bug in delete code where dropped core if deleted in character
++	  mode to an empty line.  (Rework the delete code for efficiency.)
++	+ Give up on SunOS 4.1.X, and use "cc" instead of /usr/5bin/cc.
++	+ Protect ex_getline routine from interrupted system calls (if
++	  possible, set SA_RESTART on SIGALRM, too).
++	+ Fix leftright scrolling bug, when moving to a shorter line.
++	+ Do validity checking on the copy, move, t command target line
++	  numbers.
++	+ Change for System V % pattern broke trailing flags for empty
++	  replacement strings.
++	+ Fix bug when RCM flags retained in the saved dot structure.
++	+ Make the ex '=' command work for empty files.
++	+ Fix bug where special_key array was being free'd (it's no longer
++	  allocated).
++	+ Matches cut in line mode only if the starting cursor is at or
++	  before the first nonblank in its line, and the ending cursor is
++	  at or after the last nonblank in its line.
++	+ Add the :wn command, so you can write a file and switch to a new
++	  file in one command.
++	+ Allow only a single key as an argument to :viusage.
++	+ New movement code broke filter/paragraph operations in empty
++	  files ("!}date" in an empty file was dropping core).
++1.12 -> 1.14: Mon Apr 18 11:05:10 1994 (PUBLICLY AVAILABLE VERSION, 4.4BSD)
++	+ Fix FILE structure leakage in the ex filter code.
++	+ Rework suspend code for System V curses.  Nvi has to do the
++	  the work, there's no way to get curses to do it right.
++	+ Revert SunOS 4.1.X ports to the distributed curses.  There's
++	  a bug in Sun's implementation that we can't live with.
++	+ Quit immediately if row/column values are unreasonable.
++	+ Fix the function keys to match vi historic behavior.
++	+ Replace the echo/awk magic in the Makefile's with awk scripts.
++1.11 -> 1.12: Thu Apr 14 11:10:19 1994
++	+ Fix bug where only the first vi key was checked for validity.
++	+ Make 'R' continue to overwrite after a <carriage-return>.
++	+ Only display the "no recovery" message once.
++	+ Rework line backup code to restore the line to its previous
++	  condition.
++	+ Don't permit :q in a .exrc file or EXINIT variable.
++	+ Fix wrapscan option bug where forward searches become backward
++	  searches and do cursor correction accordingly.
++	+ Change "dd" to move the cursor to the first non-blank on the line.
++	+ Delete cursor attraction to the first non-blank, change non-blank
++	  motions to set the most attractive cursor position instead.
++	+ Fix 'r' substitute option to set the RE to the last RE, not the
++	  last substitute RE.
++	+ Fix 'c' and 'g' substitute options to always toggle, and fix
++	  edcompatible option to not reset them.
++	+ Display ex error messages in inverse video.
++	+ Fix errorbells option to match historic practice.
++	+ Delete fixed character display table in favor of table built based
++	  on the current locale.
++	+ Add ":set octal" option, that displays unknown characters as octal
++	  values instead of the default hexadecimal.
++	+ Make all command and text input modes interruptible.
++	+ Fix ex input mode to display error messages immediately, instead
++	  of waiting for the lines to be resolved.
++	+ Fix bug where vi calling append could overwrite the command.
++	+ Fix off-by-one in the ex print routine tab code.
++	+ Fix incorrect ^D test in vi text input routines.
++	+ Add autoindent support for ex text insert routines.
++	+ Add System V substitute command replacement pattern semantics,
++	  where '%' means the last replacement pattern.
++	+ Fix bug that \ didn't escape newlines in ex commands.
++	+ Regularize the names of special characters to CH_*.
++	+ Change hex insert character from ^Vx<hex_char> to ^X<hex_char>
++	+ Integrate System V style curses, so SunOS and Solaris ports can
++	  use the native curses implementation.
++1.10 -> 1.11: Thu Mar 24 16:07:45 EST 1994 (PUBLICLY AVAILABLE VERSION)
++	+ Change H, M, and L to set the absolute mark, historical practice.
++	+ Fix bug in stepping through multiple tags files.
++	+ Add "remapmax" option that turns off map counts so you can remap
++	  infinitely.  If it's off, term_key() can be interrupted from the
++	  keyboard, which will cause the buffers to flush.  I also dropped
++	  the default max number of remaps to 50.  (Only Dave Hitz's TM
++	  macros and maze appear to go over that limit.)
++	+ Change :mkexrc to not dump w{300,1200,9600}, lisp options.
++	+ Fix backward search within a line bug.
++	+ Change all the includes of "pathnames.h" to use <>'s so that the
++	  PORT versions can use -I. to replace it with their own versions.
++	+ Make reads and writes interruptible.  Rework code that enters and
++	  leaves ex for '!' and filter commands, rework all interrupt and
++	  timer code.
++	+ Fix core dump when user displayed option in .exrc file.
++	+ Fix bug where writing empty files didn't update the saved
++	  modification time.
++	+ Fix bug where /pattern/ addressing was always a backward search.
++	+ Fix bug triggered by autoindent of more than 32 characters, where
++	  nvi wasn't checking the right TEXT length.
++	+ Fix bug where joining only empty lines caused a core dump.
++1.09 -> 1.10: Sat Mar 19 15:40:29 EST 1994
++	+ Fix "set all" core dump.
++1.08 -> 1.09: Sat Mar 19 10:11:14 EST 1994
++	+ If the tag's file path is relative, and it doesn't exist, check
++	  relative to the tag file location.
++	+ Fix ~ command to free temporary buffer on error return.
++	+ Create vi.ref, a first cut at a reference document for vi.
++	  The manual page and the reference document only document the
++	  set options, so far.
++	+ Fix 1G bug not always going to the first non-blank.
++	+ Upgrade PORT/regex to release alpha3.4, from Henry Spencer.
++	+ Add MKS vi's "cdpath" option, supporting a cd search path.
++	+ Handle if search as a motion was discarded, i.e. "d/<erase>".
++	+ Change nvi to not create multiple recovery files if modifying
++	  a recovered file.
++	+ Decide to ignore that the cursor is before the '$' when inserting
++	  in list mode.  It's too hard to fix.
++1.07 -> 1.08: Wed Mar 16 07:37:36 EST 1994
++	+ Leftright and big line scrolling fixes.  This meant more changes
++	  to the screen display code, so there may be new problems.
++	+ Don't permit search-style addresses until a file has been read.
++	+ "c[Ww]" command incorrectly handled the "in whitespace" case.
++	+ Fix key space allocation bug triggered by cut/paste under SunOS.
++	+ Ex move command got the final cursor position wrong.
++	+ Delete "optimize option not implemented" message.
++	+ Make the literal-next character turn off mapping for the next
++	  character in text input mode.
++1.06 -> 1.07: Mon Mar 14 11:10:33 EST 1994
++	+ The "wire down" change in 1.05 broke ex command parsing, there
++	  wasn't a corresponding change to handle multiple K_VLNEXT chars.
++	+ Fix final position for vi's 't' command.
++1.05 -> 1.06: Sun Mar 13 16:12:52 EST 1994
++	+ Wire down ^D, ^H, ^W, and ^V, regardless of the user's termios
++	  values.
++	+ Add ^D as the ex scroll command.
++	+ Support ^Q as a literal-next character.
++	+ Rework abbreviations to be delimited by any !inword() character.
++	+ Add options description to the manual page.
++	+ Minor screen cache fix for svi_get.c.
++	+ Rework beautify option support to match historical practice.
++	+ Exit immediately if not reading from a tty and a command fails.
++	+ Default the SunOS 4.* ports to the distributed curses, not SMI's.
++1.04 -> 1.05: Thu Mar 24 16:07:45 EST 1994
++	+ Make cursor keys work in input mode.
++	+ Rework screen column code in vi curses screen.  MAJOR CHANGE --
++	  after this, we'll be debugging curses screen presentation from
++	  scratch.
++	+ Explode include files in vi.h into the source files.
++1.03 -> 1.04: Sun Mar  6 14:14:16 EST 1994
++	+ Make the ex move command keep the marks on the moved lines.
++	+ Change resize semantics so you can set the screen size to a
++	  specific value.  A couple of screen fixes for the resize code.
++	+ Fixes for foreground/background due to SIGWINCH.
++	+ Complete rework of all of vi's cursor movements.  The underlying
++	  assumption in the old code was that the starting cursor position
++	  was part of the range of lines cut or deleted.  The command
++	  "d[[" is an example where this isn't true.  Change it so that all
++	  motion component commands set the final cursor position separately
++	  from the range, as it can't be done correctly later.  This is a
++	  MAJOR CHANGE -- after this change, we'll be debugging the cursor
++	  positioning from scratch.
++	+ Rewrite the B, b, E, e commands to use vi's getc() interface
++	  instead of rolling their own.
++	+ Add a second MARK structure, LMARK, which is the larger mark
++	  needed by the logging and mark queue code.  Everything else uses
++	  the reworked MARK structure, which is simply a line/column pair.
++	+ Rework cut/delete to not expect 1-past-the-end in the range, but
++	  to act on text to the end of the range, inclusive.
++	+ Sync on write's, to force NFS to flush.
++1.01 -> 1.03: Sun Jan 23 17:50:35 EST 1994 (PUBLICLY AVAILABLE VERSION)
++	+ Tag stack fixes, was returning to the tag, not the position from
++	  which the user tagged.
++	+ Only use from the cursor to the end of the word in cursor word
++	  searches and tags.  (Matches historical vi behavior.)
++	+ Fix delete-last-line bug when line number option set.
++	+ Fix usage line for :split command.
++	+ If O_NUMBER set, long input lines would eventually fail, the column
++	  count for the second screen of long lines wasn't set correctly.
++	+ Fix for [[ reaching SOF with a column longer than the first line.
++	+ Fix for multiple error messages if no screen displayed.
++	+ Fix :read to set alternate file name as in historical practice.
++	+ Fix cut to rotate the numeric buffers if line mode flag set.
++1.00 -> 1.01: Wed Jan 12 13:37:18 EST 1994
++	+ Don't put cut items into numeric buffers if cutting less than
++	  parts of two lines.
++0.94 -> 1.00: Mon Jan 10 02:27:27 EST 1994
++	+ Read-ahead not there; BSD tty driver problem, SunOS curses
++	  problem.
++	+ Global command could error if it deleted the last line of
++	  the file.
++	+ Change '.' to only apply to the 'u' if entered immediately
++	  after the 'u' command.  "1pu.u.u. is still broken, but I
++	  expect that it's going to be sacrificed for multiple undo.
++	+ If backward motion on a command, now move to the point; get
++	  yank cursor positioning correct.
++	+ Rework cut buffers to match historic practice -- yank/delete
++	  numeric buffers redone sensibly, ignoring historic practice.
++0.92 -> 0.93: Mon Dec 20 19:52:14 EST 1993
++	+ Christos Zoulas reimplemented the script windows using pty's,
++	  which means that they now work reasonably.  The down side of
++	  this is that almost all ports other than 4.4BSD need to include
++	  two new files, login_tty.c and pty.c from the PORT/clib directory.
++	  I've added them to the Makefiles.
++	+ All calloc/malloc/realloc functions now cast their pointers, for
++	  SunOS -- there should be far fewer warning messages, during the
++	  build.  The remaining messages are where CHAR_T's meet char *'s,
++	  i.e. where 8-bit clean meets strcmp.
++	+ The user's argument list handling has been reworked so that there
++	  is always a single consistent position for use by :next, :prev and
++	  :rewind.
++	+ All of the historical options are now at least accepted, although
++	  not all of them are implemented.  (Edcompatible, hardtabs, lisp,
++	  optimize, redraw, and slowopen aren't implemented.)
++	+ The RE's have been reworked so that matches of length 0 are handled
++	  in the same way as vi used to handle them.
++	+ Several more mapping fixes and ex parser addressing fixes.
+diff -Naur nvi-1.81.6.orig/nvi-1.79/docs/tutorial/vi.advanced nvi-1.81.6/nvi-1.79/docs/tutorial/vi.advanced
+--- nvi-1.81.6.orig/nvi-1.79/docs/tutorial/vi.advanced	1970-01-01 01:00:00.000000000 +0100
++++ nvi-1.81.6/nvi-1.79/docs/tutorial/vi.advanced	2008-06-22 20:35:35.000000000 +0200
+@@ -0,0 +1,1458 @@
++Section 26: Index to the rest of the tutorial
++
++The remainder of the tutorial can be perused at your leisure.  Simply find the
++topic of interest in the following list, and {/Section xx:/^M} to get to the
++appropriate section.  (Remember that ^M means the return key) 
++
++The material in the following sections is not necessarily in a bottom up
++order.  It should be fairly obvious that if a section mentions something with
++which you are not familiar, say, buffers, you might {/buffer/^M} followed by
++several {n} to do a keyword search of the file for more details on that item.
++Another point to remember is that commands are surrounded by curly-braces and
++can therefore be found rather easily.  To see where, say, the X command is
++used try {/{X}/^M}.  Subsequent {n} will show you other places the command was
++used.  We have tried to maintain the convention of placing the command letter
++surrounded by curly-braces on the section line where that command is
++mentioned.
++
++Finally, you should have enough 'savvy' at this point to be able to do your
++own experimentation with commands without too much hand-holding on the part of
++the tutorial.  Experimentation is the best way to learn the effects of the
++commands.
++
++ Section      Topic - description
++ -------      -------------------
++(Sections 1 through 25 are located in the file vi.beginner.)
++    1         introduction: {^F} {ZZ}
++    2         introduction (con't) and positioning: {^F} {^B}
++    3         introduction (con't) and positioning: {^F} {^B}
++    4         positioning: {^F} {^B} ^M (return key)
++    5         quitting: {:q!} ^M key
++    6         marking, cursor and screen positioning: {m} {G} {'} {z}
++    7         marking, cursor and screen positioning: {m} {G} {'} {z}
++    8         marking, cursor and screen positioning: {z} {m} {'}
++    9         marking and positioning: {m} {''}
++   10         line positioning: {^M} {-}
++   11         scrolling with {^M}
++   12         scrolling with {-} and screen adjustment {z}
++   13         notes on use of tutorial
++   14         other scrolling and postioning commands: {^E} {^Y} {^D} {^U}
++   15         searching: {/ .. /^M}
++   16         searching: {? .. ?^M} {n} (in search strings ^ $)
++   17         searching: \ and magic-characters in search strings
++   18         colon commands, exiting: {:} {ZZ}
++   19         screen positioning: {H} {M} {L}
++   20         character positioning: {w} {b} {0} {W} {B} {e} {E} {'} {`}
++   21         cursor positioning: {l} {k} {j} {h}
++   22         adding text: {i} {a} {I} {A} {o} {O} ^[ (escape key)
++   23         character manipulation: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J}
++   24         undo: {u} {U}
++   25         review
++(The following sections are in this file.)
++   26         Index to the rest of the tutorial ******** YOU ARE HERE *******
++   27         discussion of repeat counts and the repeat command: {.}
++   28         more on low-level character motions: {t} {T} {|}
++   29         advanced correction operators: {d} {c}
++   30         updating the screen: {^R}
++   31         text buffers: {"}
++   32         rearranging and duplicating text: {p} {P} {y} {Y}
++   33         recovering lost lines
++   34         advanced file manipulation with vi
++   34.1          more than one file at a time: {:n}
++   34.2          reading files and command output: {:r}
++   34.3          invoking vi from within vi: {:e} {:vi}
++   34.4          escaping to a shell: {:sh} {:!}
++   34.5          writing parts of a file: {:w}
++   34.6          filtering portions of text: {!}
++   35         advanced searching: magic patterns 
++   36         advanced substitution: {:s} 
++   37         advanced line addressing: {:p} {:g} {:v}
++   38         higher level text objects and nroff: ( ) { } [[ ]]
++   39         more about inserting text
++   40         more on operators: {d} {c} {<} {>} {!} {=} {y}
++   41         abbreviations: {:ab}
++   42         vi's relationship with the ex editor: {:}
++   43         vi on hardcopy terminals and dumb terminals: open mode
++   44         options: {:set} {setenv EXINIT}
++   44.1          autoindent
++   44.2          autoprint
++   44.3          autowrite
++   44.4          beautify
++   44.5          directory
++   44.6          edcompatible
++   44.7          errorbells
++   44.8          hardtabs
++   44.9          ignorecase
++   44.10         lisp
++   44.11         list
++   44.12         magic
++   44.13         mesg                    
++   44.14         number
++   44.15         open
++   44.16         optimize
++   44.17         paragraphs
++   44.18         prompt
++   44.19         readonly
++   44.20         redraw
++   44.21         remap
++   44.22         report
++   44.23         scroll
++   44.24         sections
++   44.25         shell
++   44.26         shiftwidth
++   44.27         showmatch
++   44.28         slowopen
++   44.29         tabstop
++   44.30         tags
++   44.31         taglength
++   44.32         term
++   44.33         terse
++   44.34         timeout
++   44.35         ttytype
++   44.36         warn
++   44.37         window
++   44.38         wrapscan
++   44.39         wrapmargin
++   44.40         writeany
++   44.41         w300, w1200, w9600
++
++Section 27: repetition counts and the repeat command {.}
++
++Most vi commands will use a preceding count to affect their behavior in some
++way.  We have already seen how {3x} deletes three characters, and {22G} moves
++us to line 22 of the file.  For almost all of the commands, one can survive by
++thinking of these leading numbers as a 'repeat count' specifying that the
++command is to be repeated so many number of times.
++
++Other commands use the repeat count slightly differently, like the {G} command
++which use it as a line number.
++
++For example:
++
++{3^D} means scroll down in the file three lines.  Subsequent {^D} OR {^U} will
++scroll only three lines in their respective directions!
++
++{3z^M} says put line three of the file at the top of the screen, while {3z.}
++says put line three as close to the middle of the screen as possible.
++
++{50|} moves the cursor to column fifty in the current line.
++
++{3^F} says move forward 3 screenfulls.  This is a repetition count.  The
++documents advertise that {3^B} should move BACK three screenfulls, but I
++can't get it to work.
++
++Position the cursor on some text and try {3r.}.  This replaces three characters
++with '...'.  However, {3s.....^[} is the same as {3xi.....^[}.
++
++Try {10a+----^[}.
++
++A very useful instance of a repetition count is one given to the '.' command,
++which repeats the last 'change' command.  If you {dw} and then {3.}, you will
++delete first one and then three words.  You can then delete two more words with
++{2.}.  If you {3dw}, you will delete three words.  A subsequent {.} will delete
++three more words.  But a subsequent {2.} will delete only two words, not three
++times two words.
++
++Caveat: The author has noticed that any repetition count with {^B} will NOT
++work: indeed, if you are at the end of your file and try {3^B} sufficiently
++often, the editor will hang you in an infinite loop.  Please don't try it:
++take my word for it.
++
++Section 28: {t} {T} {|}
++
++Position the cursor on line 13 below:
++
++Line 13: Four score and seven years ago, our forefathers brought ...
++
++Note that {fv} moves the cursor on/over the 'v' in 'seven'.  Do a {0} to return
++to the beginning of the line and try a {tv}.  The cursor is now on/over the
++first 'e' in 'seven'.  The {f} command finds the next occurrence of the
++specified letter and moves the cursor to it.  The {t} command finds the
++specified letter and moves the cursor to the character immediately preceding
++it.  {T} searches backwards, as does {F}.
++
++Now try {60|}: the cursor is now on the 'o' in 'brought', which is the
++sixtieth character on the line.
++
++Section 29: {d} {c}
++
++Due to their complexity we have delayed discussion of two of the most powerful
++operators in vi until now.  Effective use of these operators requires more
++explanation than was deemed appropriate for the first half of the tutorial.
++
++{d} and {c} are called operators instead of commands because they consist of
++three parts: a count specification or a buffer specification (see section
++#BUFFERS), the {d} or {c}, and the object or range description.  We will not
++discuss buffers at this stage, but will limit ourselves to count
++specifications.  Examples speak louder than words: position the cursor at the
++beginning of line 14:
++
++Line 14: Euclid alone has looked on beauty bear.
++
++Obviously, there is something wrong with this quotation.  Type {2fb} to
++position the cursor on the 'b' of 'bear'.  Now, type {cwbare^[}
++and observe the results.  The {cw} specifies that the change command {c} is to
++operate on a word object.  More accurately, it specifies that the range of the
++change command includes the next word.
++
++Position the cursor on the period in Line 14. (one way is to use {f.})
++Now, type {cbbeast^[}.  This specifies the range of the change command to be the
++previous word (the 'b' reminiscent of the {b} command).  If we had wished to
++delete the word rather than change it, we would have used the {d} operator,
++rather than the {c} operator.
++
++Position the cursor at the beginning of the line with {0}.  Type
++{d/look/^M}.  The search string specified the range of the delete.
++Everything UP TO the word 'looking' was deleted from the line.
++
++In general, almost any command that would move the cursor will specify a range
++for these commands.  The most confusing exception to this rule is when {dd} or
++{cc} is entered: they refer to the whole line.  Following is a summary of the
++suffixes (suffices? suffici?) and the ranges they specify:
++
++    suffix        will delete{d}/change{c}
++    ------        ------------------------
++      ^[            cancels the command
++      w             the word to the right of the cursor
++      W             ditto, but ignoring punctuation
++      b             the word to the left of the cursor
++      B             ditto, but ignoring punctuation
++      e             see below.
++      E               ditto
++      (space)       a character
++      $             to the end of the line
++      ^             to the beginning of the line
++      / .. /        up to, but not including, the string
++      ? .. ?        back to and including the string
++      fc            up to and including the occurrence of c 
++      Fc            back to and including the occurrence of c
++      tc            up to but not including the occurrence of c
++      Tc            back to but not including the occurrence of c
++      ^M            TWO lines (that's right: two)
++      (number)^M    that many lines plus one
++      (number)G     up to and including line (number)
++      (             the previous sentence if you are at the beginning of
++                    the current sentence, or the current sentence up to where 
++                    you are if you are not at the beginning of the current 
++                    sentence.  Here, 'sentence' refers to the intuitive
++                    notion of an English sentence, ending with '!', '?',
++                    or '.' and followed by an end of line or two spaces.
++      )             the rest of the current sentence
++      {             analogous to '(', but in reference to paragraphs:
++                    sections of text surrounded by blank lines
++      }             analogous to ')', but in reference to paragraphs
++      [[            analogous to '(', but in reference to sections
++      ]]            analogous to ')', but in reference to sections
++      H             the first line on the screen
++      M             the middle line on the screen
++      L             the last line on the screen
++      3L            through the third line from the bottom of the screen
++      ^F            forward a screenful
++      ^B            backward a screenful
++      :
++      :  etc. etc. etc.
++
++This list is not exhaustive, but it should be sufficient to get the idea
++across: after the {c} or {d} operator, you can specify a range with another
++move-the-cursor command, and that is the region of text over which the command
++will be effective.
++
++Section 30: updating the screen {^R}
++
++Vi tries to be very intelligent about the type of terminal you are working on
++and tries to use the in-terminal computing power (if any) of your terminal.
++Also if the terminal is running at a low baud rate (say 1200 or below), vi sets
++various parameters to make things easier for you.  For example, if you were
++running on a 300 baud terminal (that's 30 characters per second transmission
++rate) not all 24 lines of the screen would be used by vi.  In addition, there
++is a large portion of the editor keeping track of what your screen currently
++looks like, and what it would look like after a command has been executed.  Vi
++then compares the two, and updates only those portions of the screen that have
++changed.
++
++Furthermore, some of you may have noticed (it depends on your terminal) that 
++deleting lines or changing large portions of text may leave some lines on the 
++screen looking like: 
++@ 
++meaning that this line of the screen does not correspond to any line in your
++file. It would cost more to update the line than to leave it blank for the
++moment.  If you would like to see your screen fully up-to-date with the
++contents of your file, type {^R}.
++
++To see it in action, delete several lines with {5dd}, type {^R}, and then type
++{u} to get the lines back.
++
++Here is as good a place as any to mention that if the editor is displaying the
++end of your file, there may be lines on the screen that look like: 
++~ 
++indicating that that screen line would not be affected by {^R}.  These lines
++simply indicate the end of the file.
++
++Section 31: text buffers {"}
++
++Vi gives you the ability to store text away in "buffers".  This feature is very
++convenient for moving text around in your file.  There are a total of thirty-
++five buffers available in vi.  There is the "unnamed" buffer that is used by all
++commands that delete text, including the change operator {c}, the substitute
++and replace commands {s} and {r}, as well as the delete operator {d} and delete
++commands {x} and {X}.  This buffer is filled each time any of these commands
++are used. However, the undo command {u} has no effect on the unnamed buffer.
++
++There are twenty-six buffers named 'a' through 'z' which are available for the
++user.  If the name of the buffer is capitalized, then the buffer is not
++overwritten but appended to.  For example, the command {"qdd} will delete one
++line and store that line in the 'q' buffer, destroying the previous contents of
++the buffer.  However, {"Qdd} will delete one line of text and append that line
++to the current contents of the 'q' buffer.
++
++Finally, there are nine buffers named '1' through '9' in which the last nine
++deletes are stored.  Buffer 1 is the default buffer for the modify commands and
++is sometimes called the unnamed buffer.
++
++To reference a specific buffer, use the double-quote command {"} followed by
++the name of the buffer.  The next two sections show how buffers can be used to
++advantage.
++
++Section 32: rearranging and duplicating text: {y} {Y} {p} {P}
++
++Position yourself on line 15 below and {z^M}:
++
++Line 15: A tree as lovely as a poem ...
++Line 16: I think that I shall never see
++
++Type {dd}.  Line 15 has disappeared and been replaced with the empty line (one
++with the single character @ on it) or (again depending on your terminal) Line
++16 has moved up and taken its place.  We could recover Line 15 with an undo
++{u} but that would simply return it to its original location.  Obviously, the
++two lines are reversed, so we want to put line 15 AFTER line 16.  This is
++simply done with the put command {p}, which you should type now.  What has
++happened is that {dd} put Line 15 into the unnamed buffer, and the {p} command
++retrieved the line from the unnamed buffer.
++
++Now type {u} and observe that Line 15 disappears again (the put was undone
++without affecting the unnamed buffer).  Type {P} and see that the capital {P}
++puts the line BEFORE the cursor.
++
++To get Line 15 where it belongs again type {dd}{p}.
++
++Also in Line 15 note that the words 'tree' and 'poem' are reversed.  Using the
++unnamed buffer again: {ft}{dw}{ma}{fp}{P}{w}{dw}{`aP} will set things aright 
++(note the use of the reverse quote).
++
++The put commands {p} and {P} do not affect the contents of the buffer.
++Therefore, multiple {p} or {P} will put multiple copies of the unnamed buffer
++into your file.
++
++Experiment with {d} and {p} on words, paragraphs, etc.  Whatever {d}
++deletes, {p} can put.
++
++Position the cursor on Line 17 and {z^M}:
++
++Line 17: interest apple cat elephant boy dog girl hay farmer
++
++Our task is to alphabetize the words on line 17.  With the named buffers (and a
++contrived example) it is quite easy:
++
++{"idw}{"adw}{"cdw}{"edw}{"bdw}{"ddw}{"gdw}{"hdw}{"fdw}
++
++stores each of the words in the named buffer corresponding to the first letter
++of each of the words ('interest' goes in buffer "i, 'apple' goes in buffer "a,
++etc.).  Now to put the words in order type:
++
++{"ap$}{"bp$}{"cp$}{"dp$}{"ep$}{"fp$}{"gp$}{"hp$}{"ip$}
++
++Notice that, because 'farmer' was at the end of the line, {dw} did not include
++a space after it, and that, therefore, there is no space between 'farmer' and
++'girl'.  This is corrected with {Fg}{i ^[}.
++
++This example could have been done just as easily with lines as with
++words.
++
++You do not have to delete the text in order to put it into a buffer.  If all
++you wish to do is to copy the text somewhere else, don't use {d}, rather use
++the yank commands {y} or {Y}.  {y} is like {d} and {c} - an operator rather
++than a command.  It, too, takes a buffer specification and a range
++specification.  Therefore, instead of {dw}{P} to load the unnamed buffer with a
++word without deleting the word, use {yw} (yank a word).
++
++{Y} is designed yank lines, and not arbitrary ranges.  That is, {Y} is
++equivalent to {yy} (remember that operators doubled means the current line),
++and {3Y} is equivalent to {3yy}.
++
++If the text you yank or modify forms a part of a line, or is an object such as
++a sentence which partially spans more than one line, then when you put the text
++back, it will be placed after the cursor (or before if you use {P}).  If the
++yanked text forms whole lines, they will be put back as whole lines, without
++changing the current line.  In this case, the put acts much like the {o} or {O}
++command.
++
++The named buffers "a through "z are not affected by changing edit files.
++However, the unnamed buffer is lost when you change files, so to move text from
++one file to another you should use a named buffer.
++
++Section 33: recovering lost lines
++
++Vi also keeps track of the last nine deletes, whether you ask for it or not.
++This is very convenient if you would like to recover some text that was
++accidentally deleted or modified.  Position the cursor on line 18 following,
++and {z^M}.
++
++
++Line 18: line 1
++Line 19: line 2
++Line 20: line 3
++Line 21: line 4
++Line 22: line 5
++Line 23: line 6
++Line 24: line 7
++Line 25: line 8
++Line 26: line 9
++Type {dd} nine times: now don't cheat with {9dd}!  That is totally different.
++
++The command {"1p} will retrieve the last delete.  Furthermore, when the
++numbered buffers are used, the repeat-command command {.} will increment the
++buffer numbers before executing, so that subsequent {.} will recover all nine
++of the deleted lines, albeit in reverse order.  If you would like to review the
++last nine deletes without affecting the buffers or your file, do an undo {u}
++after each put {p} and {.}:
++
++{"1p}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}
++
++will show you all the buffers and leave them and your file intact.
++
++If you had cheated above and deleted the nine lines with {9dd}, all nine lines
++would have been stored in both the unnamed buffer and in buffer number 1. 
++(Obviously, buffer number 1 IS the unnamed buffer and is just the default
++buffer for the modify commands.)
++
++Section 34: advanced file manipulation: {:r} {:e} {:n} {:w} {!} {:!}
++
++We've already looked at writing out the file you are editing with the
++{:w} command.  Now let's look at some other vi commands to make editing
++more efficient.
++
++Section 34.1: more than one file at a time {:n} {:args}
++
++Many times you will want to edit more than one file in an editing session.
++Instead of entering vi and editing the first file, exiting, entering vi and
++editing the second, etc., vi will allow you to specify ALL files that you wish
++to edit on the invocation line.  Therefore, if you wanted to edit file1 and
++file2:
++
++% vi file1 file2
++
++will set up file1 for editing.  When you are done editing file one, write it
++out {:w^M} and then type {:n^M} to get the next file on the list.  On large
++programming projects with many source files, it is often convenient just to
++specify all source files with, say:
++
++% vi *.c
++
++If {:n^M} brings in a file that does not need any editing, another {:n^M}
++will bring in the next file.
++
++If you have made changes to the first file, but decide to discard these changes
++and proceed to the next file, {:n!^M} forces the editor to discard the current
++contents of the editor.
++
++You can specify a new list of files after {:n}; e.g., {:n f1 f2 f3^M}.  This
++will replace the current list of files (if any).
++
++You can see the current list of files being edited with {:args^M}.
++
++Section 34.2: reading files and command output: {:r}
++
++Typing {:r fname^M} will read the contents of file fname into the editor and
++put the contents AFTER the cursor line.
++
++Typing {:r !cmd^M} will read the output of the command cmd and place that
++output after the cursor line.
++
++Section 34.3: invoking vi from within vi: {:e} {:vi}
++
++To edit another file not mentioned on the invocation line, type {:e filename^M}
++or {:vi filename^M}.  If you wish to discard the changes to the current file,
++use the exclamation point after the command, e.g. {:e! filename^M}.
++
++Section 34.4: escaping to a shell: {:sh} {:!} {^Z}
++
++Occasionally, it is useful to interrupt the current editing session to perform
++a UNIX task.  However, there is no need to write the current file out, exit
++the editor, perform the task, and then reinvoke the editor on the same file.
++One thing to do is to spin off another process.  If there are several UNIX
++commands you will need to execute, simply create another shell with {:sh^M}.
++At this point, the editor is put to sleep and will be reawakened when you log
++out of the shell.
++
++If it is a single command that you want to execute, type {:!cmd^M}, where cmd
++is the command that you wish to run.  The output of the command will come to
++the terminal as normal, and will not be made part of your file.  The message
++"[Hit return to continue]" will be displayed by vi after the command is
++finished.  Hitting return will then repaint the screen.  Typing another
++{:!cmd^M} at this point is also acceptable.
++
++However, there is a quicker, easier way: type {^Z}.  Now this is a little
++tricky, but hang in there.  When you logged into UNIX, the first program you
++began communicating with was a program that is called a "shell" (i.e. it 'lays
++over' the operating system protecting you from it, sort of like a considerate
++porcupine).  When you got your first prompt on the terminal (probably a '%'
++character) this was the shell telling you to type your first command.  When
++you typed {vi filename} for some file, the shell did not go away, it just went
++to sleep.  The shell is now the parent of vi.  When you type {^Z} the editor
++goes to sleep, the shell wakes up and says "you rang?" in the form of another
++prompt (probably '%').  At this point you are talking to the shell again and
++you can do anything that you could before including edit another file!  (The
++only thing you can't do is log out: you will get the message "There are
++stopped jobs.")
++
++When your business with the shell is done, type {fg} for 'foreground' and the
++last process which you ^Z'd out of will be reawakened and the shell will go
++back to sleep.  I will refer you to the documentation for the Berkeley shell
++'csh' for more information on this useful capability.
++
++Section 34.5: writing parts of a file: {:w}
++
++The {:w} command will accept a range specifier that will then write only a
++selected range of lines to a file.  To write this section to a file, position
++the cursor on the section line (e.g. {/^Section 34.5:/^M}) and {z^M}.  Now type
++{^G} to find out the line number (it will be something like "line 513").  Now
++{/^Section 34.6:/-1^M} to find the last line of this section, and {^G} to find
++its line number (it will be something like 542).  To write out this section of
++text by itself to a separate file which we will call "sepfile", type
++{:510,542w sepfile^M}.  If sepfile already exists, you will have to use the
++exclamation point: {:1147,1168w! sepfile^M} or write to a different, non-
++existent file.
++
++{:!cat sepfile^M} will display the file just written, and it should be the
++contents of this section.
++
++There is an alternate method of determining the line numbers for the write.
++{:set number^M} will repaint the screen with each line numbered.  When the file
++is written and the numbers no longer needed, {:set nonumber^M} will remove the
++numbers, and {^R} will adjust the screen.
++
++Or, if you remember your earlier lessons about marking lines of text,
++mark the beginning and ending lines.  Suppose we had used {ma} to mark the
++first line of the section and {mb} to mark the last.  Then the command
++{:'a,'bw sepfile^M} will write the section into "sepfile".  In general,
++you can replace a line number with the 'name' of a marked line (a single-quote
++followed by the letter used to mark the line)
++
++
++Section 34.6: filtering portions of text: {!}
++
++{!} is an operator like {c} and {d}.  That is, it consists of a repetition
++count, {!}, and a range specifier.  Once the {!} operator is entered in its
++entirety, a prompt will be given at the bottom of the screen for a UNIX
++command.  The text specified by the {!} operator is then deleted and
++passed/filtered/piped to the UNIX command you type.  The output of the UNIX
++command is then placed in your file.  For example, place the cursor at the
++beginning of the following line and {z^M}:
++
++ls -l vi.tutorial
++********* marks the bottom of the output from the ls command **********
++
++Now type {!!csh^M}.  The line will be replaced with the output from the ls
++command.  The {u} command works on {!}, also.
++
++Here is an extended exercise to display some of these capabilities.  When this
++tutorial was prepared, certain auxiliary programs were created to aid in its
++development.  Of major concern was the formatting of sections of the tutorial
++to fit on a single screen, particularly the first few sections.  What was
++needed was a vi command that would 'format' a paragraph; that is, fill out
++lines with as many words as would fit in eighty columns.  There is no such vi
++command.  Therefore, another method had to be found.
++
++Of course, nroff was designed to do text formatting.  However, it produces a
++'page'; meaning that there may be many blank lines at the end of a formatted
++paragraph from nroff.  The awk program was used to strip these blank lines from
++the output from nroff.  Below are the two files used for this purpose: I refer
++you to documentation on nroff and awk for a full explanation of their function.
++Position the cursor on the next line and {z^M}.
++
++******** contents of file f **********
++#
++nroff -i form.mac | awk "length != 0 { print }"
++***** contents of file form.mac ******
++.na
++.nh
++.ll 79
++.ec \a
++.c2 \x06
++.cc \x02
++**************************************
++
++Determine the line numbers of the two lines of file f.  They should be
++something like 574 and 575, although you better double check: this file is
++under constant revision and the line numbers may change inadvertently.  Then
++{:574,575w f^M}.  Do the same for the lines of file form.mac.  They will be
++approximately 577 and 582.  Then {:577,582w form.mac^M}.  File f must have
++execute privileges as a shell file: {:!chmod 744 f^M}.
++
++Observe that this paragraph is
++rather ratty in appearance.  With our newly created files we can
++clean it up dramatically.  Position the cursor at the beginning
++of this paragraph and type the following sequence of
++characters 
++(note that we must abandon temporarily our convention
++of curly braces since the command itself contains a curly brace - we 
++will use square brackets for the nonce): [!}f^M].
++
++Here is a brief explanation of what has happened.  By typing [!}f^M] we
++specified that the paragraph (all text between the cursor and the first blank
++line) will be removed from the edit file and piped to a UNIX program called
++"f".  This is a shell command file that we have created.  This shell file runs
++nroff, pipes its output to awk to remove blank lines, and the output from awk
++is then read back into our file in the place of the old, ratty paragraph.  The
++file form.mac is a list of commands to nroff to get it to produce paragraphs
++to our taste (the right margin is not justified, the line is 79 characters
++long, words are not hyphenated, and three nroff characters are renamed to
++avoid conflict: note that in this file, the {^G} you see there is vi's display
++of the control-G character, and not the two separate characters ^ up-arrow and
++G upper-case g).
++
++This example was created before the existence of the fmt program.  I now type
++[!}fmt^M] to get the same effect much faster.  Actually, I don't type those
++six keys each time: I have an abbreviation (which see).
++
++Section 35: searching with magic patterns
++
++The documentation available for "magic patterns" (i.e. regular expressions) is
++very scanty.  The following should explain this possibly very confusing feature
++of the editor.  This section assumes that the magic option is on.  To make
++sure, you might want to type {:set magic^M}.
++
++By "magic pattern" we mean a general description of a piece of text that the
++editor attempts to find during a search.  Most search patterns consist of
++strings of characters that must be matched exactly, e.g.  {/card/^M} searches
++for a specific string of four characters.  Let us suppose that you have
++discovered that you consistently have mistyped this simple word as either ccrd
++or czrd (this is not so far-fetched for touch typists).  You could {/ccrd/^M}
++and {n} until there are no more of this spelling, followed by {/czrd/^M} and
++{n} until there are no more of these.  Or you could {/c.rd/^M} and catch all of
++them on the first pass.  Try typing {/c.rd/^M} followed by several {n} and
++observe the effect.
++
++Line 27: card cord curd ceard
++
++When '.' is used in a search string, it has the effect of matching any single
++character.
++
++The character '^' (up-arrow) used at the beginning of a search string means
++the beginning of the line.  {/^Line 27/^M} will find the example line above,
++while {/Line 27/^M} will find an occurrence of this string anywhere in the
++line.
++
++Similarly, {/ the$/^M} will find all occurrences of the word 'the' occurring
++at the end of a line.  There are several of them in this file.
++
++Note that {:set nomagic^M} will turn off the special meaning of these magic
++characters EXCEPT for '^' and '$' which retain their special meanings at the
++beginning and end of a search string.  Within the search string they hold no
++special meaning.  Try {/\/ the$\//^M} and note that the dollar-sign is not the
++last character in the search string.  Let the dollar-sign be the last
++character in the search string, as in {/\/ the$/^M} and observe the result.
++
++Observe the result of {/back.*file/^M}.  This command, followed by sufficient
++{n}, will show you all lines in the file that contain both the words 'back'
++and 'file' on the same line.  The '*' magic character specifies that the
++previous regular expression (the '.' in our example) is to be repeatedly
++matched zero or more times.  In our example we specified that the words 'back'
++and 'file' must appear on the same line (they may be parts of words such as
++'backwards' or 'workfile') separated by any number (including zero) of
++characters.
++
++We could have specified that 'back' and 'file' are to be words by themselves by
++using the magic sequences '\<' or '\>'.  E.g.  {/\<back\>.*\<file\>/^M}.  The
++sequence '\<' specifies that this point of the search string must match the
++beginning of a word, while '\>' specifies a match at the end of a word.  By
++surrounding a string with these characters we have specified that they must be
++words.
++
++To find all words that begin with an 'l' or a 'w', followed by an 'a' or an
++'e', and ending in 'ing', try {/\<[lw][ea][a-z]*ing\>/^M}.  This will match
++words like 'learning', 'warning', and 'leading'.  The '[..]' notation matches
++exactly ONE character.  The character matched will be one of the characters
++enclosed in the square brackets.  The characters may be specified individually
++as in [abcd] or a '-' may be used to specify a range of characters as in [a-d].
++That is, [az] will match the letter 'a' OR the letter 'z', while [a-z] will
++match any of the lower case letters from 'a' through 'z'.  If you would like to
++match either an 'a', a '-', or a 'z', then the '-' must be escaped: [a\-z] will
++match ONE of the three characters 'a', '-', or 'z'.
++
++If you wish to find all Capitalized words, try {/\<[A-Z][a-z]*\>/^M}.  The
++following will find all character sequences that do NOT begin with an
++uncapitalized letter by applying a special meaning to the '^' character in
++square brackets: {/\<[^a-z][a-z]*\>/^M}.  When '^' is the first character of a
++square-bracket expression, it specifies "all but these characters".  (No
++one claimed vi was consistent.)
++
++To find all variable names (the first character is alphabetic, the remaining
++characters are alphanumeric):  try {/\<[A-Za-z][A-Za-z0-9]*\>/^M}.
++
++In summary, here are the primitives for building regular expressions:
++
++     ^      at beginning of pattern, matches beginning of line
++     $      at end of pattern, matches end of line
++     .      matches any single character
++     \<     matches the beginning of a word
++     \>     matches the end of a word
++     [str]  matches any single character in str
++     [^str] matches any single character NOT in str
++     [x-y]  matches any character in the ASCII range between x and y
++     *      matches any number (including zero) of the preceding pattern
++
++Section 36: advanced substitution: {:s} 
++
++The straightforward colon-substitute command looks like the substitute
++command of most line-oriented editors.  Indeed, vi is nothing more than a
++superstructure on the line-oriented editor ex and the colon commands are
++simply a way of accessing commands within ex (see section #EX).  This gives us
++a lot of global file processing not usually found in visual oriented editors.
++
++The colon-substitute command looks like: {:s/ .. / .. /^M} and will find the
++pattern specified after the first slash (this is called the search pattern),
++and replace it with the pattern specified after the second slash (called,
++obviously enough, the replacement pattern).  E.g. position the cursor on line
++28 below and {:s/esample/example/^M}:
++
++Line 28: This is an esample.
++
++The {u} and {U} commands work for {:s}.  The first pattern (the search pattern)
++may be a regular expression just as for the search command (after all, it IS a
++search, albeit limited to the current line).  Do an {u} on the above line, and
++try the following substitute, which will do almost the same thing: 
++{:s/s[^ ]/x/^M}.  
++Better undo it with {u}.  The first pattern {s[^ ]} matches an 's'
++NOT followed by a blank: the search therefore ignores the 's'es in 'This' and
++'is'.  However, the character matched by {[^ ]} must appear in the replacement
++pattern.  But, in general, we do not know what that character is!  (In this
++particular example we obviously do, but more complicated examples will follow.)
++Therefore, vi (really ex) has a duplication mechanism to copy patterns matched
++in the search string into the replacement string.  Line 29 below is a copy of
++line 28 above so you can adjust your screen.
++
++Line 29: This is an esample.
++
++In general, you can nest parts of the search pattern in \( .. \) and refer to
++it in the replacement pattern as \n, where n is a digit.  The problem outlined
++in the previous paragraph is solved with {:s/s\([^ ]\)/x\1/^M}: try it.  Here
++\1 refers to the first pattern grouping \( .. \) in the search string.
++
++Obviously, for a single line, this is rather tedious.  Where it becomes
++powerful, if not necessary, is in colon-substitutes that cover a range of
++lines.  (See the next section for a particularly comprehensive example.)
++
++If the entire character sequence matched by the search pattern is needed in
++the replacement pattern, then the unescaped character '&' can be used.  On
++Line 29 above, try {:s/an e.ample/not &/^M}.  If another line is to have the
++word 'not' prepended to a pattern, then '~' can save you from re-typing the
++replacement pattern.  E.g. {:s/some pattern/~/^M} after the previous example
++would be equivalent to {:s/some pattern/not &/^M}.
++
++One other useful replacement pattern allows you to change the case of
++individual letters.  The sequences {\u} and {\l} cause the immediately
++following character in the replacement to be converted to upper- or lower-case,
++respectively, if this character is a letter.  The sequences {\U} and {\L} turn
++such conversion on, either until {\E} or {\e} is encountered, or until the end
++of the replacement pattern.
++
++For example, position the cursor on a line: pick a line, any line.  Type
++{:s/.*/\U&/^M} and observe the result.  You can undo it with {u}.
++
++The search pattern may actually match more than once on a single line.
++However, only the first pattern is substituted.  If you would like ALL
++patterns matched on the line to be substituted, append a 'g' after the
++replacement pattern: {:s/123/456/g^M} will substitute EVERY occurrence
++on the line of 123 with 456.
++
++Section 37: advanced line addressing: {:p} {:g} {:v}
++
++Ex (available through the colon command in vi) offers several methods for
++specifying the lines on which a set of commands will act.  For example, if you
++would like to see lines 50 through 100 of your file: {:50,100p^M} will display
++them, wait for you to [Hit return to continue], and leave you on line 100.
++Obviously, it would be easier just to do {100G} from within vi.  But
++what if you would like to make changes to just those lines?  Then the
++addressing is important and powerful.
++
++Line 30: This is a text.
++Line 31: Here is another text.
++Line 32: One more text line.
++
++The lines above contain a typing error that the author of this tutorial tends
++to make every time he attempts to type the word 'test'.  To change all of these
++'text's into 'test's, try the following:
++{:/^Line 30/,/^Line 32/s/text/test/^M}.  This finds the beginning and end of
++the portion of text to be changed, and limits the substitution to each of the
++lines in that range.  The {u} command applies to ALL of the substitutions as 
++a group.
++
++This provides a mechanism for powerful text manipulations.
++And very complicated examples.
++
++Line 33: This test is a.
++Line 34: Here test is another.
++Line 35: One line more test.
++
++The above three lines have the second word out of order.  The following command
++string will put things right.  Be very careful when typing this: it is very
++long, full of special characters, and easy to mess up.  You may want to
++consider reading the following section to understand it before trying the
++experiment.  Don't worry about messing up the rest of the file, though: the
++address range is specified.
++
++{:/^Line 33/,/^Line 35/s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/^M}
++
++There are several things to note about this command string.  First of all, the
++range of the substitute was limited by the address specification {/^Line
++33/,/^Line 35/^M}.  It might have been simpler to do {:set number^M} to see the
++line numbers directly, and then, in place of the two searches, typed
++the line numbers, e.g. {1396,1398}.  Or to mark the lines with {ma} and {mb}
++and use {'a,'b}.
++
++Then follows the substitute pattern itself.  To make it easier to understand
++what the substitute is doing, the command is duplicated below with the various
++patterns named for easier reference:
++
++     s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/
++       |--\1---|  |--\2---| |--\3---| |--\4---|
++      |--------search pattern------------------|-replacement|
++                                               |--pattern---|
++
++In overview, the substitute looks for a particular pattern made up of 
++sub-patterns, which are named \1, \2, \3, and \4.  These patterns are specified
++by stating what they are NOT.  Pattern \1 is the sequence of characters that
++are NOT colons: in the search string, {[^:]} will match exactly one character
++that is not a colon, while appending the asterisk {[^:]*} specifies that the
++'not a colon' pattern is to be repeated until no longer satisfied, and
++{\([^:]*\)} then gives the pattern its name, in this case \1.  Outside of the
++specification of \1 comes {: }, specifying that the next two characters must be
++a colon followed by a blank.
++
++Patterns \2 and \3 are similar, specifying character sequences that are
++not blanks.  Pattern \4 matches up to the period at the end of the line.
++
++The replacement pattern then consists of specifying the new order of the
++patterns.
++
++This is a particularly complicated example, perhaps the most complicated
++in this tutorial/reference.  For our small examples, it is obviously
++tedious and error prone.  For large files, however, it may be the most
++efficient way to make the desired modifications.
++
++(The reader is advised to look at the documentation for awk.  This tool is very
++powerful and slightly simpler to use than vi for this kind of file
++manipulation.  But, it is another command language to learn.)
++
++Many times, you will not want to operate on every line in a certain
++range.  Rather you will want to make changes on lines that satisfy
++certain patterns; e.g. for every line that has the string 'NPS' on it,
++change 'NPS' to 'Naval Postgraduate School'.  The {:g} addressing
++command was designed for this purpose.  The example of this paragraph
++could be typed as {:g/NPS/s//Naval Postgraduate School/^M}.
++
++The general format of the command is {:g/(pattern)/cmds^M} and it
++works in the following way: all lines that match the pattern
++following the {:g} are 'tagged' in a special way.  Then each of these
++lines have the commands following the pattern executed over them.
++
++Line 36: ABC rhino george farmer Dick jester lest
++Line 37: george farmer rhino lest jester ABC
++Line 38: rhino lest george Dick farmer ABC jester 
++
++Type:
++
++{:g/^Line.*ABC/s/Dick/Harry Binswanger/|s/george farmer/gentleman george/p^M}
++
++There are several things of note here.  First, lines 36, 37, and 38 above are
++tagged by the {:g}.  Type {:g/^Line.*ABC/p^M} to verify this.  Second, there
++are two substitutes on the same line separated by '|'.  In general, any colon
++commands can be strung together with '|'.  Third, both substitutes operate on
++all three lines, even though the first stubstitute works on only two of the
++lines (36 and 38).  Fourth, the second substitute works on only two lines (36
++and 37) and those are the two lines printed by the trailing 'p'.
++
++The {:v} command works similarly to the {:g} command, except that the sense of
++the test for 'tagging' the lines is reversed: all lines NOT matching the search
++pattern are tagged and operated on by the commands.
++
++Using {^V} to quote carriage return (see section 39) can be used in global
++substitutions to split two lines.  For example, the command 
++{:g/\.  /s//.^V^M/g^M} will change your file so that each sentence is on a 
++separate line.  (Note that we have to 'escape' the '.', because '.' by itself
++matches any character.  Our command says to find any line which contains a 
++period followed by 2 spaces, and inserts a carriage return after the period.)
++
++Caveat:  In some of the documentation for ex and vi you may find the
++comment to the effect that {\^M} can be used between commands following
++{:g}.  The author of this tutorial has never gotten this to work and has
++crashed the editor trying.
++
++Section 38: higher level text objects and nroff: {(} {)} [{] [}] {[[} {]]}
++
++(Note: this section may be a little confusing because of our command
++notation.  Using curly braces to surround command strings works fine as
++long as the command string does not contain any curly braces itself.
++However, the curly braces are legitimate commands in vi.  Therefore, for
++any command sequence that contains curly braces, we will surround that
++sequence with SQUARE braces, as on the previous Section line.)
++
++In working with a document, particularly if using the text formatting
++programs nroff or troff, it is often advantageous to work in terms of
++sentences, paragraphs, and sections.  The operations {(} and {)} move to
++the beginning of the previous and next sentences, respectively.  Thus
++the command {d)} will delete the rest of the current sentence; likewise
++{d(} will delete the previous sentence if you are at the beginning of
++the current sentence, or, if you are not at the beginning of a sentence,
++it will delete the current sentence from the beginning 
++up to where you are.
++
++A sentence is defined to end at a '.', '!', or '?' which is followed
++by either the end of a line, or by two spaces.  Any number of closing
++')', ']', '"', and ''' characters may appear after the '.', '!', or '?'
++before the spaces or end of line.  Therefore, the {(} and {)} commands
++would recognize only one sentence in the following line, but two
++sentences on the second following line.
++
++Line 39: This is one sentence. Even though it looks like two.
++Line 40: This is two sentences.  Because it has two spaces after the '.'.
++
++The operations [{] and [}] move over paragraphs and the operations {[[}
++and {]]} move over sections.
++
++A paragraph begins after each empty line, and also at each of a set of nroff
++paragraph macros.  A section begins after each line with a form-feed ^L in the
++first column, and at each of a set of nroff section macros.  When preparing a
++text file as input to nroff, you will probably be using a set of nroff macros
++to make the formatting specifications easier, or more to your taste.  These
++macros are invoked by beginning a line with a period followed by the one or two
++letter macro name. Vi has been programmed to recognize these nroff macros, and
++if it doesn't recognize your particular macro you can use the {:set paragraphs}
++or {:set sections} commands so that it will.
++
++Section 39: more about inserting text
++
++There are a number of characters which you can use to make correnctions
++during input mode.  These are summarized in the following table.
++
++    ^H      deletes the last input character
++    ^W      deletes the last input word
++    (erase) same as ^H; each terminal can define its own erase character; 
++            for some it is ^H, for others it is the DELETE key, and for
++            others it is '@'.
++    (kill)  deletes the input on this line; each terminal can define its
++            own line-kill character; for some it is ^U, for others it is
++            '@'; you will need to experiment on your terminal to find
++            out what your line-kill and erase characters are.
++    \       escapes a following ^H, (kill), and (erase) characters: i.e.
++            this is how to put these characters in your file.
++    ^[      escape key; ends insertion mode
++    ^?      the delete key; interrupts an insertion, terminating it
++            abnormally.
++    ^M      the return key; starts a new line.
++    ^D      backtabs over the indentation set by the autoindent option
++    0^D     backtabs over all indentation back to the beginning of the line
++    ^^D     (up-arrow followed by control-d)same as 0^D, except the indentation 
++	    will be restored at the beginning of the next line.
++    ^V      quotes the next non-printing character into the file
++
++If you wish to type in your erase or kill character (say # or @ or ^U) then you
++must precede it with a \, just as you would do at the normal system command
++level.  A more general way of typing non-printing characters into the file is
++to precede them with a ^V.  The ^V echoes as a ^ character on which the cursor
++rests.  This indicates that the editor expects you to type a control character
++and it will be inserted into the file at that point.  There are a few
++exceptions to note.  The implementation of the editor does not allow the null
++character ^@ to appear in files.  Also the linefeed character ^J is used by the
++editor to separate lines in the file, so it cannot appear in the middle of a
++line.  (Trying to insert a ^M into a file, or putting it in the replacement 
++part of a substitution string will result in the matched line being split in 
++two.  This, in effect, is how to split lines by using a substitution.)  You can 
++insert any other character, however, if you wait for the editor to echo the ^ 
++before you type the character.  In fact, the editor will treat a following 
++letter as a request for the corresponding control character.  This is the only 
++way to type ^S or ^Q, since the system normally uses them to suspend and resume 
++output and never gives them to the editor to process.
++
++If you are using the autoindent option you can backtab over the indent which it
++supplies by typing a ^D.  This backs up to the boundary specified by the
++shiftwidth option.  This only works immediately after the supplied autoindent.
++
++When you are using the autoindent option you may wish to place a label at the
++left margin of a line.  The way to do this easily is to type ^ (up-arrow) and
++then ^D.  The editor will move the cursor to the left margin for one line, and
++restore the previous indent on the next.  You can also type a 0 followed
++immediately by a ^D if you wish to kill all indentation and not have it resume
++on the next line.
++
++Section 40: more on operators: {d} {c} {<} {>} {!} {=} {y}
++
++Below is a non-exhaustive list of commands that can follow the operators
++to affect the range over which the operators will work.  However, note
++that the operators {<}, {>}, {!}, and {=} do not operate on any object
++less than a line.  Try {!w} and you will get a beep.  To get the
++operator to work on just the current line, double it.  E.g. {<<}.
++
++    suffix        will operate on
++    ------        ------------------------
++      ^[            cancels the command
++      w             the word to the right of the cursor
++      W             ditto, but ignoring punctuation
++      b             the word to the left of the cursor
++      B             ditto, but ignoring punctuation
++      e             see below.
++      E               ditto
++      (space)       a character
++      $             to the end of the line
++      ^             to the beginning of the line
++      / .. /        up to, but not including, the string
++      ? .. ?        back to and including the string
++      fc            up to and including the occurrence of c 
++      Fc            back to and including the occurrence of c
++      tc            up to but not including the occurrence of c
++      Tc            back to but not including the occurrence of c
++      ^M            TWO lines (that's right: two)
++      (number)^M    that many lines plus one
++      (number)G     up to and including line (number)
++      (             the previous sentence if you are at the beginning of
++                    the current sentence, or the current sentence up to where 
++                    you are if you are not at the beginning of the current 
++                    sentence.  Here, 'sentence' refers to the intuitive
++                    notion of an English sentence, ending with '!', '?',
++                    or '.' and followed by an end of line or two spaces.
++      )             the rest of the current sentence
++      {             analogous to '(', but in reference to paragraphs:
++                    sections of text surrounded by blank lines
++      }             analogous to ')', but in reference to paragraphs
++      [[            analogous to '(', but in reference to sections
++      ]]            analogous to ')', but in reference to sections
++      H             the first line on the screen
++      M             the middle line on the screen
++      L             the last line on the screen
++      3L            through the third line from the bottom of the screen
++      ^F            forward a screenful
++      ^B            backward a screenful
++      :
++      :  etc. etc. etc.
++
++This list is not exhaustive, but it should be sufficient to get the idea
++across: after the operator, you can specify a range with a move-the-cursor
++command, and that is the region of text over which the operator will be
++effective.
++
++Section 41: abbreviations: {:ab}
++
++When typing large documents you may find yourself typing a large phrase
++over and over.  Vi gives you the ability to specify an abbreviation for
++a long string such that typing the abbreviation will automatically
++expand into the longer phrase.
++
++Type {:ab nps Naval Postgraduate School^M}.  Now type:
++
++{iThis is to show off the nps's UNIX editor.^M^[}
++
++Section 42: vi's relationship with the ex editor: {:}
++
++Vi is actually one mode of editing within the editor ex.  When you are
++running vi you can escape to the line oriented editor of ex by giving
++the command {Q}.  All of the colon-commands which were introduced above
++are available in ex.  Likewise, most ex commands can be invoked from vi
++using {:}.   
++
++In rare instances, an internal error may occur in vi.  In this case you
++will get a diagnostic and will be left in the command mode of ex.  You can
++then save your work and quit if you wish by giving the command {x} after
++the colon prompt of ex.  Or you can reenter vi (if you are brave) by
++giving ex the command {vi}.
++
++Section 43: vi on hardcopy terminals and dumb terminals: open mode
++
++(The author has not checked the following documentation for accuracy.  It is
++abstracted from the Introduction to Vi Editing document.)
++
++If you are on a hardcopy terminal or a terminal which does not have a cursor
++which can move off the bottom line, you can still use the command set of vi,
++but in a different mode.  When you give the vi command to UNIX, the editor will
++tell you that it is using open mode.  This name comes from the open command in
++ex, which is used to get into the same mode.
++
++The only difference between visual mode (normal vi) and open mode is the way in
++which the text is displayed.
++
++In open mode the editor uses a single line window into the file, and moving
++backward and forward in the file causes new lines to be displayed, always below
++the current line.  Two commands of vi work differently in open: {z} and {^R}.
++The {z} command does not take parameters, but rather draws a window of context
++around the current line and then returns you to the current line.
++
++If you are on a hardcopy terminal, the {^R} command will retype the current
++line.  On such terminals, the editor normally uses two lines to represent the
++current line.  The first line is a copy of the line as you started to edit it,
++and you work on the line below this line.  When you delete characters, the
++editor types a number of \'s to show you the characters which are deleted.  The
++editor also reprints the current line soon after such changes so that you can
++see what the line looks like again.
++
++It is sometimes useful to use this mode on very slow terminals which can
++support vi in the full screen mode.  You can do this by entering ex and using
++an {open} command.
++
++*********************************************************************
++Section 44: options: {:set} {setenv EXINIT}
++
++You will discover options as you need them.  Do not worry about them very much
++on the first pass through this document.  My advice is to glance through them,
++noting the ones that look interesting, ignoring the ones you don't understand,
++and try re-scanning them in a couple of weeks.
++
++If you decide that you have a favorite set of options and would like to change
++the default values for the editor, place a {setenv EXINIT} command in your
++.login file.  When you are given an account under UNIX your directory has
++placed in it a file that is executed each time you log in.  If one of the
++commands in this file sets the environment variable EXINIT to a string of vi
++commands, you can have many things done for you each time you invoke vi.  For
++example, if you decide that you don't like tabstops placed every eight columns
++but prefer every four columns, and that you wish the editor to insert linefeeds
++for you when your typing gets you close to column 72, and you want
++autoindentation, then include the following line in your .login file:
++
++setenv EXINIT='set tabstop=4 wrapmargin=8 autoindent'
++
++or equivalently
++
++setenv EXINIT='se ts=4 wm=8 ai'
++
++Each time you bring up vi, this command will be executed and the options set.
++
++There are forty options in the vi/ex editor that the user can set for his/her
++own convenience.  They are described in more detail in individual sections
++below.  The section line will show the full spelling of the option name, the
++abbreviation, and the default value of the option.  The text itself
++comes from the ex reference manual and is not the epitome of clarity.
++
++Section 44.1: {autoindent}, {ai} default: noai
++
++Can be used to ease the preparation of structured program text.  At the
++beginning of each append, change or insert command or when a new line is opened
++or created by an append, change, insert, or substitute operation within open or
++visual mode, ex looks at the line being appended after, the first line changed
++or the line inserted before and calculates the amount of white space at the
++start of the line.  It then aligns the cursor at the level of indentation so
++determined.
++
++If the user then types lines of text in, they will continue to be justified at
++the displayed indenting level.  If more white space is typed at the beginning
++of a line, the following line will start aligned with the first non-white
++character of the previous line.  To back the cursor up to the preceding tab
++stop one can hit {^D}.  The tab stops going backwards are defined at multiples
++of the shiftwidth option.  You cannot backspace over the indent, except by
++sending an end-of-file with a {^D}.  A line with no characters added to it
++turns into a completely blank line (the white space provided for the autoindent
++is discarded). Also specially processed in this mode are lines beginning with
++an up-arrow `^' and immediately followed by a {^D}.  This causes the input to
++be repositioned at the beginning of the line, but retaining the previous indent
++for the next line.  Similarly, a `0' followed by a {^D} repositions at the
++beginning but without retaining the previous indent.  Autoindent doesn't happen
++in global commands or when the input is not a terminal.
++
++Section 44.2: {autoprint}, {ap} default: ap
++
++Causes the current line to be printed after each delete, copy, join, move,
++substitute, t, undo or shift command.  This has the same effect as supplying a
++trailing `p' to each such command.  Autoprint is suppressed in globals, and
++only applies to the last of many commands on a line.
++
++Section 44.3: {autowrite}, {aw} default: noaw
++
++Causes the contents of the buffer to be written to the current file if you have
++modified it and give a next, rewind, stop, tag, or {!} command, or a control-
++up-arrow {^^} (switch files) or {^]} (tag goto) command in visual.  Note, that
++the edit and ex commands do not autowrite.  In each case, there is an
++equivalent way of switching when autowrite is set to avoid the autowrite
++({edit} for next, rewind!  for rewind, stop!  for stop, tag!  for tag, shell
++for {!}, and {:e #} and a {:ta!} command from within visual).
++
++Section 44.4: {beautify}, {bf} default: nobeautify
++
++Causes all control characters except tab ^I, newline ^M and form-feed ^L to be
++discarded from the input.  A complaint is registered the first time a backspace
++character is discarded.  Beautify does not apply to command input.
++
++Section 44.5: {directory}, {dir} default: dir=/tmp 
++
++Specifies the directory in which ex places its buffer file.  If this directory
++in not writable, then the editor will exit abruptly when it fails to be able to
++create its buffer there.
++
++Section 44.6: {edcompatible} default: noedcompatible
++
++Causes the presence or absence of g and c suffixes on substitute commands to be
++remembered, and to be toggled by repeating the suffices.  The suffix r makes
++the substitution be as in the {~} command, instead of like {&}.
++
++[Author's note: this should not concern users of vi.]
++
++Section 44.7: {errorbells}, {eb} default: noeb
++
++Error messages are preceded by a bell.  However, bell ringing in open and
++visual modes on errors is not suppressed by setting noeb.  If possible the
++editor always places the error message in a standout mode of the terminal (such
++as inverse video) instead of ringing the bell.
++
++Section 44.8: {hardtabs}, {ht} default: ht=8
++
++Gives the boundaries on which terminal hardware tabs are set (or on which the
++system expands tabs).
++
++Section 44.9: {ignorecase}, {ic} default: noic
++
++All upper case characters in the text are mapped to lower case in regular
++expression matching.  In addition, all upper case characters in regular
++expressions are mapped to lower case except in character class specifications
++(that is, character in square brackets).
++
++Section 44.10: {lisp} default: nolisp
++
++Autoindent indents appropriately for lisp code, and the {(}, {)}, [{], [}],
++{[[}, and {]]} commands in open and visual modes are modified in a
++striaghtforward, intuitive fashion to have meaning for lisp.
++
++[Author's note: but don't ask me to define them precisely.]
++
++Section 44.11: {list} default: nolist
++
++All printed lines will be displayed (more) unambiguously, showing tabs as ^I
++and end-of-lines with `$'.  This is the same as in the ex command {list}.
++
++Section 44.12: {magic} default: magic for {ex} and {vi}, nomagic for edit.
++
++If nomagic is set, the number of regular expression metacharacters is greatly
++reduced, with only up-arrow `^' and `$' having special effects.  In addition
++the metacharacters `~' and `&' of the replacement pattern are treated as normal
++characters.  All the normal metacharacters may be made magic when nomagic is
++set by preceding them with a `\'.
++
++[Author's note: In other words, if magic is set a back-slant turns the magic
++off for the following character, and if nomagic is set a back-slant turns the
++magic ON for the following character.  And, no, we are not playing Dungeons and
++Dragons, although I think the writers of these option notes must have played it
++all the time.]
++
++Section 44.13: {mesg} default: mesg
++
++Causes write permission to be turned off to the terminal while you are in
++visual mode, if nomesg is set.
++
++[Author's note: I don't know if anyone could have made any one sentence
++paragraph more confusing than this one.  What it says is: mesg allows people to
++write to you even if you are in visual or open mode; nomesg locks your terminal
++so they can't write to you and mess up your screen.]
++
++Section 44.14: {number, nu} default: nonumber
++
++Causes all output lines to be printed with their line numbers.  In addition
++each input line will be prompted with its line number.
++
++Section 44.15: {open} default: open
++
++If {noopen}, the commands open and visual are not permitted.  This is set for
++edit to prevent confusion resulting from accidental entry to open or visual
++mode.
++
++[Author's note: As you may have guessed by now, there are actually three
++editors available under Berkeley UNIX that are in reality the same
++program, ex, with different options set: ex itself, vi, and edit.]
++
++Section 44.16: {optimize, opt} default: optimize
++
++Throughput of text is expedited by setting the terminal to not do automatic
++carriage returns when printing more than one (logical) line of output, greatly
++speeding output on terminals without addressable cursors when text with leading
++white space is printed.
++
++[Author's note: I still don't know what this option does.]
++
++Section 44.17: {paragraphs, para} default: para=IPLPPPQPP LIbp
++
++Specifies the paragraphs for the [{] and [}] operations in open and visual.
++The pairs of characters in the option's value are the names of the nroff macros
++which start paragraphs.
++
++Section 44.18: {prompt} default: prompt
++
++Command mode input is prompted for with a `:'.
++
++[Author's note: Doesn't seem to have any effect on vi.]
++
++Section 44.19: {readonly}, {ro} default: noro, unless invoked with -R 
++                                         or insufficient privileges on file
++
++This option allows you to guarantee that you won't clobber your file by
++accident.  You can set the option and writes will fail unless you use an `!'
++after the write.  Commands such as {x}, {ZZ}, the autowrite option, and in
++general anything that writes is affected.  This option is turned on if you
++invoke the editor with the -R flag.
++
++Section 44.20: {redraw} default: noredraw
++
++The editor simulates (using great amounts of output), an intelligent terminal
++on a dumb terminal (e.g. during insertions in visual the characters to the
++right of the cursor position are refreshed as each input character is typed).
++Useful only at very high baud rates, and should be used only if the system is
++not heavily loaded: you will notice the performance degradation yourself.
++
++Section 44.21: {remap} default: remap
++
++If on, macros are repeatedly tried until they are unchanged.  For example, if o
++is mapped to O, and O is mapped to I, then if remap is set, o will map to I,
++but if noremap is set, it will map to O .
++
++Section 44.22: {report} default: report=5 for ex and vi, 2 for edit
++
++Specifies a threshold for feedback from commands.  Any command which modifies
++more than the specified number of lines will provide feedback as to the scope
++of its changes.  For commands such as global, open, undo, and visual which have
++potentially more far reaching scope, the net change in the number of lines in
++the buffer is presented at the end of the command, subject to this same
++threshold.  Thus notification is suppressed during a global command on the
++individual commands performed.
++
++Section 44.23: {scroll} default: scroll=1/2 window
++
++Determines the number of logical lines scrolled when a {^D} is received from a
++terminal in command mode, and determines the number of lines printed by a
++command mode z command (double the value of scroll).
++
++[Author's note: Doesn't seem to affect {^D} and {z} in visual (vi) mode.]
++
++Section 44.24: sections {sections} default: sections=SHNHH HU 
++
++Specifies the section macros from nroff for the {[[} and {]]} operations in
++open and visual.  The pairs of characters in the options's value are the names
++of the macros which start paragraphs.
++
++Section 44.25: {shell}, {sh} default: sh=/bin/sh 
++
++Gives the path name of the shell forked for the shell escape command `!', and
++by the shell command.  The default is taken from SHELL in the environment, if
++present.
++
++[Editor's note: I would suggest that you place the following line in
++your .login file:
++setenv SHELL '/bin/csh'
++]
++
++Section 44.26: {shiftwidth}, {sw} default: sw=8 
++
++Used in reverse tabbing with {^D} when using autoindent to append text, and
++used by the shift commands.  Should probably be the same value as the tabstop
++option.
++
++Section 44.27: {showmatch}, {sm} default: nosm 
++
++In open and visual mode, when a `)' or `}' is typed, if the matching `(' or `{'
++is on the screen, move the cursor to it for one second.  Extremely useful with
++complicated nested expressions, or with lisp.
++
++Section 44.28: {slowopen}, {slow} default: terminal dependent
++
++Affects the display algorithm used in visual mode, holding off display updating
++during input of new text to improve throughput when the terminal in use is both
++slow and unintelligent.  See "An Introduction to Display Editing with Vi" for
++more details.
++
++Section 44.29: {tabstop}, {ts} default: ts=8
++
++The editor expands tabs ^I to tabstop boundaries in the display.
++
++Section 44.30: {taglength}, {tl} default: tl=0
++
++Tags are not significant beyond this many characters.
++A value of zero (the default) means that all characters are significant.
++
++Section 44.31: {tags} default: tags=tags /usr/lib/tags
++
++A path of files to be used as tag files for the tag command.  A requested tag
++is searched for in the specified files, sequentially.  By default files called
++tags are searched for in the current directory and in /usr/lib (a master file
++for the entire system).
++
++[Author's note: The author of this tutorial has never used this option, nor
++seen it used.  I'm not even sure I know what they are talking about.]
++
++Section 44.32: {term} default: from environment variable TERM
++
++The terminal type of the output device.
++
++Section 44.33: {terse} default: noterse
++
++Shorter error diagnostics are produced for the experienced user.
++
++Section 44.34: {timeout} default: timeout
++
++Causes macros to time out after one second.  Turn it off and they will
++wait forever.  This is useful if you want multi-character macros, but if
++your terminal sends escape sequences for arrow keys, it will be
++necessary to hit escape twice to get a beep.
++
++[Editor's note: Another paragraph which requires a cryptographer.]
++
++Section 44.35: ttytype
++
++[Editor's note: I have found no documentation for this option at all.]
++
++Section 44.36: {warn} default: warn
++
++Warn if there has been `[No write since last change]' before a `!' command
++escape.
++
++Section 44.37: {window} default: window=speed dependent
++
++The number of lines in a text window in the visual command.  The default is 8
++at slow speeds (600 baud or less), 16 at medium speed (1200 baud), and the full
++screen (minus one line) at higher speeds.
++
++Section 44.38: {wrapscan}, {ws} default: ws
++
++Searches using the regular expressions in addressing will wrap around past the
++end of the file.
++
++Section 44.39: {wrapmargin}, {wm} default: wm=0
++
++Defines a margin for automatic wrapover of text during input in open and visual
++modes.  The numeric value is the number of columns from the right edge of the
++screen around which vi looks for a convenient place to insert a new-line
++character (wm=0 is OFF).  This is very convenient for touch typists.
++Wrapmargin behaves much like fill/nojustify mode does in nroff.
++
++Section 44.40: {writeany}, {wa} default: nowa
++
++Inhibit the checks normally made before write commands, allowing a write to any
++file which the system protection mechanism will allow.
++
++Section 44.41: {w300}, {w1200}, {w9600} defaults: w300=8
++                                                 w1200=16
++                                                 w9600=full screen minus one
++
++These are not true options but set the default size of the window for when the
++speed is slow (300), medium (1200), or high (9600), respectively.  They are
++suitable for an EXINIT and make it easy to change the 8/16/full screen rule.
++
++Section 45: Limitations
++
++Here are some editor limits that the user is likely to encounter:
++       1024   characters per line
++       256    characters per global command list
++       128    characters per file name
++       128    characters in the previous inserted and deleted text in open or 
++              visual
++       100    characters in a shell escape command
++       63     characters in a string valued option
++       30     characters in a tag name
++       250000 lines in the file (this is silently enforced).
++
++The visual implementation limits the number of macros defined with map to 32,
++and the total number of characters in macros to be less than 512.
++
++[Editor's note: these limits may not apply to versions after 4.1BSD.]
+diff -Naur nvi-1.81.orig/nvi-1.79/docs/tutorial/vi.beginner nvi-1.81.6/nvi-1.79/docs/tutorial/vi.beginner
+--- nvi-1.81.6.orig/nvi-1.79/docs/tutorial/vi.beginner	1970-01-01 01:00:00.000000000 +0100
++++ nvi-1.81.6/nvi-1.79/docs/tutorial/vi.beginner	2008-06-22 20:35:35.000000000 +0200
+@@ -0,0 +1,741 @@
++Section 1: {^F} {ZZ}
++
++To get out of this tutorial, type: ZZ (two capital Z's).
++
++Learning a new computer system implies learning a new text editor.  These
++tutorial lessons were created by Dain Samples to help you come to grips with
++UC Berkeley's screen oriented editor called vi (for VIsual). This tutorial
++uses the vi editor itself as the means of presentation. 
++
++For best use of this tutorial, read all of a screen before performing any of
++the indicated actions.  This tutorial (or, at least, the first half of it) has
++been designed to systematically present the vi commands IF THE INSTRUCTIONS
++ARE FOLLOWED!  If you are too adventuresome, you may find yourself lost.  If
++you ever find yourself stuck, remember the first line of this section.
++
++OK, now find the control key on your keyboard; it usually has CTL or CTRL
++written on its upper surface.  Your first assignment is to hold the control
++key down while you press the 'F' key on your keyboard.  Please do so now.
++
++
++
++Section 2: {^F} {^B}
++Many of vi's commands use the control key and some other key in combination,
++as with the control and the 'F' key above.  This is abbreviated CTL-F, or ^F.
++
++As you have probably guessed by now, ^F (CTL-F) moves you forward a fixed
++number of lines in the file.  Throughout the remainder of the tutorial when
++you are ready to advance to the next section of text, hit ^F.
++
++The opposite command is ^B.  Just for fun, you might want to try a ^B to see
++the previous section again.  Be sure to do a ^F to return you here.
++
++Determine what the cursor looks like on your screen.  Whatever it is (a box,
++an underscore, blinking, flashing, inverse, etc.) it should now be positioned
++in the upper left-hand corner of your screen under or on the S of Section.
++Become familiar with your cursor: to use vi correctly it is important to
++always know where the cursor is.
++
++Did you notice that when you do a ^F the cursor is left at the top of the
++screen, and a ^B leaves the cursor near the bottom of the screen?  Try the two
++commands ^B^F again.  And now do another ^F to see the next section.
++
++Section 3: {^F} {^B}
++You now have two basic commands for examining a file, both forwards (^F) and
++backwards (^B).
++
++Note that these are vi text editing commands: they are not commands for the
++tutorial.  Indeed, this tutorial is nothing but a text file which you are now
++editing.  Everything you do and learn in this tutorial will be applicable to
++editing text files.
++
++Therefore, when you are editing a file and are ready to see more of the text,
++entering ^F will get you to the next section of the file.  Entering ^B will
++show you the previous section.
++
++Time for you to do another ^F.
++
++
++
++
++
++
++
++Section 4: {^F} {^B} {^M} (return key)
++We will adopt the notation of putting commands in curly braces so we can write
++them unambiguously.  For example, if you are to type the command sequence
++"control B control F" (as we asked you to do above) it would appear as {^B^F}.
++This allows clear delineation of the command strings from the text. Remember
++that the curly braces are NOT part of the command string you are to type. Do
++NOT type the curly braces.  
++
++Sometimes, the command string in the curly braces will be rather long, and may
++be such that the first couple of characters of the command will erase from
++the screen the string you are trying to read and type.  It is suggested that
++you write down the longer commands BEFORE you type them so you won't forget
++them once they disappear.
++
++Now locate the return key on your keyboard: it is usually marked 'RETURN',
++indicate hitting the return key.  In fact, the control-M key sequence is
++exactly the same as if you hit the return key, and vice versa.
++
++Now type {^F}.
++
++
++Section 5: {:q!} {ZZ} {^M} (return key)
++Recognize that this tutorial is nothing more than a text file that you
++are editing.  This means that if you do something wrong, it is possible
++for you to destroy the information in this file.  Don't worry.  If this
++happens, type {ZZ} (two capital Z's) or {:q!^M} to leave the tutorial.
++Restart the tutorial.  Once in the tutorial, you can then page forward
++with {^F} until you are back to where you want to be.  (There are
++easier ways to do this, some of which will be discussed later, but this
++is the most straightforward.)
++
++You may want to write these commands down in a convenient place for quick
++reference: {:q!^M} and {ZZ}
++
++We will assume that you now know to do a {^F} to advance the file
++
++
++
++
++
++
++
++Section 6: {m} {G} {'} {z}
++Now that you know how to get around in the file via ^F and ^B let's look at
++other ways of examining a text file.  Sometimes it is necessary, in the midst
++of editing a file, to examine another part of the file.  You are then faced
++with the problem of remembering your place in the file, looking at the other
++text, and then getting back to your original location.  Vi has a 'mark'
++command, m. Type {mp}.  You have just 'marked' your current location in the
++file and given it the name 'p'.  The command string below will do three
++things: position you at the beginning of the file (line 1), then return you to
++the location 'p' that you just marked with the 'm' command, and, since the
++screen will not look exactly the same as it does right now, the 'z' command
++will reposition the screen. (You may want to write the string down before
++typing it: once you type {1G} it will no longer be on the screen.)
++
++So now type {1G'pz^M} - a one followed by a capital G, followed by the quote
++mark, followed by a lower case 'p', then a lower case 'z', then a return
++(which is the same as a ^M).  The {1G} moves you to line 1, i.e. the beginning
++of the file.  The {'p} moves you to the location you marked with {mp}.  The
++{z^M} command will repaint the screen putting the cursor at the top of the
++screen. (Now {^F}.)
++
++Section 7: {m} {G} {'} {z}
++Let's look at some variations on those commands.  If you wanted to look at
++line 22 in the file and return to this location you could type {mp22G'p}.  Do
++so now, observing that {22G} puts your cursor at the beginning of section 2 in
++the middle of the screen.
++
++Also note that, without the {z^M} command, the line with 'Section 7' on it is
++now in the MIDDLE of the screen, and not at the top.  Our cursor is on the
++correct line (where we did the {mp} command) but the line is not where we
++might like it to be on the screen.  That is the function of the {z^M} command.
++(Remember, ^M is the same as the 'return' key on your keyboard.)  Type {z^M}
++now and observe the effect.
++
++As you can see, the 'Section 7' line is now at the top of the screen with the
++cursor happily under the capital S.  If you would like the cursor line (i.e.
++the line which the cursor is on) in the middle of the screen again, you would
++type {z.}.  If you wanted the cursor line to be at the BOTTOM of the screen,
++type {z-}.  Try typing {z-z.z^M} and watch what happens.
++
++{^F}
++
++Section 8: {z} {m} {'}
++
++Note that the z command does not change the position of our cursor in the file
++itself, it simply moves the cursor around on the screen by moving the contents
++of the file around on the screen.  The cursor stays on the same line of the
++file when using the z command.
++
++This brings up an important point.  There are two questions that the users of
++vi continually need to know the answer to: "Where am I in the file?" and
++"Where am I on the screen?"  The cursor on your terminal shows the answer to
++both questions.  Some commands will move you around in the file, usually
++changing the location of the cursor on the screen as well.  Other commands
++move the cursor around on the screen without changing your location in the
++file.
++
++Now type {ma}.  Your location in the file has been given the name 'a'. If you
++type {'p'a} you will see the previous location we marked in section 7, and
++then will be returned to the current location.  (You will want to do a {z^M}
++to repaint the screen afterwards.)  Try it.  
++{^F}
++
++Section 9: {m} {''}
++Now we can move about in our file pretty freely.  By using the {m} command we
++can give the current cursor position a lower-case-character name, like 'p',
++'a', 'e', 'm', or 'b'.  Using the {G} command preceded by a line number we can
++look at any line in the file we like.  Using the single quote command {'}
++followed by a character used in an {m} command, we can return to any location
++in the file we have marked.
++
++However, try {m3}, or {mM}.  You should hear a beep, or bell.  Only lower-case
++letters are acceptable to the {m} and {'} commands: numbers, upper-case
++letters, and special characters are not acceptable.
++
++If you type the {'} command with a character that is lower-case alphabetic but
++that has not been used in an {m} command, or for which the 'marked' text has
++been deleted, you will also get a beep.  Try {'i}.  You should get a beep
++because the command {mi} has never been issued.  (Unless you've been
++experimenting.)
++
++The command {''} attempts to return you to the location at which you last
++modified some part of your file.  However, my experience has been that it is
++difficult to predict exactly where you will end up.  
++Section 10: {^M} {-}
++Now do {ma}, marking your position at the top of the screen.  Now hit {^M} (or
++return) until the cursor is right ... 
++* <- here, over/under the asterisk.  Now
++type {mb'a'b} and watch the cursor move from the asterisk to the top of the
++screen and back again.
++
++The {^M} command moves the cursor to the beginning of the next line.  Now type
++{^M} until the cursor is right ...
++* <- here.  The command to move the cursor to the beginning of the
++previous line is {-}.  Practice moving the cursor around on the screen by using
++{^M} and {-}.  BE CAREFUL to not move the cursor OFF the screen just yet.  If
++you do, type {'az^M}.
++
++Now we can move to any line within the screen.  Practice moving around in the
++file using the {^F}, {^B}, {-}, {^M}, {z}, and {'} commands.  When you are
++fairly confident that you can get to where you need to be in the file, and
++position the cursor on the screen where you want it type {'az^M^F} (which, of
++course, moves you back to the beginning of this section, repositions the
++cursor at the top of the screen, and advances you to the next section).
++
++Section 11: scrolling: {^M}
++The cursor should now be on the S of 'Section 11', and this should be on the
++first line of the screen.  If it is not, do {^M} or {-} as appropriate to put
++the cursor on the section line, and type {z^M}.
++
++Type {mc} to mark your place.
++
++Now type {^M} until the cursor is on the last line of this screen.  Now do one
++more {^M} and observe the result.  This is called scrolling.  When you
++attempted to move to a line not displayed on the screen, the line at the top of
++the screen was 'scrolled off', and a line at the bottom of the screen was
++'scrolled on'.  The top line with 'Section 11' should no longer be visible.
++
++Now type {'cz^M} to reset the screen and type {^F} for the next section.
++
++
++
++
++
++
++
++Section 12: {-} {z}
++
++The {-} command moves the cursor to the previous line in the file.  Now type
++{-}, which attempts to move the cursor to the previous line in this file.
++However, that line is not on the screen.  The resulting action will depend on
++your terminal.  (Do a {^Mz^M} to reposition the file).  On intelligent
++terminals (e.g. VT100s, Z19s, Concept 100s), a top line is 'scrolled on' and
++the bottom line is 'scrolled off'.  Other terminals, however, may not have
++this 'reverse scrolling' feature.  They will simply repaint the screen with
++the cursor line in the middle of the screen.  On such terminals it is
++necessary to type {z^M} to get the cursor line back to the top of the screen.
++
++
++
++
++
++
++
++
++
++
++Section 13:
++Up until this point, the tutorial has always tried to make sure that the first
++line of each screen has on it the section number and a list of the commands
++covered in that section.  This will no longer be strictly maintained.  If you
++want the section line at the top of the screen, you now know enough commands to
++do it easily: do {^M} or {-} until the cursor is on the section line and
++then {z^M}.  Also, from this point on, it may not be the case that a {^F} will
++put you at the beginning of the next section.  Therefore, be aware of where you
++are in the file as we look at other commands.  You may have to find your way
++back to a particular section without any help from the tutorial.  If you do not
++feel comfortable with this, then it is suggested that you practice moving from
++section 1 to section 13, back and forth, using {^M}, {-}, {^F}, and {^B}
++commands for a while.
++
++Also make liberal use of the mark command {m}: if, for example, you make a
++habit of using {mz} to mark your current location in the file, then you will
++always be able to return to that location with {'z} if the editor does
++something strange and you have no idea where you are or what happened.
++
++And finally, the proscription against experimentation is hereby lifted: play
++with the editor.  Feel free to try out variations on the commands and move
++around in the file.  By this time you should be able to recover from any gross
++errors.
++
++Section 14: {^E} {^Y} {^D} {^U}
++Let us now look at a few other commands for moving around in the file, and
++moving the file around on the screen.  Note that the commands we have already
++looked at are sufficient: you really don't need any more commands for looking
++in a file.  The following commands are not absolutely necessary.  However,
++they can make editing more convenient, and you should take note of their
++existence.  But it would be perfectly valid to decide to ignore them on this
++first pass: you can learn them later when you see a need for them, if you ever
++do.
++
++First, let's clear up some potentially confusing language.  In at least one
++place in the official document ('An Introduction to Display Editing with Vi'
++by William Joy, and Mark Horton, September 1980), the expression "to scroll
++down text" means that the cursor is moved down in your file.  However, note
++that this may result in the text on the screen moving UP.  This use of the
++word 'scroll' refers to the action of the cursor within the file.  However,
++another legitimate use of the word refers to the action of the text on the
++screen.  That is, if the lines on your screen move up toward the top of the
++screen, this would be 'scrolling the screen up'.  If the lines move down
++toward the bottom of the screen, this would be refered to as scrolling down.
++
++I have tried to maintain the following jargon: 'scrolling' refers to what the
++text does on the screen, not to what the cursor does within the file.  For the
++latter I will refer to the cursor 'moving', or to 'moving the cursor'.  I
++realize that this is not necessarily consistent with Joy and Horton, but they
++were wrong.
++
++{^E} scrolls the whole screen up one line, keeping the cursor on the same line,
++if possible.  However, if the cursor line is the first line on the screen, then
++the cursor is moved to the next line in the file.  Try typing {^E}.
++
++{^Y} scrolls the screen down one line, keeping the cursor on the same line, if
++possible.  However, if the cursor line is the last line on the screen, then the
++cursor is moved to the previous line in the file.  Try it.
++
++{^D} moves the cursor down into the file, scrolling the screen up.
++
++{^U} moves the cursor up into the file, also scrolling the screen if the
++terminal you are on has the reverse scroll capability.  Otherwise the
++screen is repainted.
++
++Note that {^E} and {^Y} move the cursor on the screen while trying to keep the
++cursor at the same place in the file (if possible: however, the cursor can
++never move off screen), while {^D} and {^U} keep the cursor at the same place
++on the screen while moving the cursor within the file.
++
++Section 15: {/ .. /^M}
++
++Another way to position yourself in the file is by giving the editor a string
++to search for.  Type the following: {/Here 1/^M} and the cursor should end up
++right ...........................here ^.  Now type {/Section 15:/^M} and the
++cursor will end up over/on .....................here ^.  Now type {//^M} and
++observe that the cursor is now over the capital S five lines above this line.
++Typing {//^M} several more times will bounce the cursor back and forth between
++the two occurrences of the string.  In other words, when you type a string
++between the two slashes, it is searched for.  Typing the slashes with nothing
++between them acts as if you had typed the previous string again.
++
++Observe that the string you type between the two slashes is entered on the
++bottom line of the screen.  Now type {/Search for x /^M} except replace the 'x'
++in the string with some other character, say 'b'.  The message "Pattern not
++found" should appear on the bottom of the screen.  If you hadn't replaced the
++'x', then you would have found the string.  Try it.
++
++Section 16: {? .. ?^M} {n} (search strings: ^ $)
++
++When you surround the sought-for string with slashes as in {/Search/}, the
++file is searched beginning from your current position in the file.  If the
++string is not found by the end of the file, searching is restarted at the
++beginning of the file.  However, if you do want the search to find the
++PREVIOUS rather than the NEXT occurrence of the string, surround the string
++with question marks instead of slash marks.
++
++Below are several occurrences of the same string.  
++Here 2            Here 2 Here 2
++ Here 2             Here 2.
++Observe the effect of the following search commands (try them in the
++sequence shown):
++{/Here 2/^M}  {//^M}  {??^M}
++{/^Here 2/^M}  {//^M}  {??^M}
++{/Here 2$/^M}  {//^M}  {??^M}
++
++The first command looks for the next occurrence of the string 'Here 2'.
++However the second line of commands looks for an occurrence of 'Here 2' that
++is at the beginning of the line.  When the up-arrow is the first character of
++a search string it stands for the beginning of the line.  When the dollar-sign
++is the last character of the search string it stands for the end of the line.
++Therefore, the third line of commands searches for the string only when it is
++at the end of the line.  Since there is only one place the string begins a
++line, and only one place the string ends the line, subsequent {//^M} and
++{??^M} will find those same strings over and over.
++
++The {n} command will find the next occurrence of the / or ? search
++string.  Try {/Here 2/^M} followed by several {n} and observe the
++effect.  Then try {??^M} followed by several {n}.  The {n} command
++remembers the direction of the last search.  It is just a way to save a
++few keystrokes.
++
++Section 17: \ and magic-characters in search strings
++
++Now type {/Here 3$/^M}.  You might expect the cursor to end up
++right......^ here.  However, you will get "Pattern not found" at the bottom of
++the screen.  Remember that the dollar-sign stands for the end of the line.
++Somehow, you must tell vi that you do not want the end of the line, but a
++dollar-sign.  In other words, you must take away the special meaning that the
++dollar-sign has for the search mechanism.  You do this (for any special
++character, including the up-arrow ^) by putting a back-slash ('\', not '/') in
++front of the character.
++
++Now try {/Here 3\$/^M} and you should end up nine lines above this one.  Try
++{//^M} and note that it returns you to the same place, and not to the first
++line of this paragraph: the back-slash character is not part of the search
++string and will not be found.  To find the string in the first line of this
++paragraph, type {/Here 3\\\$/^M}.  There are three back-slashes: the first takes
++away the special meaning from the second, and the third takes away the special
++meaning from the dollar-sign.
++
++Following is a list of the characters that have special meanings in search
++strings.  If you wish to find a string containing one of these characters, you
++will have to be precede the character with a backslash.  These characters are
++called magic characters because of the fun and games you can have with them
++and they can have with you, if you aren't aware of what they do.  
++
++  ^ - (up-arrow)       beginning of a line
++  $ - (dollar-sign)    end of a line
++  . - (period)         matches any character
++  \ - (backslant)      the escape character itself
++  [ - (square bracket) for finding patterns (see section #SEARCH)
++  ] - (square bracket) ditto
++  * - (asterisk)       ditto
++
++Without trying to explain it here, note that {:set nomagic^M} turns off the
++special meanings of all but the ^ up-arrow, $ dollar-sign, and backslash
++characters.
++
++Section 18: {: (colon commands)} {ZZ}
++
++In this section we will discuss getting into and out of the editor in more
++detail.  If you are editing a file and wish to save the results the command
++sequence {:w^M} writes the current contents of the file out to disk, using the
++file name you used when you invoked the editor.  That is, if you are at the
++command level in Unix, and you invoke vi with {vi foo} where foo is the name
++of the file you wish to edit, then foo is the name of the file used by the
++{:w^M} command.
++
++If you are done, the write and quit commands can be combined into a single
++command {:wq^M}.  An even simpler way is the command {ZZ} (two capital Z's).
++
++If, for some reason, you wish to exit without saving any changes you have made,
++{:q!^M} does the trick.  If you have not made any changes, the exclamation
++point is not necessary: {:q^M}.  Vi is pretty good about not letting you
++get out without warning you that you haven't saved your file.
++
++We have mentioned before that you are currently in the vi editor, editing a
++file.  If you wish to start the tutorial over from the very beginning, you
++could {ZZ}, and then type {vi.tut beginner} in response to the Unix prompt.
++This will create a fresh copy of this file for you, which might be necessary 
++if you accidentally destroyed the copy you were working with.  Just do a 
++search for the last section you were in: e.g.  {/Section 18:/^Mz^M}.
++
++Section 19: {H} {M} {L}
++
++Here are a few more commands that will move you around on the screen.  Again,
++they are not absolutely necessary, but they can make screen positioning easier:
++
++{H} - puts the cursor at the top of the screen (the 'home' position)
++
++{M} - puts the cursor in the middle of the screen
++
++{L} - puts the cursor at the bottom of the screen.
++
++Try typing {HML} and watch the cursor.
++
++Try typing {5HM5L} and note that 5H puts you five lines from the top of the
++screen, and 5L puts you five lines from the bottom of the screen.
++
++Section 20: {w} {b} {0} {W} {B} {e} {E} {'} {`}
++
++Up to this point we have concentrated on positioning in the file, and
++positioning on the screen.  Now let's look at positioning in a line.  Put the
++cursor at the beginning of the following line and type {z^M}:
++
++This is a test line: your cursor should initially be at its beginning.
++
++The test line should now be at the top of your screen. Type {w} several times.
++Note that it moves you forward to the beginning of the next word.  Now type
++{b} (back to the beginning of the word) several times till you are at the
++beginning of the line.  (If you accidentally type too many {b}, type {w} until
++you are on the beginning of the line again.) Type {wwwww} (five w's) and note
++that the cursor is now on the colon in the sentence.  The lower-case w command
++moves you forward one word, paying attention to certain characters such as
++colon and period as delimiters and counting them as words themselves.  Now
++type {0} (zero, not o 'oh'): this moves you to the beginning of the current
++line.  Now type {5w} and notice that this has the effect of repeating {w} five
++times and that you are now back on the colon.  Type {0} (zero) again.  To
++ignore the delimiters and to move to the beginning of the next word using only
++blanks, tabs and carriage-returns (these are called white-space characters) to
++delimit the words, use the {W} command: upper-case W.  {B} takes you back a
++word using white-space characters as word delimiters.
++
++Note that the commands {wbWB} do not stop at the beginning or end of a line:
++they will continue to the next word on the next line in the direction specified
++(a blank line counts as a word).
++
++If you are interested in the END of the word, and not the BEGINNING, then use
++the {e} and {E} commands.  These commands only move forward and there are no
++corresponding 'reverse search' commands for the end of a word.
++
++Also, we have been using the {'} command to move the cursor to a position that
++we have previously marked with the {m} command.  However, position the cursor
++in the middle of a line (any line, just pick one) and type {mk}, marking that
++position with the letter k.  Now type a few returns {^M} and type {'k}.
++Observe that the cursor is now at the beginning of the line that you marked.
++Now try {`k}: note that this is the reverse apostrophe, or back-quote, or grave
++accent, or whatever you want to call it.  Also note that it moves you to the
++character that was marked, not just to the line that was marked.
++
++In addition, the {``} command works just like the {''} command except that you
++are taken to the exact character, not just to the line.  (I'm still not
++sure which exact character, just as I'm still not sure which line.)
++
++Section 21: {l} {k} {j} {h}
++
++There are several commands to move around on the screen on a character by
++character basis:
++
++l - moves the cursor one character to the RIGHT
++k - moves the cursor UP one line
++j - moves the cursor DOWN one line
++h - moves the cursor one character to the LEFT
++
++Section 22: {i} {a} {I} {A} {o} {O} ^[ (escape key)
++
++For this and following sections you will need to use the ESCAPE key on your
++terminal.  It is usually marked ESC.  Since the escape key is the same as
++typing {^[} we will use ^[ for the escape key.
++
++Probably the most often used command in an editor is the insert command.  Below
++are two lines of text, the first correct, the second incorrect.  Position your
++cursor at the beginning of Line 1 and type {z^M}.
++
++Line 1: This is an example of the insert command.
++Line 2: This is an of the insert command.
++
++To make line 2 look like line 1, we are going to insert the characters
++'example ' before the word 'of'.  So, now move the cursor so that it is
++positioned on the 'o' of 'of'.  (You can do this by typing {^M} to move
++to the beginning of line 2, followed by {6w} or {wwwwww} to position the cursor
++on the word 'of'.)
++
++Now carefully type the following string and observe the effects:
++  {iexample ^[}  (remember: ^[ is the escape key)}
++The {i} begins the insert mode, and 'example ' is inserted into the line: 
++be sure to notice the blank in 'example '.  The ^[ ends insertion mode, 
++and the line is updated to include the new string.  Line 1 should look exactly 
++like Line 2.
++
++Move the cursor to the beginning of Line 3 below and type {z^M}:
++
++Line 3: These lines are examples for the 'a' command.
++Line 4: These line are examples for the '
++
++We will change line four to look like line three by using the append command.
++We need to append an 's' to the word 'line'.  Position the cursor on the 'e'
++of 'line'.  You can do this in several ways, one way is the following:
++First, type {/line /^M}.  This puts us on the word 'line' in Line 4
++(the blank in the search string is important!).  Next, type {e}.  The 'e' puts
++us at the end of the word.  Now, type {as^[  (^[ is the escape character)}.  
++The 'a' puts us in insert mode, AFTER the current character.  We appended the 
++'s', and the escape ^[ ended the insert mode.
++
++The difference between {i} (insert) and {a} (append) is that {i} begins
++inserting text BEFORE the cursor, and {a} begins inserting AFTER the cursor.
++
++Now type {Aa' command.^[}.  The cursor is moved to the end of the line and the
++string following {A} is inserted into the text.  Line 4 should now look like
++line 3.
++
++Just as {A} moves you to the end of the line to begin inserting, {I} would
++begin inserting at the FRONT of the line.
++
++To begin the insertion of a line after the cursor line, type {o}.  To insert a
++line before the cursor line, type {O}.  In other words {o123^[} is equivalent
++to {A^M123^[}, and {O123^[} is equivalent to {I123^M^[}.  The text after the
++{o} or {O} is ended with an escape ^[.
++
++This paragraph contains information that is terminal dependent: you will just
++have to experiment to discover what your terminal does.  Once in the insert
++mode, if you make a mistake in the typing, ^H will delete the previous
++character up to the beginning of the current insertion.  ^W will delete the
++previous word, and one of ^U, @, or ^X will delete the current line (up to the
++beginning of the current insertion).  You will need to experiment with ^U, @,
++and ^X to determine which works for your terminal.
++
++Section 23: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J}
++
++Position the cursor at the beginning of line 5 and {z^M}:
++
++Line 5: The line as it should be.
++Line 6: The line as it shouldn't be.
++
++To make Line 6 like Line 5, we have to delete the 'n', the apostrophe, and the
++'t'.  There are several ways to position ourselves at the 'n'.  Choose
++whichever one suits your fancy:
++
++{/n't/^M}
++{^M7w6l}  or  {^M7w6 } (note the space)
++{^M3fn}  (finds the 3rd 'n' on the line)
++
++Now {xxx} will delete the three characters, as will {3x}.
++
++Note that {X} deletes the character just BEFORE the cursor, as opposed
++to the character AT the cursor.
++
++Position the cursor at line 7 and {z^M}:
++
++Line 7: The line as it would be.
++Line 8: The line as it could be.
++
++To change line 8 into line 7 we need to change the 'c' in 'could' into a 'w'.
++The 'r' (replace) command was designed for this.  Typing {rc} is the same as
++typing {xic^[} (i.e.  delete the 'bad' character and insert the correct
++new character).  Therefore, assuming that you have positioned the cursor on the
++'c' of 'could', the easiest way to change 'could' into 'would' is {rw}.
++
++If you would like to now change the 'would' into 'should', use the substitute
++command, 's': {ssh^[}.  The difference between 'r' and 's' is that 'r'
++(replace) replaces the current character with another character, while 's'
++(substitute) substitutes the current character with a string, ended with an
++escape.
++
++The capital letter version of replace {R} replaces each character by a
++character one at a time until you type an escape, ^[.  The 'S' command
++substitutes the whole line.
++
++Position your cursor at the beginning of line 9 and {z^M}.
++
++Line  9: Love is a many splendored thing.
++Line 10: Love is a most splendored thing.
++
++To change line 10 into line 9, position the cursor at the beginning of 'most',
++and type {Rmany^[}.
++
++You may have noticed that, when inserting text, a new line is formed by typing
++{^M}.  When changing, replacing, or substituting text you can make a new line
++by typing {^M}.  However, neither {x} nor {X} will remove ^M to make two lines 
++into one line.  To do this, position the cursor on the first of the two lines 
++you wish to make into a single line and type {J} (uppercase J for 'Join').
++
++Section 24: {u} {U}
++
++Finally, before we review, let's look at the undo command.  Position
++your cursor on line 11 below and {z^M}.
++
++Line 11: The quick brown fox jumped over the lazy hound dog.
++Line 12: the qwick black dog dumped over the laxy poune fox.
++
++Type the following set of commands, and observe carefully the effect of each 
++of the commands:
++
++{/^Line 12:/^M} {ft} {rT} {fw} {ru} {w} {Rbrown fox^[} {w} {rj} 
++{fx} {rz} {w} {Rhound dog^[}
++
++Line 12 now matches line 11.  Now type {U} - capital 'U'.  And line 12 now
++looks like it did before you typed in the command strings.  Now type:
++
++{ft} {rT} {fw} {ru} {^M} {^M}
++
++and then type {u}:  the cursor jumps back to the line containing the second
++change you made and 'undoes' it.  That is, {U} 'undoes' all the changes on the
++line, and {u} 'undoes' only the last change.  Type {u} several times and
++observe what happens: {u} can undo a previous {u}!
++
++Caveat: {U} only works as long as the cursor is still on the line.  Move the
++cursor off the line and {U} will have no effect, except to possibly beep at
++you.  However, {u} will undo the last change, no matter where it occurred.
++
++Section 25: review
++
++At this point, you have all the commands you need in order to make use of vi.
++The remainder of this tutorial will discuss variations on these commands as
++well as introduce new commands that make the job of editing more efficient.
++Here is a brief review of the basic commands we have covered.  They are listed
++in the order of increasing complexity and/or decreasing necessity (to say that
++a command is less necessary is not to say that it is less useful!).  These
++commands allow you to comfortably edit any text file.  There are other
++commands that will make life easier but will require extra time to learn,
++obviously.  You may want to consider setting this tutorial aside for several
++weeks and returning to it later after gaining experience with vi and getting
++comfortable with it.  The convenience of some of the more exotic commands may
++then be apparent and worth the extra investment of time and effort
++required to master them.
++
++to get into the editor from Unix:           {vi filename}
++to exit the editor
++      saving all changes                    {ZZ} or {:wq^M}
++      throwing away all changes             {:q!^M}
++      when no changes have been made        {:q^M}
++save a file without exiting the editor      {:w^M}
++write the file into another file            {:w filename^M}
++insert text 
++      before the cursor                     {i ...text... ^[}
++      at the beginning of the line          {I ...text... ^[}
++      after the cursor (append)             {a ...text... ^[}
++      at the end of the line                {A ...text... ^[}
++      after the current line                {o ...text... ^[}
++      before the current line               {O ...text... ^[}
++delete the character  ...
++      under the cursor                      {x}
++      to the left of the cursor             {X}
++delete n characters                         {nx} or {nX}  (for n a number)
++make two lines into one line (Join)         {J}
++find a string in the file ...
++      searching forward                     {/ ...string... /^M}
++      searching backwards                   {? ...string... ?^M}
++repeat the last search command              {n}
++repeat the last search command in the
++  opposite direction                        {N}
++find the character c on this line ...
++      searching forward                     {fc}
++      searching backward                    {Fc}
++repeat the last 'find character' command    {;}
++replace a character with character x        {rx}
++substitute a single character with text     {s ...text... ^[}
++substitute n characters with text           {ns ...text... ^[}
++replace characters one-by-one with text     {R ...text... ^[}
++undo all changes to the current line        {U}
++undo the last single change                 {u}
++move forward in the file a "screenful"      {^F}
++move back in the file a "screenful"         {^B}
++move forward in the file one line           {^M} or {+}
++move backward in the file one line          {-}
++move to the beginning of the line           {0}
++move to the end of the line                 {$}
++move forward one word                       {w}
++move forward one word, ignoring punctuation {W}
++move forward to the end of the next word    {e}
++to the end of the word, ignoring punctuation{E}
++move backward one word                      {b}
++move back one word, ignoring punctuation    {B}
++return to the last line modified            {''}
++scroll a line onto the top of the screen    {^Y}
++scroll a line onto the bottom of the screen {^E}
++move "up" in the file a half-screen         {^U}
++move "down" in the file a half-screen       {^D}
++move the cursor to the top screen line      {H}
++move the cursor to the bottom screen line   {L}
++move the cursor to the middle line          {M}
++move LEFT one character position            {h} or {^H}
++move RIGHT one character position           {l} or { }
++move UP in the same column                  {k} or {^P}
++move DOWN in the same column                {j} or {^N}
++mark the current position, name it x        {mx}
++move to the line marked/named x             {'x}
++move to the character position named x      {`x}
++move to the beginning of the file           {1G}
++move to the end of the file                 {G}
++move to line 23 in the file                 {23G}
++repaint the screen with the cursor line
++       at the top of the screen             {z^M}
++       in the middle of the screen          {z.}
++       at the bottom of the screen          {z-}
++
++More information on vi can be found in the file vi.advanced, which you can
++peruse at your leisure.  From UNIX, type {vi.tut advanced^M}.  
diff --git a/gnu/packages/patches/nvi-casting.patch b/gnu/packages/patches/nvi-casting.patch
new file mode 100644
index 0000000..2d39a1f
--- /dev/null
+++ b/gnu/packages/patches/nvi-casting.patch
@@ -0,0 +1,28 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+09casting.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Fix a casting issue.
+
+diff -Naur nvi-1.81.6.orig/vi/v_ch.c nvi-1.81.6/vi/v_ch.c
+--- nvi-1.81.6.orig/vi/v_ch.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/v_ch.c	2008-05-01 18:14:03.000000000 +0200
+@@ -165,7 +165,7 @@
+ 	endp = (startp = p) + len;
+ 	p += vp->m_start.cno;
+ 	for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
+-		while (++p < endp && *p != key);
++		while (++p < endp && *p != (char) key);
+ 		if (p == endp) {
+ 			notfound(sp, key);
+ 			return (1);
+@@ -247,7 +247,7 @@
+ 	endp = p - 1;
+ 	p += vp->m_start.cno;
+ 	for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
+-		while (--p > endp && *p != key);
++		while (--p > endp && *p != (char) key);
+ 		if (p == endp) {
+ 			notfound(sp, key);
+ 			return (1);
diff --git a/gnu/packages/patches/nvi-db4.patch b/gnu/packages/patches/nvi-db4.patch
new file mode 100644
index 0000000..c6a2db9
--- /dev/null
+++ b/gnu/packages/patches/nvi-db4.patch
@@ -0,0 +1,29 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+03db4.dpatch  by  <hesso@pool.math.tu-berlin.de>
+
+
+libdb4 compatibility adjustments.
+
+--- nvi-1.81.6.orig/common/msg.c	2009-02-26 14:26:58.350336128 +0100
++++ nvi-1.81.6/common/msg.c	2009-02-26 14:29:05.235335829 +0100
+@@ -724,9 +724,18 @@
+ 		p = buf;
+ 	} else
+ 		p = file;
++	if (access(p, F_OK) != 0) {
++		if (first) {
++			first = 0;
++			return (1);
++		}
++		sp->db_error = ENOENT;
++		msgq_str(sp, M_DBERR, p, "%s");
++		return (1);
++	}
+ 	if ((sp->db_error = db_create(&db, 0, 0)) != 0 ||
+ 	    (sp->db_error = db->set_re_source(db, p)) != 0 ||
+-	    (sp->db_error = db_open(db, NULL, DB_RECNO, 0, 0)) != 0) {
++	    (sp->db_error = db_open(db, NULL, DB_RECNO, DB_CREATE, 0)) != 0) {
+ 		if (first) {
+ 			first = 0;
+ 			return (1);
diff --git a/gnu/packages/patches/nvi-dbpagesize-binpower.patch b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
new file mode 100644
index 0000000..f37eeb2
--- /dev/null
+++ b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
@@ -0,0 +1,25 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+18dbpagesize_binpower.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Make sure that the pagesize passed to db__set_pagesize() is a power of two.
+
+--- nvi-1.81.6.orig/common/exf.c	2009-03-09 01:48:01.695862889 +0100
++++ nvi-1.81.6/common/exf.c	2009-03-09 10:42:41.147866272 +0100
+@@ -249,11 +249,10 @@
+ 		 * (vi should have good locality) or smaller than 1K.
+ 		 */
+ 		psize = ((sb.st_size / 15) + 1023) / 1024;
+-		if (psize > 10)
+-			psize = 10;
+-		if (psize == 0)
+-			psize = 1;
+-		psize *= 1024;
++		if (psize >= 8) psize=8<<10;
++		else if (psize >= 4) psize=4<<10;
++		else if (psize >= 2) psize=2<<10;
++		else psize=1<<10;
+ 
+ 		F_SET(ep, F_DEVSET);
+ 		ep->mdev = sb.st_dev;
diff --git a/gnu/packages/patches/nvi-exrc-writability-check.patch b/gnu/packages/patches/nvi-exrc-writability-check.patch
new file mode 100644
index 0000000..c0d6a21
--- /dev/null
+++ b/gnu/packages/patches/nvi-exrc-writability-check.patch
@@ -0,0 +1,62 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+21exrc_writability_check.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Improve writability checking.
+
+diff -Naur nvi-1.81.6.orig/ex/ex_init.c nvi-1.81.6/ex/ex_init.c
+--- nvi-1.81.6.orig/ex/ex_init.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/ex/ex_init.c	2008-05-01 18:24:45.000000000 +0200
+@@ -26,6 +26,9 @@
+ #include <string.h>
+ #include <unistd.h>
+ 
++#include <pwd.h>
++#include <grp.h>
++
+ #include "../common/common.h"
+ #include "tag.h"
+ #include "pathnames.h"
+@@ -346,6 +349,9 @@
+ 	int nf1, nf2;
+ 	char *a, *b, buf[MAXPATHLEN];
+ 
++	struct group *grp_p;
++	struct passwd *pwd_p;
++
+ 	/* Check for the file's existence. */
+ 	if (stat(path, sbp))
+ 		return (NOEXIST);
+@@ -359,10 +365,30 @@
+ 	}
+ 
+ 	/* Check writeability. */
+-	if (sbp->st_mode & (S_IWGRP | S_IWOTH)) {
++	if (sbp->st_mode & S_IWOTH) {
+ 		etype = WRITER;
+ 		goto denied;
+ 	}
++	if (sbp->st_mode & S_IWGRP) {
++		/* on system error (getgrgid or getpwnam return NULL) set etype to WRITER
++		 * and continue execution */
++		if( (grp_p = getgrgid(sbp->st_gid)) == NULL) {
++			etype = WRITER;
++			goto denied;
++		}
++
++		/* lookup the group members' uids for an uid different from euid */
++		while( ( *(grp_p->gr_mem) ) != NULL) { /* gr_mem is a null-terminated array */
++			if( (pwd_p = getpwnam(*(grp_p->gr_mem)++)) == NULL) {
++				etype = WRITER;
++				goto denied;
++			}
++			if(pwd_p->pw_uid != euid) {
++				etype = WRITER;
++				goto denied;
++			}
++		}
++	}
+ 	return (RCOK);
+ 
+ denied:	a = msg_print(sp, path, &nf1);
diff --git a/gnu/packages/patches/nvi-fallback-to-dumb-term.patch b/gnu/packages/patches/nvi-fallback-to-dumb-term.patch
new file mode 100644
index 0000000..08dfbbe
--- /dev/null
+++ b/gnu/packages/patches/nvi-fallback-to-dumb-term.patch
@@ -0,0 +1,30 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+24fallback_to_dumb_term.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+If there's no $TERM around, just fall back to "dumb".
+
+diff -Naur nvi-1.81.6.orig/cl/cl_main.c nvi-1.81.6/cl/cl_main.c
+--- nvi-1.81.6.orig/cl/cl_main.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/cl/cl_main.c	2008-05-01 18:29:13.000000000 +0200
+@@ -96,6 +96,7 @@
+ 	if ((ttype = getenv("TERM")) == NULL)
+ 		ttype = "unknown";
+ 	term_init(gp->progname, ttype);
++	ttype = getenv("TERM");
+ 
+ 	/* Add the terminal type to the global structure. */
+ 	if ((OG_D_STR(gp, GO_TERM) =
+@@ -233,6 +234,11 @@
+ 
+ 	/* Set up the terminal database information. */
+ 	setupterm(ttype, STDOUT_FILENO, &err);
++	if (err == 0) {
++		(void)fprintf(stderr, "%s: %s: unknown terminal type, falling back to 'dumb'\n", name, ttype);
++		setenv("TERM", "dumb", 1);
++		setupterm("dumb", STDOUT_FILENO, &err);
++	}
+ 	switch (err) {
+ 	case -1:
+ 		(void)fprintf(stderr,
diff --git a/gnu/packages/patches/nvi-file-backup.patch b/gnu/packages/patches/nvi-file-backup.patch
new file mode 100644
index 0000000..090f5e9
--- /dev/null
+++ b/gnu/packages/patches/nvi-file-backup.patch
@@ -0,0 +1,36 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+29file_backup.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Save the intermediate CHAR2INT conversion pointer because that pointer is
+reused by later conversions in calls below.
+
+--- nvi-1.81.6.orig/common/exf.c	2009-07-24 11:30:05.962060755 +0200
++++ nvi-1.81.6/common/exf.c	2009-07-24 12:09:57.511311177 +0200
+@@ -1092,8 +1092,8 @@
+ 	size_t blen;
+ 	int flags, maxnum, nr, num, nw, rfd, wfd, version;
+ 	char *bp, *estr, *p, *pct, *slash, *t, *wfname, buf[8192];
+-	CHAR_T *wp;
+-	size_t wlen;
++	CHAR_T *wp, *wp2;
++	size_t wlen, wlen2;
+ 	size_t nlen;
+ 	char *d = NULL;
+ 
+@@ -1148,8 +1148,13 @@
+ 	} else
+ 		version = 0;
+ 	CHAR2INT(sp, bname, strlen(bname) + 1, wp, wlen);
+-	if (argv_exp2(sp, &cmd, wp, wlen - 1))
++	GET_SPACE_RETW(sp, wp2, wlen2, wlen);
++	MEMCPY(wp2, wp, wlen);
++	if (argv_exp2(sp, &cmd, wp2, wlen2 - 1)) {
++		FREE_SPACEW(sp, wp2, wlen2);
+ 		return (1);
++	}
++	FREE_SPACEW(sp, wp2, wlen2);
+ 
+ 	/*
+ 	 *  0 args: impossible.
diff --git a/gnu/packages/patches/nvi-glibc-has-grantpt.patch b/gnu/packages/patches/nvi-glibc-has-grantpt.patch
new file mode 100644
index 0000000..21e9397
--- /dev/null
+++ b/gnu/packages/patches/nvi-glibc-has-grantpt.patch
@@ -0,0 +1,29 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+20glibc_has_grantpt.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+glibc has grantpt(), so only check for HAVE_SYS5_PTY on non-glibc installations.
+
+diff -Naur nvi-1.81.6.orig/ex/ex_script.c nvi-1.81.6/ex/ex_script.c
+--- nvi-1.81.6.orig/ex/ex_script.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/ex/ex_script.c	2008-05-01 18:24:06.000000000 +0200
+@@ -23,7 +23,8 @@
+ #include <sys/select.h>
+ #endif
+ #include <sys/stat.h>
+-#ifdef HAVE_SYS5_PTY
++/* glibc2.1 defines grantpt but there is no stropts.h */
++#if defined(HAVE_SYS5_PTY) && !defined(__GLIBC__)  
+ #include <sys/stropts.h>
+ #endif
+ #include <sys/time.h>
+@@ -664,7 +665,7 @@
+ 	F_CLR(gp, G_SCRWIN);
+ }
+ 
+-#ifdef HAVE_SYS5_PTY
++#if defined(HAVE_SYS5_PTY) && !defined(__GLIBC__)
+ static int ptys_open __P((int, char *));
+ static int ptym_open __P((char *));
+ 
diff --git a/gnu/packages/patches/nvi-include-term-h.patch b/gnu/packages/patches/nvi-include-term-h.patch
new file mode 100644
index 0000000..e2dbd49
--- /dev/null
+++ b/gnu/packages/patches/nvi-include-term-h.patch
@@ -0,0 +1,29 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+19include_term_h.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Add <term.h> to the include list to suppress a few warnings.
+
+diff -Naur nvi-1.81.6.orig/cl/cl_funcs.c nvi-1.81.6/cl/cl_funcs.c
+--- nvi-1.81.6.orig/cl/cl_funcs.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/cl/cl_funcs.c	2008-05-01 18:23:08.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include <sys/time.h>
+ 
+ #include <bitstring.h>
++#include <term.h>
+ #include <ctype.h>
+ #include <signal.h>
+ #include <stdio.h>
+diff -Naur nvi-1.81.6.orig/cl/cl_screen.c nvi-1.81.6/cl/cl_screen.c
+--- nvi-1.81.6.orig/cl/cl_screen.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/cl/cl_screen.c	2008-05-01 18:23:02.000000000 +0200
+@@ -17,6 +17,7 @@
+ #include <sys/queue.h>
+ 
+ #include <bitstring.h>
++#include <term.h>
+ #include <errno.h>
+ #include <signal.h>
+ #include <stdio.h>
diff --git a/gnu/packages/patches/nvi-lfs.patch b/gnu/packages/patches/nvi-lfs.patch
new file mode 100644
index 0000000..dceaefe
--- /dev/null
+++ b/gnu/packages/patches/nvi-lfs.patch
@@ -0,0 +1,29 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+08lfs.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Insert a safety check to save large files from being overwritten.
+
+diff -Naur nvi-1.81.6.orig/common/exf.c nvi-1.81.6/common/exf.c
+--- nvi-1.81.6.orig/common/exf.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/common/exf.c	2008-05-01 18:09:55.000000000 +0200
+@@ -157,6 +157,18 @@
+ 	 */
+ 	if (file_spath(sp, frp, &sb, &exists))
+ 		return (1);
++        /*
++         * On LFS systems, it's possible that stat returned an error because
++         * the file is >2GB, which nvi would normally treat as "doesn't exist"
++         * and eventually overwrite. That's no good. Rather than mess with
++         * every stat() call in file_spath, we'll just check again here.
++         */
++        if (!exists && stat(frp->name, &sb)) {
++            if (errno == EOVERFLOW) {
++                msgq(sp, M_ERR,  "File too large (>2GB, probably)");
++                goto err;
++            }
++        }
+ 
+ 	/*
+ 	 * Check whether we already have this file opened in some
diff --git a/gnu/packages/patches/nvi-manpage-errors.patch b/gnu/packages/patches/nvi-manpage-errors.patch
new file mode 100644
index 0000000..c5369a5
--- /dev/null
+++ b/gnu/packages/patches/nvi-manpage-errors.patch
@@ -0,0 +1,771 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+16manpage_errors.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Fix a truckload of roff markup glitches.
+
+diff -Naur nvi-1.81.6.orig/docs/vi.man/vi.1 nvi-1.81.6/docs/vi.man/vi.1
+--- nvi-1.81.6.orig/docs/vi.man/vi.1	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/docs/vi.man/vi.1	2008-05-01 18:17:59.000000000 +0200
+@@ -17,35 +17,35 @@
+ .SH SYNOPSIS
+ .B ex
+ [\c
+-.B -eFRrSsv\c
++.B \-eFRrSsv\c
+ ] [\c
+-.BI -c " cmd"\c
++.BI \-c " cmd"\c
+ ] [\c
+-.BI -t " tag"\c
++.BI \-t " tag"\c
+ ] [\c
+-.BI -w " size"\c
++.BI \-w " size"\c
+ ] [file ...]
+ .br
+ .B vi
+ [\c
+-.B -eFlRrSv\c
++.B \-eFlRrSv\c
+ ] [\c
+-.BI -c " cmd"\c
++.BI \-c " cmd"\c
+ ] [\c
+-.BI -t " tag"\c
++.BI \-t " tag"\c
+ ] [\c
+-.BI -w " size"\c
++.BI \-w " size"\c
+ ] [file ...]
+ .br
+ .B view
+ [\c
+-.B -eFRrSv\c
++.B \-eFRrSv\c
+ ] [\c
+-.BI -c " cmd"\c
++.BI \-c " cmd"\c
+ ] [\c
+-.BI -t " tag"\c
++.BI \-t " tag"\c
+ ] [\c
+-.BI -w " size"\c
++.BI \-w " size"\c
+ ] [file ...]
+ .SH LICENSE
+ The vi program is freely redistributable.  You are welcome to copy,
+@@ -57,7 +57,7 @@
+ .I \&Vi
+ is a screen oriented text editor.
+ .I \&Ex
+-is a line-oriented text editor.
++is a line\(hyoriented text editor.
+ .I \&Ex
+ and
+ .I \&vi
+@@ -66,7 +66,7 @@
+ .I View
+ is the equivalent of using the
+ .B \-R
+-(read-only) option of
++(read\(hyonly) option of
+ .IR \&vi .
+ .PP
+ This manual page is the one provided with the
+@@ -75,7 +75,7 @@
+ .I ex/vi
+ text editors.
+ .I Nex/nvi
+-are intended as bug-for-bug compatible replacements for the original
++are intended as bug\(hyfor\(hybug compatible replacements for the original
+ Fourth Berkeley Software Distribution (4BSD)
+ .I \&ex
+ and
+@@ -93,7 +93,7 @@
+ editor before this manual page.
+ If you're in an unfamiliar environment, and you absolutely have to
+ get work done immediately, read the section after the options
+-description, entitled ``Fast Startup''.
++description, entitled \(lqFast Startup\(rq.
+ It's probably enough to get you going.
+ .PP
+ The following options are available:
+@@ -105,7 +105,7 @@
+ Particularly useful for initial positioning in the file, however
+ .B cmd
+ is not limited to positioning commands.
+-This is the POSIX 1003.2 interface for the historic ``+cmd'' syntax.
++This is the POSIX 1003.2 interface for the historic \(lq+cmd\(rq syntax.
+ .I Nex/nvi
+ supports both the old and new syntax.
+ .TP
+@@ -122,7 +122,7 @@
+ Start editing with the lisp and showmatch options set.
+ .TP
+ .B \-R
+-Start editing in read-only mode, as if the command name was
++Start editing in read\(hyonly mode, as if the command name was
+ .IR view ,
+ or the
+ .B readonly
+@@ -151,7 +151,7 @@
+ Prompts, informative messages and other user oriented message
+ are turned off,
+ and no startup files or environmental variables are read.
+-This is the POSIX 1003.2 interface for the historic ``\-'' argument.
++This is the POSIX 1003.2 interface for the historic \(lq\-\(rq argument.
+ .I \&Nex/nvi
+ supports both the old and new syntax.
+ .TP
+@@ -215,8 +215,8 @@
+ There are commands that switch you into input mode.
+ There is only one key that takes you out of input mode,
+ and that is the <escape> key.
+-(Key names are written using less-than and greater-than signs, e.g.
+-<escape> means the ``escape'' key, usually labeled ``esc'' on your
++(Key names are written using less\(hythan and greater\(hythan signs, e.g.
++<escape> means the \(lqescape\(rq key, usually labeled \(lqesc\(rq on your
+ terminal's keyboard.)
+ If you're ever confused as to which mode you're in,
+ keep entering the <escape> key until
+@@ -227,9 +227,9 @@
+ will beep at you if you try and do something that's not allowed.
+ It will also display error messages.)
+ .PP
+-To start editing a file, enter the command ``vi file_name<carriage-return>''.
++To start editing a file, enter the command \(lqvi file_name<carriage\(hyreturn>\(rq.
+ The command you should enter as soon as you start editing is
+-``:set verbose showmode<carriage-return>''.
++\(lq:set verbose showmode<carriage\(hyreturn>\(rq.
+ This will make the editor give you verbose error messages and display
+ the current mode at the bottom of the screen.
+ .PP
+@@ -247,11 +247,11 @@
+ .B l
+ Move the cursor right one character.
+ .TP
+-.B <cursor-arrows>
++.B <cursor\(hyarrows>
+ The cursor arrow keys should work, too.
+ .TP
+-.B /text<carriage-return>
+-Search for the string ``text'' in the file,
++.B /text<carriage\(hyreturn>
++Search for the string \(lqtext\(rq in the file,
+ and move the cursor to its first character.
+ .PP
+ The commands to enter new text are:
+@@ -303,30 +303,30 @@
+ .PP
+ The commands to write the file are:
+ .TP
+-.B :w<carriage-return>
++.B :w<carriage\(hyreturn>
+ Write the file back to the file with the name that you originally used
+ as an argument on the
+ .I \&vi
+ command line.
+ .TP
+-.B ":w file_name<carriage-return>"
+-Write the file back to the file with the name ``file_name''.
++.B ":w file_name<carriage\(hyreturn>"
++Write the file back to the file with the name \(lqfile_name\(rq.
+ .PP
+ The commands to quit editing and exit the editor are:
+ .TP
+-.B :q<carriage-return>
++.B :q<carriage\(hyreturn>
+ Quit editing and leave vi (if you've modified the file, but not
+ saved your changes,
+ .I \&vi
+ will refuse to quit).
+ .TP
+-.B :q!<carriage-return>
++.B :q!<carriage\(hyreturn>
+ Quit, discarding any modifications that you may have made.
+ .PP
+ One final caution.
+ Unusual characters can take up more than one column on the screen,
+ and long lines can take up more than a single screen line.
+-The above commands work on ``physical'' characters and lines,
++The above commands work on \(lqphysical\(rq characters and lines,
+ i.e. they affect the entire line no matter how many screen lines it
+ takes up and the entire character no matter how many screen columns
+ it takes up.
+@@ -339,87 +339,87 @@
+ character.
+ .PP
+ .TP
+-.B "[count] <control-A>"
++.B "[count] <control\(hyA>"
+ Search forward
+ .I count
+ times for the current word.
+ .TP
+-.B "[count] <control-B>"
++.B "[count] <control\(hyB>"
+ Page backwards
+ .I count
+ screens.
+ .TP
+-.B "[count] <control-D>"
++.B "[count] <control\(hyD>"
+ Scroll forward
+ .I count
+ lines.
+ .TP
+-.B "[count] <control-E>"
++.B "[count] <control\(hyE>"
+ Scroll forward
+ .I count
+ lines, leaving the current line and column as is, if possible.
+ .TP
+-.B "[count] <control-F>"
++.B "[count] <control\(hyF>"
+ Page forward
+ .I count
+ screens.
+ .TP
+-.B "<control-G>"
++.B "<control\(hyG>"
+ Display the file information.
+ .TP
+-.B "<control-H>"
++.B "<control\(hyH>"
+ .TP
+ .B "[count] h"
+ Move the cursor back
+ .I count
+ characters in the current line.
+ .TP
+-.B "[count] <control-J>"
++.B "[count] <control\(hyJ>"
+ .TP
+-.B "[count] <control-N>"
++.B "[count] <control\(hyN>"
+ .TP
+ .B "[count] j"
+ Move the cursor down
+ .I count
+ lines without changing the current column.
+ .TP
+-.B "<control-L>"
++.B "<control\(hyL>"
+ .TP
+-.B "<control-R>"
++.B "<control\(hyR>"
+ Repaint the screen.
+ .TP
+-.B "[count] <control-M>"
++.B "[count] <control\(hyM>"
+ .TP
+ .B "[count] +"
+ Move the cursor down
+ .I count
+ lines to the first nonblank character of that line.
+ .TP
+-.B "[count] <control-P>"
++.B "[count] <control\(hyP>"
+ .TP
+ .B "[count] k"
+ Move the cursor up
+ .I count
+ lines, without changing the current column.
+ .TP
+-.B "<control-T>"
++.B "<control\(hyT>"
+ Return to the most recent tag context.
+ .TP
+-.B "<control-U>"
++.B "<control\(hyU>"
+ Scroll backwards
+ .I count
+ lines.
+ .TP
+-.B "<control-W>"
++.B "<control\(hyW>"
+ Switch to the next lower screen in the window, or, to the first
+ screen if there are no lower screens in the window.
+ .TP
+-.B "<control-Y>"
++.B "<control\(hyY>"
+ Scroll backwards
+ .I count
+ lines, leaving the current line and column as is, if possible.
+ .TP
+-.B "<control-Z>"
++.B "<control\(hyZ>"
+ Suspend the current editor session.
+ .TP
+ .B "<escape>"
+@@ -427,10 +427,10 @@
+ .I \&ex
+ commands or cancel partial commands.
+ .TP
+-.B "<control-]>"
++.B "<control\(hy]>"
+ Push a tag reference onto the tag stack.
+ .TP
+-.B "<control-^>"
++.B "<control\(hy^>"
+ Switch to the most recently edited file.
+ .TP
+ .B "[count] <space>"
+@@ -440,10 +440,10 @@
+ .I count
+ characters without changing the current line.
+ .TP
+-.B "[count] ! motion shell-argument(s)"
++.B "[count] ! motion shell\(hyargument(s)"
+ Replace text with results from a shell command.
+ .TP
+-.B "[count] # #|+|-"
++.B "[count] # #|+|\-"
+ Increment or decrement the cursor number.
+ .TP
+ .B "[count] $"
+@@ -457,7 +457,7 @@
+ .TP
+ .B "'<character>"
+ .TP
+-.B "`<character>"
++.B "\`<character>"
+ Return to a context marked by the character
+ .IR <character> .
+ .TP
+@@ -476,7 +476,7 @@
+ .I count
+ times.
+ .TP
+-.B "[count] -"
++.B "[count] \-"
+ Move to first nonblank of the previous line,
+ .I count
+ times.
+@@ -486,13 +486,13 @@
+ .I \&vi
+ command that modified text.
+ .TP
+-.B "/RE<carriage-return>"
++.B "/RE<carriage\(hyreturn>"
+ .TP
+-.B "/RE/ [offset]<carriage-return>"
++.B "/RE/ [offset]<carriage\(hyreturn>"
+ .TP
+-.B "?RE<carriage-return>"
++.B "?RE<carriage\(hyreturn>"
+ .TP
+-.B "?RE? [offset]<carriage-return>"
++.B "?RE? [offset]<carriage\(hyreturn>"
+ .TP
+ .B "N"
+ .TP
+@@ -527,15 +527,15 @@
+ bigwords.
+ .TP
+ .B "[buffer] [count] C"
+-Change text from the current position to the end-of-line.
++Change text from the current position to the end\(hyof\(hyline.
+ .TP
+ .B "[buffer] D"
+-Delete text from the current position to the end-of-line.
++Delete text from the current position to the end\(hyof\(hyline.
+ .TP
+ .B "[count] E"
+ Move forward
+ .I count
+-end-of-bigwords.
++end\(hyof\(hybigwords.
+ .TP
+ .B "[count] F <character>"
+ Search
+@@ -552,7 +552,7 @@
+ .TP
+ .B "[count] H"
+ Move to the screen line
+-.I "count - 1"
++.I "count \- 1"
+ lines below the top of the screen.
+ .TP
+ .B "[count] I"
+@@ -563,7 +563,7 @@
+ .TP
+ .B "[count] L"
+ Move to the screen line
+-.I "count - 1"
++.I "count \- 1"
+ lines above the bottom of the screen.
+ .TP
+ .B " M"
+@@ -614,7 +614,7 @@
+ characters before the cursor.
+ .TP
+ .B "[buffer] [count] Y"
+-Copy (or ``yank'')
++Copy (or \(lqyank\(rq)
+ .I count
+ lines into the specified buffer.
+ .TP
+@@ -637,7 +637,7 @@
+ .TP
+ .B "[count] _"
+ Move down
+-.I "count - 1"
++.I "count \- 1"
+ lines, to the first nonblank character.
+ .TP
+ .B "[count] a"
+@@ -657,7 +657,7 @@
+ .B "[count] e"
+ Move forward
+ .I count
+-end-of-words.
++end\(hyof\(hywords.
+ .TP
+ .B "[count] f<character>"
+ Search forward,
+@@ -709,12 +709,12 @@
+ characters.
+ .TP
+ .B "[buffer] [count] y motion"
+-Copy (or ``yank'')
++Copy (or \(lqyank\(rq)
+ a text region specified by the
+ .I count
+ and motion into a buffer.
+ .TP
+-.B "[count1] z [count2] -|.|+|^|<carriage-return>"
++.B "[count1] z [count2] \-|.|+|^|<carriage\(hyreturn>"
+ Redraw, optionally repositioning and resizing the screen.
+ .TP
+ .B "[count] {"
+@@ -735,13 +735,20 @@
+ .B "[count] ~"
+ Reverse the case of the next
+ .I count
+-character(s).
++character(s), if the 
++.B tildeop
++option is
++.IR unset .
+ .TP
+ .B "[count] ~ motion"
+ Reverse the case of the characters in a text region specified by the
+ .I count
+ and
+-.IR motion .
++.IR motion ,
++if the 
++.B tildeop
++option is
++.IR set .
+ .TP
+ .B "<interrupt>"
+ Interrupt the current operation.
+@@ -755,18 +762,18 @@
+ .B "<nul>"
+ Replay the previous input.
+ .TP
+-.B "<control-D>"
++.B "<control\(hyD>"
+ Erase to the previous
+ .B shiftwidth
+ column boundary.
+ .TP
+-.B "^<control-D>"
++.B "^<control\(hyD>"
+ Erase all of the autoindent characters, and reset the autoindent level.
+ .TP
+-.B "0<control-D>"
++.B "0<control\(hyD>"
+ Erase all of the autoindent characters.
+ .TP
+-.B "<control-T>"
++.B "<control\(hyT>"
+ Insert sufficient
+ .I <tab>
+ and
+@@ -777,7 +784,7 @@
+ .TP
+ .B "<erase>
+ .TP
+-.B "<control-H>"
++.B "<control\(hyH>"
+ Erase the last character.
+ .TP
+ .B "<literal next>"
+@@ -789,7 +796,7 @@
+ .B "<line erase>"
+ Erase the current line.
+ .TP
+-.B "<control-W>"
++.B "<control\(hyW>"
+ .TP
+ .B "<word erase>"
+ Erase the last word.
+@@ -799,7 +806,7 @@
+ .B ttywerase
+ options.
+ .TP
+-.B "<control-X>[0-9A-Fa-f]+"
++.B "<control\(hyX>[0\-9A\-Fa\-f]+"
+ Insert a character with the specified hexadecimal value into the text.
+ .TP
+ .B "<interrupt>"
+@@ -811,7 +818,7 @@
+ In each entry below, the tag line is a usage synopsis for the command.
+ .PP
+ .TP
+-.B "<end-of-file>"
++.B "<end\(hyof\(hyfile>"
+ Scroll the screen.
+ .TP
+ .B "! argument(s)"
+@@ -932,7 +939,7 @@
+ .I file
+ if it was previously saved.
+ .TP
+-.B "res[ize] [+|-]size"
++.B "res[ize] [+|\-]size"
+ .I \&Vi
+ mode only.
+ Grow or shrink the current screen.
+@@ -1034,7 +1041,10 @@
+ .I \&ex
+ and
+ .I \&vi
+-modes, unless otherwise specified.
++modes, unless otherwise specified. Multiple options can be given in
++one set or unset, separated by spaces or tabs.  Spaces and tabs can be
++included in string options (eg. tags or filec) by preceding each with
++a backslash.  There's no way to get backslash itself into an option.
+ .PP
+ .TP
+ .B "altwerase [off]"
+@@ -1071,7 +1081,7 @@
+ command.
+ .TP
+ .B "cedit [no default]"
+-Set the character to edit the colon command-line history.
++Set the character to edit the colon command\(hyline history.
+ .TP
+ .B "columns, co [80]"
+ Set the number of columns in the screen.
+@@ -1085,7 +1095,7 @@
+ The directory where temporary files are created.
+ .TP
+ .B "edcompatible, ed [off]"
+-Remember the values of the ``c'' and ``g'' suffices to the
++Remember the values of the \(lqc\(rq and \(lqg\(rq suffices to the
+ .B substitute
+ commands, instead of initializing them as unset for each new
+ command.
+@@ -1114,8 +1124,8 @@
+ Set the spacing between hardware tab settings.
+ .TP
+ .B "iclower [off]"
+-Makes all Regular Expressions case-insensitive,
+-as long as an upper-case letter does not appear in the search string.
++Makes all Regular Expressions case\(hyinsensitive,
++as long as an upper\(hycase letter does not appear in the search string.
+ .TP
+ .B "ignorecase, ic [off]"
+ Ignore case differences in regular expressions.
+@@ -1128,7 +1138,7 @@
+ .B "leftright [off]"
+ .I \&Vi
+ only.
+-Do left-right scrolling.
++Do left\(hyright scrolling.
+ .TP
+ .B "lines, li [24]"
+ .I \&Vi
+@@ -1227,7 +1237,7 @@
+ Display a command prompt.
+ .TP
+ .B "readonly, ro [off]"
+-Mark the file and session as read-only.
++Mark the file and session as read\(hyonly.
+ .TP
+ .B "recdir [/var/tmp/vi.recover]"
+ The directory where recovery files are stored.
+@@ -1278,7 +1288,7 @@
+ .\" to save my life.  The ONLY way I've been able to get this to work
+ .\" is with the .tr command.
+ .tr Q"
+-.ds ms shellmeta [~{[*?$`'Q\e]
++.ds ms shellmeta [~{[*?$\`'Q\e]
+ .TP
+ .B "\*(ms"
+ .tr QQ
+@@ -1291,17 +1301,17 @@
+ .B "showmatch, sm [off]"
+ .I \&Vi
+ only.
+-Note matching ``{'' and ``('' for ``}'' and ``)'' characters.
++Note matching \(lq{\(rq and \(lq(\(rq for \(lq}\(rq and \(lq)\(rq characters.
+ .TP
+ .B "showmode, smd [off]"
+ .I \&Vi
+ only.
+-Display the current editor mode and a ``modified'' flag.
++Display the current editor mode and a \(lqmodified\(rq flag.
+ .TP
+ .B "sidescroll [16]"
+ .I \&Vi
+ only.
+-Set the amount a left-right scroll will shift.
++Set the amount a left\(hyright scroll will shift.
+ .TP
+ .B "slowopen, slow [off]"
+ Delay display updating during text input.
+@@ -1379,7 +1389,7 @@
+ .I \&Vi
+ only.
+ Break lines automatically, the specified number of columns from the
+-left-hand margin.
++left\(hyhand margin.
+ If both the
+ .B wraplen
+ and
+@@ -1392,7 +1402,7 @@
+ .I \&Vi
+ only.
+ Break lines automatically, the specified number of columns from the
+-right-hand margin.
++right\(hyhand margin.
+ If both the
+ .B wraplen
+ and
+@@ -1405,7 +1415,7 @@
+ Set searches to wrap around the end or beginning of the file.
+ .TP
+ .B "writeany, wa [off]"
+-Turn off file-overwriting checks.
++Turn off file\(hyoverwriting checks.
+ .SH "ENVIRONMENT VARIABLES
+ .TP
+ .I COLUMNS
+@@ -1430,7 +1440,7 @@
+ .TP
+ .I HOME
+ The user's home directory, used as the initial directory path
+-for the startup ``$\fIHOME\fP/.nexrc'' and ``$\fIHOME\fP/.exrc''
++for the startup \(lq$\fIHOME\fP/.nexrc\(rq and \(lq$\fIHOME\fP/.exrc\(rq
+ files.
+ This value is also used as the default directory for the
+ .I \&vi
+@@ -1462,7 +1472,7 @@
+ .TP
+ .I TERM
+ The user's terminal type.
+-The default is the type ``unknown''.
++The default is the type \(lqunknown\(rq.
+ If the
+ .I TERM
+ environmental variable is not set when
+@@ -1482,7 +1492,7 @@
+ SIGALRM
+ .I \&Vi/ex
+ uses this signal for periodic backups of file modifications and to
+-display ``busy'' messages when operations are likely to take a long time.
++display \(lqbusy\(rq messages when operations are likely to take a long time.
+ .TP
+ SIGHUP
+ .TP
+@@ -1492,7 +1502,7 @@
+ be later recovered.
+ See the
+ .I \&vi/ex
+-Reference manual section entitled ``Recovery'' for more information.
++Reference manual section entitled \(lqRecovery\(rq for more information.
+ .TP
+ SIGINT
+ When an interrupt occurs,
+@@ -1506,7 +1516,7 @@
+ The screen is resized.
+ See the
+ .I \&vi/ex
+-Reference manual section entitled ``Sizing the Screen'' for more information.
++Reference manual section entitled \(lqSizing the Screen\(rq for more information.
+ .TP
+ SIGCONT
+ .TP
+@@ -1521,7 +1531,7 @@
+ The default user shell.
+ .TP
+ /etc/vi.exrc
+-System-wide vi startup file.
++System\(hywide vi startup file.
+ .TP
+ /tmp
+ Temporary file directory.
+@@ -1546,38 +1556,38 @@
+ .IR curses (3),
+ .IR dbopen (3)
+ .sp
+-The ``Vi Quick Reference'' card.
++The \(lqVi Quick Reference\(rq card.
+ .sp
+-``An Introduction to Display Editing with Vi'', found in the
+-``UNIX User's Manual Supplementary Documents''
++\(lqAn Introduction to Display Editing with Vi\(rq, found in the
++\(lqUNIX User's Manual Supplementary Documents\(rq
+ section of both the 4.3BSD and 4.4BSD manual sets.
+ This document is the closest thing available to an introduction to the
+ .I \&vi
+ screen editor.
+ .sp
+-``Ex Reference Manual (Version 3.7)'',
++\(lqEx Reference Manual (Version 3.7)\(rq,
+ found in the
+-``UNIX User's Manual Supplementary Documents''
++\(lqUNIX User's Manual Supplementary Documents\(rq
+ section of both the 4.3BSD and 4.4BSD manual sets.
+ This document is the final reference for the
+ .I \&ex
+ editor, as distributed in most historic 4BSD and System V systems.
+ .sp
+-``Edit: A tutorial'',
++\(lqEdit: A tutorial\(rq,
+ found in the
+-``UNIX User's Manual Supplementary Documents''
++\(lqUNIX User's Manual Supplementary Documents\(rq
+ section of the 4.3BSD manual set.
+ This document is an introduction to a simple version of the
+ .I \&ex
+ screen editor.
+ .sp
+-``Ex/Vi Reference Manual'',
++\(lqEx/Vi Reference Manual\(rq,
+ found in the
+-``UNIX User's Manual Supplementary Documents''
++\(lqUNIX User's Manual Supplementary Documents\(rq
+ section of the 4.4BSD manual set.
+ This document is the final reference for the
+ .I \&nex/nvi
+-text editors, as distributed in 4.4BSD and 4.4BSD-Lite.
++text editors, as distributed in 4.4BSD and 4.4BSD\(hyLite.
+ .PP
+ .I Roff
+ source for all of these documents is distributed with
+@@ -1588,7 +1598,7 @@
+ .I nex/nvi
+ source code.
+ .sp
+-The files ``autowrite'', ``input'', ``quoting'' and ``structures''
++The files \(lqautowrite\(rq, \(lqinput\(rq, \(lqquoting\(rq and \(lqstructures\(rq
+ found in the
+ .I nvi/docs/internals
+ directory of the
+@@ -1602,7 +1612,7 @@
+ editor first appeared in 4.4BSD.
+ .SH STANDARDS
+ .I \&Nex/nvi
+-is close to IEEE Std1003.2 (``POSIX'').
++is close to IEEE Std1003.2 (\(lqPOSIX\(rq).
+ That document differs from historical
+ .I ex/vi
+ practice in several places; there are changes to be made on both sides.
diff --git a/gnu/packages/patches/nvi-manpage-note-dropped-F.patch b/gnu/packages/patches/nvi-manpage-note-dropped-F.patch
new file mode 100644
index 0000000..8359b74
--- /dev/null
+++ b/gnu/packages/patches/nvi-manpage-note-dropped-F.patch
@@ -0,0 +1,59 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+25manpage_note_dropped_F.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Replace the manpage paragraph about the '-F' commandline option with a notice
+that is has been dropped.
+
+--- nvi-1.81.6+debian-1.orig/docs/vi.man/vi.1	2008-06-13 00:52:45.000000000 +0200
++++ nvi-1.81.6+debian-1/docs/vi.man/vi.1	2008-06-13 00:55:40.000000000 +0200
+@@ -17,7 +17,7 @@
+ .SH SYNOPSIS
+ .B ex
+ [\c
+-.B \-eFRrSsv\c
++.B \-eRrSsv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+@@ -28,7 +28,7 @@
+ .br
+ .B vi
+ [\c
+-.B \-eFlRrSv\c
++.B \-elRrSv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+@@ -39,7 +39,7 @@
+ .br
+ .B view
+ [\c
+-.B \-eFRrSv\c
++.B \-eRrSv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+@@ -113,11 +113,6 @@
+ Start editing in ex mode, as if the command name were
+ .IR \&ex .
+ .TP
+-.B \-F
+-Don't copy the entire file when first starting to edit.
+-(The default is to make a copy in case someone else modifies
+-the file during your edit session.)
+-.TP
+ .B \-l
+ Start editing with the lisp and showmatch options set.
+ .TP
+@@ -169,6 +164,9 @@
+ or
+ .IR view .
+ .PP
++Note that the \fB-F\fP option (which prevented \fIex/vi\fP from making
++a full backup of the target file) has been removed and is no longer available.
++.PP
+ Command input for
+ .I ex/vi
+ is read from the standard input.
diff --git a/gnu/packages/patches/nvi-no-one-line-visual.patch b/gnu/packages/patches/nvi-no-one-line-visual.patch
new file mode 100644
index 0000000..a55707e
--- /dev/null
+++ b/gnu/packages/patches/nvi-no-one-line-visual.patch
@@ -0,0 +1,25 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+10no_one_line_visual.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Catch segfaults when the screen is only one line high.
+
+diff -Naur nvi-1.81.6.orig/vi/vi.c nvi-1.81.6/vi/vi.c
+--- nvi-1.81.6.orig/vi/vi.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/vi.c	2008-05-01 18:15:14.000000000 +0200
+@@ -974,6 +974,14 @@
+ 	sp->rows = vip->srows = O_VAL(sp, O_LINES);
+ 	sp->cols = O_VAL(sp, O_COLUMNS);
+ 	sp->t_rows = sp->t_minrows = O_VAL(sp, O_WINDOW);
++	/*
++	 * To avoid segfaults on terminals with only one line,
++	 * catch this corner case now and die explicitly.
++	 */
++	if (sp->t_rows == 0) {
++		(void)fprintf(stderr, "Error: Screen too small for visual mode.\n");
++		return 1;
++	}
+ 	if (sp->rows != 1) {
+ 		if (sp->t_rows > sp->rows - 1) {
+ 			sp->t_minrows = sp->t_rows = sp->rows - 1;
diff --git a/gnu/packages/patches/nvi-private-regex-fixes.patch b/gnu/packages/patches/nvi-private-regex-fixes.patch
new file mode 100644
index 0000000..e62924a
--- /dev/null
+++ b/gnu/packages/patches/nvi-private-regex-fixes.patch
@@ -0,0 +1,32 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+14private_regex_fixes.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Fixes to the private regex library; includes fix for #523934.
+
+diff -Naur regex.orig/regcomp.c regex/regcomp.c
+--- nvi-1.81.6.orig/regex/regcomp.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/regex/regcomp.c	2008-05-01 18:37:57.000000000 +0200
+@@ -606,7 +606,8 @@
+ 		REQUIRE(starordinary, REG_BADRPT);
+ 		/* FALLTHROUGH */
+ 	default:
+-		ordinary(p, c &~ BACKSL);
++	  /* ordinary(p, c &~ BACKSL); -- Fix potential overflow */
++	        ordinary(p, c & 0xff);
+ 		break;
+ 	}
+ 
+diff -Naur regex.orig/regexec.c regex/regexec.c
+--- nvi-1.81.6.orig/regex/regexec.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/regex/regexec.c	2008-05-01 18:38:00.000000000 +0200
+@@ -63,7 +63,7 @@
+ 
+ /* macros for manipulating states, small version */
+ #define	states	int
+-#define	states1	states		/* for later use in regexec() decision */
++typedef states states1;		/* for later use in regexec() decision */
+ #define	CLEAR(v)	((v) = 0)
+ #define	SET0(v, n)	((v) &= ~(1 << (n)))
+ #define	SET1(v, n)	((v) |= 1 << (n))
diff --git a/gnu/packages/patches/nvi-safe-printf.patch b/gnu/packages/patches/nvi-safe-printf.patch
new file mode 100644
index 0000000..de7715c
--- /dev/null
+++ b/gnu/packages/patches/nvi-safe-printf.patch
@@ -0,0 +1,19 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+08safe_printf.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Fix a format security bug.
+
+diff -Naur nvi-1.81.6.orig/common/exf.c nvi-1.81.6/common/exf.c
+--- nvi-1.81.6.orig/common/exf.c	2008-05-01 18:10:20.000000000 +0200
++++ nvi-1.81.6/common/exf.c	2008-05-01 18:10:30.000000000 +0200
+@@ -1075,7 +1075,7 @@
+ 			*--s = '.';
+ 		}
+ 	}
+-	msgq(sp, M_INFO, s);
++	msgq(sp, M_INFO, "%s", s);
+ 	if (nf)
+ 		FREE_SPACE(sp, p, 0);
+ 	return (0);
diff --git a/gnu/packages/patches/nvi-search-word.patch b/gnu/packages/patches/nvi-search-word.patch
new file mode 100644
index 0000000..dbfc859
--- /dev/null
+++ b/gnu/packages/patches/nvi-search-word.patch
@@ -0,0 +1,30 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+15search_word.dpatch by  Al Viro <viro@ZenIV.linux.org.uk>
+
+
+Fix {^A} command. (End-of-word was not included in search regexp leading to
+false positives.)
+
+--- nvi-1.81.6.orig/vi/v_search.c	2007-11-18 11:41:42.000000000 -0500
++++ nvi-1.81.6/vi/v_search.c	2009-03-05 15:37:37.000000000 -0500
+@@ -322,16 +322,17 @@
+ v_searchw(SCR *sp, VICMD *vp)
+ {
+ 	size_t blen, len;
++	size_t olen = STRLEN(VIP(sp)->keyw);
+ 	int rval;
+ 	CHAR_T *bp, *p;
+ 
+-	len = VIP(sp)->klen + RE_WSTART_LEN + RE_WSTOP_LEN;
++	len = olen + RE_WSTART_LEN + RE_WSTOP_LEN;
+ 	GET_SPACE_RETW(sp, bp, blen, len);
+ 	MEMCPY(bp, RE_WSTART, RE_WSTART_LEN); 
+ 	p = bp + RE_WSTART_LEN;
+-	MEMCPY(p, VIP(sp)->keyw, VIP(sp)->klen);
+-	p += VIP(sp)->klen;
++	MEMCPY(p, VIP(sp)->keyw, olen);
++	p += olen;
+ 	MEMCPY(p, RE_WSTOP, RE_WSTOP_LEN); 
+ 
+ 	rval = v_search(sp, vp, bp, len, SEARCH_SET, FORWARD);
diff --git a/gnu/packages/patches/nvi-support-C-locale.patch b/gnu/packages/patches/nvi-support-C-locale.patch
new file mode 100644
index 0000000..6ee844d
--- /dev/null
+++ b/gnu/packages/patches/nvi-support-C-locale.patch
@@ -0,0 +1,31 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+27support_C_locale.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Allow users to edit 8-bit files even under LC_CTYPE=C.
+
+--- nvi-1.81.6.orig/common/conv.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/common/conv.c	2009-03-09 16:45:37.812022582 +0100
+@@ -322,11 +322,16 @@
+     else {
+ 	setlocale(LC_ALL, "");
+ #ifdef USE_WIDECHAR
+-	sp->conv.sys2int = cs_char2int;
+-	sp->conv.int2sys = cs_int2char;
+-	sp->conv.file2int = fe_char2int;
+-	sp->conv.int2file = fe_int2char;
+-	sp->conv.input2int = ie_char2int;
++	if (!strcmp(LANGCODESET, "ANSI_X3.4-1968")) {
++	    sp->conv.file2int = sp->conv.input2int = sp->conv.sys2int = raw2int;
++	    sp->conv.int2sys = sp->conv.int2file = int2raw;
++	} else {
++	    sp->conv.sys2int = cs_char2int;
++	    sp->conv.int2sys = cs_int2char;
++	    sp->conv.file2int = fe_char2int;
++	    sp->conv.int2file = fe_int2char;
++	    sp->conv.input2int = ie_char2int;
++	}
+ #endif
+ #ifdef USE_ICONV
+ 	o_set(sp, O_FILEENCODING, OS_STRDUP, nl_langinfo(CODESET), 0);
diff --git a/gnu/packages/patches/nvi-trailing-tab-segv.patch b/gnu/packages/patches/nvi-trailing-tab-segv.patch
new file mode 100644
index 0000000..6769d17
--- /dev/null
+++ b/gnu/packages/patches/nvi-trailing-tab-segv.patch
@@ -0,0 +1,19 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+26trailing_tab_segv.dpatch by <hesso@pool.math.tu-berlin.de>
+
+
+Prevent a segfault if a trailing tab is pushed to a new line by inserting
+characters before it if 'set number' is in effect.
+
+--- nvi-1.81.6+debian.orig/vi/vs_relative.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6+debian/vi/vs_relative.c	2008-06-13 03:22:55.000000000 +0200
+@@ -133,7 +133,7 @@
+ 	 * Initialize the pointer into the buffer and current offset.
+ 	 */
+ 	p = lp;
+-	curoff = 0;
++	curoff = scno;
+ 
+ 	/* Macro to return the display length of any signal character. */
+ #define	CHLEN(val) (ch = *(UCHAR_T *)p++) == '\t' &&			\
diff --git a/gnu/packages/patches/nvi-tutorial-typos.patch b/gnu/packages/patches/nvi-tutorial-typos.patch
new file mode 100644
index 0000000..9d11ee8
--- /dev/null
+++ b/gnu/packages/patches/nvi-tutorial-typos.patch
@@ -0,0 +1,64 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+The original file was called: 17tutorial_typos.dpatch
+
+
+Fix typos in the nvi tutorial.
+
+--- nvi-1.81.6.orig/nvi-1.79/docs/tutorial/vi.beginner
++++ nvi-1.81.6/nvi-1.79/docs/tutorial/vi.beginner
+@@ -505,7 +505,7 @@
+ j - moves the cursor DOWN one line
+ h - moves the cursor one character to the LEFT
+ 
+-Section 22: {i} {a} {I} {A} {o} {O} ^[ (escape key)
++Section 22: {i} {a} {I} {A} {o} {O} {^[} (escape key)
+ 
+ For this and following sections you will need to use the ESCAPE key on your
+ terminal.  It is usually marked ESC.  Since the escape key is the same as
+@@ -525,9 +525,9 @@
+ on the word 'of'.)
+ 
+ Now carefully type the following string and observe the effects:
+-  {iexample ^[}  (remember: ^[ is the escape key)}
++  {iexample ^[}  (remember: ^[ is the escape key)
+ The {i} begins the insert mode, and 'example ' is inserted into the line: 
+-be sure to notice the blank in 'example '.  The ^[ ends insertion mode, 
++be sure to notice the blank in 'example '.  The {^[} ends insertion mode, 
+ and the line is updated to include the new string.  Line 1 should look exactly 
+ like Line 2.
+ 
+@@ -541,9 +541,9 @@
+ of 'line'.  You can do this in several ways, one way is the following:
+ First, type {/line /^M}.  This puts us on the word 'line' in Line 4
+ (the blank in the search string is important!).  Next, type {e}.  The 'e' puts
+-us at the end of the word.  Now, type {as^[  (^[ is the escape character)}.  
++us at the end of the word.  Now, type {as^[} (^[ is the escape character).  
+ The 'a' puts us in insert mode, AFTER the current character.  We appended the 
+-'s', and the escape ^[ ended the insert mode.
++'s', and the escape '^[' ended the insert mode.
+ 
+ The difference between {i} (insert) and {a} (append) is that {i} begins
+ inserting text BEFORE the cursor, and {a} begins inserting AFTER the cursor.
+--- nvi-1.81.6.orig/nvi-1.79/docs/tutorial/vi.advanced
++++ nvi-1.81.6/nvi-1.79/docs/tutorial/vi.advanced
+@@ -26,8 +26,8 @@
+     1         introduction: {^F} {ZZ}
+     2         introduction (con't) and positioning: {^F} {^B}
+     3         introduction (con't) and positioning: {^F} {^B}
+-    4         positioning: {^F} {^B} ^M (return key)
+-    5         quitting: {:q!} ^M key
++    4         positioning: {^F} {^B} {^M} (return key)
++    5         quitting: {:q!} {^M} (return key)
+     6         marking, cursor and screen positioning: {m} {G} {'} {z}
+     7         marking, cursor and screen positioning: {m} {G} {'} {z}
+     8         marking, cursor and screen positioning: {z} {m} {'}
+@@ -44,7 +44,7 @@
+    19         screen positioning: {H} {M} {L}
+    20         character positioning: {w} {b} {0} {W} {B} {e} {E} {'} {`}
+    21         cursor positioning: {l} {k} {j} {h}
+-   22         adding text: {i} {a} {I} {A} {o} {O} ^[ (escape key)
++   22         adding text: {i} {a} {I} {A} {o} {O} {^[} (escape key)
+    23         character manipulation: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J}
+    24         undo: {u} {U}
+    25         review
diff --git a/gnu/packages/patches/nvi-widechar-horrors.patch b/gnu/packages/patches/nvi-widechar-horrors.patch
new file mode 100644
index 0000000..4ec1b01
--- /dev/null
+++ b/gnu/packages/patches/nvi-widechar-horrors.patch
@@ -0,0 +1,69 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+13widechar_horrors.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+This patch tries to cope with the fact that widechar support in nvi is at
+best rudimentary.
+
+Hunk 1)
+* Due to "ch = *t", this code is not wide-char aware, so
+  cast the value to a proper type so the KEY_ macros make
+  the right choice.
+Hunk 2)
+* Printing of the in-/decreased number back into the screen
+  buffer is not widechar-aware, either. Add a dirty fix.
+  Cf. #497349.
+
+--- nvi-1.81.6.orig/vi/vs_msg.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/vs_msg.c	2009-03-01 14:51:08.211414132 +0100
+@@ -472,10 +472,10 @@
+ 			 */
+ 			if (ch == '\t')
+ 				ch = ' ';
+-			chlen = KEY_LEN(sp, ch);
++			chlen = KEY_LEN(sp, (unsigned char)ch);
+ 			if (cbp + chlen >= ecbp)
+ 				FLUSH;
+-			for (kp = KEY_NAME(sp, ch); chlen--;)
++			for (kp = KEY_NAME(sp, (unsigned char)ch); chlen--;)
+ 				*cbp++ = *kp++;
+ 		}
+ 		if (cbp > cbuf)
+--- nvi-1.81.6.orig/vi/v_increment.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/v_increment.c	2009-03-01 15:12:50.950415874 +0100
+@@ -57,7 +57,7 @@
+ 	long change, ltmp, lval;
+ 	size_t beg, blen, end, len, nlen, wlen;
+ 	int base, isempty, rval;
+-	char *ntype, nbuf[100];
++	char *ntype, nbuf[100 * sizeof(CHAR_T)];
+ 	CHAR_T *bp, *p, *t;
+ 
+ 	/* Validate the operator. */
+@@ -202,7 +202,7 @@
+ 		/* If we cross 0, signed numbers lose their sign. */
+ 		if (lval == 0 && ntype == fmt[SDEC])
+ 			ntype = fmt[DEC];
+-		nlen = snprintf(nbuf, sizeof(nbuf), ntype, lval);
++		nlen = snprintf(nbuf, sizeof(nbuf)/sizeof(CHAR_T), ntype, lval);
+ 	} else {
+ 		if ((nret = nget_uslong(sp, &ulval, t, NULL, base)) != NUM_OK)
+ 			goto err;
+@@ -224,7 +224,15 @@
+ 		if (base == 16)
+ 			wlen -= 2;
+ 
+-		nlen = snprintf(nbuf, sizeof(nbuf), ntype, wlen, ulval);
++		nlen = snprintf(nbuf, sizeof(nbuf)/sizeof(CHAR_T), ntype, wlen, ulval);
++	}
++
++	/* Inflate the printed char buffer to CHAR_T elements if necessary */
++	if (sizeof(CHAR_T) > sizeof(char)) {
++		int nlen_inflate;
++		for (nlen_inflate = nlen; nlen_inflate >= 0; nlen_inflate--) {
++			((CHAR_T *)nbuf)[nlen_inflate] = nbuf[nlen_inflate];
++		}
+ 	}
+ 
+ 	/* Build the new line. */
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-20 18:20 Marek Benc
@ 2015-01-21  9:35 ` Andreas Enge
  0 siblings, 0 replies; 11+ messages in thread
From: Andreas Enge @ 2015-01-21  9:35 UTC (permalink / raw)
  To: Marek Benc; +Cc: guix-devel

The number of patches looks quite frightening. From the README of nvi, the
current version dates from 2007. Now if upstream is dead and does not fix
patches, it might be preferable to remove the package altogether. Is there no
viable alternative that is still alive? Or vim in legacy mode?

Andreas

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
       [not found] <54BFBAED.3090502@gmail.com>
@ 2015-01-21 14:44 ` Marek Benc
  2015-01-21 15:03   ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Marek Benc @ 2015-01-21 14:44 UTC (permalink / raw)
  To: guix-devel


On 01/21/2015 10:35 AM, Andreas Enge wrote:
> The number of patches looks quite frightening. From the README of nvi, the
> current version dates from 2007. Now if upstream is dead and does not fix
> patches, it might be preferable to remove the package altogether. Is there no
> viable alternative that is still alive? Or vim in legacy mode?

I guess there is vim, which can be configured to behave pretty similar
to vi, but I personally think that having variety is good. Of course, I
won't object if you remove the package, because objectively, it is
obsolete, and I can always put it into my private package path :)

>
> Andreas
>

Marek

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-21 14:44 ` [PATCH] gnu: Add most debian patches to nvi Marek Benc
@ 2015-01-21 15:03   ` Ludovic Courtès
  2015-01-21 15:25     ` Marek Benc
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-01-21 15:03 UTC (permalink / raw)
  To: Marek Benc; +Cc: guix-devel

Marek Benc <merkur32@gmail.com> skribis:

> On 01/21/2015 10:35 AM, Andreas Enge wrote:
>> The number of patches looks quite frightening. From the README of nvi, the
>> current version dates from 2007. Now if upstream is dead and does not fix
>> patches, it might be preferable to remove the package altogether. Is there no
>> viable alternative that is still alive? Or vim in legacy mode?
>
> I guess there is vim, which can be configured to behave pretty similar
> to vi, but I personally think that having variety is good. Of course, I
> won't object if you remove the package, because objectively, it is
> obsolete, and I can always put it into my private package path :)

I agree with Andreas: there are 20 patches, and that level of patching
goes beyond our mission, IMO.

I would rather leave it as is if it’s usable, or remove it, or point to
a new upstream if there is one.

Thanks,
Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-21 15:03   ` Ludovic Courtès
@ 2015-01-21 15:25     ` Marek Benc
  2015-01-22 16:05       ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Marek Benc @ 2015-01-21 15:25 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 533 bytes --]


On 01/21/2015 04:03 PM, Ludovic Courtès wrote:
> I agree with Andreas: there are 20 patches, and that level of patching
> goes beyond our mission, IMO.
>
> I would rather leave it as is if it’s usable, or remove it, or point to
> a new upstream if there is one.

In that case, I think at least two of the patches should be allowed to 
get in, the ones about the Berkely db library, since it's spewing out 
errors without them. (but the editor itself works)

I'm attaching a lighter version of the patch.

>
> Thanks,
> Ludo’.


[-- Attachment #2: nvi-db.patch --]
[-- Type: text/x-patch, Size: 4376 bytes --]

From 3c7dd8afb7f464077b850f1143144cf2c4663a92 Mon Sep 17 00:00:00 2001
From: Marek Benc <merkur32@gmail.com>
Date: Wed, 21 Jan 2015 16:19:41 +0100
Subject: [PATCH] gnu: nvi: Fix Berkely DB compatability issues.

* gnu/packages/patches/nvi-db4.patch: New file.
* gnu/packages/patches/nvi-dbpagesize-binpower.patch: New file.
* gnu/packages/nvi.scm (nvi): Make use of them.
* gnu-system.am (dist_patch_DATA): Add them.

---
 gnu-system.am                                      |  4 ++-
 gnu/packages/nvi.scm                               |  4 ++-
 gnu/packages/patches/nvi-db4.patch                 | 29 ++++++++++++++++++++++
 gnu/packages/patches/nvi-dbpagesize-binpower.patch | 25 +++++++++++++++++++
 4 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 gnu/packages/patches/nvi-db4.patch
 create mode 100644 gnu/packages/patches/nvi-dbpagesize-binpower.patch

diff --git a/gnu-system.am b/gnu-system.am
index f29b452..8200458 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -433,7 +433,9 @@ dist_patch_DATA =						\
   gnu/packages/patches/net-tools-bitrot.patch			\
   gnu/packages/patches/ninja-tests.patch			\
   gnu/packages/patches/nss-pkgconfig.patch			\
-  gnu/packages/patches/nvi-assume-preserve-path.patch           \
+  gnu/packages/patches/nvi-assume-preserve-path.patch		\
+  gnu/packages/patches/nvi-dbpagesize-binpower.patch		\
+  gnu/packages/patches/nvi-db4.patch				\
   gnu/packages/patches/orpheus-cast-errors-and-includes.patch	\
   gnu/packages/patches/ots-no-include-missing-file.patch	\
   gnu/packages/patches/patchelf-page-size.patch			\
diff --git a/gnu/packages/nvi.scm b/gnu/packages/nvi.scm
index 8fd736d..128715f 100644
--- a/gnu/packages/nvi.scm
+++ b/gnu/packages/nvi.scm
@@ -37,7 +37,9 @@
                          ".tar.bz2"))
         (sha256
           (base32 "0nbbs1inyrqds0ywn3ln5slv54v5zraq7lszkg8nsavv4kivhh9l"))
-        (patches (list (search-patch "nvi-assume-preserve-path.patch")))
+        (patches (list (search-patch "nvi-assume-preserve-path.patch")
+                       (search-patch "nvi-dbpagesize-binpower.patch")
+                       (search-patch "nvi-db4.patch")))
         (snippet
           ;; Create a wrapper for the configure script, make it executable.
           '(let ((conf-wrap (open-output-file "configure")))
diff --git a/gnu/packages/patches/nvi-db4.patch b/gnu/packages/patches/nvi-db4.patch
new file mode 100644
index 0000000..c6a2db9
--- /dev/null
+++ b/gnu/packages/patches/nvi-db4.patch
@@ -0,0 +1,29 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+03db4.dpatch  by  <hesso@pool.math.tu-berlin.de>
+
+
+libdb4 compatibility adjustments.
+
+--- nvi-1.81.6.orig/common/msg.c	2009-02-26 14:26:58.350336128 +0100
++++ nvi-1.81.6/common/msg.c	2009-02-26 14:29:05.235335829 +0100
+@@ -724,9 +724,18 @@
+ 		p = buf;
+ 	} else
+ 		p = file;
++	if (access(p, F_OK) != 0) {
++		if (first) {
++			first = 0;
++			return (1);
++		}
++		sp->db_error = ENOENT;
++		msgq_str(sp, M_DBERR, p, "%s");
++		return (1);
++	}
+ 	if ((sp->db_error = db_create(&db, 0, 0)) != 0 ||
+ 	    (sp->db_error = db->set_re_source(db, p)) != 0 ||
+-	    (sp->db_error = db_open(db, NULL, DB_RECNO, 0, 0)) != 0) {
++	    (sp->db_error = db_open(db, NULL, DB_RECNO, DB_CREATE, 0)) != 0) {
+ 		if (first) {
+ 			first = 0;
+ 			return (1);
diff --git a/gnu/packages/patches/nvi-dbpagesize-binpower.patch b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
new file mode 100644
index 0000000..f37eeb2
--- /dev/null
+++ b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
@@ -0,0 +1,25 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+18dbpagesize_binpower.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Make sure that the pagesize passed to db__set_pagesize() is a power of two.
+
+--- nvi-1.81.6.orig/common/exf.c	2009-03-09 01:48:01.695862889 +0100
++++ nvi-1.81.6/common/exf.c	2009-03-09 10:42:41.147866272 +0100
+@@ -249,11 +249,10 @@
+ 		 * (vi should have good locality) or smaller than 1K.
+ 		 */
+ 		psize = ((sb.st_size / 15) + 1023) / 1024;
+-		if (psize > 10)
+-			psize = 10;
+-		if (psize == 0)
+-			psize = 1;
+-		psize *= 1024;
++		if (psize >= 8) psize=8<<10;
++		else if (psize >= 4) psize=4<<10;
++		else if (psize >= 2) psize=2<<10;
++		else psize=1<<10;
+ 
+ 		F_SET(ep, F_DEVSET);
+ 		ep->mdev = sb.st_dev;
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-21 15:25     ` Marek Benc
@ 2015-01-22 16:05       ` Ludovic Courtès
  2015-01-22 16:39         ` Marek Benc
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-01-22 16:05 UTC (permalink / raw)
  To: Marek Benc; +Cc: guix-devel

Marek Benc <merkur32@gmail.com> skribis:

> On 01/21/2015 04:03 PM, Ludovic Courtès wrote:
>> I agree with Andreas: there are 20 patches, and that level of patching
>> goes beyond our mission, IMO.
>>
>> I would rather leave it as is if it’s usable, or remove it, or point to
>> a new upstream if there is one.
>
> In that case, I think at least two of the patches should be allowed to
> get in, the ones about the Berkely db library, since it's spewing out
> errors without them. (but the editor itself works)

You mean there are run-time errors without nvi-db4.patch?  What kind?

The second patch is about page sizes apparently.  Do you know what the
deal is?

Two/three patches would be OK, but we need to have an understanding of
why we’re carrying these particular patches.

Thank you!

Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-22 16:05       ` Ludovic Courtès
@ 2015-01-22 16:39         ` Marek Benc
  2015-01-22 16:45           ` Marek Benc
  2015-01-22 20:52           ` Ludovic Courtès
  0 siblings, 2 replies; 11+ messages in thread
From: Marek Benc @ 2015-01-22 16:39 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel


On 01/22/2015 05:05 PM, Ludovic Courtès wrote:
> Marek Benc <merkur32@gmail.com> skribis:
>
>> On 01/21/2015 04:03 PM, Ludovic Courtès wrote:
>>> I agree with Andreas: there are 20 patches, and that level of patching
>>> goes beyond our mission, IMO.
>>>
>>> I would rather leave it as is if it’s usable, or remove it, or point to
>>> a new upstream if there is one.
>> In that case, I think at least two of the patches should be allowed to
>> get in, the ones about the Berkely db library, since it's spewing out
>> errors without them. (but the editor itself works)
> You mean there are run-time errors without nvi-db4.patch?  What kind?

I mistyped, it's only warnings, the editor seems to work okay. In 
particular,
the warnings look like this:

BDB0635 DB_CREATE must be specified to create databases.
BDB0511 page sizes must be a power-of-2

> The second patch is about page sizes apparently.  Do you know what the
> deal is?

nvi seems to store the data of files in Berkely DB database objects, and 
when
setting up a database for a file, it determines a page size to fit the file
into 15 pages or less, using a page size of at least 1K and at most 10K.

The way it does the calculation, I quote:
   psize = ((sb.st_size / 15) + 1023) / 1024;
   if (psize > 10)
     psize = 10;
   if (psize == 0)
     psize = 1;
   psize *= 1024;

makes psize hold a variable that's a multiple of 1024, but not necessarilya
power of two (for example, 3072). This didn't use to be a problem 
before, but
nowadays, BDB requires pages to be powers of two, and so the modified 
code, I
quote:

   psize = ((sb.st_size / 15) + 1023) / 1024;
   if (psize >= 8) psize=8<<10;
   else if (psize >= 4) psize=4<<10;
   else if (psize >= 2) psize=2<<10;
   else psize=1<<10;
   psize *= 1024;

fixes that problem.

> Two/three patches would be OK, but we need to have an understanding of
> why we’re carrying these particular patches.

Sure, I understand.

>
> Thank you!
>
> Ludo’.

Marek

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-22 16:39         ` Marek Benc
@ 2015-01-22 16:45           ` Marek Benc
  2015-01-22 20:52           ` Ludovic Courtès
  1 sibling, 0 replies; 11+ messages in thread
From: Marek Benc @ 2015-01-22 16:45 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel


On 01/22/2015 05:39 PM, Marek Benc wrote:
> psize = ((sb.st_size / 15) + 1023) / 1024;
>   if (psize >= 8) psize=8<<10;
>   else if (psize >= 4) psize=4<<10;
>   else if (psize >= 2) psize=2<<10;
>   else psize=1<<10;
>   psize *= 1024; 
Oops, ignore the last line, it's a typo on my end and not a problem of 
the patch (the patch removes it).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-22 16:39         ` Marek Benc
  2015-01-22 16:45           ` Marek Benc
@ 2015-01-22 20:52           ` Ludovic Courtès
  2015-01-22 22:17             ` Marek Benc
  1 sibling, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2015-01-22 20:52 UTC (permalink / raw)
  To: Marek Benc; +Cc: guix-devel

Marek Benc <merkur32@gmail.com> skribis:

> On 01/22/2015 05:05 PM, Ludovic Courtès wrote:
>> Marek Benc <merkur32@gmail.com> skribis:
>>
>>> On 01/21/2015 04:03 PM, Ludovic Courtès wrote:
>>>> I agree with Andreas: there are 20 patches, and that level of patching
>>>> goes beyond our mission, IMO.
>>>>
>>>> I would rather leave it as is if it’s usable, or remove it, or point to
>>>> a new upstream if there is one.
>>> In that case, I think at least two of the patches should be allowed to
>>> get in, the ones about the Berkely db library, since it's spewing out
>>> errors without them. (but the editor itself works)
>> You mean there are run-time errors without nvi-db4.patch?  What kind?
>
> I mistyped, it's only warnings, the editor seems to work okay. In
> particular,
> the warnings look like this:
>
> BDB0635 DB_CREATE must be specified to create databases.
> BDB0511 page sizes must be a power-of-2

OK.

>> The second patch is about page sizes apparently.  Do you know what the
>> deal is?
>
> nvi seems to store the data of files in Berkely DB database objects,
> and when
> setting up a database for a file, it determines a page size to fit the file
> into 15 pages or less, using a page size of at least 1K and at most 10K.
>
> The way it does the calculation, I quote:
>   psize = ((sb.st_size / 15) + 1023) / 1024;
>   if (psize > 10)
>     psize = 10;
>   if (psize == 0)
>     psize = 1;
>   psize *= 1024;
>
> makes psize hold a variable that's a multiple of 1024, but not necessarilya
> power of two (for example, 3072). This didn't use to be a problem
> before, but
> nowadays, BDB requires pages to be powers of two, and so the modified
> code, I

Oh, OK.

Could you quote the warnings and fold these explanations at the top of
the patches?  And then we’ll be all set.

Thanks for the explanation,
Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-22 20:52           ` Ludovic Courtès
@ 2015-01-22 22:17             ` Marek Benc
  2015-01-23  8:48               ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Marek Benc @ 2015-01-22 22:17 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel

[-- Attachment #1: Type: text/plain, Size: 2008 bytes --]


On 01/22/2015 09:52 PM, Ludovic Courtès wrote:
> Marek Benc <merkur32@gmail.com> skribis:
>
>> On 01/22/2015 05:05 PM, Ludovic Courtès wrote:
>>> Marek Benc <merkur32@gmail.com> skribis:
>>>
>>>> On 01/21/2015 04:03 PM, Ludovic Courtès wrote:
>>>>> I agree with Andreas: there are 20 patches, and that level of patching
>>>>> goes beyond our mission, IMO.
>>>>>
>>>>> I would rather leave it as is if it’s usable, or remove it, or point to
>>>>> a new upstream if there is one.
>>>> In that case, I think at least two of the patches should be allowed to
>>>> get in, the ones about the Berkely db library, since it's spewing out
>>>> errors without them. (but the editor itself works)
>>> You mean there are run-time errors without nvi-db4.patch?  What kind?
>> I mistyped, it's only warnings, the editor seems to work okay. In
>> particular,
>> the warnings look like this:
>>
>> BDB0635 DB_CREATE must be specified to create databases.
>> BDB0511 page sizes must be a power-of-2
> OK.
>
>>> The second patch is about page sizes apparently.  Do you know what the
>>> deal is?
>> nvi seems to store the data of files in Berkely DB database objects,
>> and when
>> setting up a database for a file, it determines a page size to fit the file
>> into 15 pages or less, using a page size of at least 1K and at most 10K.
>>
>> The way it does the calculation, I quote:
>>    psize = ((sb.st_size / 15) + 1023) / 1024;
>>    if (psize > 10)
>>      psize = 10;
>>    if (psize == 0)
>>      psize = 1;
>>    psize *= 1024;
>>
>> makes psize hold a variable that's a multiple of 1024, but not necessarilya
>> power of two (for example, 3072). This didn't use to be a problem
>> before, but
>> nowadays, BDB requires pages to be powers of two, and so the modified
>> code, I
> Oh, OK.
>
> Could you quote the warnings and fold these explanations at the top of
> the patches?  And then we’ll be all set.

Sure thing, they're in now.

>
> Thanks for the explanation,
> Ludo’.

No problem, and thanks,
Marek.

[-- Attachment #2: nvi-db.patch --]
[-- Type: text/x-patch, Size: 5127 bytes --]

From e101c036615bb22b05744789fbc0f5ddb7f71413 Mon Sep 17 00:00:00 2001
From: Marek Benc <merkur32@gmail.com>
Date: Thu, 22 Jan 2015 23:08:16 +0100
Subject: [PATCH] gnu: nvi: Fix Berkely DB compatability issues.

* gnu/packages/patches/nvi-db4.patch: New file.
* gnu/packages/patches/nvi-dbpagesize-binpower.patch: New file.
* gnu/packages/nvi.scm (nvi): Make use of them.
* gnu-system.am (dist_patch_DATA): Add them.

---
 gnu-system.am                                      |  4 ++-
 gnu/packages/nvi.scm                               |  4 ++-
 gnu/packages/patches/nvi-db4.patch                 | 35 ++++++++++++++++++++++
 gnu/packages/patches/nvi-dbpagesize-binpower.patch | 35 ++++++++++++++++++++++
 4 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 gnu/packages/patches/nvi-db4.patch
 create mode 100644 gnu/packages/patches/nvi-dbpagesize-binpower.patch

diff --git a/gnu-system.am b/gnu-system.am
index d1fc59a..5d773ca 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -443,7 +443,9 @@ dist_patch_DATA =						\
   gnu/packages/patches/net-tools-bitrot.patch			\
   gnu/packages/patches/ninja-tests.patch			\
   gnu/packages/patches/nss-pkgconfig.patch			\
-  gnu/packages/patches/nvi-assume-preserve-path.patch           \
+  gnu/packages/patches/nvi-assume-preserve-path.patch		\
+  gnu/packages/patches/nvi-dbpagesize-binpower.patch		\
+  gnu/packages/patches/nvi-db4.patch				\
   gnu/packages/patches/orpheus-cast-errors-and-includes.patch	\
   gnu/packages/patches/ots-no-include-missing-file.patch	\
   gnu/packages/patches/patchelf-page-size.patch			\
diff --git a/gnu/packages/nvi.scm b/gnu/packages/nvi.scm
index 8fd736d..128715f 100644
--- a/gnu/packages/nvi.scm
+++ b/gnu/packages/nvi.scm
@@ -37,7 +37,9 @@
                          ".tar.bz2"))
         (sha256
           (base32 "0nbbs1inyrqds0ywn3ln5slv54v5zraq7lszkg8nsavv4kivhh9l"))
-        (patches (list (search-patch "nvi-assume-preserve-path.patch")))
+        (patches (list (search-patch "nvi-assume-preserve-path.patch")
+                       (search-patch "nvi-dbpagesize-binpower.patch")
+                       (search-patch "nvi-db4.patch")))
         (snippet
           ;; Create a wrapper for the configure script, make it executable.
           '(let ((conf-wrap (open-output-file "configure")))
diff --git a/gnu/packages/patches/nvi-db4.patch b/gnu/packages/patches/nvi-db4.patch
new file mode 100644
index 0000000..03b736c
--- /dev/null
+++ b/gnu/packages/patches/nvi-db4.patch
@@ -0,0 +1,35 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+03db4.dpatch  by  <hesso@pool.math.tu-berlin.de>
+
+
+libdb4 compatibility adjustments.
+
+In particular, this patch adds extra file permission checking and passes the
+DB_CREATE flag to the first invocation of db_open on the file's database
+structure, which rids us of the following message:
+
+  BDB0635 DB_CREATE must be specified to create databases.
+
+--- nvi-1.81.6.orig/common/msg.c	2009-02-26 14:26:58.350336128 +0100
++++ nvi-1.81.6/common/msg.c	2009-02-26 14:29:05.235335829 +0100
+@@ -724,9 +724,18 @@
+ 		p = buf;
+ 	} else
+ 		p = file;
++	if (access(p, F_OK) != 0) {
++		if (first) {
++			first = 0;
++			return (1);
++		}
++		sp->db_error = ENOENT;
++		msgq_str(sp, M_DBERR, p, "%s");
++		return (1);
++	}
+ 	if ((sp->db_error = db_create(&db, 0, 0)) != 0 ||
+ 	    (sp->db_error = db->set_re_source(db, p)) != 0 ||
+-	    (sp->db_error = db_open(db, NULL, DB_RECNO, 0, 0)) != 0) {
++	    (sp->db_error = db_open(db, NULL, DB_RECNO, DB_CREATE, 0)) != 0) {
+ 		if (first) {
+ 			first = 0;
+ 			return (1);
diff --git a/gnu/packages/patches/nvi-dbpagesize-binpower.patch b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
new file mode 100644
index 0000000..7dde693
--- /dev/null
+++ b/gnu/packages/patches/nvi-dbpagesize-binpower.patch
@@ -0,0 +1,35 @@
+This patch originates from the Debian project, see https://www.debian.org/
+
+18dbpagesize_binpower.dpatch by  <hesso@pool.math.tu-berlin.de>
+
+
+Make sure that the pagesize passed to db__set_pagesize() is a power of two.
+
+nvi stores the content of files in BDB database structures. When initiating a
+file, it picks a page size for the database to fit the file within 15 pages,
+with a minimal page size of 1K and maximal of 10K.
+
+In vanilla nvi, this size is calculated as a multiple of 1024. Modern versions
+of BDB, however, require the page size of a database to be a power of two, which
+this patch addresses, ridding us of the following message:
+
+  BDB0511 page sizes must be a power-of-2
+
+--- nvi-1.81.6.orig/common/exf.c	2009-03-09 01:48:01.695862889 +0100
++++ nvi-1.81.6/common/exf.c	2009-03-09 10:42:41.147866272 +0100
+@@ -249,11 +249,10 @@
+ 		 * (vi should have good locality) or smaller than 1K.
+ 		 */
+ 		psize = ((sb.st_size / 15) + 1023) / 1024;
+-		if (psize > 10)
+-			psize = 10;
+-		if (psize == 0)
+-			psize = 1;
+-		psize *= 1024;
++		if (psize >= 8) psize=8<<10;
++		else if (psize >= 4) psize=4<<10;
++		else if (psize >= 2) psize=2<<10;
++		else psize=1<<10;
+ 
+ 		F_SET(ep, F_DEVSET);
+ 		ep->mdev = sb.st_dev;
-- 
2.2.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH] gnu: Add most debian patches to nvi.
  2015-01-22 22:17             ` Marek Benc
@ 2015-01-23  8:48               ` Ludovic Courtès
  0 siblings, 0 replies; 11+ messages in thread
From: Ludovic Courtès @ 2015-01-23  8:48 UTC (permalink / raw)
  To: Marek Benc; +Cc: guix-devel

Marek Benc <merkur32@gmail.com> skribis:

> From e101c036615bb22b05744789fbc0f5ddb7f71413 Mon Sep 17 00:00:00 2001
> From: Marek Benc <merkur32@gmail.com>
> Date: Thu, 22 Jan 2015 23:08:16 +0100
> Subject: [PATCH] gnu: nvi: Fix Berkely DB compatability issues.
>
> * gnu/packages/patches/nvi-db4.patch: New file.
> * gnu/packages/patches/nvi-dbpagesize-binpower.patch: New file.
> * gnu/packages/nvi.scm (nvi): Make use of them.
> * gnu-system.am (dist_patch_DATA): Add them.

Applied, thanks!

Ludo’.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-01-23  8:48 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <54BFBAED.3090502@gmail.com>
2015-01-21 14:44 ` [PATCH] gnu: Add most debian patches to nvi Marek Benc
2015-01-21 15:03   ` Ludovic Courtès
2015-01-21 15:25     ` Marek Benc
2015-01-22 16:05       ` Ludovic Courtès
2015-01-22 16:39         ` Marek Benc
2015-01-22 16:45           ` Marek Benc
2015-01-22 20:52           ` Ludovic Courtès
2015-01-22 22:17             ` Marek Benc
2015-01-23  8:48               ` Ludovic Courtès
2015-01-20 18:20 Marek Benc
2015-01-21  9:35 ` Andreas Enge

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).