diff options
author | peter <peter@FreeBSD.org> | 2013-08-11 08:38:10 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2013-08-11 08:38:10 +0000 |
commit | 75700a8c067d4d910e2017f0aa29cbbca644f9cc (patch) | |
tree | fcfc8dee7b416cacdea763f18f34e0930234186a /docs/internals | |
parent | 3102470d94db36e49a2262542f69cc4219ae1aee (diff) | |
download | FreeBSD-src-75700a8c067d4d910e2017f0aa29cbbca644f9cc.zip FreeBSD-src-75700a8c067d4d910e2017f0aa29cbbca644f9cc.tar.gz |
Post-cvs2svn flatten pass.
Diffstat (limited to 'docs/internals')
-rw-r--r-- | docs/internals/autowrite | 88 | ||||
-rw-r--r-- | docs/internals/context | 32 | ||||
-rw-r--r-- | docs/internals/cscope.NOTES | 142 | ||||
-rw-r--r-- | docs/internals/gdb.script | 76 | ||||
-rw-r--r-- | docs/internals/input | 350 | ||||
-rw-r--r-- | docs/internals/openmode | 36 | ||||
-rw-r--r-- | docs/internals/quoting | 208 | ||||
-rw-r--r-- | docs/internals/structures | 68 |
8 files changed, 1000 insertions, 0 deletions
diff --git a/docs/internals/autowrite b/docs/internals/autowrite new file mode 100644 index 0000000..dbad6c8 --- /dev/null +++ b/docs/internals/autowrite @@ -0,0 +1,88 @@ +# @(#)autowrite 8.3 (Berkeley) 2/17/95 + +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/docs/internals/context b/docs/internals/context new file mode 100644 index 0000000..8b1db32 --- /dev/null +++ b/docs/internals/context @@ -0,0 +1,32 @@ +# @(#)context 8.6 (Berkeley) 10/14/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, v + +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/docs/internals/cscope.NOTES b/docs/internals/cscope.NOTES new file mode 100644 index 0000000..e0e3483 --- /dev/null +++ b/docs/internals/cscope.NOTES @@ -0,0 +1,142 @@ +Cscope Notes: + +The nvi tags structure has been reworked to handle the notion of multiple +locations per tag. This supports cscope, which returns multiple locations +per query. It will hopefully support ctags programs that create databases +with multiple locations per tag as well. + +There is now a list of "tag queues" chained from each screen. Each tag +queue has one or more "tag locations". + + +----+ +----+ +----+ +----+ + | EP | -> | Q1 | <-- | T1 | <-- | T2 | + +----+ +----+ --> +----+ --> +----+ + | + +----+ +----+ + | Q2 | <-- | T1 | + +----+ --> +----+ + | + +----+ +----+ + | Q3 | <-- | T1 | + +----+ --> +----+ + +In the above diagram, each "Q" is a "tag queue", and each "T" is a +tag location. Generally, the commands: + + :tag create a new Q + ^[ create a new Q + :cscope find create a new Q + :tagnext move to the next T + :tagprev move to the previous T + :tagpop discard one or more Q's + ^T discard the most recent Q + :tagtop discard all Q's + +More specifically: + +:cs[cope] a[dd] cscope-dir + + Attach to the cscope database in cscope-dir. + +:cs[cope] f[ind] c|d|e|f|g|i|s|t buffer|pattern + + Query all attached cscopes for the pattern. The pattern is a + regular expression. If the pattern is a double-quote character + followed by a valid buffer name (e.g., "t), then the contents + of the named buffer are used as the pattern. + + c: find callers of name + d: find all function calls made from name + e: find pattern + f: find files with name as substring + g: find definition of name + i: find files #including name + s: find all uses of name + t: find assignments to name + + The find command pushes the current location onto the tags stack, + and switches to the first location resulting from the query, if + the query returned at least one result. + +:cs[cope] h[elp] [command] + + List the cscope commands, or usage help on one command. + +:display c[onnections] + + Display the list of cscope connections + +:display t[ags] + + The tags display has been enhanced to display multiple tag + locations per tag query. + +:cs[cope] k[ill] # + + Kill cscope connection number #. + +:cs[cope] r[eset] + Kill all attached cscopes. Useful if one got hung but you don't + know which one. + +:tagn[ext][!] + + Move to the next tag resulting from a query. + +:tagpr[ev][!] + + Return to the previous tag resulting from a query. + +:tagp[op], ^T + + Return to the previous tag group (no change). + +:tagt[op] + + Discard all tag groups (no change). + +Suggested maps: + + " ^N: move to the next tag + map ^N :tagnext^M + " ^P: move to the previous tag + map ^P :tagprev^M + + " Tab+letter performs a C-Scope query on the current word. + " C-Scope 12.9 has a text-string query (type t). + " C-Scope 13.3 replaces it with an assignment query; hence a==t. + map <tab>a "tye:csc find t"t
+ map <tab>c "tye:csc find c"t
+ map <tab>d "tye:csc find d"t
+ map <tab>e "tye:csc find e"t
+ map <tab>f "tye:csc find f"t
+ map <tab>g "tye:csc find g"t
+ map <tab>i "tye:csc find i"t
+ map <tab>s "tye:csc find s"t
+ map <tab>t "tye:csc find t"t
+ +To start nvi with an initial set of cscope directories, use the environment +variable CSCOPE_DIRS. This variable should contain a <blank>-separated +list of directories containing cscope databases. (This MAY be changed to +be an edit option, I haven't really decided, yet.) + +Each cscope directory must contain a file named "cscope.out" which is the +main cscope database, or nvi will not attempt to connect to a cscope to +handle requests for that database. + +The file "cscope.tpath" may contain a colon-separated directory search +path which will be used to find the files reported by cscope. If this +cscope.tpath does not exist, then the paths are assumed to be relative to +the cscope directory itself. This is an extension to the standard cscope, +but seems important enough to keep. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +Cscope Availability: + +UNIXWare System V Release 4.0 variants such as Sun Solaris 2.x +(/opt/SUNWspro/bin) have version 11.5, and UNIXWare System V +Release 4.1 has version 12.10 with an option for much faster +searching. + +You can buy version 13.3 source with an unrestricted license +for $400 from AT&T Software Solutions by calling +1-800-462-8146. diff --git a/docs/internals/gdb.script b/docs/internals/gdb.script new file mode 100644 index 0000000..a112234 --- /dev/null +++ b/docs/internals/gdb.script @@ -0,0 +1,76 @@ +# @(#)gdb.script 8.5 (Berkeley) 5/4/96 + +# display the VI screen map +# usage dmap(sp) +define dmap + set $h = ((VI_PRIVATE *)$arg0->vi_private)->h_smap + set $t = ((VI_PRIVATE *)$arg0->vi_private)->t_smap + while ($h <= $t) + printf "lno: %2d; soff %d coff %d ", \ + (int)$h->lno, (int)$h->soff, (int)$h->coff + 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 VI screen map +define tmap + set $h = ((VI_PRIVATE *)$arg0->vi_private)->h_smap + set $t = ((VI_PRIVATE *)$arg0->vi_private)->t_smap + while ($t >= $h) + printf "lno: %2d; soff %d coff %d ", \ + (int)$t->lno, (int)$t->soff, (int)$t->coff + 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 clp + print *((CL_PRIVATE *)sp->gp->cl_private) +end +define vip + print *((VI_PRIVATE *)sp->vi_private) +end +define exp + print *((EX_PRIVATE *)sp->ex_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/docs/internals/input b/docs/internals/input new file mode 100644 index 0000000..9a7506e --- /dev/null +++ b/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/docs/internals/openmode b/docs/internals/openmode new file mode 100644 index 0000000..c64b767 --- /dev/null +++ b/docs/internals/openmode @@ -0,0 +1,36 @@ + @(#)openmode 8.1 (Berkeley) 10/29/94 + +Open mode has the following special behaviors: + +z, ^F, ^B: + If count is not specified, it shall default to the window + edit option - 2. + + Write lines from the edit buffer starting at: + + (the current line) - ((count - 2) / 2) + + until: + + (((count + 1) / 2) * 2) - 1 + + lines, or the last line in the edit buffer has been written. A + line consisting of the smaller of the number of columns in the + display divided by two or 40 ``-'' characters shall be written + immediately before and after the specified is written. These two + lines shall count against the total number of lines to be written. + A blank line shall be written after the last line is written. + + z, ^F and ^B all behave identically. + +^D: Display the next scroll value lines, change the current line. + +^U: Change the current line, do nothing else. + +^E, ^Y: Do nothing. + +^L: Clear the screen and redisplay the current line. + +H, L, M: + Move to the first nonblank of the current line and do nothing + else. diff --git a/docs/internals/quoting b/docs/internals/quoting new file mode 100644 index 0000000..a5fb892 --- /dev/null +++ b/docs/internals/quoting @@ -0,0 +1,208 @@ +# @(#)quoting 5.5 (Berkeley) 11/12/94 + +QUOTING IN EX/VI: + +There are four escape characters in historic ex/vi: + + \ (backslashes) + ^V + ^Q (assuming it wasn't used for IXON/IXOFF) + The terminal literal next character. + +Vi did not use the lnext character, it always used ^V (or ^Q). +^V and ^Q were equivalent in all cases for vi. + +There are four different areas in ex/vi where escaping characters +is interesting: + + 1: In vi text input mode. + 2: In vi command mode. + 3: In ex command and text input modes. + 4: In the ex commands themselves. + +1: Vi text input mode (a, i, o, :colon commands, etc.): + + The set of characters that users might want to escape are as follows. + As ^L and ^Z were not special in input mode, they are not listed. + + carriage return (^M) + escape (^[) + autoindents (^D, 0, ^, ^T) + erase (^H) + word erase (^W) + line erase (^U) + newline (^J) (not historic practice) + + Historic practice was that ^V was the only way to escape any + of these characters, and that whatever character followed + the ^V was taken literally, e.g. ^V^V is a single ^V. I + don't see any strong reason to make it possible to escape + ^J, so I'm going to leave that alone. + + 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. + + Abbreviations were not performed if the non-word character + that triggered the abbreviation was escaped by a ^V. Input + maps were not triggered if any part of the map was escaped + by a ^V. + + The historic vi implementation for the 'r' command requires + two leading ^V's to replace a character with a literal + character. This is obviously a bug, and should be fixed. + +2: Vi command mode + + Command maps were not triggered if the second or later + character of a map was escaped by a ^V. + + The obvious extension is that ^V should keep the next command + character from being mapped, so you can do ":map x xxx" and + then enter ^Vx to delete a single character. + +3: Ex command and text input modes. + + As ex ran in canonical mode, there was little work that it + needed to do for quoting. The notable differences between + ex and vi are that it was possible to escape a <newline> in + the ex command and text input modes, and ex used the "literal + next" character, not control-V/control-Q. + +4: The ex commands: + + Ex commands are delimited by '|' or newline characters. + Within the commands, whitespace characters delimit the + arguments. Backslash will generally escape any following + character. In the abbreviate, unabbreviate, map and unmap + commands, control-V escapes the next character, instead. + + This is historic behavior in vi, although there are special + cases where it's impossible to escape a character, generally + a whitespace character. + + 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) + + Since file names are also subject to word expansion, the + underlying shell had better be doing the correct backslash + escaping. This is NOT historic behavior in vi, making it + impossible to insert a whitespace, newline or carriage return + character into a file name. + +4: Escaping characters in non-file arguments in ex commands: + + :abbreviate word string (word, string) +* :edit [+cmd] [file] (+cmd) +* :ex [+cmd] [file] (+cmd) + :map word string (word, string) +* :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/docs/internals/structures b/docs/internals/structures new file mode 100644 index 0000000..a25c780 --- /dev/null +++ b/docs/internals/structures @@ -0,0 +1,68 @@ +# @(#)structures 5.4 (Berkeley) 10/4/95 + +There are three major data structures in this package, plus a single data +structure per screen type. The first is a single global structure (GS) +which contains information common to all files and screens. It hold +global things like the input key queues, and functions as a single place +to hang things. For example, interrupt routines have to be able to find +screen structures, and they can only do this if they have a starting +point. The number of globals in nvi is dependent on the screen type, but +every screen type will have at least one global, __global_list, which +references the GS structure. + +The GS structure contains linked lists of screen (SCR) structures. +Each SCR structure normally references a file (EXF) structure. + +The GS 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 never goes away. The SCR structure persists over +instances of screens, and the EXF structure persists over references to +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, which usually +references an underlying EXF structure. 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 various ex commands will substitute a new EXF in place of the current +one, and there's no way to detect this. + +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. + +CL The curses screen private data structure. Everything to + do standalone curses screens. + +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. + +TK The Tcl/Tk screen private data structure. Everything to + do standalone Tcl/Tk screens. + +EXCMD In nvi/ex/ex.h. 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.) + +VICMD In nvi/vi/vi.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.) |