summaryrefslogtreecommitdiff
path: root/usr.bin/vi/docs/internals
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-10-18 08:53:40 +0000
commitd6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch)
treeece253b876159b39c620e62b6c9b1174642e070e /usr.bin/vi/docs/internals
initial import of NetBSD tree
Diffstat (limited to 'usr.bin/vi/docs/internals')
-rw-r--r--usr.bin/vi/docs/internals/autowrite88
-rw-r--r--usr.bin/vi/docs/internals/context32
-rw-r--r--usr.bin/vi/docs/internals/gdb.script77
-rw-r--r--usr.bin/vi/docs/internals/input350
-rw-r--r--usr.bin/vi/docs/internals/quoting219
-rw-r--r--usr.bin/vi/docs/internals/structures61
6 files changed, 827 insertions, 0 deletions
diff --git a/usr.bin/vi/docs/internals/autowrite b/usr.bin/vi/docs/internals/autowrite
new file mode 100644
index 00000000000..55cd13b8f72
--- /dev/null
+++ b/usr.bin/vi/docs/internals/autowrite
@@ -0,0 +1,88 @@
+# @(#)autowrite 8.2 (Berkeley) 9/28/93
+
+Vi autowrite behavior, the fields with *'s are "don't cares".
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+Commands that are affected only by autowrite:
+
+Command File Autowrite? Action:
+ modified?
+-----------------------------------------------
+^Z Y Y Write file and suspend.
+^Z Y N Suspend.
+^Z N * Suspend.
+
+# This behavior is NOT identical to :edit.
+^ Y Y Write file and jump.
+^ Y N Error.
+^ N * Jump.
+
+# The new nvi command ^T (:tagpop) behaves identically to ^].
+# This behavior is identical to :tag, :tagpop, and :tagpush with
+# force always set to N.
+^] Y Y Write file and jump.
+^] Y N Error.
+^] N * Jump.
+
+# There's no way to specify a force flag to the '!' command.
+:! Y Y Write file and execute.
+:! Y N Warn (if warn option) and execute.
+:! N * Execute.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+Commands that are affected by both autowrite and force:
+
+NOTE: the "force" flag is never passed on, i.e. the write
+to the file caused by the autowrite flag is never forced.
+
+Command File Autowrite? Force? Action:
+ modified? (!)
+-------------------------------------------------------
+# The first rule (YYY) is historic practice, but seems wrong.
+# In nvi, :next and :prev commands behave identically to :rewind.
+:next Y Y Y Write changes and jump.
+:next Y Y N Write changes and jump.
+:next Y N Y Abandon changes and jump.
+:next Y N N Error.
+:next N * * Jump.
+
+:rewind Y Y Y Abandon changes and jump.
+:rewind Y Y N Write changes and jump.
+:rewind Y N Y Abandon changes and jump.
+:rewind Y N N Error.
+:rewind N * * Jump.
+
+# The new nvi commands, :tagpop and :tagtop, behave identically to :tag.
+# Note, this behavior is the same as :rewind and friends, as well.
+:tag Y Y Y Abandon changes and jump.
+:tag Y Y N Write changes and jump.
+:tag Y N Y Abandon changes and jump.
+:tag Y N N Error.
+:tag N * * Jump.
+
+# The command :suspend behaves identically to :stop.
+:stop Y Y Y Suspend.
+:stop Y Y N Write changes and suspend.
+:stop Y N Y Suspend.
+:stop Y N N Suspend.
+:stop N * * Suspend.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+Commands that might be affected by autowrite, but aren't:
+
+Command File Autowrite? Force? Action:
+ modified? (!)
+-------------------------------------------------------
+#:ex, and :vi (executed while in vi mode) behave identically to :edit.
+:edit Y * Y Abandon changes and jump.
+:edit Y * N Error.
+:edit N * * Jump.
+
+:quit Y * Y Quit.
+:quit Y * N Error.
+:quit N * * Quit.
+
+:shell * * * Execute shell.
+
+:xit Y * * Write changes and exit.
+:xit N * * Exit.
diff --git a/usr.bin/vi/docs/internals/context b/usr.bin/vi/docs/internals/context
new file mode 100644
index 00000000000..139a1c3fdb4
--- /dev/null
+++ b/usr.bin/vi/docs/internals/context
@@ -0,0 +1,32 @@
+# @(#)context 8.5 (Berkeley) 7/23/94
+
+In historic vi, the previous context mark was always set:
+
+ex address:
+ any number, <question-mark>, <slash>, <dollar-sign>,
+ <single-quote>, <backslash>
+
+ex commands: undo, "z.", global, vglobal
+
+vi commands: (, ), {, }, %, [[, ]], ^]
+
+nvi adds the vi command ^T to this list.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+In historic vi, the previous context mark was set if the
+line changed:
+
+vi commands: '<mark>, G, H, L, M, z
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+In historic vi, the previous context mark was set if the
+line or column changed:
+
+vi commands: `<mark>, /, ?, N, n
+
+nvi adds the vi command ^A to this list.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+In historic vi, the previous context mark was set in non-visual
+mode for ^R and ^L if the line changed, but I have yet to figure
+out how the line could change.
diff --git a/usr.bin/vi/docs/internals/gdb.script b/usr.bin/vi/docs/internals/gdb.script
new file mode 100644
index 00000000000..c875bf73a01
--- /dev/null
+++ b/usr.bin/vi/docs/internals/gdb.script
@@ -0,0 +1,77 @@
+# @(#)gdb.script 8.3 (Berkeley) 8/16/94
+
+# display the SVI screen map
+# usage dmap(sp)
+define dmap
+ set $h = ((SVI_PRIVATE *)$arg0->svi_private)->h_smap
+ set $t = ((SVI_PRIVATE *)$arg0->svi_private)->t_smap
+ while ($h <= $t)
+ printf "lno: %d; off %d ", (int)$h->lno, (int)$h->off
+ if ($h->c_ecsize == 0)
+ printf "flushed\n"
+ else
+ printf "\n\tsboff %d; scoff %d\n", \
+ (int)$h->c_sboff, (int)$h->c_scoff
+ printf "\teboff %d; eclen %d; ecsize %d\n", \
+ (int)$h->c_eboff, (int)$h->c_eclen, \
+ (int)$h->c_ecsize
+ end
+ set $h = $h + 1
+ end
+end
+
+# display the tail of the SVI screen map
+define tmap
+ set $h = ((SVI_PRIVATE *)$arg0->svi_private)->h_smap
+ set $t = ((SVI_PRIVATE *)$arg0->svi_private)->t_smap
+ while ($t >= $h)
+ printf "lno: %d; off %d ", (int)$t->lno, (int)$t->off
+ if ($t->c_ecsize == 0)
+ printf "flushed\n"
+ else
+ printf "\n\tsboff %d; scoff %d\n", \
+ (int)$t->c_sboff, (int)$t->c_scoff
+ printf "\teboff %d; eclen %d; ecsize %d\n", \
+ (int)$t->c_eboff, (int)$t->c_eclen, \
+ (int)$t->c_ecsize
+ end
+ set $t = $t - 1
+ end
+end
+
+# display the private structures
+define vip
+ print *((VI_PRIVATE *)sp->vi_private)
+end
+define svp
+ print *((SVI_PRIVATE *)sp->svi_private)
+end
+define exp
+ print *((EX_PRIVATE *)sp->ex_private)
+end
+define sxp
+ print *((SEX_PRIVATE *)sp->sex_private)
+end
+
+# display the marks
+define markp
+ set $h = sp->ep->marks.next
+ set $t = &sp->ep->marks
+ while ($h != 0 && $h != $t)
+ printf "key %c lno: %d cno: %d flags: %x\n", \
+ ((MARK *)$h)->name, ((MARK *)$h)->lno, \
+ ((MARK *)$h)->cno, ((MARK *)$h)->flags
+ set $h = ((MARK *)$h)->next
+ end
+end
+
+# display the tags
+define tagp
+ set $h = sp->taghdr.next
+ set $t = &sp->taghdr
+ while ($h != 0 && $h != $t)
+ printf "tag: %s lno %d cno %d\n", ((TAG *)$h)->frp->fname, \
+ ((TAG *)$h)->lno, ((TAG *)$h)->cno
+ set $h= ((TAG *)$h)->next
+ end
+end
diff --git a/usr.bin/vi/docs/internals/input b/usr.bin/vi/docs/internals/input
new file mode 100644
index 00000000000..9a7506ee233
--- /dev/null
+++ b/usr.bin/vi/docs/internals/input
@@ -0,0 +1,350 @@
+# @(#)input 5.5 (Berkeley) 7/2/94
+
+MAPS, EXECUTABLE BUFFERS AND INPUT IN EX/VI:
+
+The basic rule is that input in ex/vi is a stack. Every time a key which
+gets expanded is encountered, it is expanded and the expansion is treated
+as if it were input from the user. So, maps and executable buffers are
+simply pushed onto the stack from which keys are returned. The exception
+is that if the "remap" option is turned off, only a single map expansion
+is done. I intend to be fully backward compatible with this.
+
+Historically, if the mode of the editor changed (ex to vi or vice versa),
+any queued input was silently discarded. I don't see any reason to either
+support or not support this semantic. I intend to retain the queued input,
+mostly because it's simpler than throwing it away.
+
+Historically, neither the initial command on the command line (the + flag)
+or the +cmd associated with the ex and edit commands was subject to mapping.
+Also, while the +cmd appears to be subject to "@buffer" expansion, once
+expanded it doesn't appear to work correctly. I don't see any reason to
+either support or not support these semantics, so, for consistency, I intend
+to pass both the initial command and the command associated with ex and edit
+commands through the standard mapping and @ buffer expansion.
+
+One other difference between the historic ex/vi and nex/nvi is that nex
+displays the executed buffers as it executes them. This means that if
+the file is:
+
+ set term=xterm
+ set term=yterm
+ set term=yterm
+
+the user will see the following during a typical edit session:
+
+ nex testfile
+ testfile: unmodified: line 3
+ :1,$yank a
+ :@a
+ :set term=zterm
+ :set term=yterm
+ :set term=xterm
+ :q!
+
+This seems like a feature and unlikely to break anything, so I don't
+intend to match historic practice in this area.
+
+The rest of this document is a set of conclusions as to how I believe
+the historic maps and @ buffers work. The summary is as follows:
+
+1: For buffers that are cut in "line mode", or buffers that are not cut
+ in line mode but which contain portions of more than a single line, a
+ trailing <newline> character appears in the input for each line in the
+ buffer when it is executed. For buffers not cut in line mode and which
+ contain portions of only a single line, no additional characters
+ appear in the input.
+2: Executable buffers that execute other buffers don't load their
+ contents until they execute them.
+3: Maps and executable buffers are copied when they are executed --
+ they can be modified by the command but that does not change their
+ actions.
+4: Historically, executable buffers are discarded if the editor
+ switches between ex and vi modes.
+5: Executable buffers inside of map commands are expanded normally.
+ Maps inside of executable buffers are expanded normally.
+6: If an error is encountered while executing a mapped command or buffer,
+ the rest of the mapped command/buffer is discarded. No user input
+ characters are discarded.
+7: Characters in executable buffers are remapped.
+8: Characters in executable buffers are not quoted.
+
+Individual test cases follow. Note, in the test cases, control characters
+are not literal and will have to be replaced to make the test cases work.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+1: For buffers that are cut in "line mode", or buffers that are not cut
+ in line mode but which contain portions of more than a single line, a
+ trailing <newline> character appears in the input for each line in the
+ buffer when it is executed. For buffers not cut in line mode and which
+ contain portions of only a single line, no additional characters
+ appear in the input.
+
+=== test file ===
+3Gw
+w
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+=== end test file ===
+
+ If the first line is loaded into 'a' and executed:
+
+1G"ayy@a
+
+ The cursor ends up on the '2', a result of pushing "3Gw^J" onto
+ the stack.
+
+ If the first two lines are loaded into 'a' and executed:
+
+1G2"ayy@a
+
+ The cursor ends up on the 'f' in "foo" in the fifth line of the
+ file, a result of pushing "3Gw^Jw^J" onto the stack.
+
+ If the first line is loaded into 'a', but not using line mode,
+ and executed:
+
+1G"ay$@a
+
+ The cursor ends up on the '1', a result of pushing "3Gw" onto
+ the stack
+
+ If the first two lines are loaded into 'a', but not using line mode,
+ and executed:
+
+1G2"ay$@a
+
+ The cursor ends up on the 'f' in "foo" in the fifth line of the
+ file, a result of pushing "3Gw^Jw^J" onto the stack.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+2: Executable buffers that execute other buffers don't load their
+ contents until they execute them.
+
+=== test file ===
+cwLOAD B^[
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+@a@b
+"byy
+=== end test file ===
+
+ The command is loaded into 'e', and then executed. 'e' executes
+ 'a', which loads 'b', then 'e' executes 'b'.
+
+5G"eyy6G"ayy1G@e
+
+ The output should be:
+
+=== output file ===
+cwLOAD B^[
+LOAD B 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+@a@b
+"byy
+=== end output file ===
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+3: Maps and executable buffers are copied when they are executed --
+ they can be modified by the command but that does not change their
+ actions.
+
+ Executable buffers:
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+@a@b
+"eyy
+cwEXECUTE B^[
+=== end test file ===
+
+4G"eyy5G"ayy6G"byy1G@eG"ep
+
+ The command is loaded into 'e', and then executed. 'e' executes
+ 'a', which loads 'e', then 'e' executes 'b' anyway.
+
+ The output should be:
+
+=== output file ===
+line 1 foo bar baz
+EXECUTE B 2 foo bar baz
+line 3 foo bar baz
+@a@b
+"eyy
+cwEXECUTE B^[
+line 1 foo bar baz
+=== end output file ===
+
+ Maps:
+
+=== test file ===
+Cine 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+=== end test file ===
+
+ Entering the command ':map = :map = rB^V^MrA^M1G==' shows that
+ the first time the '=' is entered the '=' map is set and the
+ character is changed to 'A', the second time the character is
+ changed to 'B'.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+4: Historically, executable buffers are discarded if the editor
+ switches between ex and vi modes.
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+cwCHANGE^[Q:set
+set|visual|1Gwww
+=== end test file ===
+
+vi testfile
+4G"ayy@a
+
+ex testfile
+$p
+yank a
+@a
+
+ In vi, the command is loaded into 'a' and then executed. The command
+ subsequent to the 'Q' is (historically, silently) discarded.
+
+ In ex, the command is loaded into 'a' and then executed. The command
+ subsequent to the 'visual' is (historically, silently) discarded. The
+ first set command is output by ex, although refreshing the screen usually
+ causes it not to be seen.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+5: Executable buffers inside of map commands are expanded normally.
+ Maps inside of executable buffers are expanded normally.
+
+ Buffers inside of map commands:
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+cwREPLACE BY A^[
+=== end test file ===
+
+4G"ay$:map x @a
+1Gx
+
+ The output should be:
+
+=== output file ===
+REPLACE BY A 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+cwREPLACE BY A^[
+=== end output file ===
+
+ Maps commands inside of executable buffers:
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+X
+=== end test file ===
+
+:map X cwREPLACE BY XMAP^[
+4G"ay$1G@a
+
+ The output should be:
+
+=== output file ===
+REPLACE BY XMAP 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+X
+=== end output file ===
+
+ Here's a test that does both, repeatedly.
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+X
+Y
+cwREPLACED BY C^[
+blank line
+=== end test file ===
+
+:map x @a
+4G"ay$
+:map X @b
+5G"by$
+:map Y @c
+6G"cy$
+1Gx
+
+ The output should be:
+
+=== output file ===
+REPLACED BY C 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+X
+Y
+cwREPLACED BY C^[
+blank line
+=== end output file ===
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+6: If an error is encountered while executing a mapped command or
+ a buffer, the rest of the mapped command/buffer is discarded. No
+ user input characters are discarded.
+
+=== test file ===
+line 1 foo bar baz
+line 2 foo bar baz
+line 3 foo bar baz
+:map = 10GcwREPLACMENT^V^[^[
+=== end test file ===
+
+ The above mapping fails, however, if the 10G is changed to 1, 2,
+ or 3G, it will succeed.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+7: Characters in executable buffers are remapped.
+
+=== test file ===
+abcdefghijklmnnop
+ggg
+=== end test file ===
+
+:map g x
+2G"ay$1G@a
+
+ The output should be:
+
+=== output file ===
+defghijklmnnop
+ggg
+=== end output file ===
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+8: Characters in executable buffers are not quoted.
+
+=== test file ===
+iFOO^[
+
+=== end test file ===
+
+1G"ay$2G@a
+
+ The output should be:
+
+=== output file ===
+iFOO^[
+FOO
+=== end output file ===
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
diff --git a/usr.bin/vi/docs/internals/quoting b/usr.bin/vi/docs/internals/quoting
new file mode 100644
index 00000000000..f20bd3f2b1e
--- /dev/null
+++ b/usr.bin/vi/docs/internals/quoting
@@ -0,0 +1,219 @@
+# @(#)quoting 5.4 (Berkeley) 8/20/93
+
+QUOTING IN EX/VI:
+
+There are two escape characters in historic ex/vi, ^V (or whatever
+character the user specified as their literal next character) and
+backslashes. There are two different areas in ex/vi where escaping
+is interesting: the command and text input modes, and within the ex
+commands themselves. In the examples below, ^V is used as the
+typical literal next character.
+
+1: Escaping characters in ex and vi command and text input modes.
+ The set of characters that users might want to escape are as
+ follows:
+
+ vi text input mode (a, i, o, etc.):
+
+ carriage return (^M)
+ escape (^[)
+ autoindent characters
+ (^D, 0, ^, ^T)
+ erase, word erase, and line erase
+ (^H, ^W, ^U)
+ newline (^J) (not historic practice)
+ suspend (^Z) (not historic practice)
+ repaint (^L) (not historic practice)
+
+ vi command line (:colon commands):
+
+ carriage return (^M)
+ escape (^[)
+ erase, word erase, and line erase
+ (^H, ^W, ^U)
+ newline (^J) (not historic practice)
+ suspend (^Z) (not historic practice)
+ repaint (^L) (not historic practice)
+
+ ex text input mode (a, i, o, etc.):
+
+ carriage return (^M)
+ erase, word erase, and line erase
+ (^H, ^W, ^U)
+ newline (^J) (not historic practice)
+
+ ex command line:
+
+ carriage return (^M)
+ erase, word erase, and line erase
+ (^H, ^W, ^U)
+ newline (^J) (not historic practice)
+ suspend (^Z)
+
+ I intend to follow historic practice for all of these cases, which
+ was that ^V was the only way to escape any of these characters, and
+ that whatever character followed the ^V was taken literally, i.e.
+ ^V^V is a single ^V.
+
+ The historic ex/vi disallowed the insertion of various control
+ characters (^D, ^T, whatever) during various different modes, or,
+ permitted the insertion of only a single one, or lots of other random
+ behaviors (you can use ^D to enter a command in ex). I have
+ regularized this behavior in nvi, there are no characters that cannot
+ be entered or which have special meaning other than the ones listed
+ above.
+
+ One comment regarding the autoindent characters. In historic vi,
+ if you entered "^V0^D" autoindent erasure was still triggered,
+ although it wasn't if you entered "0^V^D". In nvi, if you escape
+ either character, autoindent erasure is not triggered.
+
+ This doesn't permit whitespace in command names, but that wasn't
+ historic practice and doesn't seem worth doing.
+
+ Fun facts to know and tell:
+ The historic vi implementation for the 'r' command requires
+ *three* ^V's to replace a single character with ^V.
+
+2: Ex commands:
+
+ Ex commands are delimited by '|' or newline characters. Within
+ the commands, whitespace characters delimit the arguments.
+
+ I intend to treat ^V, followed by any character, as that literal
+ character.
+
+ This is historic behavior in vi, although there are special
+ cases where it's impossible to escape a character, generally
+ a whitespace character.
+
+3: Escaping characters in file names in ex commands:
+
+ :cd [directory] (directory)
+ :chdir [directory] (directory)
+ :edit [+cmd] [file] (file)
+ :ex [+cmd] [file] (file)
+ :file [file] (file)
+ :next [file ...] (file ...)
+ :read [!cmd | file] (file)
+ :source [file] (file)
+ :write [!cmd | file] (file)
+ :wq [file] (file)
+ :xit [file] (file)
+
+ I intend to treat a backslash in a file name, followed by any
+ character, as that literal character.
+
+ This is historic behavior in vi.
+
+ In addition, since file names are also subject to word expansion,
+ the rules for escape characters in section 3 of this document also
+ apply. This is NOT historic behavior in vi, making it impossible
+ to insert a whitespace, newline or carriage return character into
+ a file name. This change could cause a problem if there were files
+ with ^V's in their names, but I think that's unlikely.
+
+4: Escaping characters in non-file arguments in ex commands:
+
+ :abbreviate word string (word, string)
+* :edit [+cmd] [file] (+cmd)
+* :ex [+cmd] [file] (+cmd)
+ :k key (key)
+ :map word string (word, string)
+ :mark key (key)
+* :set [option ...] (option)
+* :tag string (string)
+ :unabbreviate word (word)
+ :unmap word (word)
+
+ These commands use whitespace to delimit their arguments, and use
+ ^V to escape those characters. The exceptions are starred in the
+ above list, and are discussed below.
+
+ In general, I intend to treat a ^V in any argument, followed by
+ any character, as that literal character. This will permit
+ editing of files name "foo|", for example, by using the string
+ "foo\^V|", where the literal next character protects the pipe
+ from the ex command parser and the backslash protects it from the
+ shell expansion.
+
+ This is backward compatible with historical vi, although there
+ were a number of special cases where vi wasn't consistent.
+
+4.1: The edit/ex commands:
+
+ The edit/ex commands are a special case because | symbols may
+ occur in the "+cmd" field, for example:
+
+ :edit +10|s/abc/ABC/ file.c
+
+ In addition, the edit and ex commands have historically ignored
+ literal next characters in the +cmd string, so that the following
+ command won't work.
+
+ :edit +10|s/X/^V / file.c
+
+ I intend to handle the literal next character in edit/ex consistently
+ with how it is handled in other commands.
+
+ More fun facts to know and tell:
+ The acid test for the ex/edit commands:
+
+ date > file1; date > file2
+ vi
+ :edit +1|s/./XXX/|w file1| e file2|1 | s/./XXX/|wq
+
+ No version of vi, of which I'm aware, handles it.
+
+4.2: The set command:
+
+ The set command treats ^V's as literal characters, so the following
+ command won't work. Backslashes do work in this case, though, so
+ the second version of the command does work.
+
+ set tags=tags_file1^V tags_file2
+ set tags=tags_file1\ tags_file2
+
+ I intend to continue permitting backslashes in set commands, but
+ to also permit literal next characters to work as well. This is
+ backward compatible, but will also make set consistent with the
+ other commands. I think it's unlikely to break any historic
+ .exrc's, given that there are probably very few files with ^V's
+ in their name.
+
+4.3: The tag command:
+
+ The tag command ignores ^V's and backslashes; there's no way to
+ get a space into a tag name.
+
+ I think this is a don't care, and I don't intend to fix it.
+
+5: Regular expressions:
+
+ :global /pattern/ command
+ :substitute /pattern/replace/
+ :vglobal /pattern/ command
+
+ I intend to treat a backslash in the pattern, followed by the
+ delimiter character or a backslash, as that literal character.
+
+ This is historic behavior in vi. It would get rid of a fairly
+ hard-to-explain special case if we could just use the character
+ immediately following the backslash in all cases, or, if we
+ changed nvi to permit using the literal next character as a
+ pattern escape character, but that would probably break historic
+ scripts.
+
+ There is an additional escaping issue for regular expressions.
+ Within the pattern and replacement, the '|' character did not
+ delimit ex commands. For example, the following is legal.
+
+ :substitute /|/PIPE/|s/P/XXX/
+
+ This is a special case that I will support.
+
+6: Ending anything with an escape character:
+
+ In all of the above rules, an escape character (either ^V or a
+ backslash) at the end of an argument or file name is not handled
+ specially, but used as a literal character.
diff --git a/usr.bin/vi/docs/internals/structures b/usr.bin/vi/docs/internals/structures
new file mode 100644
index 00000000000..d49ab65cbee
--- /dev/null
+++ b/usr.bin/vi/docs/internals/structures
@@ -0,0 +1,61 @@
+# @(#)structures 5.2 (Berkeley) 11/1/93
+
+There are three major data structures in this package. The first is a
+single global structure (named GS) which contains information common to
+all files and screens. It's really pretty tiny, and functions more as a
+single place to hang things than anything else.
+
+The second and third structures are the file structures (named EXF) and
+the screen structures (named SCR). They contain information theoretically
+unique to a screen or file, respectively. Each SCR structure has a set
+of functions which update the screen and/or return information about the
+screen from the underlying screen package.
+
+The GS structure contains linked lists SCR structures. The structures
+can also be classed by persistence. The GS structure never goes away
+and the SCR structure persists over instances of files.
+
+File names have different properties than files themselves, so the name
+information for a file is held in an FREF structure which is chained from
+the SCR structure.
+
+In general, functions are always passed an SCR structure and often an EXF
+structure as well. The SCR structure is necessary for any routine that
+wishes to talk to the screen, the EXF structure is necessary for any
+routine that wants to modify the file. The relationship between an SCR
+structure and its underlying EXF structure is not fixed, and although you
+can translate from an SCR to the underlying EXF, it is discouraged. If
+this becomes too onerous, I suspect I'll just stop passing around the EXF
+in the future.
+
+The naming of the structures is consistent across the program. (Macros
+even depend on it, so don't try and change it!) The global structure is
+"gp", the screen structure is "sp", and the file structure is "ep".
+
+A few other data structures:
+
+TEXT In nvi/cut.h. This structure describes a portion of a line,
+ and is used by the input routines and as the "line" part of a
+ cut buffer.
+
+CB In nvi/cut.h. A cut buffer. A cut buffer is a place to
+ hang a list of TEXT structures.
+
+MARK In nvi/mark.h. A cursor position, consisting of a line number
+ and a column number.
+
+MSG In nvi/msg.h. A chain of messages for the user.
+
+SEQ In nvi/seq.h. An abbreviation or a map entry.
+
+EXCMDARG
+ In nvi/ex/excmd.h.stub. The structure that gets passed around
+ to the functions that implement the ex commands. (The main
+ ex command loop (see nvi/ex/ex.c) builds this up and then passes
+ it to the ex functions.)
+
+VICMDARG
+ In nvi/vi/vcmd.h. The structure that gets passed around to the
+ functions that implement the vi commands. (The main vi command
+ loop (see nvi/vi/vi.c) builds this up and then passes it to the
+ vi functions.)