Mail archive

[alpine-aports] [PATCH] testing/nvi: new aport

From: Sören Tempel <>
Date: Mon, 30 Nov 2015 19:14:21 +0100

Including a subset of the debian patchset.
 testing/nvi/01additional_upstream_data.patch | 3482 ++++++++++++++++++++++++++
 testing/nvi/03db4.patch                      |   25 +
 testing/nvi/04confdefs.patch                 |   10 +
 testing/nvi/06default_value_escapetime.patch |   15 +
 testing/nvi/07flush_cache.patch              |   46 +
 testing/nvi/08lfs.patch                      |   25 +
 testing/nvi/08safe_printf.patch              |   15 +
 testing/nvi/08tempfile_umask.patch           |   28 +
 testing/nvi/09casting.patch                  |   24 +
 testing/nvi/10no_one_line_visual.patch       |   21 +
 testing/nvi/11backward_sentence_moving.patch |   15 +
 testing/nvi/12horiz_scroll_count.patch       |   15 +
 testing/nvi/13widechar_horrors.patch         |   64 +
 testing/nvi/14private_regex_fixes.patch      |   28 +
 testing/nvi/15search_word.patch              |   26 +
 testing/nvi/16manpage_errors.patch           |  767 ++++++
 testing/nvi/17tutorial_typos.patch           |   60 +
 testing/nvi/18dbpagesize_binpower.patch      |   22 +
 testing/nvi/19include_term_h.patch           |   25 +
 testing/nvi/21exrc_writability_check.patch   |   58 +
 testing/nvi/24fallback_to_dumb_term.patch    |   26 +
 testing/nvi/25manpage_note_dropped_F.patch   |   55 +
 testing/nvi/26trailing_tab_segv.patch        |   15 +
 testing/nvi/27support_C_locale.patch         |   27 +
 testing/nvi/29file_backup.patch              |   32 +
 testing/nvi/APKBUILD                         |  171 ++
 26 files changed, 5097 insertions(+)
 create mode 100644 testing/nvi/01additional_upstream_data.patch
 create mode 100644 testing/nvi/03db4.patch
 create mode 100644 testing/nvi/04confdefs.patch
 create mode 100644 testing/nvi/06default_value_escapetime.patch
 create mode 100644 testing/nvi/07flush_cache.patch
 create mode 100644 testing/nvi/08lfs.patch
 create mode 100644 testing/nvi/08safe_printf.patch
 create mode 100644 testing/nvi/08tempfile_umask.patch
 create mode 100644 testing/nvi/09casting.patch
 create mode 100644 testing/nvi/10no_one_line_visual.patch
 create mode 100644 testing/nvi/11backward_sentence_moving.patch
 create mode 100644 testing/nvi/12horiz_scroll_count.patch
 create mode 100644 testing/nvi/13widechar_horrors.patch
 create mode 100644 testing/nvi/14private_regex_fixes.patch
 create mode 100644 testing/nvi/15search_word.patch
 create mode 100644 testing/nvi/16manpage_errors.patch
 create mode 100644 testing/nvi/17tutorial_typos.patch
 create mode 100644 testing/nvi/18dbpagesize_binpower.patch
 create mode 100644 testing/nvi/19include_term_h.patch
 create mode 100644 testing/nvi/21exrc_writability_check.patch
 create mode 100644 testing/nvi/24fallback_to_dumb_term.patch
 create mode 100644 testing/nvi/25manpage_note_dropped_F.patch
 create mode 100644 testing/nvi/26trailing_tab_segv.patch
 create mode 100644 testing/nvi/27support_C_locale.patch
 create mode 100644 testing/nvi/29file_backup.patch
 create mode 100644 testing/nvi/APKBUILD
diff --git a/testing/nvi/01additional_upstream_data.patch b/testing/nvi/01additional_upstream_data.patch
new file mode 100644
index 0000000..2517bbb
--- /dev/null
+++ b/testing/nvi/01additional_upstream_data.patch
_at_@ -0,0 +1,3482 @@
+From: <>
+Subject: 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
+_at_@ -0,0 +1,160 @@
++_at_(#)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, or you can contact him
++   at
++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
++, or you can contact him at
++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 Hiebert)
++ (Darren Hiebert)
++	Maintained-by: (Darren Hiebert)
++ (Darren Hiebert)
++	Primary-site: /pub/Linux/devel/lang/c
++			27kB ctags-1.3.tar.gz
++	Alternate-site: /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
+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
+_at_@ -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, 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 _at_ 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
++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 _at_<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 [_at_*]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
+_at_@ -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
++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
++ 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
++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
++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 _at_ 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:
++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:
++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
++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}
++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 {.}:
++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
++% 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 ******
++.ll 79 
++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
++(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
++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
++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
++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
++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
++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 
++{: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 '_at_'.
++    (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
++            '_at_'; 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 _at_ 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 ^_at_ 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
++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
++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
++[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
++[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
++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
++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
+_at_@ -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.
++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
++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.  
++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
++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
++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
++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 ^.  Now type {/Section 15:/^M} and the
++cursor will end up over/on ^.  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
++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, _at_, or ^X will delete the current line (up to the
++beginning of the current insertion).  You will need to experiment with ^U, _at_,
++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:
++{^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
++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/testing/nvi/03db4.patch b/testing/nvi/03db4.patch
new file mode 100644
index 0000000..474011b
--- /dev/null
+++ b/testing/nvi/03db4.patch
_at_@ -0,0 +1,25 @@
+From: <>
+Subject: 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
+_at_@ -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/testing/nvi/04confdefs.patch b/testing/nvi/04confdefs.patch
new file mode 100644
index 0000000..d5dd21b
--- /dev/null
+++ b/testing/nvi/04confdefs.patch
_at_@ -0,0 +1,10 @@
+From: <>
+Subject: Help configure by decreeing that some headers are present.
+diff -Naur nvi-1.81.6.orig/build/confdefs.h nvi-1.81.6/build/confdefs.h
+--- nvi-1.81.6.orig/build/confdefs.h	1970-01-01 01:00:00.000000000 +0100
++++ nvi-1.81.6/build/confdefs.h	2008-05-01 18:05:00.000000000 +0200
+_at_@ -0,0 +1,3 @@
++#define HAVE_SYS_MMAN_H 1
++#define HAVE_SYS_SELECT_H 1
diff --git a/testing/nvi/06default_value_escapetime.patch b/testing/nvi/06default_value_escapetime.patch
new file mode 100644
index 0000000..a551d42
--- /dev/null
+++ b/testing/nvi/06default_value_escapetime.patch
_at_@ -0,0 +1,15 @@
+From: <>
+Subject: Increase the default 'escapetime' setting to accommodate slow lines.
+diff -Naur nvi-1.81.6.orig/common/options.c nvi-1.81.6/common/options.c
+--- nvi-1.81.6.orig/common/options.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/common/options.c	2008-05-01 18:06:18.000000000 +0200
+_at_@ -356,7 +356,7 @@
+ 	(void)SPRINTF(b2, SIZE(b2),
+ 	    L("directory=%s"), (s = getenv("TMPDIR")) == NULL ? _PATH_TMP : s);
+-	OI(O_ESCAPETIME, L("escapetime=1"));
++	OI(O_ESCAPETIME, L("escapetime=3"));
+ 	OI(O_KEYTIME, L("keytime=6"));
+ 	OI(O_MATCHTIME, L("matchtime=7"));
+ 	(void)SPRINTF(b2, SIZE(b2), L("msgcat=%s"), _PATH_MSGCAT);
diff --git a/testing/nvi/07flush_cache.patch b/testing/nvi/07flush_cache.patch
new file mode 100644
index 0000000..7479177
--- /dev/null
+++ b/testing/nvi/07flush_cache.patch
_at_@ -0,0 +1,46 @@
+From: <>
+Subject: No description.
+diff -Naur nvi-1.81.6.orig/common/db1.c nvi-1.81.6/common/db1.c
+--- nvi-1.81.6.orig/common/db1.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/common/db1.c	2008-05-01 18:07:58.000000000 +0200
+_at_@ -262,8 +262,7 @@
+ 	}
+ 	/* Flush the cache, update line count, before screen update. */
+-	if (lno <= ep->c_lno)
+-		ep->c_lno = OOBLNO;
++	ep->c_lno = OOBLNO;
+ 	if (ep->c_nlines != OOBLNO)
+ 		--ep->c_nlines;
+_at_@ -314,8 +313,7 @@
+ 	}
+ 	/* Flush the cache, update line count, before screen update. */
+-	if (lno < ep->c_lno)
+-		ep->c_lno = OOBLNO;
++	ep->c_lno = OOBLNO;
+ 	if (ep->c_nlines != OOBLNO)
+ 		++ep->c_nlines;
+_at_@ -386,8 +384,7 @@
+ 	}
+ 	/* Flush the cache, update line count, before screen update. */
+-	if (lno >= ep->c_lno)
+-		ep->c_lno = OOBLNO;
++	ep->c_lno = OOBLNO;
+ 	if (ep->c_nlines != OOBLNO)
+ 		++ep->c_nlines;
+_at_@ -459,8 +456,7 @@
+ 	}
+ 	/* Flush the cache, before logging or screen update. */
+-	if (lno == ep->c_lno)
+-		ep->c_lno = OOBLNO;
++	ep->c_lno = OOBLNO;
+ 	/* File now dirty. */
diff --git a/testing/nvi/08lfs.patch b/testing/nvi/08lfs.patch
new file mode 100644
index 0000000..e5d9399
--- /dev/null
+++ b/testing/nvi/08lfs.patch
_at_@ -0,0 +1,25 @@
+From: <>
+Subject: 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
+_at_@ -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/testing/nvi/08safe_printf.patch b/testing/nvi/08safe_printf.patch
new file mode 100644
index 0000000..13ef3e1
--- /dev/null
+++ b/testing/nvi/08safe_printf.patch
_at_@ -0,0 +1,15 @@
+From: <>
+Subject: No description.
+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
+_at_@ -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/testing/nvi/08tempfile_umask.patch b/testing/nvi/08tempfile_umask.patch
new file mode 100644
index 0000000..3debcb7
--- /dev/null
+++ b/testing/nvi/08tempfile_umask.patch
_at_@ -0,0 +1,28 @@
+From: <>
+Subject: No description.
+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:45.000000000 +0200
++++ nvi-1.81.6/common/exf.c	2008-05-01 18:13:23.000000000 +0200
+_at_@ -207,16 +207,21 @@
+ 	 */
+ 	oname = frp->name;
+ 	if (LF_ISSET(FS_OPENERR) || oname == NULL || !exists) {
++		mode_t orig_umask;
+ 		if (opts_empty(sp, O_TMP_DIRECTORY, 0))
+ 			goto err;
++		orig_umask = umask(0);
++		umask(orig_umask & 0177);
+ 		(void)snprintf(tname, sizeof(tname),
+ 		    "%s/vi.XXXXXX", O_STR(sp, O_TMP_DIRECTORY));
+ 		if ((fd = mkstemp(tname)) == -1) {
++			umask(orig_umask);
+ 			msgq(sp, M_SYSERR,
+ 			    "237|Unable to create temporary file");
+ 			goto err;
+ 		}
+ 		(void)close(fd);
++		umask(orig_umask);
+ 		if (frp->name == NULL)
+ 			F_SET(frp, FR_TMPFILE);
diff --git a/testing/nvi/09casting.patch b/testing/nvi/09casting.patch
new file mode 100644
index 0000000..9f0b217
--- /dev/null
+++ b/testing/nvi/09casting.patch
_at_@ -0,0 +1,24 @@
+From: <>
+Subject: No description.
+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
+_at_@ -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);
+_at_@ -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/testing/nvi/10no_one_line_visual.patch b/testing/nvi/10no_one_line_visual.patch
new file mode 100644
index 0000000..41a638d
--- /dev/null
+++ b/testing/nvi/10no_one_line_visual.patch
_at_@ -0,0 +1,21 @@
+From: <>
+Subject: 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
+_at_@ -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/testing/nvi/11backward_sentence_moving.patch b/testing/nvi/11backward_sentence_moving.patch
new file mode 100644
index 0000000..d3b563b
--- /dev/null
+++ b/testing/nvi/11backward_sentence_moving.patch
_at_@ -0,0 +1,15 @@
+From: <>
+Subject: No description.
+diff -Naur nvi-1.81.6.orig/vi/v_sentence.c nvi-1.81.6/vi/v_sentence.c
+--- nvi-1.81.6.orig/vi/v_sentence.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/v_sentence.c	2008-05-01 18:15:37.000000000 +0200
+_at_@ -291,7 +291,7 @@
+ 			 * we can end up where we started.  Fix it.
+ 			 */
+ 			if (vp->m_start.lno != cs.cs_lno ||
+-			    vp->m_start.cno != cs.cs_cno)
++			    vp->m_start.cno > cs.cs_cno)
+ 				goto okret;
+ 			/*
diff --git a/testing/nvi/12horiz_scroll_count.patch b/testing/nvi/12horiz_scroll_count.patch
new file mode 100644
index 0000000..cad4958
--- /dev/null
+++ b/testing/nvi/12horiz_scroll_count.patch
_at_@ -0,0 +1,15 @@
+From: <>
+Subject: No description.
+diff -Naur nvi-1.81.6.orig/vi/vs_refresh.c nvi-1.81.6/vi/vs_refresh.c
+--- nvi-1.81.6.orig/vi/vs_refresh.c	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/vi/vs_refresh.c	2008-05-01 18:16:01.000000000 +0200
+_at_@ -569,7 +569,7 @@
+ 		 * for the number option offset.
+ 		 */
+ 		cnt = vs_columns(sp, NULL, LNO, &CNO, NULL);
+-		if (O_ISSET(sp, O_NUMBER))
++		if (O_ISSET(sp, O_NUMBER) && cnt)
+ 			cnt -= O_NUMBER_LENGTH;
+ 		/* Adjust the window towards the beginning of the line. */
diff --git a/testing/nvi/13widechar_horrors.patch b/testing/nvi/13widechar_horrors.patch
new file mode 100644
index 0000000..d6b5f33
--- /dev/null
+++ b/testing/nvi/13widechar_horrors.patch
_at_@ -0,0 +1,64 @@
+From: <>
+Subject: 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
+_at_@ -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
+_at_@ -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. */
+_at_@ -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;
+_at_@ -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. */
diff --git a/testing/nvi/14private_regex_fixes.patch b/testing/nvi/14private_regex_fixes.patch
new file mode 100644
index 0000000..b98f553
--- /dev/null
+++ b/testing/nvi/14private_regex_fixes.patch
_at_@ -0,0 +1,28 @@
+From: <>
+Subject: 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
+_at_@ -606,7 +606,8 @@
+ 		REQUIRE(starordinary, REG_BADRPT);
+ 	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
+_at_@ -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/testing/nvi/15search_word.patch b/testing/nvi/15search_word.patch
new file mode 100644
index 0000000..f782978
--- /dev/null
+++ b/testing/nvi/15search_word.patch
_at_@ -0,0 +1,26 @@
+From: Al Viro <>
+Subject: 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
+_at_@ -322,15 +322,16 @@
+ 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);
+ 	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;
+ 	rval = v_search(sp, vp, bp, len, SEARCH_SET, FORWARD);
diff --git a/testing/nvi/16manpage_errors.patch b/testing/nvi/16manpage_errors.patch
new file mode 100644
index 0000000..e167c5f
--- /dev/null
+++ b/testing/nvi/16manpage_errors.patch
_at_@ -0,0 +1,767 @@
+From: <>
+Subject: Fix a truckload of roff markup glitches.
+diff -Naur nvi-1.81.6.orig/docs/ nvi-1.81.6/docs/
+--- nvi-1.81.6.orig/docs/	2007-11-18 17:41:42.000000000 +0100
++++ nvi-1.81.6/docs/	2008-05-01 18:17:59.000000000 +0200
+_at_@ -17,35 +17,35 @@
+ .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 ...]
+ The vi program is freely redistributable.  You are welcome to copy,
+_at_@ -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
+_at_@ -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
+_at_@ -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
+_at_@ -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:
+_at_@ -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
+_at_@ -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
+_at_@ -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
+_at_@ -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
+_at_@ -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
+_at_@ -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:
+_at_@ -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.
+_at_@ -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>"
+_at_@ -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>"
+_at_@ -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] $"
+_at_@ -457,7 +457,7 @@
+ .TP
+ .B "'<character>"
+ .TP
+-.B "`<character>"
++.B "\`<character>"
+ Return to a context marked by the character
+ .IR <character> .
+ .TP
+_at_@ -476,7 +476,7 @@
+ .I count
+ times.
+ .TP
+-.B "[count] -"
++.B "[count] \-"
+ Move to first nonblank of the previous line,
+ .I count
+ times.
+_at_@ -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
+_at_@ -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
+ .TP
+ .B "[count] F <character>"
+ Search
+_at_@ -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"
+_at_@ -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"
+_at_@ -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
+_at_@ -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"
+_at_@ -657,7 +657,7 @@
+ .B "[count] e"
+ Move forward
+ .I count
+ .TP
+ .B "[count] f<character>"
+ Search forward,
+_at_@ -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] {"
+_at_@ -735,13 +735,20 @@
+ .B "[count] ~"
+ Reverse the case of the next
+ .I count
++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.
+_at_@ -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
+_at_@ -777,7 +784,7 @@
+ .TP
+ .B "<erase>
+ .TP
+-.B "<control-H>"
++.B "<control\(hyH>"
+ Erase the last character.
+ .TP
+ .B "<literal next>"
+_at_@ -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.
+_at_@ -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>"
+_at_@ -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)"
+_at_@ -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.
+_at_@ -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]"
+_at_@ -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.
+_at_@ -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.
+_at_@ -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.
+_at_@ -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
+_at_@ -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.
+_at_@ -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
+_at_@ -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.
+_at_@ -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
+_at_@ -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
+_at_@ -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.
+ .TP
+_at_@ -1430,7 +1440,7 @@
+ .TP
+ 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
+_at_@ -1462,7 +1472,7 @@
+ .TP
+ The user's terminal type.
+-The default is the type ``unknown''.
++The default is the type \(lqunknown\(rq.
+ If the
+ environmental variable is not set when
+_at_@ -1482,7 +1492,7 @@
+ .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
+ .TP
+_at_@ -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
+ When an interrupt occurs,
+_at_@ -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
+ .TP
+_at_@ -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.
+_at_@ -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
+_at_@ -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
+_at_@ -1602,7 +1612,7 @@
+ editor first appeared in 4.4BSD.
+ .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/testing/nvi/17tutorial_typos.patch b/testing/nvi/17tutorial_typos.patch
new file mode 100644
index 0000000..a7b002d
--- /dev/null
+++ b/testing/nvi/17tutorial_typos.patch
_at_@ -0,0 +1,60 @@
+From: Unknown
+Subject: 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
+_at_@ -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
+_at_@ -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.
+_at_@ -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
+_at_@ -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} {'}
+_at_@ -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/testing/nvi/18dbpagesize_binpower.patch b/testing/nvi/18dbpagesize_binpower.patch
new file mode 100644
index 0000000..ec04504
--- /dev/null
+++ b/testing/nvi/18dbpagesize_binpower.patch
_at_@ -0,0 +1,22 @@
+From: <>
+Subject: 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
+_at_@ -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/testing/nvi/19include_term_h.patch b/testing/nvi/19include_term_h.patch
new file mode 100644
index 0000000..bb774e0
--- /dev/null
+++ b/testing/nvi/19include_term_h.patch
_at_@ -0,0 +1,25 @@
+From: <>
+Subject: 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
+_at_@ -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
+_at_@ -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/testing/nvi/21exrc_writability_check.patch b/testing/nvi/21exrc_writability_check.patch
new file mode 100644
index 0000000..e310931
--- /dev/null
+++ b/testing/nvi/21exrc_writability_check.patch
_at_@ -0,0 +1,58 @@
+From: <>
+Subject: No description.
+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
+_at_@ -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"
+_at_@ -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);
+_at_@ -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/testing/nvi/24fallback_to_dumb_term.patch b/testing/nvi/24fallback_to_dumb_term.patch
new file mode 100644
index 0000000..60aa4cc
--- /dev/null
+++ b/testing/nvi/24fallback_to_dumb_term.patch
_at_@ -0,0 +1,26 @@
+From: <>
+Subject: 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
+_at_@ -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) =
+_at_@ -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/testing/nvi/25manpage_note_dropped_F.patch b/testing/nvi/25manpage_note_dropped_F.patch
new file mode 100644
index 0000000..9eb68c1
--- /dev/null
+++ b/testing/nvi/25manpage_note_dropped_F.patch
_at_@ -0,0 +1,55 @@
+From: <>
+Subject: 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/	2008-06-13 00:52:45.000000000 +0200
++++ nvi-1.81.6+debian-1/docs/	2008-06-13 00:55:40.000000000 +0200
+_at_@ -17,7 +17,7 @@
+ .B ex
+ [\c
+-.B \-eFRrSsv\c
++.B \-eRrSsv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+_at_@ -28,7 +28,7 @@
+ .br
+ .B vi
+ [\c
+-.B \-eFlRrSv\c
++.B \-elRrSv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+_at_@ -39,7 +39,7 @@
+ .br
+ .B view
+ [\c
+-.B \-eFRrSv\c
++.B \-eRrSv\c
+ ] [\c
+ .BI \-c " cmd"\c
+ ] [\c
+_at_@ -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.)
+ .B \-l
+ Start editing with the lisp and showmatch options set.
+ .TP
+_at_@ -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.
+ Command input for
+ .I ex/vi
+ is read from the standard input.
diff --git a/testing/nvi/26trailing_tab_segv.patch b/testing/nvi/26trailing_tab_segv.patch
new file mode 100644
index 0000000..d6c5a90
--- /dev/null
+++ b/testing/nvi/26trailing_tab_segv.patch
_at_@ -0,0 +1,15 @@
+From: <>
+Subject: 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
+_at_@ -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/testing/nvi/27support_C_locale.patch b/testing/nvi/27support_C_locale.patch
new file mode 100644
index 0000000..97d2141
--- /dev/null
+++ b/testing/nvi/27support_C_locale.patch
_at_@ -0,0 +1,27 @@
+From: <>
+Subject: 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
+_at_@ -322,11 +322,16 @@
+     else {
+ 	setlocale(LC_ALL, "");
+-	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/testing/nvi/29file_backup.patch b/testing/nvi/29file_backup.patch
new file mode 100644
index 0000000..52b1e92
--- /dev/null
+++ b/testing/nvi/29file_backup.patch
_at_@ -0,0 +1,32 @@
+From: <>
+Subject: 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
+_at_@ -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;
+_at_@ -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/testing/nvi/APKBUILD b/testing/nvi/APKBUILD
new file mode 100644
index 0000000..5e1973f
--- /dev/null
+++ b/testing/nvi/APKBUILD
_at_@ -0,0 +1,171 @@
+# Contributor: Sören Tempel <>
+# Maintainer: Sören Tempel <>
+pkgdesc="Re-implementation of the vi editor"
+makedepends="db-dev ncurses-dev"
+subpackages="$pkgname-doc $pkgname-catalog"
+	01additional_upstream_data.patch
+	03db4.patch
+	04confdefs.patch
+	06default_value_escapetime.patch
+	07flush_cache.patch
+	08lfs.patch
+	08safe_printf.patch
+	08tempfile_umask.patch
+	09casting.patch
+	10no_one_line_visual.patch
+	11backward_sentence_moving.patch
+	12horiz_scroll_count.patch
+	13widechar_horrors.patch
+	14private_regex_fixes.patch
+	15search_word.patch
+	16manpage_errors.patch
+	17tutorial_typos.patch
+	18dbpagesize_binpower.patch
+	19include_term_h.patch
+	21exrc_writability_check.patch
+	24fallback_to_dumb_term.patch
+	25manpage_note_dropped_F.patch
+	26trailing_tab_segv.patch
+	27support_C_locale.patch
+	29file_backup.patch"
+prepare() {
+	cd "$_builddir"
+	update_config_sub || return 1
+	for i in $source; do
+		case $i in
+		*.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+		esac
+	done
+build() {
+	cd "$_builddir"/dist
+	./configure \
+		--build=$CBUILD \
+		--host=$CHOST \
+		--prefix=/usr \
+		--sysconfdir=/etc \
+		--mandir=/usr/share/man \
+		--localstatedir=/var \
+		--program-prefix=n \
+		--enable-widechar \
+		--enable-threads \
+		--disable-static \
+		|| return 1
+	make || return 1
+package() {
+	mkdir -p "$pkgdir"/usr/bin || return 1
+	make -j1 PREFIX=/usr DESTDIR="$pkgdir" \
+		install -C "$_builddir"/dist || return 1
+	# Remove tcl and perl scripts.
+	rm -rf "$pkgdir"/usr/share/vi/tcl
+	rm -rf "$pkgdir"/usr/share/vi/perl
+	# Remove cat man pages.
+	rm -rf "$pkgdir"/usr/share/man/cat1
+catalog() {
+	pkgdesc="$pkgdesc (catalog files)"
+	depends=""
+	arch="noarch"
+	mkdir -p "$subpkgdir"/usr/share/vi/
+	mv "$pkgdir"/usr/share/vi/catalog/ \
+		"$subpkgdir"/usr/share/vi/ || return 1
+md5sums="f7e65a969045dafd53aea7e3e80b8cf2  nvi_1.81.6.orig.tar.gz
+7b54dcc34076857127e4a555db7987f5  01additional_upstream_data.patch
+b4a2947050cf3c3bba907dce1fe92b94  03db4.patch
+936f99d503b1b9ccd12bd90ab2cf9bf4  04confdefs.patch
+15c8eb6006a0ae554c79a95eab68e6d3  06default_value_escapetime.patch
+a26c89008d6a739e1325abf27067353b  07flush_cache.patch
+90d7e4004327473cb9caec998e45b1f7  08lfs.patch
+48b1c7b5c7e92389b5def6c41af9faa5  08safe_printf.patch
+f69d0024e73e924184157db83cf21151  08tempfile_umask.patch
+f1e3574b9249d6559b8b07014c713388  09casting.patch
+2995a5dadb8dea7201bf7a732037ae81  10no_one_line_visual.patch
+1adde09ecc00e5aedbe1bba9e89867c7  11backward_sentence_moving.patch
+9bcaa4dcc6b6605e1b81804aa59a1714  12horiz_scroll_count.patch
+d8985b75ddc1e6bbdb95b15e8af75885  13widechar_horrors.patch
+de4a3d239fb0bce60c40473d342398a4  14private_regex_fixes.patch
+441fbe26900747892cfd0680b0265e58  15search_word.patch
+ce43f59a26fc445586b00bd53b8b81c8  16manpage_errors.patch
+8ba107264cc9dbfe83d1ec72ff2c3ec0  17tutorial_typos.patch
+7646959e48fdf3a91f0f06d4305de6fa  18dbpagesize_binpower.patch
+b0066d3cf7f9689cecc487bfbdc976d5  19include_term_h.patch
+33a5d7f1ec10a688c429b78ccd82d044  21exrc_writability_check.patch
+bf9b5d890869069963e0233129debf79  24fallback_to_dumb_term.patch
+25c66adcfe779a5deaa7636f9076f2e3  25manpage_note_dropped_F.patch
+724d2369993aadd1388f9ede54d0e28f  26trailing_tab_segv.patch
+ad5cd0869a18e8f027435b9c0643a039  27support_C_locale.patch
+77d8610f0a37e5575d5ae73173e7b449  29file_backup.patch"
+sha256sums="8bc348889159a34cf268f80720b26f459dbd723b5616107d36739d007e4c978d  nvi_1.81.6.orig.tar.gz
+a7a3fb399359f492943d6e72e5c1233023184f0ae96ab1bebec64c0d08641f4f  01additional_upstream_data.patch
+0affc8e156ab1666edec12254d87d427fd45dbebb51da184b47ab82bc9334ea1  03db4.patch
+bb3e29a84602f8477e6bf6e2756057cf0164fddf7dc80863e15858dbdbe8dbf4  04confdefs.patch
+3b15340e9bb51da467bcbea1ad97589fa084bed68a2ee4ce7fd9797a4279e2cf  06default_value_escapetime.patch
+c26a36151ee4f839724a70e22d9b5fdac9ed3686a10842ecc807c5a9d8d63c10  07flush_cache.patch
+26f39687f25de32a5c448b71c820a72cfc9310686842d291160cd830e44c673b  08lfs.patch
+c5ea81a9e8da852c846d004603df49829342048e8b3959c7e1f074c9195ec866  08safe_printf.patch
+56e82712e8df73b1c64dd28da6ea503555ec6b65286e42519fe023f28382064c  08tempfile_umask.patch
+c06373abfd4054fb86edcb8b3844bfc773b4badd313d452d775029beb2ce25da  09casting.patch
+8ed25a56255c5cf68464d8b6958be7f48aefd19a77a6eec13556505cb8f49843  10no_one_line_visual.patch
+7649b5e154377a1eea7e4882eb333c51d2395b4042bc7e67c59b58d0df496995  11backward_sentence_moving.patch
+c7266a713911a7b8d7d178311f089e587a8e5dfd89e3e926c68b10158bb809ea  12horiz_scroll_count.patch
+ebf75d78a72bf12f812b734bcea9893c8499dfc3e7080b1552ca9f0d748ca337  13widechar_horrors.patch
+b0c8209cb4f96e2843ba58a266ad6a52339b2d6cf9b9fd877692d78c5e2608cd  14private_regex_fixes.patch
+05d1398e3c6611a2a62af73f55590d9a2e43ef17ac75522eff46f156a8135161  15search_word.patch
+130285cfce4e4a4c726570da61ec270cba9a27eddac6efffa3fd45070b6d86d0  16manpage_errors.patch
+15f2f46652e48513e272cd07cb6208cde83643db554a76eda77d84c66ea5ae35  17tutorial_typos.patch
+0a9e321b571bddabd502b7f58fa365dd2095f2e344cdb3cb87888f4027b78e28  18dbpagesize_binpower.patch
+31d51075014635fd3cad77f4e6bebfa192ee2c2ee0bba2b6c331a20eaca3b04c  19include_term_h.patch
+ba47cf3e453d20cb584c68b5da898a79d3263efb3b95b50598f0d269ff4ecc0f  21exrc_writability_check.patch
+e77f879c208d45e77c1d86558aef42bdfa4aa534f8f46c0e3dfe5de58272b003  24fallback_to_dumb_term.patch
+7bcecd8a722582d2888d92a6d99849332ef27539cc09dce258ea97c1ca3867c0  25manpage_note_dropped_F.patch
+8c59c97350ea8641eb86c330bf95dc2da3c6d7d61c205a8dbb3dc1f1ace63ac6  26trailing_tab_segv.patch
+9bd2a5070858143dd4cde5a292890b50d209da9726883e1fb1809439c5a568fd  27support_C_locale.patch
+2ef8ba25a45f264f8c63f115e7e922bc4b838f8c5d324640087be6387e4610dc  29file_backup.patch"
+sha512sums="1be798daf0cd05010ddaf0aa0510dc799708fd79d4b243e2700adff18e931ddd9d11621796fa8086088c3e93ba20f15ab86783732665169c52b73eaf587ff0b3  nvi_1.81.6.orig.tar.gz
+ec998baba23d15c957dbdb121a4ba7eddf0aac15503e381a1318a7e7127b0c06f3bd05ebd474175f39a6fb050ed6fd3a1f4bd348d92770355e8bc3d8d37277c9  01additional_upstream_data.patch
+d635c86c52cf16ccc947ee8a4593160adf183b236ae7c2eb03ff2ea628f493e484f906b762eb1d90ec1febc48119cac955382af3ebc223e29622123500a45f97  03db4.patch
+9b45e0639a30b81204e1c9b43877a6a83df2a5bba3b85a410427ead1e639cc9882f0ca162721074782870742af449c5a3f00b5051d459491bf9afb7cd718450d  04confdefs.patch
+4820b584614d321b6528b9400429440b126c5c8ccc502f9e61ec7ff9cd7769e7c53e04f83ffcd4804c6baed5ac55953834644444c11e9cf42841e8fb371196ca  06default_value_escapetime.patch
+df74b0977e7d864e7ea9833404f818cfb644c9fa188024b6174c7a2360350cc63f8cd8cd7fc19e54dbc5db8e2b6310be9807bb7bd108ab56dbc2d3d9cf8bff14  07flush_cache.patch
+0a432a0823d0d0b2bba2dba6ee24f1b173b4552245c1bba1727804dfa8eff09dfd88129fb615eae5846aa6ef929c08a0a23a505b000dc77ecc6de578d3dc8026  08lfs.patch
+2c1afb271f60031a15d4e2093b4e04c02462cc1d1815ce557049364bcdc81f83d3c6e25766a7a7efa8d04cc1c8284e9684df12ab161aba16bb479c9ee4660012  08safe_printf.patch
+af723124cef36966c57785f9066cc924d155a0d495375849db36a1bf1ef1b166afd8f057d258ada9367fbf82cd30694efeeeb246d0fb14ff07fcdb807230e109  08tempfile_umask.patch
+e70ee763a5c54424f75143ce892b93d8046618935bdc50bc3e646848b9b0f3d4bacf0a362b4203984527dbd98ea321a12b81b69eee7aa340e745b5d77492aca0  09casting.patch
+65776b87d86cde21ef8034a1c1fe88daaac03a960223a05fdb2e1005b7e44348dc4571abe0addeef65f08fbeef72fb376486b3dccaaff4cc7d4c39bdc206026d  10no_one_line_visual.patch
+f99afc8f83ea84ce059dbd5dc7b1bf726dbb2c64de8b12a7de21ca42a76e0a3b9f19d0c8c73bd046d7e0ad5ae81afed7f8e472232bcc55eb221b479ab4671f48  11backward_sentence_moving.patch
+3f77c69d08d8c807eb62332eca84af898849214660e238915cadf60e46014295889bb4c66fc116846d1d9cdc2cd4d3b89b4c9c4c6a5e908ebd530f6b9fee00f0  12horiz_scroll_count.patch
+97e403723934bf634120e53b7d629ca87dbae73ed0a736cf2c15d4d3f7432792535a106fbf5eb959d3b1706a868d79bf24f450e24c9b2fe295df9443ef017504  13widechar_horrors.patch
+e5b1c0d7d7f96a2066f637f848564877920f163c715a1b2c4248298ed0b6a420fd3fe4e61c3925c48bd96168352cb3935b713abff8cb33d069362192f99047d7  14private_regex_fixes.patch
+eadc89e64b93043dfcf8493ff8a36bc7c2f147c313a958a68edbea577cef92d10f9f2262dbb464016e4008e232a6efdb83cc0b3469cdc75b49eab7419a9ef01e  15search_word.patch
+21ab846548101d58d1d9d2a93c6f309729dfdc3df33a0dd73bf55d30fc42314e4dabdeb605178a6bd256ecdab4f4331e3c156b1071c0bbf82046acb40434b7ce  16manpage_errors.patch
+2dfc294f98302afad67095c8376de4de3bd582f890151ba495d1c4212964c360a9fc2afc7d988be0715b4e5d498c99f228f01d516ad57435baf07993c21c13a1  17tutorial_typos.patch
+4d8999b235634fc040d45036624d880ed3c6be614cd52c7f642f8144d24726ad764a71e385445c6346f101f65febe3e609e9c9452744ee4cef5774f9048f0029  18dbpagesize_binpower.patch
+27be473dc1628c407963eb4c828caa8c41ad57abb75ddf9adefe7a065ce9f8cfe16536aabeb1f078f859fa7a8817ea8d5d2ca1cb36c47be27436a9789faeb504  19include_term_h.patch
+4065b814649cbbc57535941b4f20ceacc925b0ef6decfbaa5a60c6c4b943f2a5b6c68371fa87f8dce5b6c219740a10339948ffdce226c88509a807580e19864d  21exrc_writability_check.patch
+b0a4c9ba713d8fb8fa8559b6038bcb70d0fb6e411a3a73cf677c38d8288f28a2febfa92f387aef899ac3959fb7bdf5220334e025b71260157f935b0f79f01e66  24fallback_to_dumb_term.patch
+9a6a71574c3fb6073d3fdd0abf783f0053fbfb1ee8408e208c9368a72c3b25a5f56156da50bdd06ebf381210278c91036cca29333b48a0d5f432bbaa1d82bbd5  25manpage_note_dropped_F.patch
+89ae70a8a2dd4fbb51e1f6e570f958e7dc63e4f60076446f5f0ce063f4dac19d2d1c8da241b4a709ef028459e4b43c682f1a3021ef4f04a72be98b7e2c7b9fd1  26trailing_tab_segv.patch
+c091a870efc7181b3480998b8b8427cdec4b37ef66358ae8bfd2c79d6037c9b64fd6e004e39400680d1d67f608c35d56e7e36d91810ded04f984fe89a052925a  27support_C_locale.patch
+4c050c5d8ee298f88bc59fd7282739dfe9202610285ca64c59b579698667ac6c8940ecf91b2b3df34d31a8ee818b9c18b1a4f9a0b47894dd4c6f8bd20c9f1c75  29file_backup.patch"
Received on Mon Nov 30 2015 - 19:14:21 UTC