diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /usr.bin/vi/docs |
initial import of NetBSD tree
Diffstat (limited to 'usr.bin/vi/docs')
-rw-r--r-- | usr.bin/vi/docs/README | 200 | ||||
-rw-r--r-- | usr.bin/vi/docs/bugs.current | 44 | ||||
-rw-r--r-- | usr.bin/vi/docs/changelog | 528 | ||||
-rw-r--r-- | usr.bin/vi/docs/ev | 55 | ||||
-rw-r--r-- | usr.bin/vi/docs/features | 87 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/autowrite | 88 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/context | 32 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/gdb.script | 77 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/input | 350 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/quoting | 219 | ||||
-rw-r--r-- | usr.bin/vi/docs/internals/structures | 61 | ||||
-rw-r--r-- | usr.bin/vi/docs/tutorial/vi.advanced | 1458 | ||||
-rw-r--r-- | usr.bin/vi/docs/tutorial/vi.beginner | 741 | ||||
-rw-r--r-- | usr.bin/vi/docs/tutorial/vi.tut.csh | 24 |
14 files changed, 3964 insertions, 0 deletions
diff --git a/usr.bin/vi/docs/README b/usr.bin/vi/docs/README new file mode 100644 index 00000000000..0fe3a12fd3b --- /dev/null +++ b/usr.bin/vi/docs/README @@ -0,0 +1,200 @@ +# @(#)README 8.86 (Berkeley) 8/17/94 + +This is the README for version 1.34 of nex/nvi, a freely redistributable +replacement for the Berkeley ex and vi text editors. The compressed or +gzip'd archives for this and future versions, can be retrieved by using +anonymous ftp to ftp.cs.berkeley.edu, from the file ucb/4bsd/nvi.tar.Z, +or ucb/4bsd/nvi.tar.gz. + +If you have any questions about nvi, or problems making it work, please +contact me by electronic mail at one of the following addresses: + + uunet!bostic + bostic@cs.berkeley.edu + +Keith Bostic + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +o Redistribution: + +This software is copyrighted by the The Regents of the University of +California, but may be freely redistributed (or sold, or used to line +your birdcage) under the following conditions: + +/*- + * Copyright (c) 1991, 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +o Credit where it's due: + + This software was originally derived from software contributed + to the University of California, Berkeley by Steve Kirkendall, + the author of the vi clone elvis. Without his work, this work + would have been far more difficult. + + POSIX 1003.2 style regular expression support is courtesy of + Henry Spencer, for which I am *very* grateful. + + The curses library was originally done by Ken Arnold. Scrolling + and general reworking for 4.4BSD was done by Elan Amir. + +o From the original vi acknowledgements, by William Joy and Mark Horton: + + Bruce Englar encouraged the early development of this display + editor. Peter Kessler helped bring sanity to version 2's + command layout. Bill Joy wrote versions 1 and 2.0 through 2.7, + and created the framework that users see in the present editor. + Mark Horton added macros and other features and made the editor + work on a large number of terminals and Unix systems. + +o And... + The financial support of UUNET Communications Services is gratefully + acknowledged. + +=-=-=-=-=-=-=-=-=-=-= +o Status: + +This software is in beta test, and it's pretty stable. Almost all of +the historic functionality in ex/vi is there, the only major missing +pieces are open mode and the lisp option. (Also, the options hardtabs, +optimize, redraw, and slowopen are recognized, but ignored.) + +Nvi is mostly 8-bit clean. This isn't difficult to fix, and was left +in during initial development to keep things simple. Wide character +support will be integrated at the same time that it is made fully 8-bit +clean. + +There aren't a lot of new features in nex/nvi, but there are a few things +you might like. The "Additional Features" section of the reference page +(USD.doc/vi.ref/vi.ref.txt, USD.doc/vi.ref/vi.ref.ps) has more information. + +=-=-=-=-=-=-=-=-=-=-= +o Porting information: + +The directory "PORT" has directories for specific OS/machine combinations, +including V7-style Makefiles, for building nex/nvi on different machines. +See the file PORT/README for detailed information. + +=-=-=-=-=-=-=-=-=-=-= +o Debugging: + +Code fixes are appreciated, of course, but if you can't provide them, +please email me as much information as you can as to how to reproduce +the bug, and I'll try to fix it locally. Stack traces of core dumps +are only rarely helpful -- an example file with a set of keystrokes that +causes the problem is almost invariably necessary. + +Please include the following in the bug report; + + o The version of nvi you're running (use :version to get it). + o The row/column dimensions of the screen (80 x 32). + o Unless you're confident that they're not part of the problem, + your startup files (.exrc, .nexrc) and the environment variable + (EXININT, NEXINIT) values. (Cutting and pasting the output + of ":set all" is usually sufficient.) + +If you're running a memory checker (e.g. Purify) on nvi, you will want +to recompile everything with "-DPURIFY" in the CFLAGS, first. By +default, allocated pages are not initialized by the DB code, and they +will show up as reads of uninitialized memory in the buffer write routines. + +=-=-=-=-=-=-=-=-=-=-= +o Directory layout: + +nvi/USD.doc: + Ex/vi documentation, both historic and current. + + edit/ Roff source for "Edit: A tutorial", USD:14 in the + 4.3BSD manuals. + ex/ Roff source for "Ex Reference Manual -- Version + 3.7", USD:16 in the 4.3BSD manuals. + vi/ Roff source for "An Introduction to Display + Editing with Vi", USD:15 in the 4.3BSD manuals. + Includes the "Vi Quick Reference" card. + vi.man/ Manual page for nex/nvi; an updated version of + the document distributed with 4.4BSD-Lite. + vi.ref/ Reference document for nex/nvi; an updated version + of the document distributed with 4.4BSD-Lite. + +nvi/common: + Source files for pieces of code that are shared by all the editors, + like searching and logging code or code translating line numbers + into requests to the dbopen(3) database code. It also has the + interface code for modifying "records" in the underlying database. + +nvi/docs: + Random nvi documentation: + + README -- Nvi main README file. + bugs.current -- Major known bugs in the current nvi. + changelog -- Log of changes from version to version. + features -- Todo list, suggested features list. + internals/ + autowrite -- Vi autowrite option discussion. + gdb.script -- GDB debugging scripts. + input -- Vi maps, executable buffers, and input discussion. + quoting -- Vi quoting discussion. + structures -- Out-of-date nvi internal structure description. + tutorial/ -- Historic vi tutorial(s), of unknown quality. + +nvi/ex: + The ex source code. Because vi has the colon command, lots of + this code is used by vi. Generally, if functionality is shared + by both ex and vi, it's in nvi/ex. If it's vi only, it's in + nvi/vi. Files are generally named by the command(s) they support, + but occasionally with a name that describes their functionality. + +nvi/install: + Things to install on the local system. + + recover.script -- Vi recovery script. + +nvi/PORT: + Porting directories, one per OS/architecture combination. See + nvi/PORT/README for porting information. + + curses/ -- 4.4BSD curses implementation + db/ -- 4.4BSD DB routines. + regex/ -- Henry Spencer's POSIX.2 RE support. + +nvi/sex: + The screen support for the ex editor. + +nvi/svi: + The screen support for a curses based vi editor. + +nvi/vi: + The vi source code. + +nvi/xaw: + Place reserved for an X11 (Athena Widget) screen. diff --git a/usr.bin/vi/docs/bugs.current b/usr.bin/vi/docs/bugs.current new file mode 100644 index 00000000000..500f3ba6d51 --- /dev/null +++ b/usr.bin/vi/docs/bugs.current @@ -0,0 +1,44 @@ +List of known bugs: + ++ The number option doesn't display line numbers in ex append/insert + mode. + ++ The option sidescroll is completely wrong, and setting it does more + harm than good. + ++ When nvi edits files that don't have trailing newlines, it appends + one, regardless. + ++ Open mode is not yet implemented. + ++ ^C isn't passed to the shell in the script windows as an interrupt + character. + ++ The options: + + hardtabs, lisp, optimize, redraw, slowopen + + are recognized, but not implemented. These options are unlikely to + be implemented, so if you want them you might want to say something! + I will implement lisp if anyone ever documents how it worked. + ++ Screen repainting over slow lines, for some screen changes, isn't + as good as the historic vi's. + ++ The line movement commands ('k', 'j' are easy examples) don't find the + most attractive cursor position correctly when wrapped lines are longer + than 80 characters, and they're on the second or subsequent lines. + ++ Colon commands longer than a single line cause the display to be + incorrect. + ++ The usages of S_{REDRAW,REFORMAT,REFRESH,RENUMBER,RESIZE} are + inconsistent, and should be reviewed. In particular, S_REFRESH + in any screen redraws all screens. + ++ Historic vi permitted :g/xxx/vi, i.e. you could execute ex/vi as + global commands. Need to review all of the old commands to verify + which ones could/could not be used as global commands. + ++ If you run out of space in the recovery directory, the recovery + file is left in place. diff --git a/usr.bin/vi/docs/changelog b/usr.bin/vi/docs/changelog new file mode 100644 index 00000000000..54e98a2edc4 --- /dev/null +++ b/usr.bin/vi/docs/changelog @@ -0,0 +1,528 @@ +1.33 -> 1.34 Wed Aug 17 14:37:32 1994 (PUBLICLY AVAILABLE VERSION) + + Back out sccsid string fix, it won't work on SunOS 4.1. +1.32 -> 1.33 Wed Aug 17 09:31:41 1994 (PUBLICLY AVAILABLE VERSION) + + Get back 5K of data space for the sccsid strings. + + Fix bug where cG fix in version 1.31 broke cw cursor positioning + when the change command extended the line. + + Fix core dump in map/seq code if character larger than 7 bits. + + Block signals when manipulating the SCR chains. + + Fix memory allocation for machines with multiple pointer sizes. +1.31 -> 1.32 Mon Aug 15 14:27:49 1994 + + Turn off recno mmap call for Solaris 2.4/SunOS 5.4. +1.30 -> 1.31 Sun Aug 14 13:13:35 1994 + + Fix bug were cG on the last line of a file wasn't done in line mode, + and where the cursor wasn't positioned correctly after exiting text + insert mode. + + Add termcap workaround to make function keys greater than 9 work + correctly (or fail if old-style termcap support). + + Change ex/vi to not flush mapped keys on error -- this is historic + practice, and people depended on it. + + Rework vi parser so that no command including a mapped key ever + becomes the '.' command, matching historic practice. + + Make <escape> cancellation in the vi parser match POSIX 1003.2. + + Fix curses bug where standout string was written for each standout + character, and where standout mode was never exited explicitly. + Fix bugs in curses SF/sf and SR/sr scrolling, as seen on Sun and + x86 consoles. + + The v/global commands execute the print command by default. + + The number option historically applies to ex as well as vi. +1.29 -> 1.30 Mon Aug 8 10:30:42 1994 + + Make first read into a temporary set the file's name. + + Permit any key to continue scrolling or ex commands -- this + allows stacked colon commands, and matches historic practice. + + Don't output normal ! command commentary in ex silent mode. + + Allow +/- flags after substitute commands, make line (flag) + offsets from vi mode match historic practice. + + Return <eof> to ex immediately, even if preceded by spaces. Rework + ex parser to do erase the prompt instead of depending on the print + routines to do it. Minor fixes to the ex parser for display of + default and scrolling commands. MORE EX PARSER CHANGES. +1.28 -> 1.29 Fri Aug 5 10:18:07 1994 + + Make the abbreviated ex delete command work (:dele---###lll for + example, is historically legal. + + When autoprint fires, multiple flags may be set, use ex_print + directly instead of the stub routines. + + Change v/global commands to turn off autoprint while running. + + Minor changes to make the ! command display match historic output. + + Rework the ex parser to permit multiple command separators without + commands -- MAJOR CHANGE, likely to introduce all sorts of new bugs. + + Fix cd command to expand argument in the context of each element + of the cdpath option, make relative paths always relative to the + current directory. + + Rework write/quit cases for temporary files, so that user's don't + discard them accidentally. + + Check for window size changes when continuing after a suspend. + + Fix memory problem in svi_screen, used free'd memory. + + Change the ex change, insert, append commands to match historic + cursor positions if no data entered by the user. + + Change ex format flags (#, l, p) to affect future commands, not + just the current one, to match historic practice. + + Make the user's EOF character an additional scroll character in ex. + + Fix ex ^D scrolling to be the value of the scroll option, not half + the screen. + + Fix buffer execution to match historic practice -- bugs where the + '*' command didn't work, and @<carriage-return> didn't work. + + Fix doubled reporting of deleted lines in filters. + + Rework the % ` / ? ( ) N n { and ^A commands to always cut into + numeric buffers regardless of the location or length of the cut. + This matches historic practice. + + Fix the { command to check the current line if the cursor doesn't + start on the first character of the line. + + Do '!' expansion in the ex read command arguments, it's historic + practice. In addition, it sets the last '!' command. +1.27 -> 1.28 Wed Jul 27 21:29:18 1994 + + Add support for scrolling using the CS and SF/sf/SR/sr termcap + strings to the 4BSD curses. + + Rework of getkey() introduced a bug where command interrupt put + nvi into an infinite loop. + + Piping through a filter historically cut the replaced lines into + the default buffer, although not the numeric ones. + + Read of a filter and !! historically moved to the first nonblank + of the resulting cursor line (most of the time). + + Rework cursor motion flags, to support '!' as a motion command. +1.26 -> 1.27 Tue Jul 26 10:27:58 1994 + + Add the meta option, to specify characters the shell will expand. + + Fix the read command to match historic practice, the white space + and bang characters weren't getting parsed correctly. + + Change SIGALRM handler to save and restore errno. + + Change SunOS include/compat.h to include <vfork.h> so that the + ex/filter.c code works again. + + Don't put lines deleted by the ex delete command into the numeric + buffers, matching historic practice. + + Fix; if appending to a buffer, default buffer historically only + references the appended text, not the resulting text. + + Support multiple, semi-colon separated search strings, and 'z' + commands after search strings. + + Make previous context mark setting match historic practice (see + docs/internals/context). + + Fix the set command to permit whitespace between the option and + the question mark, fix question marks in general. + + Fix bug where ex error messages could be accidentally preceded + by a single space. + + Fix bug where curses reorganization could lose screen specific + mappings as soon as any screen exited. + + Fix bug in paragraph code where invalid macros could be matched. + Make paragraph motions stop at formfeed (^L) characters. + + Change 'c' to match historic practice, it cut text into numeric + buffers. +1.25 -> 1.26 Tue Jul 19 17:46:24 1994 + + Ignore SIGWINCH if the screen size is unchanged; SunOS systems + deliver one when a screen is uncovered. + + Fix: don't permit a command with a motion component to wrap due + to wrapscan and return to the original cursor position. + + Fix: ^E wasn't beeping when reaching the bottom of the file. + + Fix bg/fg bug where tmp file exiting caused a NULL dereference. + + Rework file locking code to use fcntl(2) explicitly. + + Fix bug in section code where invalid macros could be matched. + + Fix bug where line number reset by vi's Q command. + + Add explicit character mode designation to character mode buffers. + + Add <sys/ioctl.h> include to sex/sex_window.c, needed by NET/2 + vintage systems. + + Change to always flush a character during suspend, 4BSD curses + has the optimization where it doesn't flush after a standend(). + + Fix bug on OSF1 where <curses.h> changes the values of VERASE, + VKILL and VWERASE to incorrect ones. + + Fix bug where optarg used incorrectly in main.c. + + Block all signals when acting on a signal delivery. + + Fix recovery bug where RCV_EMAIL could fire even if there wasn't + a backing file; format recovery message. +1.24 -> 1.25 Sun Jul 17 14:33:38 1994 + + Stop allowing keyboard suspends (^Z) in insert mode, it's hard + to get autowrite correct, and it's not historic practice. + + Fix z^, z+ to match historic practice. + + Bug in message handling, "vi +35 non-existent_file" lost the + status message because the "+35" pushed onto the stack erased + it. For now, change so that messages aren't displayed if there + are keys waiting -- may need to add a "don't-erase" bit to the + character in the stack instead. + + Bug in svi_msgflush(), where error messages could come out in + normal video. +1.23 -> 1.24 Sat Jul 16 18:30:18 1994 + + Fix core dump in exf.c, where editing a non-existent file and + exiting could cause already free'd memory to be free'd. + + Clean up numerous memory errors, courtesy of Purify. + + Change process wait code to fail if wait fails, and not attempt + to interpret the wait return information. + + Open recovery and DB files for writing as well as reading, System + V (fcntl) won't let you acquire LOCK_EX locks otherwise. + + Fix substitute bug where could malloc 0 bytes (AIX breaks). + + Permit the mapping of <carriage-return>, it's historic practice. + + Historic vi didn't eat <blank> characters before the force + flag, match historic practice. + + Bug in ex argument parsing, corrected for literal characters + twice. + + Delete screen specific maps when the screen closes. + + Move to the first non-<blank> in the line on startup; historic + practice. + + Change the ex visual command to move directly to a line if no + trailing 'z' command. + + Fix "[[" and "]]" to match historic practice (yet again...). + + Fix "yb" and "y{" commands to update the cursor correctly. + + Change "~<motion>" to match the yank cursor movement semantics + exactly. + + Move all of the curses related code into sex/svi -- major rework, + but should help in future ports. + + Fix bug in split code caused by new file naming code, where would + drop core when a split screen exited. + + Change svi_ex_write to do character display translation, so that + messages with file names in them are displayed correctly. + + Display the file name on split screens instead of a divider line. + + Fix move bug, wasn't copying lines before putting them. + + Fix bug were :n dropped core if no arguments supplied. + + Don't quote characters in executed buffer: "ifoo<esc>" should leave + insert mode after the buffer is executed. + + Tagpop and tagpush should set the absolute mark in case only moving + within a file. + + Skip leading whitespace characters before tags and cursor word + searches. + + Fix bug in ex_global where re_conv() was allocating the temporary + buffer and not freeing it. +1.22 -> 1.23: Wed Jun 29 19:22:33 1994 + + New <sys/cdefs.h> required "inline" to change to "__inline" + + Fix System V curses code for new ^Z support. + + Fix off-by-one in the move code, avoid ":1,$mo$" with only one + line in the buffer. + + Line orientation of motion commands was remembered too long, + i.e. '.' command could be incorrectly marked as line oriented. + + Move file modification time into EXF, so it's shared across + split screens. + + Put the prev[ious] command back in, people complained. + + Random fixes to next/prev semantics changed in 1.22. + + Historically vi doesn't only move to the last address if there's + ANYTHING after the addresses, e.g. ":3" moves to line 3, ":3|" + prints line 3. +1.21 -> 1.22: Mon Jun 27 11:01:41 1994 + + Make the line between split screens inverse video again. + + Delete the prev[ious] command, it's not useful enough to keep. + + Rework :args/file name handling from scratch -- MAJOR CHANGE, + likely to introduce all sorts of new bugs. + + Fix RE bug where no subexpressions in the pattern but there were + subexpressions referenced in the replacement, e.g. "s/XXX/\1/g". + + Change recovery to not leave unmodified files around after a + crash, by using the owner 'x' bit on unmodified backup files. + MAJOR CHANGE, the system recovery script has to change! + + Change -r option to delete recovery.* files that reference non- + existent vi.* files. + + Rework recovery locking so that fcntl(2) locking will work. + + Fix append (upper-case) buffers, broken by cut fixes. + + Fix | to not set the absolute motion mark. + + Read $HOME/.exrc file on startup if the effective user ID is + root. This makes running vi while su(1)'d work correctly. + + Use the full pathname of the file as the recovery name, not + just the last component. Matches historic practice. + + Keep marks in empty files from being destroyed. + + Block all caught signals before calling the DB routines. + + Make the line change report match historic practice (yanked + lines were different than everything else). + + Add section on multiple screens to the reference manual. + + Display all messages at once, combine onto a single line if + possible. Delete the trailing period from all messages. +1.20 -> 1.21: Thu May 19 12:21:58 1994 + + Delete the -l flag from the recover mail. + + Send the user email if ex command :preserve executed, this matches + historic practice. Lots of changes to the preserve and recovery + code, change preserve to snapshot files (again, historic practice). + + Make buffers match historic practice: "add logically stores text + into buffer a, buffer 1, and the unnamed buffer. + + Print <tab> characters as ^I on the colon command line if the + list option set. + + Adjust ^F and ^B scroll values in the presence of split screens + and small windows. + + Break msg* routines out from util.c into msg.c, start thinking + about message catalogs. + + Add tildeop set option, based on stevie's option of the same name. + Changes the ~ command into "[count] ~ motion", i.e. ~ takes a + trailing motion. + + Chose NOT to match historic practice on cursor positioning after + consecutive undo commands on a single line; see vi/v_undo.c for + the comment. + + Add a one line cache so that multiple changes to the same line + are only counted once (e.g. "dl35p" changes one line, not 35). + + Rework signals some more. Block file sync signals in vi routines + that interface to DB, so can sync the files at interrupt time. + Write up all of the signal handling arguments, see signal.c. +1.19 -> 1.20: Thu May 5 19:24:57 1994 + + Return ^Z to synchronous handling. See the dicussion in signal.c + and svi_screen.c:svi_curses_init(). + + Fix bug where line change report was wrong in util.c:msg_rpt(). +1.18 -> 1.19: Thu May 5 12:59:51 1994 + + Block DSUSP so that ^Y isn't delivered at SIGTSTP. + + Fix bug -- put into an empty file leaves the cursor at 1,0, + not the first nonblank. + + Fix bug were number of lines reported for the 'P' command was + off-by-one. + + Fix bug were 0^D wasn't being handled correctly. + + Delete remnants of ^Z as a raw character. + + Fix bug where if a map was an entire colon command, it may never + have been displayed. + + Final cursor position fixes for the vi T and t commands. + + The ex :next command took an optional ex command as it's first + argument similar to the :edit commands. Match historic practice. +1.17 -> 1.18: Wed May 4 13:57:10 1994 + + Rework curses information in the PORT/Makefile's. + + Minor fixes to ^Z asynchronous code. +1.16 -> 1.17: Wed May 4 11:15:56 1994 + + Make ex comment handling match historic practice. + + Make ^Z work asynchronously, we can no longer use the SIGTSTP + handler in the curses library. +1.15 -> 1.16: Mon May 2 19:42:07 1994 + + Make the 'p' and 'P' commands support counts, i.e. "Y10p" works. + + Make characters that map to themselves as the first part of the + mapping work, it's historic practice. + + Fix bug where "s/./\& /" discarded the space in the replacement + string. + + Add support for up/down cursor arrows in text input mode, rework + left/right support to match industry practice. + + Fix bug were enough character remapping could corrupt memory. + + Delete O_REMAPMAX in favor of setting interrupts after N mapped + characters without a read, delete the map counter per character. + MAJOR CHANGE. All of the interrupt signal handling has been + reworked so that interrupts are always turned on instead of + being turned on periodically, when an interruptible operation is + pending. + + Fix bug where vi wait() was interrupted by the recovery alarm. + + Make +cmd's and initial commands execute with the current line + set to the last line of the file. This is historic practice. + + Change "lock failed" error message to a file status message. + It always fails over NFS, and making all NFS files readonly + isn't going to fly. + + Use the historic line number format, but check for overflow. + + Fix bug where vi command parser ignored buffers specified as + part of the motion command. + + Make [@*]buffer commands on character mode buffers match historic + practice. + + Fix bug where the cmap/chf entries of the tty structure weren't + being cleared when new characters were read. + + Fix bug where the default command motion flags were being set + when the command was a motion component. + + Fix wrapmargin bug; if appending characters, and wrapmargin breaks + the line, an additional space is eaten. +1.14 -> 1.15: Fri Apr 29 07:44:57 1994 + + Make the ex delete command work in any empty file. + + Fix bug where 't' command placed the cursor on the character + instead of to its left. + + ^D and ^U didn't set the scroll option value historically. + Note, this change means that any user set value (e.g. 15^D) + will be lost when splitting the screen, since the split code + now resets the scroll value regardless. + + Fix the ( command to set the absolute movement mark. + + Only use TIOCGWINSZ for window information if SIGWINCH signal + caught. + + Delete the -l flag, and make -r work for multiple arguments. + Add the ex "recover[!] file" command. + + Switch into ex terminal mode and use the sex routines when + append/change/insert called from vi mode. + + Make ^F and ^B match historic practice. This required a fairly + extensive rework of the svi scrolling code. + + Cursor positioning in H, M, L, G (first non-blank for 1G) wasn't + being done correctly. Delete the SETLFNB flag. H, M, and L stay + logical movements (SETNNB) and G always moves to the first nonblank. + + System V uses "lines" and "cols", not "li" and "co", change as + necessary. Check termcap function returns for errors. + + Fix `<character> command to do start/end of line correction, + and to set line mode if starting and stopping at column 0. + + Fix bug in delete code where dropped core if deleted in character + mode to an empty line. (Rework the delete code for efficiency.) + + Give up on SunOS 4.1.X, and use "cc" instead of /usr/5bin/cc. + + Protect ex_getline routine from interrupted system calls (if + possible, set SA_RESTART on SIGALRM, too). + + Fix leftright scrolling bug, when moving to a shorter line. + + Do validity checking on the copy, move, t command target line + numbers. + + Change for System V % pattern broke trailing flags for empty + replacement strings. + + Fix bug when RCM flags retained in the saved dot structure. + + Make the ex '=' command work for empty files. + + Fix bug where special_key array was being free'd (it's no longer + allocated). + + Matches cut in line mode only if the starting cursor is at or + before the first nonblank in its line, and the ending cursor is + at or after the last nonblank in its line. + + Add the :wn command, so you can write a file and switch to a new + file in one command. + + Allow only a single key as an argument to :viusage. + + New movement code broke filter/paragraph operations in empty + files ("!}date" in an empty file was dropping core). +1.12 -> 1.14: Mon Apr 18 11:05:10 1994 (PUBLICLY AVAILABLE VERSION, 4.4BSD) + + Fix FILE structure leakage in the ex filter code. + + Rework suspend code for System V curses. Nvi has to do the + the work, there's no way to get curses to do it right. + + Revert SunOS 4.1.X ports to the distributed curses. There's + a bug in Sun's implementation that we can't live with. + + Quit immediately if row/column values are unreasonable. + + Fix the function keys to match vi historic behavior. + + Replace the echo/awk magic in the Makefile's with awk scripts. +1.11 -> 1.12: Thu Apr 14 11:10:19 1994 + + Fix bug where only the first vi key was checked for validity. + + Make 'R' continue to overwrite after a <carriage-return>. + + Only display the "no recovery" message once. + + Rework line backup code to restore the line to its previous + condition. + + Don't permit :q in a .exrc file or EXINIT variable. + + Fix wrapscan option bug where forward searches become backward + searches and do cursor correction accordingly. + + Change "dd" to move the cursor to the first non-blank on the line. + + Delete cursor attraction to the first non-blank, change non-blank + motions to set the most attractive cursor position instead. + + Fix 'r' substitute option to set the RE to the last RE, not the + last substitute RE. + + Fix 'c' and 'g' substitute options to always toggle, and fix + edcompatible option to not reset them. + + Display ex error messages in inverse video. + + Fix errorbells option to match historic practice. + + Delete fixed character display table in favor of table built based + on the current locale. + + Add ":set octal" option, that displays unknown characters as octal + values instead of the default hexadecimal. + + Make all command and text input modes interruptible. + + Fix ex input mode to display error messages immediately, instead + of waiting for the lines to be resolved. + + Fix bug where vi calling append could overwrite the command. + + Fix off-by-one in the ex print routine tab code. + + Fix incorrect ^D test in vi text input routines. + + Add autoindent support for ex text insert routines. + + Add System V substitute command replacement pattern semantics, + where '%' means the last replacement pattern. + + Fix bug that \ didn't escape newlines in ex commands. + + Regularize the names of special characters to CH_*. + + Change hex insert character from ^Vx<hex_char> to ^X<hex_char> + + Integrate System V style curses, so SunOS and Solaris ports can + use the native curses implementation. +1.10 -> 1.11: Thu Mar 24 16:07:45 EST 1994 (PUBLICLY AVAILABLE VERSION) + + Change H, M, and L to set the absolute mark, historical practice. + + Fix bug in stepping through multiple tags files. + + Add "remapmax" option that turns off map counts so you can remap + infinitely. If it's off, term_key() can be interrupted from the + keyboard, which will cause the buffers to flush. I also dropped + the default max number of remaps to 50. (Only Dave Hitz's TM + macros and maze appear to go over that limit.) + + Change :mkexrc to not dump w{300,1200,9600}, lisp options. + + Fix backward search within a line bug. + + Change all the includes of "pathnames.h" to use <>'s so that the + PORT versions can use -I. to replace it with their own versions. + + Make reads and writes interruptible. Rework code that enters and + leaves ex for '!' and filter commands, rework all interrupt and + timer code. + + Fix core dump when user displayed option in .exrc file. + + Fix bug where writing empty files didn't update the saved + modification time. + + Fix bug where /pattern/ addressing was always a backward search. + + Fix bug triggered by autoindent of more than 32 characters, where + nvi wasn't checking the right TEXT length. + + Fix bug where joining only empty lines caused a core dump. +1.09 -> 1.10: Sat Mar 19 15:40:29 EST 1994 + + Fix "set all" core dump. +1.08 -> 1.09: Sat Mar 19 10:11:14 EST 1994 + + If the tag's file path is relative, and it doesn't exist, check + relative to the tag file location. + + Fix ~ command to free temporary buffer on error return. + + Create vi.ref, a first cut at a reference document for vi. + The manual page and the reference document only document the + set options, so far. + + Fix 1G bug not always going to the first non-blank. + + Upgrade PORT/regex to release alpha3.4, from Henry Spencer. + + Add MKS vi's "cdpath" option, supporting a cd search path. + + Handle if search as a motion was discarded, i.e. "d/<erase>". + + Change nvi to not create multiple recovery files if modifying + a recovered file. + + Decide to ignore that the cursor is before the '$' when inserting + in list mode. It's too hard to fix. +1.07 -> 1.08: Wed Mar 16 07:37:36 EST 1994 + + Leftright and big line scrolling fixes. This meant more changes + to the screen display code, so there may be new problems. + + Don't permit search-style addresses until a file has been read. + + "c[Ww]" command incorrectly handled the "in whitespace" case. + + Fix key space allocation bug triggered by cut/paste under SunOS. + + Ex move command got the final cursor position wrong. + + Delete "optimize option not implemented" message. + + Make the literal-next character turn off mapping for the next + character in text input mode. +1.06 -> 1.07: Mon Mar 14 11:10:33 EST 1994 + + The "wire down" change in 1.05 broke ex command parsing, there + wasn't a corresponding change to handle multiple K_VLNEXT chars. + + Fix final position for vi's 't' command. +1.05 -> 1.06: Sun Mar 13 16:12:52 EST 1994 + + Wire down ^D, ^H, ^W, and ^V, regardless of the user's termios + values. + + Add ^D as the ex scroll command. + + Support ^Q as a literal-next character. + + Rework abbreviations to be delimited by any !inword() character. + + Add options description to the manual page. + + Minor screen cache fix for svi_get.c. + + Rework beautify option support to match historical practice. + + Exit immediately if not reading from a tty and a command fails. + + Default the SunOS 4.* ports to the distributed curses, not SMI's. +1.04 -> 1.05: Thu Mar 24 16:07:45 EST 1994 + + Make cursor keys work in input mode. + + Rework screen column code in vi curses screen. MAJOR CHANGE -- + after this, we'll be debugging curses screen presentation from + scratch. + + Explode include files in vi.h into the source files. +1.03 -> 1.04: Sun Mar 6 14:14:16 EST 1994 + + Make the ex move command keep the marks on the moved lines. + + Change resize semantics so you can set the screen size to a + specific value. A couple of screen fixes for the resize code. + + Fixes for foreground/background due to SIGWINCH. + + Complete rework of all of vi's cursor movements. The underlying + assumption in the old code was that the starting cursor position + was part of the range of lines cut or deleted. The command + "d[[" is an example where this isn't true. Change it so that all + motion component commands set the final cursor position separately + from the range, as it can't be done correctly later. This is a + MAJOR CHANGE -- after this change, we'll be debugging the cursor + positioning from scratch. + + Rewrite the B, b, E, e commands to use vi's getc() interface + instead of rolling their own. + + Add a second MARK structure, LMARK, which is the larger mark + needed by the logging and mark queue code. Everything else uses + the reworked MARK structure, which is simply a line/column pair. + + Rework cut/delete to not expect 1-past-the-end in the range, but + to act on text to the end of the range, inclusive. + + Sync on write's, to force NFS to flush. +1.01 -> 1.03: Sun Jan 23 17:50:35 EST 1994 (PUBLICLY AVAILABLE VERSION) + + Tag stack fixes, was returning to the tag, not the position from + which the user tagged. + + Only use from the cursor to the end of the word in cursor word + searches and tags. (Matches historical vi behavior.) + + Fix delete-last-line bug when line number option set. + + Fix usage line for :split command. + + If O_NUMBER set, long input lines would eventually fail, the column + count for the second screen of long lines wasn't set correctly. + + Fix for [[ reaching SOF with a column longer than the first line. + + Fix for multiple error messages if no screen displayed. + + Fix :read to set alternate file name as in historical practice. + + Fix cut to rotate the numeric buffers if line mode flag set. +1.00 -> 1.01: Wed Jan 12 13:37:18 EST 1994 + + Don't put cut items into numeric buffers if cutting less than + parts of two lines. +0.94 -> 1.00: Mon Jan 10 02:27:27 EST 1994 + + Read-ahead not there; BSD tty driver problem, SunOS curses + problem. + + Global command could error if it deleted the last line of + the file. + + Change '.' to only apply to the 'u' if entered immediately + after the 'u' command. "1pu.u.u. is still broken, but I + expect that it's going to be sacrificed for multiple undo. + + If backward motion on a command, now move to the point; get + yank cursor positioning correct. + + Rework cut buffers to match historic practice -- yank/delete + numeric buffers redone sensibly, ignoring historic practice. +0.92 -> 0.93: Mon Dec 20 19:52:14 EST 1993 + + Christos Zoulas reimplemented the script windows using pty's, + which means that they now work reasonably. The down side of + this is that almost all ports other than 4.4BSD need to include + two new files, login_tty.c and pty.c from the PORT/clib directory. + I've added them to the Makefiles. + + All calloc/malloc/realloc functions now cast their pointers, for + SunOS -- there should be far fewer warning messages, during the + build. The remaining messages are where CHAR_T's meet char *'s, + i.e. where 8-bit clean meets strcmp. + + The user's argument list handling has been reworked so that there + is always a single consistent position for use by :next, :prev and + :rewind. + + All of the historical options are now at least accepted, although + not all of them are implemented. (Edcompatible, hardtabs, lisp, + optimize, redraw, and slowopen aren't implemented.) + + The RE's have been reworked so that matches of length 0 are handled + in the same way as vi used to handle them. + + Several more mapping fixes and ex parser addressing fixes. diff --git a/usr.bin/vi/docs/ev b/usr.bin/vi/docs/ev new file mode 100644 index 00000000000..144295a319f --- /dev/null +++ b/usr.bin/vi/docs/ev @@ -0,0 +1,55 @@ +# @(#)ev 8.4 (Berkeley) 4/29/94 + +Ev: Vi: Result: +<CK> <CK> (Cursor keys). Move around the file. + +Meta key commands: +^A<#> <#>G Goto line #. +^A$ G Goto the end of the file. +^A/ / Prompt and execute a forward search. +^A: : Prompt and execute an ex command. +^A? ? Prompt and execute a backward search. +^Ac y'<c> Copy to mark in line mode (or copy the current line). +^AC y`<c> Copy to mark in character mode. +^Ad d'<c> Delete to mark in line mode (or delete the current line). +^AD d`<c> Delete to mark in character mode. +^Aj J Join lines. +^Am m<c> Mark the current cursor position. +^AN N Repeat search in the reverse direction. +^An ^A Search for the word under the cursor. +^Ar u Redo a command. +^Au u Undo a command. + +Single key commands: +^B ^B Page up a screen. +^C ^C Interrupt long-running commands. +^D ^D Page down a half-screen. +^E $ End of line. +^F ^F Page down a screen. +^G ^G File status/information. +^H X Delete the character to the left of the cursor. +^I (TAB) +^J j Cursor down one line. +^K k Cursor up one line. +^L ^L Redraw the screen. +^M (CR) ^M In insert mode, split the line at the current cursor, + creating a new line. + In overwrite mode, cursor down one line. +^N n Repeat previous search, in previous direction. +^O (UNUSED) +^P p Paste the cut text at the cursor position. +^Q (XON/XOFF) +^R (UNUSED) +^S (XON/XOFF) +^T D Truncate the line at the cursor position. +^U ^U Page up a half-screen. +^V<c> ^V<c> Insert/overwrite with a literal next character. +^W w Move forward one whitespace separated word. +^X x Delete the current character. +^Y (UNUSED) +^Z ^Z Suspend. + +New ex mode commands: + +^A:set ov[erwrite] Toggle "insert" mode, so that input keys overwrite + the existing characters. diff --git a/usr.bin/vi/docs/features b/usr.bin/vi/docs/features new file mode 100644 index 00000000000..ed785644a10 --- /dev/null +++ b/usr.bin/vi/docs/features @@ -0,0 +1,87 @@ +List of things that should be added: +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + ++ X11 (Tk, Motif, Xaw) interface. ++ Interpreted language (Perl5, Scheme, Tcl) ++ Ports: Windows, Windows NT, MSDOS ++ Message catalogs. ++ Forms editing package; use RE's to verify field contents. ++ Internationalization, including wide character support. ++ Support for single line window editing, including full editing + capability on the vi colon command line. ++ Rob Pike's sam style RE's. + +List of suggested features: +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ++ Filename completion. While on the subject of completion, it would be + nice to have the completion mechanism found in tcsh version >= 6.03. + For instance, the completion for the `:cd' command will be directories + only. The completion for the `:set' command will be all options not + set at that moment, and for `:set un' will be all options that are set + at that moment. The completion for `:< count' will be the flags. + ++ Add a "push" command that would push a file on the tags stack. + (Essentially make tags a special case of the stack, and make + the stack more general purpose.) + ++ Make :script just run a command and edit the output, and :interactive, + which allows interactive shell session, instead of just the current + :script. + ++ Add versioning based on a "set version" variable, that would + create backup copies when the file was written back, i.e. the + ":w" and autowrite's would copy the original. + ++ Add tagging information to the man page so that users can display + the part of the man page that discusses the command in which they're + interested. + ++ Add a zone option so that you can declare that top/bottom few lines + of the screen aren't filled except by accident, so that the text + you ask for is always concentrated in the center of the screen. + ++ Add "set searchdir" for a list of directories to look in for + files to edit. The semantic is that ":e foo" is replaced with + the file name that is found, so there's no confusion as to + which file is written. + ++ Change + :di[splay] tags -> :tags + :di[splay] screens -> :screens + :di[splay] buffers -> :buffers + ++ A macro record function. Add the ability to record a sequence + of keystrokes into a named buffer for later use. Handy when + you're trying to build a semi-complex macro. + ++ The semantics of :split, :bg, and :fg aren't right. Someone needs to + rethink how they should interact. The main problem arises when users + want to get a window into a new file. Currently, the necessary sequence + is ":split newfile|^W|:bg". It would be nice if you could simply + background the current screen and edit a new one. + ++ An option to turn on a ``quarter plane'' model so that you can + go as far to the right or down as you wish. The File or the + current line is only extended if you actually put down a char at + the new location. Very handy for ascii graphics and tables. + ++ Some way of replacing the command bindings. For this to work + cleanly the notion of a command must be separate from that of a + key. (Simulate the Rand editor?) + ++ Vertical splitting, so you can see files side by side. + ++ Tracking. Two or more files are associated so that when one file + is scrolled up/down/left/right other files track by the same amount. + Tracking may be constrained such that two files only track vertically + or horizontally. This is relatively easy to implement. + ++ A status file so that the next time invocation of the editor returns + to the same place, with the same number of windows etc. In case of + change of the screen size, reasonable defaults are used. For each + window size and location of the window, name of the file and position + in it, any tab settings, any other settings for the window (such as + insert/overwrite mode, auto indent etc). Last search RE and maybe + direction. If a file does not exist the next time you invoke the + editor, its window is left in the same place but with some default + message. 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.) diff --git a/usr.bin/vi/docs/tutorial/vi.advanced b/usr.bin/vi/docs/tutorial/vi.advanced new file mode 100644 index 00000000000..f757ad19c44 --- /dev/null +++ b/usr.bin/vi/docs/tutorial/vi.advanced @@ -0,0 +1,1458 @@ +Section 26: Index to the rest of the tutorial + +The remainder of the tutorial can be perused at your leisure. Simply find the +topic of interest in the following list, and {/Section xx:/^M} to get to the +appropriate section. (Remember that ^M means the return key) + +The material in the following sections is not necessarily in a bottom up +order. It should be fairly obvious that if a section mentions something with +which you are not familiar, say, buffers, you might {/buffer/^M} followed by +several {n} to do a keyword search of the file for more details on that item. +Another point to remember is that commands are surrounded by curly-braces and +can therefore be found rather easily. To see where, say, the X command is +used try {/{X}/^M}. Subsequent {n} will show you other places the command was +used. We have tried to maintain the convention of placing the command letter +surrounded by curly-braces on the section line where that command is +mentioned. + +Finally, you should have enough 'savvy' at this point to be able to do your +own experimentation with commands without too much hand-holding on the part of +the tutorial. Experimentation is the best way to learn the effects of the +commands. + + Section Topic - description + ------- ------------------- +(Sections 1 through 25 are located in the file vi.beginner.) + 1 introduction: {^F} {ZZ} + 2 introduction (con't) and positioning: {^F} {^B} + 3 introduction (con't) and positioning: {^F} {^B} + 4 positioning: {^F} {^B} ^M (return key) + 5 quitting: {:q!} ^M key + 6 marking, cursor and screen positioning: {m} {G} {'} {z} + 7 marking, cursor and screen positioning: {m} {G} {'} {z} + 8 marking, cursor and screen positioning: {z} {m} {'} + 9 marking and positioning: {m} {''} + 10 line positioning: {^M} {-} + 11 scrolling with {^M} + 12 scrolling with {-} and screen adjustment {z} + 13 notes on use of tutorial + 14 other scrolling and postioning commands: {^E} {^Y} {^D} {^U} + 15 searching: {/ .. /^M} + 16 searching: {? .. ?^M} {n} (in search strings ^ $) + 17 searching: \ and magic-characters in search strings + 18 colon commands, exiting: {:} {ZZ} + 19 screen positioning: {H} {M} {L} + 20 character positioning: {w} {b} {0} {W} {B} {e} {E} {'} {`} + 21 cursor positioning: {l} {k} {j} {h} + 22 adding text: {i} {a} {I} {A} {o} {O} ^[ (escape key) + 23 character manipulation: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J} + 24 undo: {u} {U} + 25 review +(The following sections are in this file.) + 26 Index to the rest of the tutorial ******** YOU ARE HERE ******* + 27 discussion of repeat counts and the repeat command: {.} + 28 more on low-level character motions: {t} {T} {|} + 29 advanced correction operators: {d} {c} + 30 updating the screen: {^R} + 31 text buffers: {"} + 32 rearranging and duplicating text: {p} {P} {y} {Y} + 33 recovering lost lines + 34 advanced file manipulation with vi + 34.1 more than one file at a time: {:n} + 34.2 reading files and command output: {:r} + 34.3 invoking vi from within vi: {:e} {:vi} + 34.4 escaping to a shell: {:sh} {:!} + 34.5 writing parts of a file: {:w} + 34.6 filtering portions of text: {!} + 35 advanced searching: magic patterns + 36 advanced substitution: {:s} + 37 advanced line addressing: {:p} {:g} {:v} + 38 higher level text objects and nroff: ( ) { } [[ ]] + 39 more about inserting text + 40 more on operators: {d} {c} {<} {>} {!} {=} {y} + 41 abbreviations: {:ab} + 42 vi's relationship with the ex editor: {:} + 43 vi on hardcopy terminals and dumb terminals: open mode + 44 options: {:set} {setenv EXINIT} + 44.1 autoindent + 44.2 autoprint + 44.3 autowrite + 44.4 beautify + 44.5 directory + 44.6 edcompatible + 44.7 errorbells + 44.8 hardtabs + 44.9 ignorecase + 44.10 lisp + 44.11 list + 44.12 magic + 44.13 mesg + 44.14 number + 44.15 open + 44.16 optimize + 44.17 paragraphs + 44.18 prompt + 44.19 readonly + 44.20 redraw + 44.21 remap + 44.22 report + 44.23 scroll + 44.24 sections + 44.25 shell + 44.26 shiftwidth + 44.27 showmatch + 44.28 slowopen + 44.29 tabstop + 44.30 tags + 44.31 taglength + 44.32 term + 44.33 terse + 44.34 timeout + 44.35 ttytype + 44.36 warn + 44.37 window + 44.38 wrapscan + 44.39 wrapmargin + 44.40 writeany + 44.41 w300, w1200, w9600 + +Section 27: repetition counts and the repeat command {.} + +Most vi commands will use a preceding count to affect their behavior in some +way. We have already seen how {3x} deletes three characters, and {22G} moves +us to line 22 of the file. For almost all of the commands, one can survive by +thinking of these leading numbers as a 'repeat count' specifying that the +command is to be repeated so many number of times. + +Other commands use the repeat count slightly differently, like the {G} command +which use it as a line number. + +For example: + +{3^D} means scroll down in the file three lines. Subsequent {^D} OR {^U} will +scroll only three lines in their respective directions! + +{3z^M} says put line three of the file at the top of the screen, while {3z.} +says put line three as close to the middle of the screen as possible. + +{50|} moves the cursor to column fifty in the current line. + +{3^F} says move forward 3 screenfulls. This is a repetition count. The +documents advertise that {3^B} should move BACK three screenfulls, but I +can't get it to work. + +Position the cursor on some text and try {3r.}. This replaces three characters +with '...'. However, {3s.....^[} is the same as {3xi.....^[}. + +Try {10a+----^[}. + +A very useful instance of a repetition count is one given to the '.' command, +which repeats the last 'change' command. If you {dw} and then {3.}, you will +delete first one and then three words. You can then delete two more words with +{2.}. If you {3dw}, you will delete three words. A subsequent {.} will delete +three more words. But a subsequent {2.} will delete only two words, not three +times two words. + +Caveat: The author has noticed that any repetition count with {^B} will NOT +work: indeed, if you are at the end of your file and try {3^B} sufficiently +often, the editor will hang you in an infinite loop. Please don't try it: +take my word for it. + +Section 28: {t} {T} {|} + +Position the cursor on line 13 below: + +Line 13: Four score and seven years ago, our forefathers brought ... + +Note that {fv} moves the cursor on/over the 'v' in 'seven'. Do a {0} to return +to the beginning of the line and try a {tv}. The cursor is now on/over the +first 'e' in 'seven'. The {f} command finds the next occurrence of the +specified letter and moves the cursor to it. The {t} command finds the +specified letter and moves the cursor to the character immediately preceding +it. {T} searches backwards, as does {F}. + +Now try {60|}: the cursor is now on the 'o' in 'brought', which is the +sixtieth character on the line. + +Section 29: {d} {c} + +Due to their complexity we have delayed discussion of two of the most powerful +operators in vi until now. Effective use of these operators requires more +explanation than was deemed appropriate for the first half of the tutorial. + +{d} and {c} are called operators instead of commands because they consist of +three parts: a count specification or a buffer specification (see section +#BUFFERS), the {d} or {c}, and the object or range description. We will not +discuss buffers at this stage, but will limit ourselves to count +specifications. Examples speak louder than words: position the cursor at the +beginning of line 14: + +Line 14: Euclid alone has looked on beauty bear. + +Obviously, there is something wrong with this quotation. Type {2fb} to +position the cursor on the 'b' of 'bear'. Now, type {cwbare^[} +and observe the results. The {cw} specifies that the change command {c} is to +operate on a word object. More accurately, it specifies that the range of the +change command includes the next word. + +Position the cursor on the period in Line 14. (one way is to use {f.}) +Now, type {cbbeast^[}. This specifies the range of the change command to be the +previous word (the 'b' reminiscent of the {b} command). If we had wished to +delete the word rather than change it, we would have used the {d} operator, +rather than the {c} operator. + +Position the cursor at the beginning of the line with {0}. Type +{d/look/^M}. The search string specified the range of the delete. +Everything UP TO the word 'looking' was deleted from the line. + +In general, almost any command that would move the cursor will specify a range +for these commands. The most confusing exception to this rule is when {dd} or +{cc} is entered: they refer to the whole line. Following is a summary of the +suffixes (suffices? suffici?) and the ranges they specify: + + suffix will delete{d}/change{c} + ------ ------------------------ + ^[ cancels the command + w the word to the right of the cursor + W ditto, but ignoring punctuation + b the word to the left of the cursor + B ditto, but ignoring punctuation + e see below. + E ditto + (space) a character + $ to the end of the line + ^ to the beginning of the line + / .. / up to, but not including, the string + ? .. ? back to and including the string + fc up to and including the occurrence of c + Fc back to and including the occurrence of c + tc up to but not including the occurrence of c + Tc back to but not including the occurrence of c + ^M TWO lines (that's right: two) + (number)^M that many lines plus one + (number)G up to and including line (number) + ( the previous sentence if you are at the beginning of + the current sentence, or the current sentence up to where + you are if you are not at the beginning of the current + sentence. Here, 'sentence' refers to the intuitive + notion of an English sentence, ending with '!', '?', + or '.' and followed by an end of line or two spaces. + ) the rest of the current sentence + { analogous to '(', but in reference to paragraphs: + sections of text surrounded by blank lines + } analogous to ')', but in reference to paragraphs + [[ analogous to '(', but in reference to sections + ]] analogous to ')', but in reference to sections + H the first line on the screen + M the middle line on the screen + L the last line on the screen + 3L through the third line from the bottom of the screen + ^F forward a screenful + ^B backward a screenful + : + : etc. etc. etc. + +This list is not exhaustive, but it should be sufficient to get the idea +across: after the {c} or {d} operator, you can specify a range with another +move-the-cursor command, and that is the region of text over which the command +will be effective. + +Section 30: updating the screen {^R} + +Vi tries to be very intelligent about the type of terminal you are working on +and tries to use the in-terminal computing power (if any) of your terminal. +Also if the terminal is running at a low baud rate (say 1200 or below), vi sets +various parameters to make things easier for you. For example, if you were +running on a 300 baud terminal (that's 30 characters per second transmission +rate) not all 24 lines of the screen would be used by vi. In addition, there +is a large portion of the editor keeping track of what your screen currently +looks like, and what it would look like after a command has been executed. Vi +then compares the two, and updates only those portions of the screen that have +changed. + +Furthermore, some of you may have noticed (it depends on your terminal) that +deleting lines or changing large portions of text may leave some lines on the +screen looking like: +@ +meaning that this line of the screen does not correspond to any line in your +file. It would cost more to update the line than to leave it blank for the +moment. If you would like to see your screen fully up-to-date with the +contents of your file, type {^R}. + +To see it in action, delete several lines with {5dd}, type {^R}, and then type +{u} to get the lines back. + +Here is as good a place as any to mention that if the editor is displaying the +end of your file, there may be lines on the screen that look like: +~ +indicating that that screen line would not be affected by {^R}. These lines +simply indicate the end of the file. + +Section 31: text buffers {"} + +Vi gives you the ability to store text away in "buffers". This feature is very +convenient for moving text around in your file. There are a total of thirty- +five buffers available in vi. There is the "unnamed" buffer that is used by all +commands that delete text, including the change operator {c}, the substitute +and replace commands {s} and {r}, as well as the delete operator {d} and delete +commands {x} and {X}. This buffer is filled each time any of these commands +are used. However, the undo command {u} has no effect on the unnamed buffer. + +There are twenty-six buffers named 'a' through 'z' which are available for the +user. If the name of the buffer is capitalized, then the buffer is not +overwritten but appended to. For example, the command {"qdd} will delete one +line and store that line in the 'q' buffer, destroying the previous contents of +the buffer. However, {"Qdd} will delete one line of text and append that line +to the current contents of the 'q' buffer. + +Finally, there are nine buffers named '1' through '9' in which the last nine +deletes are stored. Buffer 1 is the default buffer for the modify commands and +is sometimes called the unnamed buffer. + +To reference a specific buffer, use the double-quote command {"} followed by +the name of the buffer. The next two sections show how buffers can be used to +advantage. + +Section 32: rearranging and duplicating text: {y} {Y} {p} {P} + +Position yourself on line 15 below and {z^M}: + +Line 15: A tree as lovely as a poem ... +Line 16: I think that I shall never see + +Type {dd}. Line 15 has disappeared and been replaced with the empty line (one +with the single character @ on it) or (again depending on your terminal) Line +16 has moved up and taken its place. We could recover Line 15 with an undo +{u} but that would simply return it to its original location. Obviously, the +two lines are reversed, so we want to put line 15 AFTER line 16. This is +simply done with the put command {p}, which you should type now. What has +happened is that {dd} put Line 15 into the unnamed buffer, and the {p} command +retrieved the line from the unnamed buffer. + +Now type {u} and observe that Line 15 disappears again (the put was undone +without affecting the unnamed buffer). Type {P} and see that the capital {P} +puts the line BEFORE the cursor. + +To get Line 15 where it belongs again type {dd}{p}. + +Also in Line 15 note that the words 'tree' and 'poem' are reversed. Using the +unnamed buffer again: {ft}{dw}{ma}{fp}{P}{w}{dw}{`aP} will set things aright +(note the use of the reverse quote). + +The put commands {p} and {P} do not affect the contents of the buffer. +Therefore, multiple {p} or {P} will put multiple copies of the unnamed buffer +into your file. + +Experiment with {d} and {p} on words, paragraphs, etc. Whatever {d} +deletes, {p} can put. + +Position the cursor on Line 17 and {z^M}: + +Line 17: interest apple cat elephant boy dog girl hay farmer + +Our task is to alphabetize the words on line 17. With the named buffers (and a +contrived example) it is quite easy: + +{"idw}{"adw}{"cdw}{"edw}{"bdw}{"ddw}{"gdw}{"hdw}{"fdw} + +stores each of the words in the named buffer corresponding to the first letter +of each of the words ('interest' goes in buffer "i, 'apple' goes in buffer "a, +etc.). Now to put the words in order type: + +{"ap$}{"bp$}{"cp$}{"dp$}{"ep$}{"fp$}{"gp$}{"hp$}{"ip$} + +Notice that, because 'farmer' was at the end of the line, {dw} did not include +a space after it, and that, therefore, there is no space between 'farmer' and +'girl'. This is corrected with {Fg}{i ^[}. + +This example could have been done just as easily with lines as with +words. + +You do not have to delete the text in order to put it into a buffer. If all +you wish to do is to copy the text somewhere else, don't use {d}, rather use +the yank commands {y} or {Y}. {y} is like {d} and {c} - an operator rather +than a command. It, too, takes a buffer specification and a range +specification. Therefore, instead of {dw}{P} to load the unnamed buffer with a +word without deleting the word, use {yw} (yank a word). + +{Y} is designed yank lines, and not arbitrary ranges. That is, {Y} is +equivalent to {yy} (remember that operators doubled means the current line), +and {3Y} is equivalent to {3yy}. + +If the text you yank or modify forms a part of a line, or is an object such as +a sentence which partially spans more than one line, then when you put the text +back, it will be placed after the cursor (or before if you use {P}). If the +yanked text forms whole lines, they will be put back as whole lines, without +changing the current line. In this case, the put acts much like the {o} or {O} +command. + +The named buffers "a through "z are not affected by changing edit files. +However, the unnamed buffer is lost when you change files, so to move text from +one file to another you should use a named buffer. + +Section 33: recovering lost lines + +Vi also keeps track of the last nine deletes, whether you ask for it or not. +This is very convenient if you would like to recover some text that was +accidentally deleted or modified. Position the cursor on line 18 following, +and {z^M}. + + +Line 18: line 1 +Line 19: line 2 +Line 20: line 3 +Line 21: line 4 +Line 22: line 5 +Line 23: line 6 +Line 24: line 7 +Line 25: line 8 +Line 26: line 9 +Type {dd} nine times: now don't cheat with {9dd}! That is totally different. + +The command {"1p} will retrieve the last delete. Furthermore, when the +numbered buffers are used, the repeat-command command {.} will increment the +buffer numbers before executing, so that subsequent {.} will recover all nine +of the deleted lines, albeit in reverse order. If you would like to review the +last nine deletes without affecting the buffers or your file, do an undo {u} +after each put {p} and {.}: + +{"1p}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.} + +will show you all the buffers and leave them and your file intact. + +If you had cheated above and deleted the nine lines with {9dd}, all nine lines +would have been stored in both the unnamed buffer and in buffer number 1. +(Obviously, buffer number 1 IS the unnamed buffer and is just the default +buffer for the modify commands.) + +Section 34: advanced file manipulation: {:r} {:e} {:n} {:w} {!} {:!} + +We've already looked at writing out the file you are editing with the +{:w} command. Now let's look at some other vi commands to make editing +more efficient. + +Section 34.1: more than one file at a time {:n} {:args} + +Many times you will want to edit more than one file in an editing session. +Instead of entering vi and editing the first file, exiting, entering vi and +editing the second, etc., vi will allow you to specify ALL files that you wish +to edit on the invocation line. Therefore, if you wanted to edit file1 and +file2: + +% vi file1 file2 + +will set up file1 for editing. When you are done editing file one, write it +out {:w^M} and then type {:n^M} to get the next file on the list. On large +programming projects with many source files, it is often convenient just to +specify all source files with, say: + +% vi *.c + +If {:n^M} brings in a file that does not need any editing, another {:n^M} +will bring in the next file. + +If you have made changes to the first file, but decide to discard these changes +and proceed to the next file, {:n!^M} forces the editor to discard the current +contents of the editor. + +You can specify a new list of files after {:n}; e.g., {:n f1 f2 f3^M}. This +will replace the current list of files (if any). + +You can see the current list of files being edited with {:args^M}. + +Section 34.2: reading files and command output: {:r} + +Typing {:r fname^M} will read the contents of file fname into the editor and +put the contents AFTER the cursor line. + +Typing {:r !cmd^M} will read the output of the command cmd and place that +output after the cursor line. + +Section 34.3: invoking vi from within vi: {:e} {:vi} + +To edit another file not mentioned on the invocation line, type {:e filename^M} +or {:vi filename^M}. If you wish to discard the changes to the current file, +use the exclamation point after the command, e.g. {:e! filename^M}. + +Section 34.4: escaping to a shell: {:sh} {:!} {^Z} + +Occasionally, it is useful to interrupt the current editing session to perform +a UNIX task. However, there is no need to write the current file out, exit +the editor, perform the task, and then reinvoke the editor on the same file. +One thing to do is to spin off another process. If there are several UNIX +commands you will need to execute, simply create another shell with {:sh^M}. +At this point, the editor is put to sleep and will be reawakened when you log +out of the shell. + +If it is a single command that you want to execute, type {:!cmd^M}, where cmd +is the command that you wish to run. The output of the command will come to +the terminal as normal, and will not be made part of your file. The message +"[Hit return to continue]" will be displayed by vi after the command is +finished. Hitting return will then repaint the screen. Typing another +{:!cmd^M} at this point is also acceptable. + +However, there is a quicker, easier way: type {^Z}. Now this is a little +tricky, but hang in there. When you logged into UNIX, the first program you +began communicating with was a program that is called a "shell" (i.e. it 'lays +over' the operating system protecting you from it, sort of like a considerate +porcupine). When you got your first prompt on the terminal (probably a '%' +character) this was the shell telling you to type your first command. When +you typed {vi filename} for some file, the shell did not go away, it just went +to sleep. The shell is now the parent of vi. When you type {^Z} the editor +goes to sleep, the shell wakes up and says "you rang?" in the form of another +prompt (probably '%'). At this point you are talking to the shell again and +you can do anything that you could before including edit another file! (The +only thing you can't do is log out: you will get the message "There are +stopped jobs.") + +When your business with the shell is done, type {fg} for 'foreground' and the +last process which you ^Z'd out of will be reawakened and the shell will go +back to sleep. I will refer you to the documentation for the Berkeley shell +'csh' for more information on this useful capability. + +Section 34.5: writing parts of a file: {:w} + +The {:w} command will accept a range specifier that will then write only a +selected range of lines to a file. To write this section to a file, position +the cursor on the section line (e.g. {/^Section 34.5:/^M}) and {z^M}. Now type +{^G} to find out the line number (it will be something like "line 513"). Now +{/^Section 34.6:/-1^M} to find the last line of this section, and {^G} to find +its line number (it will be something like 542). To write out this section of +text by itself to a separate file which we will call "sepfile", type +{:510,542w sepfile^M}. If sepfile already exists, you will have to use the +exclamation point: {:1147,1168w! sepfile^M} or write to a different, non- +existent file. + +{:!cat sepfile^M} will display the file just written, and it should be the +contents of this section. + +There is an alternate method of determining the line numbers for the write. +{:set number^M} will repaint the screen with each line numbered. When the file +is written and the numbers no longer needed, {:set nonumber^M} will remove the +numbers, and {^R} will adjust the screen. + +Or, if you remember your earlier lessons about marking lines of text, +mark the beginning and ending lines. Suppose we had used {ma} to mark the +first line of the section and {mb} to mark the last. Then the command +{:'a,'bw sepfile^M} will write the section into "sepfile". In general, +you can replace a line number with the 'name' of a marked line (a single-quote +followed by the letter used to mark the line) + + +Section 34.6: filtering portions of text: {!} + +{!} is an operator like {c} and {d}. That is, it consists of a repetition +count, {!}, and a range specifier. Once the {!} operator is entered in its +entirety, a prompt will be given at the bottom of the screen for a UNIX +command. The text specified by the {!} operator is then deleted and +passed/filtered/piped to the UNIX command you type. The output of the UNIX +command is then placed in your file. For example, place the cursor at the +beginning of the following line and {z^M}: + +ls -l vi.tutorial +********* marks the bottom of the output from the ls command ********** + +Now type {!!csh^M}. The line will be replaced with the output from the ls +command. The {u} command works on {!}, also. + +Here is an extended exercise to display some of these capabilities. When this +tutorial was prepared, certain auxiliary programs were created to aid in its +development. Of major concern was the formatting of sections of the tutorial +to fit on a single screen, particularly the first few sections. What was +needed was a vi command that would 'format' a paragraph; that is, fill out +lines with as many words as would fit in eighty columns. There is no such vi +command. Therefore, another method had to be found. + +Of course, nroff was designed to do text formatting. However, it produces a +'page'; meaning that there may be many blank lines at the end of a formatted +paragraph from nroff. The awk program was used to strip these blank lines from +the output from nroff. Below are the two files used for this purpose: I refer +you to documentation on nroff and awk for a full explanation of their function. +Position the cursor on the next line and {z^M}. + +******** contents of file f ********** +# +nroff -i form.mac | awk "length != 0 { print }" +***** contents of file form.mac ****** +.na +.nh +.ll 79 +.ec +.c2 +.cc +************************************** + +Determine the line numbers of the two lines of file f. They should be +something like 574 and 575, although you better double check: this file is +under constant revision and the line numbers may change inadvertently. Then +{:574,575w f^M}. Do the same for the lines of file form.mac. They will be +approximately 577 and 582. Then {:577,582w form.mac^M}. File f must have +execute privileges as a shell file: {:!chmod 744 f^M}. + +Observe that this paragraph is +rather ratty in appearance. With our newly created files we can +clean it up dramatically. Position the cursor at the beginning +of this paragraph and type the following sequence of +characters +(note that we must abandon temporarily our convention +of curly braces since the command itself contains a curly brace - we +will use square brackets for the nonce): [!}f^M]. + +Here is a brief explanation of what has happened. By typing [!}f^M] we +specified that the paragraph (all text between the cursor and the first blank +line) will be removed from the edit file and piped to a UNIX program called +"f". This is a shell command file that we have created. This shell file runs +nroff, pipes its output to awk to remove blank lines, and the output from awk +is then read back into our file in the place of the old, ratty paragraph. The +file form.mac is a list of commands to nroff to get it to produce paragraphs +to our taste (the right margin is not justified, the line is 79 characters +long, words are not hyphenated, and three nroff characters are renamed to +avoid conflict: note that in this file, the {^G} you see there is vi's display +of the control-G character, and not the two separate characters ^ up-arrow and +G upper-case g). + +This example was created before the existence of the fmt program. I now type +[!}fmt^M] to get the same effect much faster. Actually, I don't type those +six keys each time: I have an abbreviation (which see). + +Section 35: searching with magic patterns + +The documentation available for "magic patterns" (i.e. regular expressions) is +very scanty. The following should explain this possibly very confusing feature +of the editor. This section assumes that the magic option is on. To make +sure, you might want to type {:set magic^M}. + +By "magic pattern" we mean a general description of a piece of text that the +editor attempts to find during a search. Most search patterns consist of +strings of characters that must be matched exactly, e.g. {/card/^M} searches +for a specific string of four characters. Let us suppose that you have +discovered that you consistently have mistyped this simple word as either ccrd +or czrd (this is not so far-fetched for touch typists). You could {/ccrd/^M} +and {n} until there are no more of this spelling, followed by {/czrd/^M} and +{n} until there are no more of these. Or you could {/c.rd/^M} and catch all of +them on the first pass. Try typing {/c.rd/^M} followed by several {n} and +observe the effect. + +Line 27: card cord curd ceard + +When '.' is used in a search string, it has the effect of matching any single +character. + +The character '^' (up-arrow) used at the beginning of a search string means +the beginning of the line. {/^Line 27/^M} will find the example line above, +while {/Line 27/^M} will find an occurrence of this string anywhere in the +line. + +Similarly, {/ the$/^M} will find all occurrences of the word 'the' occurring +at the end of a line. There are several of them in this file. + +Note that {:set nomagic^M} will turn off the special meaning of these magic +characters EXCEPT for '^' and '$' which retain their special meanings at the +beginning and end of a search string. Within the search string they hold no +special meaning. Try {/\/ the$\//^M} and note that the dollar-sign is not the +last character in the search string. Let the dollar-sign be the last +character in the search string, as in {/\/ the$/^M} and observe the result. + +Observe the result of {/back.*file/^M}. This command, followed by sufficient +{n}, will show you all lines in the file that contain both the words 'back' +and 'file' on the same line. The '*' magic character specifies that the +previous regular expression (the '.' in our example) is to be repeatedly +matched zero or more times. In our example we specified that the words 'back' +and 'file' must appear on the same line (they may be parts of words such as +'backwards' or 'workfile') separated by any number (including zero) of +characters. + +We could have specified that 'back' and 'file' are to be words by themselves by +using the magic sequences '\<' or '\>'. E.g. {/\<back\>.*\<file\>/^M}. The +sequence '\<' specifies that this point of the search string must match the +beginning of a word, while '\>' specifies a match at the end of a word. By +surrounding a string with these characters we have specified that they must be +words. + +To find all words that begin with an 'l' or a 'w', followed by an 'a' or an +'e', and ending in 'ing', try {/\<[lw][ea][a-z]*ing\>/^M}. This will match +words like 'learning', 'warning', and 'leading'. The '[..]' notation matches +exactly ONE character. The character matched will be one of the characters +enclosed in the square brackets. The characters may be specified individually +as in [abcd] or a '-' may be used to specify a range of characters as in [a-d]. +That is, [az] will match the letter 'a' OR the letter 'z', while [a-z] will +match any of the lower case letters from 'a' through 'z'. If you would like to +match either an 'a', a '-', or a 'z', then the '-' must be escaped: [a\-z] will +match ONE of the three characters 'a', '-', or 'z'. + +If you wish to find all Capitalized words, try {/\<[A-Z][a-z]*\>/^M}. The +following will find all character sequences that do NOT begin with an +uncapitalized letter by applying a special meaning to the '^' character in +square brackets: {/\<[^a-z][a-z]*\>/^M}. When '^' is the first character of a +square-bracket expression, it specifies "all but these characters". (No +one claimed vi was consistent.) + +To find all variable names (the first character is alphabetic, the remaining +characters are alphanumeric): try {/\<[A-Za-z][A-Za-z0-9]*\>/^M}. + +In summary, here are the primitives for building regular expressions: + + ^ at beginning of pattern, matches beginning of line + $ at end of pattern, matches end of line + . matches any single character + \< matches the beginning of a word + \> matches the end of a word + [str] matches any single character in str + [^str] matches any single character NOT in str + [x-y] matches any character in the ASCII range between x and y + * matches any number (including zero) of the preceding pattern + +Section 36: advanced substitution: {:s} + +The straightforward colon-substitute command looks like the substitute +command of most line-oriented editors. Indeed, vi is nothing more than a +superstructure on the line-oriented editor ex and the colon commands are +simply a way of accessing commands within ex (see section #EX). This gives us +a lot of global file processing not usually found in visual oriented editors. + +The colon-substitute command looks like: {:s/ .. / .. /^M} and will find the +pattern specified after the first slash (this is called the search pattern), +and replace it with the pattern specified after the second slash (called, +obviously enough, the replacement pattern). E.g. position the cursor on line +28 below and {:s/esample/example/^M}: + +Line 28: This is an esample. + +The {u} and {U} commands work for {:s}. The first pattern (the search pattern) +may be a regular expression just as for the search command (after all, it IS a +search, albeit limited to the current line). Do an {u} on the above line, and +try the following substitute, which will do almost the same thing: +{:s/s[^ ]/x/^M}. +Better undo it with {u}. The first pattern {s[^ ]} matches an 's' +NOT followed by a blank: the search therefore ignores the 's'es in 'This' and +'is'. However, the character matched by {[^ ]} must appear in the replacement +pattern. But, in general, we do not know what that character is! (In this +particular example we obviously do, but more complicated examples will follow.) +Therefore, vi (really ex) has a duplication mechanism to copy patterns matched +in the search string into the replacement string. Line 29 below is a copy of +line 28 above so you can adjust your screen. + +Line 29: This is an esample. + +In general, you can nest parts of the search pattern in \( .. \) and refer to +it in the replacement pattern as \n, where n is a digit. The problem outlined +in the previous paragraph is solved with {:s/s\([^ ]\)/x\1/^M}: try it. Here +\1 refers to the first pattern grouping \( .. \) in the search string. + +Obviously, for a single line, this is rather tedious. Where it becomes +powerful, if not necessary, is in colon-substitutes that cover a range of +lines. (See the next section for a particularly comprehensive example.) + +If the entire character sequence matched by the search pattern is needed in +the replacement pattern, then the unescaped character '&' can be used. On +Line 29 above, try {:s/an e.ample/not &/^M}. If another line is to have the +word 'not' prepended to a pattern, then '~' can save you from re-typing the +replacement pattern. E.g. {:s/some pattern/~/^M} after the previous example +would be equivalent to {:s/some pattern/not &/^M}. + +One other useful replacement pattern allows you to change the case of +individual letters. The sequences {\u} and {\l} cause the immediately +following character in the replacement to be converted to upper- or lower-case, +respectively, if this character is a letter. The sequences {\U} and {\L} turn +such conversion on, either until {\E} or {\e} is encountered, or until the end +of the replacement pattern. + +For example, position the cursor on a line: pick a line, any line. Type +{:s/.*/\U&/^M} and observe the result. You can undo it with {u}. + +The search pattern may actually match more than once on a single line. +However, only the first pattern is substituted. If you would like ALL +patterns matched on the line to be substituted, append a 'g' after the +replacement pattern: {:s/123/456/g^M} will substitute EVERY occurrence +on the line of 123 with 456. + +Section 37: advanced line addressing: {:p} {:g} {:v} + +Ex (available through the colon command in vi) offers several methods for +specifying the lines on which a set of commands will act. For example, if you +would like to see lines 50 through 100 of your file: {:50,100p^M} will display +them, wait for you to [Hit return to continue], and leave you on line 100. +Obviously, it would be easier just to do {100G} from within vi. But +what if you would like to make changes to just those lines? Then the +addressing is important and powerful. + +Line 30: This is a text. +Line 31: Here is another text. +Line 32: One more text line. + +The lines above contain a typing error that the author of this tutorial tends +to make every time he attempts to type the word 'test'. To change all of these +'text's into 'test's, try the following: +{:/^Line 30/,/^Line 32/s/text/test/^M}. This finds the beginning and end of +the portion of text to be changed, and limits the substitution to each of the +lines in that range. The {u} command applies to ALL of the substitutions as +a group. + +This provides a mechanism for powerful text manipulations. +And very complicated examples. + +Line 33: This test is a. +Line 34: Here test is another. +Line 35: One line more test. + +The above three lines have the second word out of order. The following command +string will put things right. Be very careful when typing this: it is very +long, full of special characters, and easy to mess up. You may want to +consider reading the following section to understand it before trying the +experiment. Don't worry about messing up the rest of the file, though: the +address range is specified. + +{:/^Line 33/,/^Line 35/s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/^M} + +There are several things to note about this command string. First of all, the +range of the substitute was limited by the address specification {/^Line +33/,/^Line 35/^M}. It might have been simpler to do {:set number^M} to see the +line numbers directly, and then, in place of the two searches, typed +the line numbers, e.g. {1396,1398}. Or to mark the lines with {ma} and {mb} +and use {'a,'b}. + +Then follows the substitute pattern itself. To make it easier to understand +what the substitute is doing, the command is duplicated below with the various +patterns named for easier reference: + + s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/ + |--\1---| |--\2---| |--\3---| |--\4---| + |--------search pattern------------------|-replacement| + |--pattern---| + +In overview, the substitute looks for a particular pattern made up of +sub-patterns, which are named \1, \2, \3, and \4. These patterns are specified +by stating what they are NOT. Pattern \1 is the sequence of characters that +are NOT colons: in the search string, {[^:]} will match exactly one character +that is not a colon, while appending the asterisk {[^:]*} specifies that the +'not a colon' pattern is to be repeated until no longer satisfied, and +{\([^:]*\)} then gives the pattern its name, in this case \1. Outside of the +specification of \1 comes {: }, specifying that the next two characters must be +a colon followed by a blank. + +Patterns \2 and \3 are similar, specifying character sequences that are +not blanks. Pattern \4 matches up to the period at the end of the line. + +The replacement pattern then consists of specifying the new order of the +patterns. + +This is a particularly complicated example, perhaps the most complicated +in this tutorial/reference. For our small examples, it is obviously +tedious and error prone. For large files, however, it may be the most +efficient way to make the desired modifications. + +(The reader is advised to look at the documentation for awk. This tool is very +powerful and slightly simpler to use than vi for this kind of file +manipulation. But, it is another command language to learn.) + +Many times, you will not want to operate on every line in a certain +range. Rather you will want to make changes on lines that satisfy +certain patterns; e.g. for every line that has the string 'NPS' on it, +change 'NPS' to 'Naval Postgraduate School'. The {:g} addressing +command was designed for this purpose. The example of this paragraph +could be typed as {:g/NPS/s//Naval Postgraduate School/^M}. + +The general format of the command is {:g/(pattern)/cmds^M} and it +works in the following way: all lines that match the pattern +following the {:g} are 'tagged' in a special way. Then each of these +lines have the commands following the pattern executed over them. + +Line 36: ABC rhino george farmer Dick jester lest +Line 37: george farmer rhino lest jester ABC +Line 38: rhino lest george Dick farmer ABC jester + +Type: + +{:g/^Line.*ABC/s/Dick/Harry Binswanger/|s/george farmer/gentleman george/p^M} + +There are several things of note here. First, lines 36, 37, and 38 above are +tagged by the {:g}. Type {:g/^Line.*ABC/p^M} to verify this. Second, there +are two substitutes on the same line separated by '|'. In general, any colon +commands can be strung together with '|'. Third, both substitutes operate on +all three lines, even though the first stubstitute works on only two of the +lines (36 and 38). Fourth, the second substitute works on only two lines (36 +and 37) and those are the two lines printed by the trailing 'p'. + +The {:v} command works similarly to the {:g} command, except that the sense of +the test for 'tagging' the lines is reversed: all lines NOT matching the search +pattern are tagged and operated on by the commands. + +Using {^V} to quote carriage return (see section 39) can be used in global +substitutions to split two lines. For example, the command +{:g/\. /s//.^V^M/g^M} will change your file so that each sentence is on a +separate line. (Note that we have to 'escape' the '.', because '.' by itself +matches any character. Our command says to find any line which contains a +period followed by 2 spaces, and inserts a carriage return after the period.) + +Caveat: In some of the documentation for ex and vi you may find the +comment to the effect that {\^M} can be used between commands following +{:g}. The author of this tutorial has never gotten this to work and has +crashed the editor trying. + +Section 38: higher level text objects and nroff: {(} {)} [{] [}] {[[} {]]} + +(Note: this section may be a little confusing because of our command +notation. Using curly braces to surround command strings works fine as +long as the command string does not contain any curly braces itself. +However, the curly braces are legitimate commands in vi. Therefore, for +any command sequence that contains curly braces, we will surround that +sequence with SQUARE braces, as on the previous Section line.) + +In working with a document, particularly if using the text formatting +programs nroff or troff, it is often advantageous to work in terms of +sentences, paragraphs, and sections. The operations {(} and {)} move to +the beginning of the previous and next sentences, respectively. Thus +the command {d)} will delete the rest of the current sentence; likewise +{d(} will delete the previous sentence if you are at the beginning of +the current sentence, or, if you are not at the beginning of a sentence, +it will delete the current sentence from the beginning +up to where you are. + +A sentence is defined to end at a '.', '!', or '?' which is followed +by either the end of a line, or by two spaces. Any number of closing +')', ']', '"', and ''' characters may appear after the '.', '!', or '?' +before the spaces or end of line. Therefore, the {(} and {)} commands +would recognize only one sentence in the following line, but two +sentences on the second following line. + +Line 39: This is one sentence. Even though it looks like two. +Line 40: This is two sentences. Because it has two spaces after the '.'. + +The operations [{] and [}] move over paragraphs and the operations {[[} +and {]]} move over sections. + +A paragraph begins after each empty line, and also at each of a set of nroff +paragraph macros. A section begins after each line with a form-feed ^L in the +first column, and at each of a set of nroff section macros. When preparing a +text file as input to nroff, you will probably be using a set of nroff macros +to make the formatting specifications easier, or more to your taste. These +macros are invoked by beginning a line with a period followed by the one or two +letter macro name. Vi has been programmed to recognize these nroff macros, and +if it doesn't recognize your particular macro you can use the {:set paragraphs} +or {:set sections} commands so that it will. + +Section 39: more about inserting text + +There are a number of characters which you can use to make correnctions +during input mode. These are summarized in the following table. + + ^H deletes the last input character + ^W deletes the last input word + (erase) same as ^H; each terminal can define its own erase character; + for some it is ^H, for others it is the DELETE key, and for + others it is '@'. + (kill) deletes the input on this line; each terminal can define its + own line-kill character; for some it is ^U, for others it is + '@'; you will need to experiment on your terminal to find + out what your line-kill and erase characters are. + \ escapes a following ^H, (kill), and (erase) characters: i.e. + this is how to put these characters in your file. + ^[ escape key; ends insertion mode + ^? the delete key; interrupts an insertion, terminating it + abnormally. + ^M the return key; starts a new line. + ^D backtabs over the indentation set by the autoindent option + 0^D backtabs over all indentation back to the beginning of the line + ^^D (up-arrow followed by control-d)same as 0^D, except the indentation + will be restored at the beginning of the next line. + ^V quotes the next non-printing character into the file + +If you wish to type in your erase or kill character (say # or @ or ^U) then you +must precede it with a \, just as you would do at the normal system command +level. A more general way of typing non-printing characters into the file is +to precede them with a ^V. The ^V echoes as a ^ character on which the cursor +rests. This indicates that the editor expects you to type a control character +and it will be inserted into the file at that point. There are a few +exceptions to note. The implementation of the editor does not allow the null +character ^@ to appear in files. Also the linefeed character ^J is used by the +editor to separate lines in the file, so it cannot appear in the middle of a +line. (Trying to insert a ^M into a file, or putting it in the replacement +part of a substitution string will result in the matched line being split in +two. This, in effect, is how to split lines by using a substitution.) You can +insert any other character, however, if you wait for the editor to echo the ^ +before you type the character. In fact, the editor will treat a following +letter as a request for the corresponding control character. This is the only +way to type ^S or ^Q, since the system normally uses them to suspend and resume +output and never gives them to the editor to process. + +If you are using the autoindent option you can backtab over the indent which it +supplies by typing a ^D. This backs up to the boundary specified by the +shiftwidth option. This only works immediately after the supplied autoindent. + +When you are using the autoindent option you may wish to place a label at the +left margin of a line. The way to do this easily is to type ^ (up-arrow) and +then ^D. The editor will move the cursor to the left margin for one line, and +restore the previous indent on the next. You can also type a 0 followed +immediately by a ^D if you wish to kill all indentation and not have it resume +on the next line. + +Section 40: more on operators: {d} {c} {<} {>} {!} {=} {y} + +Below is a non-exhaustive list of commands that can follow the operators +to affect the range over which the operators will work. However, note +that the operators {<}, {>}, {!}, and {=} do not operate on any object +less than a line. Try {!w} and you will get a beep. To get the +operator to work on just the current line, double it. E.g. {<<}. + + suffix will operate on + ------ ------------------------ + ^[ cancels the command + w the word to the right of the cursor + W ditto, but ignoring punctuation + b the word to the left of the cursor + B ditto, but ignoring punctuation + e see below. + E ditto + (space) a character + $ to the end of the line + ^ to the beginning of the line + / .. / up to, but not including, the string + ? .. ? back to and including the string + fc up to and including the occurrence of c + Fc back to and including the occurrence of c + tc up to but not including the occurrence of c + Tc back to but not including the occurrence of c + ^M TWO lines (that's right: two) + (number)^M that many lines plus one + (number)G up to and including line (number) + ( the previous sentence if you are at the beginning of + the current sentence, or the current sentence up to where + you are if you are not at the beginning of the current + sentence. Here, 'sentence' refers to the intuitive + notion of an English sentence, ending with '!', '?', + or '.' and followed by an end of line or two spaces. + ) the rest of the current sentence + { analogous to '(', but in reference to paragraphs: + sections of text surrounded by blank lines + } analogous to ')', but in reference to paragraphs + [[ analogous to '(', but in reference to sections + ]] analogous to ')', but in reference to sections + H the first line on the screen + M the middle line on the screen + L the last line on the screen + 3L through the third line from the bottom of the screen + ^F forward a screenful + ^B backward a screenful + : + : etc. etc. etc. + +This list is not exhaustive, but it should be sufficient to get the idea +across: after the operator, you can specify a range with a move-the-cursor +command, and that is the region of text over which the operator will be +effective. + +Section 41: abbreviations: {:ab} + +When typing large documents you may find yourself typing a large phrase +over and over. Vi gives you the ability to specify an abbreviation for +a long string such that typing the abbreviation will automatically +expand into the longer phrase. + +Type {:ab nps Naval Postgraduate School^M}. Now type: + +{iThis is to show off the nps's UNIX editor.^M^[} + +Section 42: vi's relationship with the ex editor: {:} + +Vi is actually one mode of editing within the editor ex. When you are +running vi you can escape to the line oriented editor of ex by giving +the command {Q}. All of the colon-commands which were introduced above +are available in ex. Likewise, most ex commands can be invoked from vi +using {:}. + +In rare instances, an internal error may occur in vi. In this case you +will get a diagnostic and will be left in the command mode of ex. You can +then save your work and quit if you wish by giving the command {x} after +the colon prompt of ex. Or you can reenter vi (if you are brave) by +giving ex the command {vi}. + +Section 43: vi on hardcopy terminals and dumb terminals: open mode + +(The author has not checked the following documentation for accuracy. It is +abstracted from the Introduction to Vi Editing document.) + +If you are on a hardcopy terminal or a terminal which does not have a cursor +which can move off the bottom line, you can still use the command set of vi, +but in a different mode. When you give the vi command to UNIX, the editor will +tell you that it is using open mode. This name comes from the open command in +ex, which is used to get into the same mode. + +The only difference between visual mode (normal vi) and open mode is the way in +which the text is displayed. + +In open mode the editor uses a single line window into the file, and moving +backward and forward in the file causes new lines to be displayed, always below +the current line. Two commands of vi work differently in open: {z} and {^R}. +The {z} command does not take parameters, but rather draws a window of context +around the current line and then returns you to the current line. + +If you are on a hardcopy terminal, the {^R} command will retype the current +line. On such terminals, the editor normally uses two lines to represent the +current line. The first line is a copy of the line as you started to edit it, +and you work on the line below this line. When you delete characters, the +editor types a number of \'s to show you the characters which are deleted. The +editor also reprints the current line soon after such changes so that you can +see what the line looks like again. + +It is sometimes useful to use this mode on very slow terminals which can +support vi in the full screen mode. You can do this by entering ex and using +an {open} command. + +********************************************************************* +Section 44: options: {:set} {setenv EXINIT} + +You will discover options as you need them. Do not worry about them very much +on the first pass through this document. My advice is to glance through them, +noting the ones that look interesting, ignoring the ones you don't understand, +and try re-scanning them in a couple of weeks. + +If you decide that you have a favorite set of options and would like to change +the default values for the editor, place a {setenv EXINIT} command in your +.login file. When you are given an account under UNIX your directory has +placed in it a file that is executed each time you log in. If one of the +commands in this file sets the environment variable EXINIT to a string of vi +commands, you can have many things done for you each time you invoke vi. For +example, if you decide that you don't like tabstops placed every eight columns +but prefer every four columns, and that you wish the editor to insert linefeeds +for you when your typing gets you close to column 72, and you want +autoindentation, then include the following line in your .login file: + +setenv EXINIT='set tabstop=4 wrapmargin=8 autoindent' + +or equivalently + +setenv EXINIT='se ts=4 wm=8 ai' + +Each time you bring up vi, this command will be executed and the options set. + +There are forty options in the vi/ex editor that the user can set for his/her +own convenience. They are described in more detail in individual sections +below. The section line will show the full spelling of the option name, the +abbreviation, and the default value of the option. The text itself +comes from the ex reference manual and is not the epitome of clarity. + +Section 44.1: {autoindent}, {ai} default: noai + +Can be used to ease the preparation of structured program text. At the +beginning of each append, change or insert command or when a new line is opened +or created by an append, change, insert, or substitute operation within open or +visual mode, ex looks at the line being appended after, the first line changed +or the line inserted before and calculates the amount of white space at the +start of the line. It then aligns the cursor at the level of indentation so +determined. + +If the user then types lines of text in, they will continue to be justified at +the displayed indenting level. If more white space is typed at the beginning +of a line, the following line will start aligned with the first non-white +character of the previous line. To back the cursor up to the preceding tab +stop one can hit {^D}. The tab stops going backwards are defined at multiples +of the shiftwidth option. You cannot backspace over the indent, except by +sending an end-of-file with a {^D}. A line with no characters added to it +turns into a completely blank line (the white space provided for the autoindent +is discarded). Also specially processed in this mode are lines beginning with +an up-arrow `^' and immediately followed by a {^D}. This causes the input to +be repositioned at the beginning of the line, but retaining the previous indent +for the next line. Similarly, a `0' followed by a {^D} repositions at the +beginning but without retaining the previous indent. Autoindent doesn't happen +in global commands or when the input is not a terminal. + +Section 44.2: {autoprint}, {ap} default: ap + +Causes the current line to be printed after each delete, copy, join, move, +substitute, t, undo or shift command. This has the same effect as supplying a +trailing `p' to each such command. Autoprint is suppressed in globals, and +only applies to the last of many commands on a line. + +Section 44.3: {autowrite}, {aw} default: noaw + +Causes the contents of the buffer to be written to the current file if you have +modified it and give a next, rewind, stop, tag, or {!} command, or a control- +up-arrow {^^} (switch files) or {^]} (tag goto) command in visual. Note, that +the edit and ex commands do not autowrite. In each case, there is an +equivalent way of switching when autowrite is set to avoid the autowrite +({edit} for next, rewind! for rewind, stop! for stop, tag! for tag, shell +for {!}, and {:e #} and a {:ta!} command from within visual). + +Section 44.4: {beautify}, {bf} default: nobeautify + +Causes all control characters except tab ^I, newline ^M and form-feed ^L to be +discarded from the input. A complaint is registered the first time a backspace +character is discarded. Beautify does not apply to command input. + +Section 44.5: {directory}, {dir} default: dir=/tmp + +Specifies the directory in which ex places its buffer file. If this directory +in not writable, then the editor will exit abruptly when it fails to be able to +create its buffer there. + +Section 44.6: {edcompatible} default: noedcompatible + +Causes the presence or absence of g and c suffixes on substitute commands to be +remembered, and to be toggled by repeating the suffices. The suffix r makes +the substitution be as in the {~} command, instead of like {&}. + +[Author's note: this should not concern users of vi.] + +Section 44.7: {errorbells}, {eb} default: noeb + +Error messages are preceded by a bell. However, bell ringing in open and +visual modes on errors is not suppressed by setting noeb. If possible the +editor always places the error message in a standout mode of the terminal (such +as inverse video) instead of ringing the bell. + +Section 44.8: {hardtabs}, {ht} default: ht=8 + +Gives the boundaries on which terminal hardware tabs are set (or on which the +system expands tabs). + +Section 44.9: {ignorecase}, {ic} default: noic + +All upper case characters in the text are mapped to lower case in regular +expression matching. In addition, all upper case characters in regular +expressions are mapped to lower case except in character class specifications +(that is, character in square brackets). + +Section 44.10: {lisp} default: nolisp + +Autoindent indents appropriately for lisp code, and the {(}, {)}, [{], [}], +{[[}, and {]]} commands in open and visual modes are modified in a +striaghtforward, intuitive fashion to have meaning for lisp. + +[Author's note: but don't ask me to define them precisely.] + +Section 44.11: {list} default: nolist + +All printed lines will be displayed (more) unambiguously, showing tabs as ^I +and end-of-lines with `$'. This is the same as in the ex command {list}. + +Section 44.12: {magic} default: magic for {ex} and {vi}, nomagic for edit. + +If nomagic is set, the number of regular expression metacharacters is greatly +reduced, with only up-arrow `^' and `$' having special effects. In addition +the metacharacters `~' and `&' of the replacement pattern are treated as normal +characters. All the normal metacharacters may be made magic when nomagic is +set by preceding them with a `\'. + +[Author's note: In other words, if magic is set a back-slant turns the magic +off for the following character, and if nomagic is set a back-slant turns the +magic ON for the following character. And, no, we are not playing Dungeons and +Dragons, although I think the writers of these option notes must have played it +all the time.] + +Section 44.13: {mesg} default: mesg + +Causes write permission to be turned off to the terminal while you are in +visual mode, if nomesg is set. + +[Author's note: I don't know if anyone could have made any one sentence +paragraph more confusing than this one. What it says is: mesg allows people to +write to you even if you are in visual or open mode; nomesg locks your terminal +so they can't write to you and mess up your screen.] + +Section 44.14: {number, nu} default: nonumber + +Causes all output lines to be printed with their line numbers. In addition +each input line will be prompted with its line number. + +Section 44.15: {open} default: open + +If {noopen}, the commands open and visual are not permitted. This is set for +edit to prevent confusion resulting from accidental entry to open or visual +mode. + +[Author's note: As you may have guessed by now, there are actually three +editors available under Berkeley UNIX that are in reality the same +program, ex, with different options set: ex itself, vi, and edit.] + +Section 44.16: {optimize, opt} default: optimize + +Throughput of text is expedited by setting the terminal to not do automatic +carriage returns when printing more than one (logical) line of output, greatly +speeding output on terminals without addressable cursors when text with leading +white space is printed. + +[Author's note: I still don't know what this option does.] + +Section 44.17: {paragraphs, para} default: para=IPLPPPQPP LIbp + +Specifies the paragraphs for the [{] and [}] operations in open and visual. +The pairs of characters in the option's value are the names of the nroff macros +which start paragraphs. + +Section 44.18: {prompt} default: prompt + +Command mode input is prompted for with a `:'. + +[Author's note: Doesn't seem to have any effect on vi.] + +Section 44.19: {readonly}, {ro} default: noro, unless invoked with -R + or insufficient privileges on file + +This option allows you to guarantee that you won't clobber your file by +accident. You can set the option and writes will fail unless you use an `!' +after the write. Commands such as {x}, {ZZ}, the autowrite option, and in +general anything that writes is affected. This option is turned on if you +invoke the editor with the -R flag. + +Section 44.20: {redraw} default: noredraw + +The editor simulates (using great amounts of output), an intelligent terminal +on a dumb terminal (e.g. during insertions in visual the characters to the +right of the cursor position are refreshed as each input character is typed). +Useful only at very high baud rates, and should be used only if the system is +not heavily loaded: you will notice the performance degradation yourself. + +Section 44.21: {remap} default: remap + +If on, macros are repeatedly tried until they are unchanged. For example, if o +is mapped to O, and O is mapped to I, then if remap is set, o will map to I, +but if noremap is set, it will map to O . + +Section 44.22: {report} default: report=5 for ex and vi, 2 for edit + +Specifies a threshold for feedback from commands. Any command which modifies +more than the specified number of lines will provide feedback as to the scope +of its changes. For commands such as global, open, undo, and visual which have +potentially more far reaching scope, the net change in the number of lines in +the buffer is presented at the end of the command, subject to this same +threshold. Thus notification is suppressed during a global command on the +individual commands performed. + +Section 44.23: {scroll} default: scroll=1/2 window + +Determines the number of logical lines scrolled when a {^D} is received from a +terminal in command mode, and determines the number of lines printed by a +command mode z command (double the value of scroll). + +[Author's note: Doesn't seem to affect {^D} and {z} in visual (vi) mode.] + +Section 44.24: sections {sections} default: sections=SHNHH HU + +Specifies the section macros from nroff for the {[[} and {]]} operations in +open and visual. The pairs of characters in the options's value are the names +of the macros which start paragraphs. + +Section 44.25: {shell}, {sh} default: sh=/bin/sh + +Gives the path name of the shell forked for the shell escape command `!', and +by the shell command. The default is taken from SHELL in the environment, if +present. + +[Editor's note: I would suggest that you place the following line in +your .login file: +setenv SHELL '/bin/csh' +] + +Section 44.26: {shiftwidth}, {sw} default: sw=8 + +Used in reverse tabbing with {^D} when using autoindent to append text, and +used by the shift commands. Should probably be the same value as the tabstop +option. + +Section 44.27: {showmatch}, {sm} default: nosm + +In open and visual mode, when a `)' or `}' is typed, if the matching `(' or `{' +is on the screen, move the cursor to it for one second. Extremely useful with +complicated nested expressions, or with lisp. + +Section 44.28: {slowopen}, {slow} default: terminal dependent + +Affects the display algorithm used in visual mode, holding off display updating +during input of new text to improve throughput when the terminal in use is both +slow and unintelligent. See "An Introduction to Display Editing with Vi" for +more details. + +Section 44.29: {tabstop}, {ts} default: ts=8 + +The editor expands tabs ^I to tabstop boundaries in the display. + +Section 44.30: {taglength}, {tl} default: tl=0 + +Tags are not significant beyond this many characters. +A value of zero (the default) means that all characters are significant. + +Section 44.31: {tags} default: tags=tags /usr/lib/tags + +A path of files to be used as tag files for the tag command. A requested tag +is searched for in the specified files, sequentially. By default files called +tags are searched for in the current directory and in /usr/lib (a master file +for the entire system). + +[Author's note: The author of this tutorial has never used this option, nor +seen it used. I'm not even sure I know what they are talking about.] + +Section 44.32: {term} default: from environment variable TERM + +The terminal type of the output device. + +Section 44.33: {terse} default: noterse + +Shorter error diagnostics are produced for the experienced user. + +Section 44.34: {timeout} default: timeout + +Causes macros to time out after one second. Turn it off and they will +wait forever. This is useful if you want multi-character macros, but if +your terminal sends escape sequences for arrow keys, it will be +necessary to hit escape twice to get a beep. + +[Editor's note: Another paragraph which requires a cryptographer.] + +Section 44.35: ttytype + +[Editor's note: I have found no documentation for this option at all.] + +Section 44.36: {warn} default: warn + +Warn if there has been `[No write since last change]' before a `!' command +escape. + +Section 44.37: {window} default: window=speed dependent + +The number of lines in a text window in the visual command. The default is 8 +at slow speeds (600 baud or less), 16 at medium speed (1200 baud), and the full +screen (minus one line) at higher speeds. + +Section 44.38: {wrapscan}, {ws} default: ws + +Searches using the regular expressions in addressing will wrap around past the +end of the file. + +Section 44.39: {wrapmargin}, {wm} default: wm=0 + +Defines a margin for automatic wrapover of text during input in open and visual +modes. The numeric value is the number of columns from the right edge of the +screen around which vi looks for a convenient place to insert a new-line +character (wm=0 is OFF). This is very convenient for touch typists. +Wrapmargin behaves much like fill/nojustify mode does in nroff. + +Section 44.40: {writeany}, {wa} default: nowa + +Inhibit the checks normally made before write commands, allowing a write to any +file which the system protection mechanism will allow. + +Section 44.41: {w300}, {w1200}, {w9600} defaults: w300=8 + w1200=16 + w9600=full screen minus one + +These are not true options but set the default size of the window for when the +speed is slow (300), medium (1200), or high (9600), respectively. They are +suitable for an EXINIT and make it easy to change the 8/16/full screen rule. + +Section 45: Limitations + +Here are some editor limits that the user is likely to encounter: + 1024 characters per line + 256 characters per global command list + 128 characters per file name + 128 characters in the previous inserted and deleted text in open or + visual + 100 characters in a shell escape command + 63 characters in a string valued option + 30 characters in a tag name + 250000 lines in the file (this is silently enforced). + +The visual implementation limits the number of macros defined with map to 32, +and the total number of characters in macros to be less than 512. + +[Editor's note: these limits may not apply to versions after 4.1BSD.] diff --git a/usr.bin/vi/docs/tutorial/vi.beginner b/usr.bin/vi/docs/tutorial/vi.beginner new file mode 100644 index 00000000000..3bf35ac939f --- /dev/null +++ b/usr.bin/vi/docs/tutorial/vi.beginner @@ -0,0 +1,741 @@ +Section 1: {^F} {ZZ} + +To get out of this tutorial, type: ZZ (two capital Z's). + +Learning a new computer system implies learning a new text editor. These +tutorial lessons were created by Dain Samples to help you come to grips with +UC Berkeley's screen oriented editor called vi (for VIsual). This tutorial +uses the vi editor itself as the means of presentation. + +For best use of this tutorial, read all of a screen before performing any of +the indicated actions. This tutorial (or, at least, the first half of it) has +been designed to systematically present the vi commands IF THE INSTRUCTIONS +ARE FOLLOWED! If you are too adventuresome, you may find yourself lost. If +you ever find yourself stuck, remember the first line of this section. + +OK, now find the control key on your keyboard; it usually has CTL or CTRL +written on its upper surface. Your first assignment is to hold the control +key down while you press the 'F' key on your keyboard. Please do so now. + + + +Section 2: {^F} {^B} +Many of vi's commands use the control key and some other key in combination, +as with the control and the 'F' key above. This is abbreviated CTL-F, or ^F. + +As you have probably guessed by now, ^F (CTL-F) moves you forward a fixed +number of lines in the file. Throughout the remainder of the tutorial when +you are ready to advance to the next section of text, hit ^F. + +The opposite command is ^B. Just for fun, you might want to try a ^B to see +the previous section again. Be sure to do a ^F to return you here. + +Determine what the cursor looks like on your screen. Whatever it is (a box, +an underscore, blinking, flashing, inverse, etc.) it should now be positioned +in the upper left-hand corner of your screen under or on the S of Section. +Become familiar with your cursor: to use vi correctly it is important to +always know where the cursor is. + +Did you notice that when you do a ^F the cursor is left at the top of the +screen, and a ^B leaves the cursor near the bottom of the screen? Try the two +commands ^B^F again. And now do another ^F to see the next section. + +Section 3: {^F} {^B} +You now have two basic commands for examining a file, both forwards (^F) and +backwards (^B). + +Note that these are vi text editing commands: they are not commands for the +tutorial. Indeed, this tutorial is nothing but a text file which you are now +editing. Everything you do and learn in this tutorial will be applicable to +editing text files. + +Therefore, when you are editing a file and are ready to see more of the text, +entering ^F will get you to the next section of the file. Entering ^B will +show you the previous section. + +Time for you to do another ^F. + + + + + + + +Section 4: {^F} {^B} {^M} (return key) +We will adopt the notation of putting commands in curly braces so we can write +them unambiguously. For example, if you are to type the command sequence +"control B control F" (as we asked you to do above) it would appear as {^B^F}. +This allows clear delineation of the command strings from the text. Remember +that the curly braces are NOT part of the command string you are to type. Do +NOT type the curly braces. + +Sometimes, the command string in the curly braces will be rather long, and may +be such that the first couple of characters of the command will erase from +the screen the string you are trying to read and type. It is suggested that +you write down the longer commands BEFORE you type them so you won't forget +them once they disappear. + +Now locate the return key on your keyboard: it is usually marked 'RETURN', +indicate hitting the return key. In fact, the control-M key sequence is +exactly the same as if you hit the return key, and vice versa. + +Now type {^F}. + + +Section 5: {:q!} {ZZ} {^M} (return key) +Recognize that this tutorial is nothing more than a text file that you +are editing. This means that if you do something wrong, it is possible +for you to destroy the information in this file. Don't worry. If this +happens, type {ZZ} (two capital Z's) or {:q!^M} to leave the tutorial. +Restart the tutorial. Once in the tutorial, you can then page forward +with {^F} until you are back to where you want to be. (There are +easier ways to do this, some of which will be discussed later, but this +is the most straightforward.) + +You may want to write these commands down in a convenient place for quick +reference: {:q!^M} and {ZZ} + +We will assume that you now know to do a {^F} to advance the file + + + + + + + +Section 6: {m} {G} {'} {z} +Now that you know how to get around in the file via ^F and ^B let's look at +other ways of examining a text file. Sometimes it is necessary, in the midst +of editing a file, to examine another part of the file. You are then faced +with the problem of remembering your place in the file, looking at the other +text, and then getting back to your original location. Vi has a 'mark' +command, m. Type {mp}. You have just 'marked' your current location in the +file and given it the name 'p'. The command string below will do three +things: position you at the beginning of the file (line 1), then return you to +the location 'p' that you just marked with the 'm' command, and, since the +screen will not look exactly the same as it does right now, the 'z' command +will reposition the screen. (You may want to write the string down before +typing it: once you type {1G} it will no longer be on the screen.) + +So now type {1G'pz^M} - a one followed by a capital G, followed by the quote +mark, followed by a lower case 'p', then a lower case 'z', then a return +(which is the same as a ^M). The {1G} moves you to line 1, i.e. the beginning +of the file. The {'p} moves you to the location you marked with {mp}. The +{z^M} command will repaint the screen putting the cursor at the top of the +screen. (Now {^F}.) + +Section 7: {m} {G} {'} {z} +Let's look at some variations on those commands. If you wanted to look at +line 22 in the file and return to this location you could type {mp22G'p}. Do +so now, observing that {22G} puts your cursor at the beginning of section 2 in +the middle of the screen. + +Also note that, without the {z^M} command, the line with 'Section 7' on it is +now in the MIDDLE of the screen, and not at the top. Our cursor is on the +correct line (where we did the {mp} command) but the line is not where we +might like it to be on the screen. That is the function of the {z^M} command. +(Remember, ^M is the same as the 'return' key on your keyboard.) Type {z^M} +now and observe the effect. + +As you can see, the 'Section 7' line is now at the top of the screen with the +cursor happily under the capital S. If you would like the cursor line (i.e. +the line which the cursor is on) in the middle of the screen again, you would +type {z.}. If you wanted the cursor line to be at the BOTTOM of the screen, +type {z-}. Try typing {z-z.z^M} and watch what happens. + +{^F} + +Section 8: {z} {m} {'} + +Note that the z command does not change the position of our cursor in the file +itself, it simply moves the cursor around on the screen by moving the contents +of the file around on the screen. The cursor stays on the same line of the +file when using the z command. + +This brings up an important point. There are two questions that the users of +vi continually need to know the answer to: "Where am I in the file?" and +"Where am I on the screen?" The cursor on your terminal shows the answer to +both questions. Some commands will move you around in the file, usually +changing the location of the cursor on the screen as well. Other commands +move the cursor around on the screen without changing your location in the +file. + +Now type {ma}. Your location in the file has been given the name 'a'. If you +type {'p'a} you will see the previous location we marked in section 7, and +then will be returned to the current location. (You will want to do a {z^M} +to repaint the screen afterwards.) Try it. +{^F} + +Section 9: {m} {''} +Now we can move about in our file pretty freely. By using the {m} command we +can give the current cursor position a lower-case-character name, like 'p', +'a', 'e', 'm', or 'b'. Using the {G} command preceded by a line number we can +look at any line in the file we like. Using the single quote command {'} +followed by a character used in an {m} command, we can return to any location +in the file we have marked. + +However, try {m3}, or {mM}. You should hear a beep, or bell. Only lower-case +letters are acceptable to the {m} and {'} commands: numbers, upper-case +letters, and special characters are not acceptable. + +If you type the {'} command with a character that is lower-case alphabetic but +that has not been used in an {m} command, or for which the 'marked' text has +been deleted, you will also get a beep. Try {'i}. You should get a beep +because the command {mi} has never been issued. (Unless you've been +experimenting.) + +The command {''} attempts to return you to the location at which you last +modified some part of your file. However, my experience has been that it is +difficult to predict exactly where you will end up. +Section 10: {^M} {-} +Now do {ma}, marking your position at the top of the screen. Now hit {^M} (or +return) until the cursor is right ... +* <- here, over/under the asterisk. Now +type {mb'a'b} and watch the cursor move from the asterisk to the top of the +screen and back again. + +The {^M} command moves the cursor to the beginning of the next line. Now type +{^M} until the cursor is right ... +* <- here. The command to move the cursor to the beginning of the +previous line is {-}. Practice moving the cursor around on the screen by using +{^M} and {-}. BE CAREFUL to not move the cursor OFF the screen just yet. If +you do, type {'az^M}. + +Now we can move to any line within the screen. Practice moving around in the +file using the {^F}, {^B}, {-}, {^M}, {z}, and {'} commands. When you are +fairly confident that you can get to where you need to be in the file, and +position the cursor on the screen where you want it type {'az^M^F} (which, of +course, moves you back to the beginning of this section, repositions the +cursor at the top of the screen, and advances you to the next section). + +Section 11: scrolling: {^M} +The cursor should now be on the S of 'Section 11', and this should be on the +first line of the screen. If it is not, do {^M} or {-} as appropriate to put +the cursor on the section line, and type {z^M}. + +Type {mc} to mark your place. + +Now type {^M} until the cursor is on the last line of this screen. Now do one +more {^M} and observe the result. This is called scrolling. When you +attempted to move to a line not displayed on the screen, the line at the top of +the screen was 'scrolled off', and a line at the bottom of the screen was +'scrolled on'. The top line with 'Section 11' should no longer be visible. + +Now type {'cz^M} to reset the screen and type {^F} for the next section. + + + + + + + +Section 12: {-} {z} + +The {-} command moves the cursor to the previous line in the file. Now type +{-}, which attempts to move the cursor to the previous line in this file. +However, that line is not on the screen. The resulting action will depend on +your terminal. (Do a {^Mz^M} to reposition the file). On intelligent +terminals (e.g. VT100s, Z19s, Concept 100s), a top line is 'scrolled on' and +the bottom line is 'scrolled off'. Other terminals, however, may not have +this 'reverse scrolling' feature. They will simply repaint the screen with +the cursor line in the middle of the screen. On such terminals it is +necessary to type {z^M} to get the cursor line back to the top of the screen. + + + + + + + + + + +Section 13: +Up until this point, the tutorial has always tried to make sure that the first +line of each screen has on it the section number and a list of the commands +covered in that section. This will no longer be strictly maintained. If you +want the section line at the top of the screen, you now know enough commands to +do it easily: do {^M} or {-} until the cursor is on the section line and +then {z^M}. Also, from this point on, it may not be the case that a {^F} will +put you at the beginning of the next section. Therefore, be aware of where you +are in the file as we look at other commands. You may have to find your way +back to a particular section without any help from the tutorial. If you do not +feel comfortable with this, then it is suggested that you practice moving from +section 1 to section 13, back and forth, using {^M}, {-}, {^F}, and {^B} +commands for a while. + +Also make liberal use of the mark command {m}: if, for example, you make a +habit of using {mz} to mark your current location in the file, then you will +always be able to return to that location with {'z} if the editor does +something strange and you have no idea where you are or what happened. + +And finally, the proscription against experimentation is hereby lifted: play +with the editor. Feel free to try out variations on the commands and move +around in the file. By this time you should be able to recover from any gross +errors. + +Section 14: {^E} {^Y} {^D} {^U} +Let us now look at a few other commands for moving around in the file, and +moving the file around on the screen. Note that the commands we have already +looked at are sufficient: you really don't need any more commands for looking +in a file. The following commands are not absolutely necessary. However, +they can make editing more convenient, and you should take note of their +existence. But it would be perfectly valid to decide to ignore them on this +first pass: you can learn them later when you see a need for them, if you ever +do. + +First, let's clear up some potentially confusing language. In at least one +place in the official document ('An Introduction to Display Editing with Vi' +by William Joy, and Mark Horton, September 1980), the expression "to scroll +down text" means that the cursor is moved down in your file. However, note +that this may result in the text on the screen moving UP. This use of the +word 'scroll' refers to the action of the cursor within the file. However, +another legitimate use of the word refers to the action of the text on the +screen. That is, if the lines on your screen move up toward the top of the +screen, this would be 'scrolling the screen up'. If the lines move down +toward the bottom of the screen, this would be refered to as scrolling down. + +I have tried to maintain the following jargon: 'scrolling' refers to what the +text does on the screen, not to what the cursor does within the file. For the +latter I will refer to the cursor 'moving', or to 'moving the cursor'. I +realize that this is not necessarily consistent with Joy and Horton, but they +were wrong. + +{^E} scrolls the whole screen up one line, keeping the cursor on the same line, +if possible. However, if the cursor line is the first line on the screen, then +the cursor is moved to the next line in the file. Try typing {^E}. + +{^Y} scrolls the screen down one line, keeping the cursor on the same line, if +possible. However, if the cursor line is the last line on the screen, then the +cursor is moved to the previous line in the file. Try it. + +{^D} moves the cursor down into the file, scrolling the screen up. + +{^U} moves the cursor up into the file, also scrolling the screen if the +terminal you are on has the reverse scroll capability. Otherwise the +screen is repainted. + +Note that {^E} and {^Y} move the cursor on the screen while trying to keep the +cursor at the same place in the file (if possible: however, the cursor can +never move off screen), while {^D} and {^U} keep the cursor at the same place +on the screen while moving the cursor within the file. + +Section 15: {/ .. /^M} + +Another way to position yourself in the file is by giving the editor a string +to search for. Type the following: {/Here 1/^M} and the cursor should end up +right ...........................here ^. Now type {/Section 15:/^M} and the +cursor will end up over/on .....................here ^. Now type {//^M} and +observe that the cursor is now over the capital S five lines above this line. +Typing {//^M} several more times will bounce the cursor back and forth between +the two occurrences of the string. In other words, when you type a string +between the two slashes, it is searched for. Typing the slashes with nothing +between them acts as if you had typed the previous string again. + +Observe that the string you type between the two slashes is entered on the +bottom line of the screen. Now type {/Search for x /^M} except replace the 'x' +in the string with some other character, say 'b'. The message "Pattern not +found" should appear on the bottom of the screen. If you hadn't replaced the +'x', then you would have found the string. Try it. + +Section 16: {? .. ?^M} {n} (search strings: ^ $) + +When you surround the sought-for string with slashes as in {/Search/}, the +file is searched beginning from your current position in the file. If the +string is not found by the end of the file, searching is restarted at the +beginning of the file. However, if you do want the search to find the +PREVIOUS rather than the NEXT occurrence of the string, surround the string +with question marks instead of slash marks. + +Below are several occurrences of the same string. +Here 2 Here 2 Here 2 + Here 2 Here 2. +Observe the effect of the following search commands (try them in the +sequence shown): +{/Here 2/^M} {//^M} {??^M} +{/^Here 2/^M} {//^M} {??^M} +{/Here 2$/^M} {//^M} {??^M} + +The first command looks for the next occurrence of the string 'Here 2'. +However the second line of commands looks for an occurrence of 'Here 2' that +is at the beginning of the line. When the up-arrow is the first character of +a search string it stands for the beginning of the line. When the dollar-sign +is the last character of the search string it stands for the end of the line. +Therefore, the third line of commands searches for the string only when it is +at the end of the line. Since there is only one place the string begins a +line, and only one place the string ends the line, subsequent {//^M} and +{??^M} will find those same strings over and over. + +The {n} command will find the next occurrence of the / or ? search +string. Try {/Here 2/^M} followed by several {n} and observe the +effect. Then try {??^M} followed by several {n}. The {n} command +remembers the direction of the last search. It is just a way to save a +few keystrokes. + +Section 17: \ and magic-characters in search strings + +Now type {/Here 3$/^M}. You might expect the cursor to end up +right......^ here. However, you will get "Pattern not found" at the bottom of +the screen. Remember that the dollar-sign stands for the end of the line. +Somehow, you must tell vi that you do not want the end of the line, but a +dollar-sign. In other words, you must take away the special meaning that the +dollar-sign has for the search mechanism. You do this (for any special +character, including the up-arrow ^) by putting a back-slash ('\', not '/') in +front of the character. + +Now try {/Here 3\$/^M} and you should end up nine lines above this one. Try +{//^M} and note that it returns you to the same place, and not to the first +line of this paragraph: the back-slash character is not part of the search +string and will not be found. To find the string in the first line of this +paragraph, type {/Here 3\\\$/^M}. There are three back-slashes: the first takes +away the special meaning from the second, and the third takes away the special +meaning from the dollar-sign. + +Following is a list of the characters that have special meanings in search +strings. If you wish to find a string containing one of these characters, you +will have to be precede the character with a backslash. These characters are +called magic characters because of the fun and games you can have with them +and they can have with you, if you aren't aware of what they do. + + ^ - (up-arrow) beginning of a line + $ - (dollar-sign) end of a line + . - (period) matches any character + \ - (backslant) the escape character itself + [ - (square bracket) for finding patterns (see section #SEARCH) + ] - (square bracket) ditto + * - (asterisk) ditto + +Without trying to explain it here, note that {:set nomagic^M} turns off the +special meanings of all but the ^ up-arrow, $ dollar-sign, and backslash +characters. + +Section 18: {: (colon commands)} {ZZ} + +In this section we will discuss getting into and out of the editor in more +detail. If you are editing a file and wish to save the results the command +sequence {:w^M} writes the current contents of the file out to disk, using the +file name you used when you invoked the editor. That is, if you are at the +command level in Unix, and you invoke vi with {vi foo} where foo is the name +of the file you wish to edit, then foo is the name of the file used by the +{:w^M} command. + +If you are done, the write and quit commands can be combined into a single +command {:wq^M}. An even simpler way is the command {ZZ} (two capital Z's). + +If, for some reason, you wish to exit without saving any changes you have made, +{:q!^M} does the trick. If you have not made any changes, the exclamation +point is not necessary: {:q^M}. Vi is pretty good about not letting you +get out without warning you that you haven't saved your file. + +We have mentioned before that you are currently in the vi editor, editing a +file. If you wish to start the tutorial over from the very beginning, you +could {ZZ}, and then type {vi.tut beginner} in response to the Unix prompt. +This will create a fresh copy of this file for you, which might be necessary +if you accidentally destroyed the copy you were working with. Just do a +search for the last section you were in: e.g. {/Section 18:/^Mz^M}. + +Section 19: {H} {M} {L} + +Here are a few more commands that will move you around on the screen. Again, +they are not absolutely necessary, but they can make screen positioning easier: + +{H} - puts the cursor at the top of the screen (the 'home' position) + +{M} - puts the cursor in the middle of the screen + +{L} - puts the cursor at the bottom of the screen. + +Try typing {HML} and watch the cursor. + +Try typing {5HM5L} and note that 5H puts you five lines from the top of the +screen, and 5L puts you five lines from the bottom of the screen. + +Section 20: {w} {b} {0} {W} {B} {e} {E} {'} {`} + +Up to this point we have concentrated on positioning in the file, and +positioning on the screen. Now let's look at positioning in a line. Put the +cursor at the beginning of the following line and type {z^M}: + +This is a test line: your cursor should initially be at its beginning. + +The test line should now be at the top of your screen. Type {w} several times. +Note that it moves you forward to the beginning of the next word. Now type +{b} (back to the beginning of the word) several times till you are at the +beginning of the line. (If you accidentally type too many {b}, type {w} until +you are on the beginning of the line again.) Type {wwwww} (five w's) and note +that the cursor is now on the colon in the sentence. The lower-case w command +moves you forward one word, paying attention to certain characters such as +colon and period as delimiters and counting them as words themselves. Now +type {0} (zero, not o 'oh'): this moves you to the beginning of the current +line. Now type {5w} and notice that this has the effect of repeating {w} five +times and that you are now back on the colon. Type {0} (zero) again. To +ignore the delimiters and to move to the beginning of the next word using only +blanks, tabs and carriage-returns (these are called white-space characters) to +delimit the words, use the {W} command: upper-case W. {B} takes you back a +word using white-space characters as word delimiters. + +Note that the commands {wbWB} do not stop at the beginning or end of a line: +they will continue to the next word on the next line in the direction specified +(a blank line counts as a word). + +If you are interested in the END of the word, and not the BEGINNING, then use +the {e} and {E} commands. These commands only move forward and there are no +corresponding 'reverse search' commands for the end of a word. + +Also, we have been using the {'} command to move the cursor to a position that +we have previously marked with the {m} command. However, position the cursor +in the middle of a line (any line, just pick one) and type {mk}, marking that +position with the letter k. Now type a few returns {^M} and type {'k}. +Observe that the cursor is now at the beginning of the line that you marked. +Now try {`k}: note that this is the reverse apostrophe, or back-quote, or grave +accent, or whatever you want to call it. Also note that it moves you to the +character that was marked, not just to the line that was marked. + +In addition, the {``} command works just like the {''} command except that you +are taken to the exact character, not just to the line. (I'm still not +sure which exact character, just as I'm still not sure which line.) + +Section 21: {l} {k} {j} {h} + +There are several commands to move around on the screen on a character by +character basis: + +l - moves the cursor one character to the RIGHT +k - moves the cursor UP one line +j - moves the cursor DOWN one line +h - moves the cursor one character to the LEFT + +Section 22: {i} {a} {I} {A} {o} {O} ^[ (escape key) + +For this and following sections you will need to use the ESCAPE key on your +terminal. It is usually marked ESC. Since the escape key is the same as +typing {^[} we will use ^[ for the escape key. + +Probably the most often used command in an editor is the insert command. Below +are two lines of text, the first correct, the second incorrect. Position your +cursor at the beginning of Line 1 and type {z^M}. + +Line 1: This is an example of the insert command. +Line 2: This is an of the insert command. + +To make line 2 look like line 1, we are going to insert the characters +'example ' before the word 'of'. So, now move the cursor so that it is +positioned on the 'o' of 'of'. (You can do this by typing {^M} to move +to the beginning of line 2, followed by {6w} or {wwwwww} to position the cursor +on the word 'of'.) + +Now carefully type the following string and observe the effects: + {iexample ^[} (remember: ^[ is the escape key)} +The {i} begins the insert mode, and 'example ' is inserted into the line: +be sure to notice the blank in 'example '. The ^[ ends insertion mode, +and the line is updated to include the new string. Line 1 should look exactly +like Line 2. + +Move the cursor to the beginning of Line 3 below and type {z^M}: + +Line 3: These lines are examples for the 'a' command. +Line 4: These line are examples for the ' + +We will change line four to look like line three by using the append command. +We need to append an 's' to the word 'line'. Position the cursor on the 'e' +of 'line'. You can do this in several ways, one way is the following: +First, type {/line /^M}. This puts us on the word 'line' in Line 4 +(the blank in the search string is important!). Next, type {e}. The 'e' puts +us at the end of the word. Now, type {as^[ (^[ is the escape character)}. +The 'a' puts us in insert mode, AFTER the current character. We appended the +'s', and the escape ^[ ended the insert mode. + +The difference between {i} (insert) and {a} (append) is that {i} begins +inserting text BEFORE the cursor, and {a} begins inserting AFTER the cursor. + +Now type {Aa' command.^[}. The cursor is moved to the end of the line and the +string following {A} is inserted into the text. Line 4 should now look like +line 3. + +Just as {A} moves you to the end of the line to begin inserting, {I} would +begin inserting at the FRONT of the line. + +To begin the insertion of a line after the cursor line, type {o}. To insert a +line before the cursor line, type {O}. In other words {o123^[} is equivalent +to {A^M123^[}, and {O123^[} is equivalent to {I123^M^[}. The text after the +{o} or {O} is ended with an escape ^[. + +This paragraph contains information that is terminal dependent: you will just +have to experiment to discover what your terminal does. Once in the insert +mode, if you make a mistake in the typing, ^H will delete the previous +character up to the beginning of the current insertion. ^W will delete the +previous word, and one of ^U, @, or ^X will delete the current line (up to the +beginning of the current insertion). You will need to experiment with ^U, @, +and ^X to determine which works for your terminal. + +Section 23: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J} + +Position the cursor at the beginning of line 5 and {z^M}: + +Line 5: The line as it should be. +Line 6: The line as it shouldn't be. + +To make Line 6 like Line 5, we have to delete the 'n', the apostrophe, and the +'t'. There are several ways to position ourselves at the 'n'. Choose +whichever one suits your fancy: + +{/n't/^M} +{^M7w6l} or {^M7w6 } (note the space) +{^M3fn} (finds the 3rd 'n' on the line) + +Now {xxx} will delete the three characters, as will {3x}. + +Note that {X} deletes the character just BEFORE the cursor, as opposed +to the character AT the cursor. + +Position the cursor at line 7 and {z^M}: + +Line 7: The line as it would be. +Line 8: The line as it could be. + +To change line 8 into line 7 we need to change the 'c' in 'could' into a 'w'. +The 'r' (replace) command was designed for this. Typing {rc} is the same as +typing {xic^[} (i.e. delete the 'bad' character and insert the correct +new character). Therefore, assuming that you have positioned the cursor on the +'c' of 'could', the easiest way to change 'could' into 'would' is {rw}. + +If you would like to now change the 'would' into 'should', use the substitute +command, 's': {ssh^[}. The difference between 'r' and 's' is that 'r' +(replace) replaces the current character with another character, while 's' +(substitute) substitutes the current character with a string, ended with an +escape. + +The capital letter version of replace {R} replaces each character by a +character one at a time until you type an escape, ^[. The 'S' command +substitutes the whole line. + +Position your cursor at the beginning of line 9 and {z^M}. + +Line 9: Love is a many splendored thing. +Line 10: Love is a most splendored thing. + +To change line 10 into line 9, position the cursor at the beginning of 'most', +and type {Rmany^[}. + +You may have noticed that, when inserting text, a new line is formed by typing +{^M}. When changing, replacing, or substituting text you can make a new line +by typing {^M}. However, neither {x} nor {X} will remove ^M to make two lines +into one line. To do this, position the cursor on the first of the two lines +you wish to make into a single line and type {J} (uppercase J for 'Join'). + +Section 24: {u} {U} + +Finally, before we review, let's look at the undo command. Position +your cursor on line 11 below and {z^M}. + +Line 11: The quick brown fox jumped over the lazy hound dog. +Line 12: the qwick black dog dumped over the laxy poune fox. + +Type the following set of commands, and observe carefully the effect of each +of the commands: + +{/^Line 12:/^M} {ft} {rT} {fw} {ru} {w} {Rbrown fox^[} {w} {rj} +{fx} {rz} {w} {Rhound dog^[} + +Line 12 now matches line 11. Now type {U} - capital 'U'. And line 12 now +looks like it did before you typed in the command strings. Now type: + +{ft} {rT} {fw} {ru} {^M} {^M} + +and then type {u}: the cursor jumps back to the line containing the second +change you made and 'undoes' it. That is, {U} 'undoes' all the changes on the +line, and {u} 'undoes' only the last change. Type {u} several times and +observe what happens: {u} can undo a previous {u}! + +Caveat: {U} only works as long as the cursor is still on the line. Move the +cursor off the line and {U} will have no effect, except to possibly beep at +you. However, {u} will undo the last change, no matter where it occurred. + +Section 25: review + +At this point, you have all the commands you need in order to make use of vi. +The remainder of this tutorial will discuss variations on these commands as +well as introduce new commands that make the job of editing more efficient. +Here is a brief review of the basic commands we have covered. They are listed +in the order of increasing complexity and/or decreasing necessity (to say that +a command is less necessary is not to say that it is less useful!). These +commands allow you to comfortably edit any text file. There are other +commands that will make life easier but will require extra time to learn, +obviously. You may want to consider setting this tutorial aside for several +weeks and returning to it later after gaining experience with vi and getting +comfortable with it. The convenience of some of the more exotic commands may +then be apparent and worth the extra investment of time and effort +required to master them. + +to get into the editor from Unix: {vi filename} +to exit the editor + saving all changes {ZZ} or {:wq^M} + throwing away all changes {:q!^M} + when no changes have been made {:q^M} +save a file without exiting the editor {:w^M} +write the file into another file {:w filename^M} +insert text + before the cursor {i ...text... ^[} + at the beginning of the line {I ...text... ^[} + after the cursor (append) {a ...text... ^[} + at the end of the line {A ...text... ^[} + after the current line {o ...text... ^[} + before the current line {O ...text... ^[} +delete the character ... + under the cursor {x} + to the left of the cursor {X} +delete n characters {nx} or {nX} (for n a number) +make two lines into one line (Join) {J} +find a string in the file ... + searching forward {/ ...string... /^M} + searching backwards {? ...string... ?^M} +repeat the last search command {n} +repeat the last search command in the + opposite direction {N} +find the character c on this line ... + searching forward {fc} + searching backward {Fc} +repeat the last 'find character' command {;} +replace a character with character x {rx} +substitute a single character with text {s ...text... ^[} +substitute n characters with text {ns ...text... ^[} +replace characters one-by-one with text {R ...text... ^[} +undo all changes to the current line {U} +undo the last single change {u} +move forward in the file a "screenful" {^F} +move back in the file a "screenful" {^B} +move forward in the file one line {^M} or {+} +move backward in the file one line {-} +move to the beginning of the line {0} +move to the end of the line {$} +move forward one word {w} +move forward one word, ignoring punctuation {W} +move forward to the end of the next word {e} +to the end of the word, ignoring punctuation{E} +move backward one word {b} +move back one word, ignoring punctuation {B} +return to the last line modified {''} +scroll a line onto the top of the screen {^Y} +scroll a line onto the bottom of the screen {^E} +move "up" in the file a half-screen {^U} +move "down" in the file a half-screen {^D} +move the cursor to the top screen line {H} +move the cursor to the bottom screen line {L} +move the cursor to the middle line {M} +move LEFT one character position {h} or {^H} +move RIGHT one character position {l} or { } +move UP in the same column {k} or {^P} +move DOWN in the same column {j} or {^N} +mark the current position, name it x {mx} +move to the line marked/named x {'x} +move to the character position named x {`x} +move to the beginning of the file {1G} +move to the end of the file {G} +move to line 23 in the file {23G} +repaint the screen with the cursor line + at the top of the screen {z^M} + in the middle of the screen {z.} + at the bottom of the screen {z-} + +More information on vi can be found in the file vi.advanced, which you can +peruse at your leisure. From UNIX, type {vi.tut advanced^M}. diff --git a/usr.bin/vi/docs/tutorial/vi.tut.csh b/usr.bin/vi/docs/tutorial/vi.tut.csh new file mode 100644 index 00000000000..01554bc4e5f --- /dev/null +++ b/usr.bin/vi/docs/tutorial/vi.tut.csh @@ -0,0 +1,24 @@ +#!/bin/csh -f +# +# This makes the user's EXINIT variable set to the 'correct' things. +# I don't know what will happen if they also have a .exrc file! +# +# XXX +# Make sure that user is using a 24 line window!!! +# +if ($1 != "beginner" && $1 != "advanced") then + echo Usage: $0 beginner or $0 advanced + exit +endif + +if ($?EXINIT) then + set oexinit="$EXINIT" + setenv EXINIT 'se ts=4 wm=8 sw=4' +endif + +vi vi.{$1} + +onintr: + if ($?oexinit) then + setenv EXINIT "$oexinit" +endif |