diff --git a/pkin/TODO b/pkin/TODO new file mode 100644 index 0000000..45183b4 --- /dev/null +++ b/pkin/TODO @@ -0,0 +1,2 @@ +fetch caching +make pkin_extractjobs nproc(1) by default diff --git a/pkin/asset/Makefile b/pkin/asset/Makefile new file mode 100644 index 0000000..5ec22d9 --- /dev/null +++ b/pkin/asset/Makefile @@ -0,0 +1,2 @@ +example.binpkg.tar: + cd example.binpkg; tar vcf ../$@ * diff --git a/pkin/asset/example.a b/pkin/asset/example.a index f74ba44..eacc288 100644 --- a/pkin/asset/example.a +++ b/pkin/asset/example.a @@ -1,2 +1,2 @@ -lr 1.0 foo https://lab0x13.site/index.html +lr 1.0 foo http://localhost:8081/example.binpkg.tar asd 1.0 asd http://kentoj/index.html diff --git a/pkin/asset/example.binpkg.tar b/pkin/asset/example.binpkg.tar new file mode 100644 index 0000000..53ccb8c Binary files /dev/null and b/pkin/asset/example.binpkg.tar differ diff --git a/pkin/asset/example.binpkg/bin/vi b/pkin/asset/example.binpkg/bin/vi new file mode 100755 index 0000000..1529ecc Binary files /dev/null and b/pkin/asset/example.binpkg/bin/vi differ diff --git a/pkin/asset/example.binpkg/man/man1/vi.1 b/pkin/asset/example.binpkg/man/man1/vi.1 new file mode 100644 index 0000000..7cb80f3 --- /dev/null +++ b/pkin/asset/example.binpkg/man/man1/vi.1 @@ -0,0 +1,1616 @@ +.\" Copyright (c) 1994 +.\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 1994, 1995, 1996 +.\" Keith Bostic. All rights reserved. +.\" +.\" This document may not be republished without written permission from +.\" Keith Bostic. +.\" +.\" See the LICENSE file for redistribution information. +.\" +.\" $Id: vi.1,v 8.53 2001/01/28 13:20:06 skimo Exp $ (Berkeley) $Date: 2001/01/28 13:20:06 $ +.\" +.TH VI 1 "%Q%" +.UC +.SH NAME +ex, vi, view \- text editors +.SH SYNOPSIS +.B ex +[\c +.B \-eRrSsv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.br +.B vi +[\c +.B \-elRrSv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.br +.B view +[\c +.B \-eRrSv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.SH LICENSE +The vi program is freely redistributable. You are welcome to copy, +modify and share it with others under the conditions listed in the +LICENSE file. If any company (not individual!) finds vi sufficiently +useful that you would have purchased it, or if any company wishes to +redistribute it, contributions to the authors would be appreciated. +.SH DESCRIPTION +.I \&Vi +is a screen oriented text editor. +.I \&Ex +is a line\(hyoriented text editor. +.I \&Ex +and +.I \&vi +are different interfaces to the same program, +and it is possible to switch back and forth during an edit session. +.I View +is the equivalent of using the +.B \-R +(read\(hyonly) option of +.IR \&vi . +.PP +This manual page is the one provided with the +.I nex/nvi +versions of the +.I ex/vi +text editors. +.I Nex/nvi +are intended as bug\(hyfor\(hybug compatible replacements for the original +Fourth Berkeley Software Distribution (4BSD) +.I \&ex +and +.I \&vi +programs. +For the rest of this manual page, +.I nex/nvi +is used only when it's necessary to distinguish it from the historic +implementations of +.IR ex/vi . +.PP +This manual page is intended for users already familiar with +.IR ex/vi . +Anyone else should almost certainly read a good tutorial on the +editor before this manual page. +If you're in an unfamiliar environment, and you absolutely have to +get work done immediately, read the section after the options +description, entitled \(lqFast Startup\(rq. +It's probably enough to get you going. +.PP +The following options are available: +.TP +.B \-c +Execute +.B cmd +immediately after starting the edit session. +Particularly useful for initial positioning in the file, however +.B cmd +is not limited to positioning commands. +This is the POSIX 1003.2 interface for the historic \(lq+cmd\(rq syntax. +.I Nex/nvi +supports both the old and new syntax. +.TP +.B \-e +Start editing in ex mode, as if the command name were +.IR \&ex . +.TP +.B \-l +Start editing with the lisp and showmatch options set. +.TP +.B \-R +Start editing in read\(hyonly mode, as if the command name was +.IR view , +or the +.B readonly +option was set. +.TP +.B \-r +Recover the specified files, or, if no files are specified, +list the files that could be recovered. +If no recoverable files by the specified name exist, +the file is edited as if the +.B \-r +option had not been specified. +.TP +.B \-S +Run with the +.B secure +edit option set, disallowing all access to external programs. +.TP +.B \-s +Enter batch mode; applicable only to +.I \&ex +edit sessions. +Batch mode is useful when running +.I \&ex +scripts. +Prompts, informative messages and other user oriented message +are turned off, +and no startup files or environmental variables are read. +This is the POSIX 1003.2 interface for the historic \(lq\-\(rq argument. +.I \&Nex/nvi +supports both the old and new syntax. +.TP +.B \-t +Start editing at the specified tag. +(See +.IR ctags (1)). +.TP +.B \-w +Set the initial window size to the specified number of lines. +.TP +.B \-v +Start editing in vi mode, as if the command name was +.I \&vi +or +.IR view . +.PP +Note that the \fB-F\fP option (which prevented \fIex/vi\fP from making +a full backup of the target file) has been removed and is no longer available. +.PP +Command input for +.I ex/vi +is read from the standard input. +In the +.I \&vi +interface, it is an error if standard input is not a terminal. +In the +.I \&ex +interface, if standard input is not a terminal, +.I \&ex +will read commands from it regardless, however, the session will be a +batch mode session, exactly as if the +.B \-s +option had been specified. +.PP +.I Ex/vi +exits 0 on success, and greater than 0 if an error occurs. +.SH FAST STARTUP +This section will tell you the minimum amount that you need to +do simple editing tasks using +.IR \&vi . +If you've never used any screen editor before, you're likely to have +problems even with this simple introduction. +In that case you should find someone that already knows +.I \&vi +and have them walk you through this section. +.PP +.I \&Vi +is a screen editor. +This means that it takes up almost the entire screen, displaying part +of the file on each screen line, except for the last line of the screen. +The last line of the screen is used for you to give commands to +.IR \&vi , +and for +.I \&vi +to give information to you. +.PP +The other fact that you need to understand is that +.I \&vi +is a modeful editor, i.e. you are either entering text or you +are executing commands, and you have to be in the right mode +to do one or the other. +You will be in command mode when you first start editing a file. +There are commands that switch you into input mode. +There is only one key that takes you out of input mode, +and that is the key. +(Key names are written using less\(hythan and greater\(hythan signs, e.g. + means the \(lqescape\(rq key, usually labeled \(lqesc\(rq on your +terminal's keyboard.) +If you're ever confused as to which mode you're in, +keep entering the key until +.I \&vi +beeps at you. +(Generally, +.I \&vi +will beep at you if you try and do something that's not allowed. +It will also display error messages.) +.PP +To start editing a file, enter the command \(lqvi file_name\(rq. +The command you should enter as soon as you start editing is +\(lq:set verbose showmode\(rq. +This will make the editor give you verbose error messages and display +the current mode at the bottom of the screen. +.PP +The commands to move around the file are: +.TP +.B h +Move the cursor left one character. +.TP +.B j +Move the cursor down one line. +.TP +.B k +Move the cursor up one line. +.TP +.B l +Move the cursor right one character. +.TP +.B +The cursor arrow keys should work, too. +.TP +.B /text +Search for the string \(lqtext\(rq in the file, +and move the cursor to its first character. +.PP +The commands to enter new text are: +.TP +.B a +Append new text, +.I after +the cursor. +.TP +.B i +Insert new text, +.I before +the cursor. +.TP +.B o +Open a new line below the line the cursor is on, and start +entering text. +.TP +.B O +Open a new line above the line the cursor is on, and start +entering text. +.TP +.B +Once you've entered input mode using the one of the +.BR \&a , +.BR \&i , +.BR \&O +or +.B \&o +commands, use +.B +to quit entering text and return to command mode. +.PP +The commands to copy text are: +.TP +.B yy +Copy the line the cursor is on. +.TP +.B p +Append the copied line after the line the cursor is on. +.PP +The commands to delete text are: +.TP +.B dd +Delete the line the cursor is on. +.TP +.B x +Delete the character the cursor is on. +.PP +The commands to write the file are: +.TP +.B :w +Write the file back to the file with the name that you originally used +as an argument on the +.I \&vi +command line. +.TP +.B ":w file_name" +Write the file back to the file with the name \(lqfile_name\(rq. +.PP +The commands to quit editing and exit the editor are: +.TP +.B :q +Quit editing and leave vi (if you've modified the file, but not +saved your changes, +.I \&vi +will refuse to quit). +.TP +.B :q! +Quit, discarding any modifications that you may have made. +.PP +One final caution. +Unusual characters can take up more than one column on the screen, +and long lines can take up more than a single screen line. +The above commands work on \(lqphysical\(rq characters and lines, +i.e. they affect the entire line no matter how many screen lines it +takes up and the entire character no matter how many screen columns +it takes up. +.SH VI COMMANDS +The following section describes the commands available in the command +mode of the +.I \&vi +editor. +In each entry below, the tag line is a usage synopsis for the command +character. +.PP +.TP +.B "[count] " +Search forward +.I count +times for the current word. +.TP +.B "[count] " +Page backwards +.I count +screens. +.TP +.B "[count] " +Scroll forward +.I count +lines. +.TP +.B "[count] " +Scroll forward +.I count +lines, leaving the current line and column as is, if possible. +.TP +.B "[count] " +Page forward +.I count +screens. +.TP +.B "" +Display the file information. +.TP +.B "" +.TP +.B "[count] h" +Move the cursor back +.I count +characters in the current line. +.TP +.B "[count] " +.TP +.B "[count] " +.TP +.B "[count] j" +Move the cursor down +.I count +lines without changing the current column. +.TP +.B "" +.TP +.B "" +Repaint the screen. +.TP +.B "[count] " +.TP +.B "[count] +" +Move the cursor down +.I count +lines to the first nonblank character of that line. +.TP +.B "[count] " +.TP +.B "[count] k" +Move the cursor up +.I count +lines, without changing the current column. +.TP +.B "" +Return to the most recent tag context. +.TP +.B "" +Scroll backwards +.I count +lines. +.TP +.B "" +Switch to the next lower screen in the window, or, to the first +screen if there are no lower screens in the window. +.TP +.B "" +Scroll backwards +.I count +lines, leaving the current line and column as is, if possible. +.TP +.B "" +Suspend the current editor session. +.TP +.B "" +Execute +.I \&ex +commands or cancel partial commands. +.TP +.B "" +Push a tag reference onto the tag stack. +.TP +.B "" +Switch to the most recently edited file. +.TP +.B "[count] " +.TP +.B "[count] l" +Move the cursor forward +.I count +characters without changing the current line. +.TP +.B "[count] ! motion shell\(hyargument(s)" +Replace text with results from a shell command. +.TP +.B "[count] # #|+|\-" +Increment or decrement the cursor number. +.TP +.B "[count] $" +Move the cursor to the end of a line. +.TP +.B "%" +Move to the matching character. +.TP +.B "&" +Repeat the previous substitution command on the current line. +.TP +.B "'" +.TP +.B "\`" +Return to a context marked by the character +.IR . +.TP +.B "[count] (" +Back up +.I count +sentences. +.TP +.B "[count] )" +Move forward +.I count +sentences. +.TP +.B "[count] ," +Reverse find character +.I count +times. +.TP +.B "[count] \-" +Move to first nonblank of the previous line, +.I count +times. +.TP +.B "[count] ." +Repeat the last +.I \&vi +command that modified text. +.TP +.B "/RE" +.TP +.B "/RE/ [offset]" +.TP +.B "?RE" +.TP +.B "?RE? [offset]" +.TP +.B "N" +.TP +.B "n" +Search forward or backward for a regular expression. +.TP +.B "0" +Move to the first character in the current line. +.TP +.B ":" +Execute an ex command. +.TP +.B "[count] ;" +Repeat the last character find +.I count +times. +.TP +.B "[count] < motion" +.TP +.B "[count] > motion" +Shift lines left or right. +.TP +.B "@ buffer" +Execute a named buffer. +.TP +.B "[count] A" +Enter input mode, appending the text after the end of the line. +.TP +.B "[count] B" +Move backwards +.I count +bigwords. +.TP +.B "[buffer] [count] C" +Change text from the current position to the end\(hyof\(hyline. +.TP +.B "[buffer] D" +Delete text from the current position to the end\(hyof\(hyline. +.TP +.B "[count] E" +Move forward +.I count +end\(hyof\(hybigwords. +.TP +.B "[count] F " +Search +.I count +times backward through the current line for +.IR . +.TP +.B "[count] G" +Move to line +.IR count , +or the last line of the file if +.I count +not specified. +.TP +.B "[count] H" +Move to the screen line +.I "count \- 1" +lines below the top of the screen. +.TP +.B "[count] I" +Enter input mode, inserting the text at the beginning of the line. +.TP +.B "[count] J" +Join lines. +.TP +.B "[count] L" +Move to the screen line +.I "count \- 1" +lines above the bottom of the screen. +.TP +.B " M" +Move to the screen line in the middle of the screen. +.TP +.B "[count] O" +Enter input mode, appending text in a new line above the current line. +.TP +.B "[buffer] P" +Insert text from a buffer. +.TP +.B "Q" +Exit +.I \&vi +(or visual) mode and switch to +.I \&ex +mode. +.TP +.B "[count] R" +Enter input mode, replacing the characters in the current line. +.TP +.B "[buffer] [count] S" +Substitute +.I count +lines. +.TP +.B "[count] T " +Search backwards, +.I count +times, +through the current line for the character +.I after +the specified +.IR . +.TP +.B "U" +Restore the current line to its state before the cursor last +moved to it. +.TP +.B "[count] W" +Move forward +.I count +bigwords. +.TP +.B "[buffer] [count] X" +Delete +.I count +characters before the cursor. +.TP +.B "[buffer] [count] Y" +Copy (or \(lqyank\(rq) +.I count +lines into the specified buffer. +.TP +.B "ZZ" +Write the file and exit +.IR \&vi . +.TP +.B "[count] [[" +Back up +.I count +section boundaries. +.TP +.B "[count] ]]" +Move forward +.I count +section boundaries. +.TP +.B "\&^" +Move to first nonblank character on the current line. +.TP +.B "[count] _" +Move down +.I "count \- 1" +lines, to the first nonblank character. +.TP +.B "[count] a" +Enter input mode, appending the text after the cursor. +.TP +.B "[count] b" +Move backwards +.I count +words. +.TP +.B "[buffer] [count] c motion" +Change a region of text. +.TP +.B "[buffer] [count] d motion" +Delete a region of text. +.TP +.B "[count] e" +Move forward +.I count +end\(hyof\(hywords. +.TP +.B "[count] f" +Search forward, +.I count +times, through the rest of the current line for +.IR . +.TP +.B "[count] i" +Enter input mode, inserting the text before the cursor. +.TP +.B "m " +Save the current context (line and column) as +.IR . +.TP +.B "[count] o" +Enter input mode, appending text in a new line under the current line. +.TP +.B "[buffer] p" +Append text from a buffer. +.TP +.B "[count] r " +Replace +.I count +characters. +.TP +.B "[buffer] [count] s" +Substitute +.I count +characters in the current line starting with the current character. +.TP +.B "[count] t " +Search forward, +.I count +times, through the current line for the character immediately +.I before +.IR . +.TP +.B "u" +Undo the last change made to the file. +.TP +.B "[count] w" +Move forward +.I count +words. +.TP +.B "[buffer] [count] x" +Delete +.I count +characters. +.TP +.B "[buffer] [count] y motion" +Copy (or \(lqyank\(rq) +a text region specified by the +.I count +and motion into a buffer. +.TP +.B "[count1] z [count2] \-|.|+|^|" +Redraw, optionally repositioning and resizing the screen. +.TP +.B "[count] {" +Move backward +.I count +paragraphs. +.TP +.B "[count] |" +Move to a specific +.I column +position on the current line. +.TP +.B "[count] }" +Move forward +.I count +paragraphs. +.TP +.B "[count] ~" +Reverse the case of the next +.I count +character(s), if the +.B tildeop +option is +.IR unset . +.TP +.B "[count] ~ motion" +Reverse the case of the characters in a text region specified by the +.I count +and +.IR motion , +if the +.B tildeop +option is +.IR set . +.TP +.B "" +Interrupt the current operation. +.SH VI TEXT INPUT COMMANDS +The following section describes the commands available in the text +input mode of the +.I \&vi +editor. +.PP +.TP +.B "" +Replay the previous input. +.TP +.B "" +Erase to the previous +.B shiftwidth +column boundary. +.TP +.B "^" +Erase all of the autoindent characters, and reset the autoindent level. +.TP +.B "0" +Erase all of the autoindent characters. +.TP +.B "" +Insert sufficient +.I +and +.I +characters to move forward to the next +.B shiftwidth +column boundary. +.TP +.B " +.TP +.B "" +Erase the last character. +.TP +.B "" +Quote the next character. +.TP +.B " +Resolve all text input into the file, and return to command mode. +.TP +.B "" +Erase the current line. +.TP +.B "" +.TP +.B "" +Erase the last word. +The definition of word is dependent on the +.B altwerase +and +.B ttywerase +options. +.TP +.B "[0\-9A\-Fa\-f]+" +Insert a character with the specified hexadecimal value into the text. +.TP +.B "" +Interrupt text input mode, returning to command mode. +.SH EX COMMANDS +The following section describes the commands available in the +.I \&ex +editor. +In each entry below, the tag line is a usage synopsis for the command. +.PP +.TP +.B "" +Scroll the screen. +.TP +.B "! argument(s)" +.TP +.B "[range]! argument(s)" +Execute a shell command, or filter lines through a shell command. +.TP +.B \&" +A comment. +.TP +.B "[range] nu[mber] [count] [flags]" +.TP +.B "[range] # [count] [flags]" +Display the selected lines, each preceded with its line number. +.TP +.B "@ buffer" +.TP +.B "* buffer" +Execute a buffer. +.TP +.B "[line] a[ppend][!]" +The input text is appended after the specified line. +.TP +.B "[range] c[hange][!] [count]" +The input text replaces the specified range. +.TP +.B "cs[cope] add | find | help | kill | reset" +Execute a Cscope command. +.TP +.B "[range] d[elete] [buffer] [count] [flags]" +Delete the lines from the file. +.TP +.B "di[splay] b[uffers] | c[onnections] | s[creens] | t[ags]" +Display buffers, Cscope connections, screens or tags. +.TP +.B "[Ee][dit][!] [+cmd] [file]" +.TP +.B "[Ee]x[!] [+cmd] [file]" +Edit a different file. +.TP +.B "exu[sage] [command]" +Display usage for an +.I \&ex +command. +.TP +.B "f[ile] [file]" +Display and optionally change the file name. +.TP +.B "[Ff]g [name]" +.I \&Vi +mode only. +Foreground the specified screen. +.TP +.B "[range] g[lobal] /pattern/ [commands]" +.TP +.B "[range] v /pattern/ [commands]" +Apply commands to lines matching (or not matching) a pattern. +.TP +.B "he[lp]" +Display a help message. +.TP +.B "[line] i[nsert][!]" +The input text is inserted before the specified line. +.TP +.B "[range] j[oin][!] [count] [flags]" +Join lines of text together. +.TP +.B "[range] l[ist] [count] [flags]" +Display the lines unambiguously. +.TP +.B "map[!] [lhs rhs]" +Define or display maps (for +.I \&vi +only). +.TP +.B "[line] ma[rk] " +.TP +.B "[line] k " +Mark the line with the mark +.IR . +.TP +.B "[range] m[ove] line" +Move the specified lines after the target line. +.TP +.B "mk[exrc][!] file" +Write the abbreviations, editor options and maps to the specified +file. +.TP +.B "[Nn][ext][!] [file ...]" +Edit the next file from the argument list. +.TP +.B "[line] o[pen] /pattern/ [flags]" +Enter open mode. +.TP +.B "pre[serve]" +Save the file in a form that can later be recovered using the +.I \&ex +.B \-r +option. +.TP +.B "[Pp]rev[ious][!]" +Edit the previous file from the argument list. +.TP +.B "[range] p[rint] [count] [flags]" +Display the specified lines. +.TP +.B "[line] pu[t] [buffer]" +Append buffer contents to the current line. +.TP +.B "q[uit][!]" +End the editing session. +.TP +.B "[line] r[ead][!] [file]" +Read a file. +.TP +.B "rec[over] file" +Recover +.I file +if it was previously saved. +.TP +.B "res[ize] [+|\-]size" +.I \&Vi +mode only. +Grow or shrink the current screen. +.TP +.B "rew[ind][!]" +Rewind the argument list. +.TP +.B "se[t] [option[=[value]] ...] [nooption ...] [option? ...] [all]" +Display or set editor options. +.TP +.B "sh[ell]" +Run a shell program. +.TP +.B "so[urce] file" +Read and execute +.I \&ex +commands from a file. +.TP +.B "[range] s[ubstitute] [/pattern/replace/] [options] [count] [flags]" +.TP +.B "[range] & [options] [count] [flags]" +.TP +.B "[range] ~ [options] [count] [flags]" +Make substitutions. +.TP +.B "su[spend][!]" +.TP +.B "st[op][!]" +.TP +.B +Suspend the edit session. +.TP +.B "[Tt]a[g][!] tagstring" +Edit the file containing the specified tag. +.TP +.B "tagn[ext][!]" +Edit the file containing the next context for the current tag. +.TP +.B "tagp[op][!] [file | number]" +Pop to the specified tag in the tags stack. +.TP +.B "tagp[rev][!]" +Edit the file containing the previous context for the current tag. +.TP +.B "unm[ap][!] lhs" +Unmap a mapped string. +.TP +.B "ve[rsion]" +Display the version of the +.I \&ex/vi +editor. +.TP +.B "[line] vi[sual] [type] [count] [flags]" +.I \&Ex +mode only. +Enter +.IR \&vi . +.TP +.B "[Vi]i[sual][!] [+cmd] [file]" +.I \&Vi +mode only. +Edit a new file. +.TP +.B "viu[sage] [command]" +Display usage for a +.I \&vi +command. +.TP +.B "[range] w[rite][!] [>>] [file]" +.TP +.B "[range] w[rite] [!] [file]" +.TP +.B "[range] wn[!] [>>] [file]" +.TP +.B "[range] wq[!] [>>] [file]" +Write the file. +.TP +.B "[range] x[it][!] [file]" +Write the file if it has been modified. +.TP +.B "[range] ya[nk] [buffer] [count]" +Copy the specified lines to a buffer. +.TP +.B "[line] z [type] [count] [flags]" +Adjust the window. +.SH SET OPTIONS +There are a large number of options that may be set (or unset) to +change the editor's behavior. +This section describes the options, their abbreviations and their +default values. +.PP +In each entry below, the first part of the tag line is the full name +of the option, followed by any equivalent abbreviations. +The part in square brackets is the default value of the option. +Most of the options are boolean, i.e. they are either on or off, +and do not have an associated value. +.PP +Options apply to both +.I \&ex +and +.I \&vi +modes, unless otherwise specified. Multiple options can be given in +one set or unset, separated by spaces or tabs. Spaces and tabs can be +included in string options (eg. tags or filec) by preceding each with +a backslash. There's no way to get backslash itself into an option. +.PP +.TP +.B "altwerase [off]" +.I \&Vi +only. +Select an alternate word erase algorithm. +.TP +.B "autoindent, ai [off]" +Automatically indent new lines. +.TP +.B "autoprint, ap [off]" +.I \&Ex +only. +Display the current line automatically. +.TP +.B "autowrite, aw [off]" +Write modified files automatically when changing files. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms backup [QQ] +.TP +.B "\*(ms" +.tr QQ +Backup files before they are overwritten. +.TP +.B "beautify, bf [off]" +Discard control characters. +.TP +.B "cdpath [environment variable CDPATH, or current directory]" +The directory paths used as path prefixes for the +.B cd +command. +.TP +.B "cedit [no default]" +Set the character to edit the colon command\(hyline history. +.TP +.B "columns, co [80]" +Set the number of columns in the screen. +.TP +.B "comment [off]" +.I \&Vi +only. +Skip leading comments in shell, C and C++ language files. +.TP +.B "directory, dir [environment variable TMPDIR, or /tmp]" +The directory where temporary files are created. +.TP +.B "edcompatible, ed [off]" +Remember the values of the \(lqc\(rq and \(lqg\(rq suffices to the +.B substitute +commands, instead of initializing them as unset for each new +command. +.TP +.B "errorbells, eb [off]" +.I \&Ex +only. +Announce error messages with a bell. +.TP +.B "exrc, ex [off]" +Read the startup files in the local directory. +.TP +.B "extended [off]" +Regular expressions are extended (i.e. +.IR egrep (1)\-\c +style) expressions. +.TP +.B "filec [no default]" +Set the character to perform file path completion on the colon +command line. +.TP +.B "flash [on]" +Flash the screen instead of beeping the keyboard on error. +.TP +.B "hardtabs, ht [8]" +Set the spacing between hardware tab settings. +.TP +.B "iclower [off]" +Makes all Regular Expressions case\(hyinsensitive, +as long as an upper\(hycase letter does not appear in the search string. +.TP +.B "ignorecase, ic [off]" +Ignore case differences in regular expressions. +.TP +.B "keytime [6]" +The 10th's of a second +.I ex/vi +waits for a subsequent key to complete a key mapping. +.TP +.B "leftright [off]" +.I \&Vi +only. +Do left\(hyright scrolling. +.TP +.B "lines, li [24]" +.I \&Vi +only. +Set the number of lines in the screen. +.TP +.B "lisp [off]" +.I \&Vi +only. +Modify various search commands and options to work with Lisp. +.I "This option is not yet implemented." +.TP +.B "list [off]" +Display lines in an unambiguous fashion. +.TP +.B "lock [on]" +Attempt to get an exclusive lock on any file being edited, +read or written. +.TP +.B "magic [on]" +Treat certain characters specially in regular expressions. +.TP +.B "matchtime [7]" +.I \&Vi +only. +The 10th's of a second +.I ex/vi +pauses on the matching character when the +.B showmatch +option is set. +.TP +.B "mesg [on]" +Permit messages from other users. +.TP +.B "modelines, modeline [off]" +Read the first and last few lines of each file for +.I ex +commands. +.I "This option will never be implemented." +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms noprint [QQ] +.TP +.B "\*(ms" +.tr QQ +Characters that are never handled as printable characters. +.TP +.B "number, nu [off]" +Precede each line displayed with its current line number. +.TP +.B "octal [off]" +Display unknown characters as octal numbers, instead of the default +hexadecimal. +.TP +.B "open [on]" +.I \&Ex +only. +If this option is not set, the +.B open +and +.B visual +commands are disallowed. +.TP +.B "optimize, opt [on]" +.I \&Vi +only. +Optimize text throughput to dumb terminals. +.I "This option is not yet implemented." +.TP +.B "paragraphs, para [IPLPPPQPP LIpplpipbp]" +.I \&Vi +only. +Define additional paragraph boundaries for the +.B \&{ +and +.B \&} +commands. +.TP +.B "path []" +Define additional directories to search for files being edited. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms print [QQ] +.TP +.B "\*(ms" +.tr QQ +Characters that are always handled as printable characters. +.TP +.B "prompt [on]" +.I \&Ex +only. +Display a command prompt. +.TP +.B "readonly, ro [off]" +Mark the file and session as read\(hyonly. +.TP +.B "recdir [/var/tmp/vi.recover]" +The directory where recovery files are stored. +.TP +.B "redraw, re [off]" +.I \&Vi +only. +Simulate an intelligent terminal on a dumb one. +.I "This option is not yet implemented." +.TP +.B "remap [on]" +Remap keys until resolved. +.TP +.B "report [5]" +Set the number of lines about which the editor reports changes +or yanks. +.TP +.B "ruler [off]" +.I \&Vi +only. +Display a row/column ruler on the colon command line. +.TP +.B "scroll, scr [window / 2]" +Set the number of lines scrolled. +.TP +.B "searchincr [off]" +Makes the +.B \&/ +and +.B \&? +commands incremental. +.TP +.B "sections, sect [NHSHH HUnhsh]" +.I \&Vi +only. +Define additional section boundaries for the +.B \&[[ +and +.B \&]] +commands. +.TP +.B "secure [off]" +Turns off all access to external programs. +.TP +.B "shell, sh [environment variable SHELL, or /bin/sh]" +Select the shell used by the editor. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms shellmeta [~{[*?$\`'Q\e] +.TP +.B "\*(ms" +.tr QQ +Set the meta characters checked to determine if file name expansion +is necessary. +.TP +.B "shiftwidth, sw [8]" +Set the autoindent and shift command indentation width. +.TP +.B "showmatch, sm [off]" +.I \&Vi +only. +Note matching \(lq{\(rq and \(lq(\(rq for \(lq}\(rq and \(lq)\(rq characters. +.TP +.B "showmode, smd [off]" +.I \&Vi +only. +Display the current editor mode and a \(lqmodified\(rq flag. +.TP +.B "sidescroll [16]" +.I \&Vi +only. +Set the amount a left\(hyright scroll will shift. +.TP +.B "slowopen, slow [off]" +Delay display updating during text input. +.I "This option is not yet implemented." +.TP +.B "sourceany [off]" +Read startup files not owned by the current user. +.I "This option will never be implemented." +.TP +.B "tabstop, ts [8]" +This option sets tab widths for the editor display. +.TP +.B "taglength, tl [0]" +Set the number of significant characters in tag names. +.TP +.B "tags, tag [tags /var/db/libc.tags /sys/kern/tags]" +Set the list of tags files. +.TP +.B "term, ttytype, tty [environment variable TERM]" +Set the terminal type. +.TP +.B "terse [off]" +This option has historically made editor messages less verbose. +It has no effect in this implementation. +.TP +.B "tildeop [off]" +Modify the +.B \&~ +command to take an associated motion. +.TP +.B "timeout, to [on]" +Time out on keys which may be mapped. +.TP +.B "ttywerase [off]" +.I \&Vi +only. +Select an alternate erase algorithm. +.TP +.B "verbose [off]" +.I \&Vi +only. +Display an error message for every error. +.TP +.B "w300 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is less than 1200 baud. +.TP +.B "w1200 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is equal to 1200 baud. +.TP +.B "w9600 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is greater than 1200 baud. +.TP +.B "warn [on]" +.I \&Ex +only. +This option causes a warning message to the terminal if the file has +been modified, since it was last written, before a +.B \&! +command. +.TP +.B "window, w, wi [environment variable LINES]" +Set the window size for the screen. +.TP +.B "windowname [off]" +Change the icon/window name to the current file name even if it can't +be restored on editor exit. +.TP +.B "wraplen, wl [0]" +.I \&Vi +only. +Break lines automatically, the specified number of columns from the +left\(hyhand margin. +If both the +.B wraplen +and +.B wrapmargin +edit options are set, the +.B wrapmargin +value is used. +.TP +.B "wrapmargin, wm [0]" +.I \&Vi +only. +Break lines automatically, the specified number of columns from the +right\(hyhand margin. +If both the +.B wraplen +and +.B wrapmargin +edit options are set, the +.B wrapmargin +value is used. +.TP +.B "wrapscan, ws [on]" +Set searches to wrap around the end or beginning of the file. +.TP +.B "writeany, wa [off]" +Turn off file\(hyoverwriting checks. +.SH "ENVIRONMENT VARIABLES +.TP +.I COLUMNS +The number of columns on the screen. +This value overrides any system or terminal specific values. +If the +.I COLUMNS +environmental variable is not set when +.I ex/vi +runs, or the +.B columns +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I EXINIT +A list of +.I \&ex +startup commands, read if the variable +.I NEXINIT +is not set. +.TP +.I HOME +The user's home directory, used as the initial directory path +for the startup \(lq$\fIHOME\fP/.nexrc\(rq and \(lq$\fIHOME\fP/.exrc\(rq +files. +This value is also used as the default directory for the +.I \&vi +.B \&cd +command. +.TP +.I LINES +The number of rows on the screen. +This value overrides any system or terminal specific values. +If the +.I LINES +environmental variable is not set when +.I ex/vi +runs, or the +.B lines +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I NEXINIT +A list of +.I \&ex +startup commands. +.TP +.I SHELL +The user's shell of choice (see also the +.B shell +option). +.TP +.I TERM +The user's terminal type. +The default is the type \(lqunknown\(rq. +If the +.I TERM +environmental variable is not set when +.I ex/vi +runs, or the +.B term +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I TMPDIR +The location used to stored temporary files (see also the +.B directory +edit option). +.SH ASYNCHRONOUS EVENTS +.TP +SIGALRM +.I \&Vi/ex +uses this signal for periodic backups of file modifications and to +display \(lqbusy\(rq messages when operations are likely to take a long time. +.TP +SIGHUP +.TP +SIGTERM +If the current buffer has changed since it was last written in its +entirety, the editor attempts to save the modified file so it can +be later recovered. +See the +.I \&vi/ex +Reference manual section entitled \(lqRecovery\(rq for more information. +.TP +SIGINT +When an interrupt occurs, +the current operation is halted, +and the editor returns to the command level. +If interrupted during text input, +the text already input is resolved into the file as if the text +input had been normally terminated. +.TP +SIGWINCH +The screen is resized. +See the +.I \&vi/ex +Reference manual section entitled \(lqSizing the Screen\(rq for more information. +.TP +SIGCONT +.TP +SIGQUIT +.TP +SIGTSTP +.I \&Vi/ex +ignores these signals. +.SH FILES +.TP +/bin/sh +The default user shell. +.TP +/etc/vi.exrc +System\(hywide vi startup file. +.TP +/tmp +Temporary file directory. +.TP +/var/tmp/vi.recover +The default recovery file directory. +.TP +$HOME/.nexrc +1st choice for user's home directory startup file. +.TP +$HOME/.exrc +2nd choice for user's home directory startup file. +.TP +\&.nexrc +1st choice for local directory startup file. +.TP +\&.exrc +2nd choice for local directory startup file. +.SH SEE ALSO +.IR ctags (1), +.IR more (1), +.IR curses (3), +.IR dbopen (3) +.sp +The \(lqVi Quick Reference\(rq card. +.sp +\(lqAn Introduction to Display Editing with Vi\(rq, found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of both the 4.3BSD and 4.4BSD manual sets. +This document is the closest thing available to an introduction to the +.I \&vi +screen editor. +.sp +\(lqEx Reference Manual (Version 3.7)\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of both the 4.3BSD and 4.4BSD manual sets. +This document is the final reference for the +.I \&ex +editor, as distributed in most historic 4BSD and System V systems. +.sp +\(lqEdit: A tutorial\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of the 4.3BSD manual set. +This document is an introduction to a simple version of the +.I \&ex +screen editor. +.sp +\(lqEx/Vi Reference Manual\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of the 4.4BSD manual set. +This document is the final reference for the +.I \&nex/nvi +text editors, as distributed in 4.4BSD and 4.4BSD\(hyLite. +.PP +.I Roff +source for all of these documents is distributed with +.I nex/nvi +in the +.I nvi/USD.doc +directory of the +.I nex/nvi +source code. +.sp +The files \(lqautowrite\(rq, \(lqinput\(rq, \(lqquoting\(rq and \(lqstructures\(rq +found in the +.I nvi/docs/internals +directory of the +.I nex/nvi +source code. +.SH HISTORY +The +.I nex/nvi +replacements for the +.I ex/vi +editor first appeared in 4.4BSD. +.SH STANDARDS +.I \&Nex/nvi +is close to IEEE Std1003.2 (\(lqPOSIX\(rq). +That document differs from historical +.I ex/vi +practice in several places; there are changes to be made on both sides. diff --git a/pkin/asset/example.lr.tar.gz b/pkin/asset/example.lr.tar.gz new file mode 100644 index 0000000..61951ca Binary files /dev/null and b/pkin/asset/example.lr.tar.gz differ diff --git a/pkin/lr.archive b/pkin/lr.archive new file mode 100644 index 0000000..53ccb8c Binary files /dev/null and b/pkin/lr.archive differ diff --git a/pkin/lr/bin/vi b/pkin/lr/bin/vi new file mode 100755 index 0000000..1529ecc Binary files /dev/null and b/pkin/lr/bin/vi differ diff --git a/pkin/lr/man/man1/vi.1 b/pkin/lr/man/man1/vi.1 new file mode 100644 index 0000000..7cb80f3 --- /dev/null +++ b/pkin/lr/man/man1/vi.1 @@ -0,0 +1,1616 @@ +.\" Copyright (c) 1994 +.\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 1994, 1995, 1996 +.\" Keith Bostic. All rights reserved. +.\" +.\" This document may not be republished without written permission from +.\" Keith Bostic. +.\" +.\" See the LICENSE file for redistribution information. +.\" +.\" $Id: vi.1,v 8.53 2001/01/28 13:20:06 skimo Exp $ (Berkeley) $Date: 2001/01/28 13:20:06 $ +.\" +.TH VI 1 "%Q%" +.UC +.SH NAME +ex, vi, view \- text editors +.SH SYNOPSIS +.B ex +[\c +.B \-eRrSsv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.br +.B vi +[\c +.B \-elRrSv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.br +.B view +[\c +.B \-eRrSv\c +] [\c +.BI \-c " cmd"\c +] [\c +.BI \-t " tag"\c +] [\c +.BI \-w " size"\c +] [file ...] +.SH LICENSE +The vi program is freely redistributable. You are welcome to copy, +modify and share it with others under the conditions listed in the +LICENSE file. If any company (not individual!) finds vi sufficiently +useful that you would have purchased it, or if any company wishes to +redistribute it, contributions to the authors would be appreciated. +.SH DESCRIPTION +.I \&Vi +is a screen oriented text editor. +.I \&Ex +is a line\(hyoriented text editor. +.I \&Ex +and +.I \&vi +are different interfaces to the same program, +and it is possible to switch back and forth during an edit session. +.I View +is the equivalent of using the +.B \-R +(read\(hyonly) option of +.IR \&vi . +.PP +This manual page is the one provided with the +.I nex/nvi +versions of the +.I ex/vi +text editors. +.I Nex/nvi +are intended as bug\(hyfor\(hybug compatible replacements for the original +Fourth Berkeley Software Distribution (4BSD) +.I \&ex +and +.I \&vi +programs. +For the rest of this manual page, +.I nex/nvi +is used only when it's necessary to distinguish it from the historic +implementations of +.IR ex/vi . +.PP +This manual page is intended for users already familiar with +.IR ex/vi . +Anyone else should almost certainly read a good tutorial on the +editor before this manual page. +If you're in an unfamiliar environment, and you absolutely have to +get work done immediately, read the section after the options +description, entitled \(lqFast Startup\(rq. +It's probably enough to get you going. +.PP +The following options are available: +.TP +.B \-c +Execute +.B cmd +immediately after starting the edit session. +Particularly useful for initial positioning in the file, however +.B cmd +is not limited to positioning commands. +This is the POSIX 1003.2 interface for the historic \(lq+cmd\(rq syntax. +.I Nex/nvi +supports both the old and new syntax. +.TP +.B \-e +Start editing in ex mode, as if the command name were +.IR \&ex . +.TP +.B \-l +Start editing with the lisp and showmatch options set. +.TP +.B \-R +Start editing in read\(hyonly mode, as if the command name was +.IR view , +or the +.B readonly +option was set. +.TP +.B \-r +Recover the specified files, or, if no files are specified, +list the files that could be recovered. +If no recoverable files by the specified name exist, +the file is edited as if the +.B \-r +option had not been specified. +.TP +.B \-S +Run with the +.B secure +edit option set, disallowing all access to external programs. +.TP +.B \-s +Enter batch mode; applicable only to +.I \&ex +edit sessions. +Batch mode is useful when running +.I \&ex +scripts. +Prompts, informative messages and other user oriented message +are turned off, +and no startup files or environmental variables are read. +This is the POSIX 1003.2 interface for the historic \(lq\-\(rq argument. +.I \&Nex/nvi +supports both the old and new syntax. +.TP +.B \-t +Start editing at the specified tag. +(See +.IR ctags (1)). +.TP +.B \-w +Set the initial window size to the specified number of lines. +.TP +.B \-v +Start editing in vi mode, as if the command name was +.I \&vi +or +.IR view . +.PP +Note that the \fB-F\fP option (which prevented \fIex/vi\fP from making +a full backup of the target file) has been removed and is no longer available. +.PP +Command input for +.I ex/vi +is read from the standard input. +In the +.I \&vi +interface, it is an error if standard input is not a terminal. +In the +.I \&ex +interface, if standard input is not a terminal, +.I \&ex +will read commands from it regardless, however, the session will be a +batch mode session, exactly as if the +.B \-s +option had been specified. +.PP +.I Ex/vi +exits 0 on success, and greater than 0 if an error occurs. +.SH FAST STARTUP +This section will tell you the minimum amount that you need to +do simple editing tasks using +.IR \&vi . +If you've never used any screen editor before, you're likely to have +problems even with this simple introduction. +In that case you should find someone that already knows +.I \&vi +and have them walk you through this section. +.PP +.I \&Vi +is a screen editor. +This means that it takes up almost the entire screen, displaying part +of the file on each screen line, except for the last line of the screen. +The last line of the screen is used for you to give commands to +.IR \&vi , +and for +.I \&vi +to give information to you. +.PP +The other fact that you need to understand is that +.I \&vi +is a modeful editor, i.e. you are either entering text or you +are executing commands, and you have to be in the right mode +to do one or the other. +You will be in command mode when you first start editing a file. +There are commands that switch you into input mode. +There is only one key that takes you out of input mode, +and that is the key. +(Key names are written using less\(hythan and greater\(hythan signs, e.g. + means the \(lqescape\(rq key, usually labeled \(lqesc\(rq on your +terminal's keyboard.) +If you're ever confused as to which mode you're in, +keep entering the key until +.I \&vi +beeps at you. +(Generally, +.I \&vi +will beep at you if you try and do something that's not allowed. +It will also display error messages.) +.PP +To start editing a file, enter the command \(lqvi file_name\(rq. +The command you should enter as soon as you start editing is +\(lq:set verbose showmode\(rq. +This will make the editor give you verbose error messages and display +the current mode at the bottom of the screen. +.PP +The commands to move around the file are: +.TP +.B h +Move the cursor left one character. +.TP +.B j +Move the cursor down one line. +.TP +.B k +Move the cursor up one line. +.TP +.B l +Move the cursor right one character. +.TP +.B +The cursor arrow keys should work, too. +.TP +.B /text +Search for the string \(lqtext\(rq in the file, +and move the cursor to its first character. +.PP +The commands to enter new text are: +.TP +.B a +Append new text, +.I after +the cursor. +.TP +.B i +Insert new text, +.I before +the cursor. +.TP +.B o +Open a new line below the line the cursor is on, and start +entering text. +.TP +.B O +Open a new line above the line the cursor is on, and start +entering text. +.TP +.B +Once you've entered input mode using the one of the +.BR \&a , +.BR \&i , +.BR \&O +or +.B \&o +commands, use +.B +to quit entering text and return to command mode. +.PP +The commands to copy text are: +.TP +.B yy +Copy the line the cursor is on. +.TP +.B p +Append the copied line after the line the cursor is on. +.PP +The commands to delete text are: +.TP +.B dd +Delete the line the cursor is on. +.TP +.B x +Delete the character the cursor is on. +.PP +The commands to write the file are: +.TP +.B :w +Write the file back to the file with the name that you originally used +as an argument on the +.I \&vi +command line. +.TP +.B ":w file_name" +Write the file back to the file with the name \(lqfile_name\(rq. +.PP +The commands to quit editing and exit the editor are: +.TP +.B :q +Quit editing and leave vi (if you've modified the file, but not +saved your changes, +.I \&vi +will refuse to quit). +.TP +.B :q! +Quit, discarding any modifications that you may have made. +.PP +One final caution. +Unusual characters can take up more than one column on the screen, +and long lines can take up more than a single screen line. +The above commands work on \(lqphysical\(rq characters and lines, +i.e. they affect the entire line no matter how many screen lines it +takes up and the entire character no matter how many screen columns +it takes up. +.SH VI COMMANDS +The following section describes the commands available in the command +mode of the +.I \&vi +editor. +In each entry below, the tag line is a usage synopsis for the command +character. +.PP +.TP +.B "[count] " +Search forward +.I count +times for the current word. +.TP +.B "[count] " +Page backwards +.I count +screens. +.TP +.B "[count] " +Scroll forward +.I count +lines. +.TP +.B "[count] " +Scroll forward +.I count +lines, leaving the current line and column as is, if possible. +.TP +.B "[count] " +Page forward +.I count +screens. +.TP +.B "" +Display the file information. +.TP +.B "" +.TP +.B "[count] h" +Move the cursor back +.I count +characters in the current line. +.TP +.B "[count] " +.TP +.B "[count] " +.TP +.B "[count] j" +Move the cursor down +.I count +lines without changing the current column. +.TP +.B "" +.TP +.B "" +Repaint the screen. +.TP +.B "[count] " +.TP +.B "[count] +" +Move the cursor down +.I count +lines to the first nonblank character of that line. +.TP +.B "[count] " +.TP +.B "[count] k" +Move the cursor up +.I count +lines, without changing the current column. +.TP +.B "" +Return to the most recent tag context. +.TP +.B "" +Scroll backwards +.I count +lines. +.TP +.B "" +Switch to the next lower screen in the window, or, to the first +screen if there are no lower screens in the window. +.TP +.B "" +Scroll backwards +.I count +lines, leaving the current line and column as is, if possible. +.TP +.B "" +Suspend the current editor session. +.TP +.B "" +Execute +.I \&ex +commands or cancel partial commands. +.TP +.B "" +Push a tag reference onto the tag stack. +.TP +.B "" +Switch to the most recently edited file. +.TP +.B "[count] " +.TP +.B "[count] l" +Move the cursor forward +.I count +characters without changing the current line. +.TP +.B "[count] ! motion shell\(hyargument(s)" +Replace text with results from a shell command. +.TP +.B "[count] # #|+|\-" +Increment or decrement the cursor number. +.TP +.B "[count] $" +Move the cursor to the end of a line. +.TP +.B "%" +Move to the matching character. +.TP +.B "&" +Repeat the previous substitution command on the current line. +.TP +.B "'" +.TP +.B "\`" +Return to a context marked by the character +.IR . +.TP +.B "[count] (" +Back up +.I count +sentences. +.TP +.B "[count] )" +Move forward +.I count +sentences. +.TP +.B "[count] ," +Reverse find character +.I count +times. +.TP +.B "[count] \-" +Move to first nonblank of the previous line, +.I count +times. +.TP +.B "[count] ." +Repeat the last +.I \&vi +command that modified text. +.TP +.B "/RE" +.TP +.B "/RE/ [offset]" +.TP +.B "?RE" +.TP +.B "?RE? [offset]" +.TP +.B "N" +.TP +.B "n" +Search forward or backward for a regular expression. +.TP +.B "0" +Move to the first character in the current line. +.TP +.B ":" +Execute an ex command. +.TP +.B "[count] ;" +Repeat the last character find +.I count +times. +.TP +.B "[count] < motion" +.TP +.B "[count] > motion" +Shift lines left or right. +.TP +.B "@ buffer" +Execute a named buffer. +.TP +.B "[count] A" +Enter input mode, appending the text after the end of the line. +.TP +.B "[count] B" +Move backwards +.I count +bigwords. +.TP +.B "[buffer] [count] C" +Change text from the current position to the end\(hyof\(hyline. +.TP +.B "[buffer] D" +Delete text from the current position to the end\(hyof\(hyline. +.TP +.B "[count] E" +Move forward +.I count +end\(hyof\(hybigwords. +.TP +.B "[count] F " +Search +.I count +times backward through the current line for +.IR . +.TP +.B "[count] G" +Move to line +.IR count , +or the last line of the file if +.I count +not specified. +.TP +.B "[count] H" +Move to the screen line +.I "count \- 1" +lines below the top of the screen. +.TP +.B "[count] I" +Enter input mode, inserting the text at the beginning of the line. +.TP +.B "[count] J" +Join lines. +.TP +.B "[count] L" +Move to the screen line +.I "count \- 1" +lines above the bottom of the screen. +.TP +.B " M" +Move to the screen line in the middle of the screen. +.TP +.B "[count] O" +Enter input mode, appending text in a new line above the current line. +.TP +.B "[buffer] P" +Insert text from a buffer. +.TP +.B "Q" +Exit +.I \&vi +(or visual) mode and switch to +.I \&ex +mode. +.TP +.B "[count] R" +Enter input mode, replacing the characters in the current line. +.TP +.B "[buffer] [count] S" +Substitute +.I count +lines. +.TP +.B "[count] T " +Search backwards, +.I count +times, +through the current line for the character +.I after +the specified +.IR . +.TP +.B "U" +Restore the current line to its state before the cursor last +moved to it. +.TP +.B "[count] W" +Move forward +.I count +bigwords. +.TP +.B "[buffer] [count] X" +Delete +.I count +characters before the cursor. +.TP +.B "[buffer] [count] Y" +Copy (or \(lqyank\(rq) +.I count +lines into the specified buffer. +.TP +.B "ZZ" +Write the file and exit +.IR \&vi . +.TP +.B "[count] [[" +Back up +.I count +section boundaries. +.TP +.B "[count] ]]" +Move forward +.I count +section boundaries. +.TP +.B "\&^" +Move to first nonblank character on the current line. +.TP +.B "[count] _" +Move down +.I "count \- 1" +lines, to the first nonblank character. +.TP +.B "[count] a" +Enter input mode, appending the text after the cursor. +.TP +.B "[count] b" +Move backwards +.I count +words. +.TP +.B "[buffer] [count] c motion" +Change a region of text. +.TP +.B "[buffer] [count] d motion" +Delete a region of text. +.TP +.B "[count] e" +Move forward +.I count +end\(hyof\(hywords. +.TP +.B "[count] f" +Search forward, +.I count +times, through the rest of the current line for +.IR . +.TP +.B "[count] i" +Enter input mode, inserting the text before the cursor. +.TP +.B "m " +Save the current context (line and column) as +.IR . +.TP +.B "[count] o" +Enter input mode, appending text in a new line under the current line. +.TP +.B "[buffer] p" +Append text from a buffer. +.TP +.B "[count] r " +Replace +.I count +characters. +.TP +.B "[buffer] [count] s" +Substitute +.I count +characters in the current line starting with the current character. +.TP +.B "[count] t " +Search forward, +.I count +times, through the current line for the character immediately +.I before +.IR . +.TP +.B "u" +Undo the last change made to the file. +.TP +.B "[count] w" +Move forward +.I count +words. +.TP +.B "[buffer] [count] x" +Delete +.I count +characters. +.TP +.B "[buffer] [count] y motion" +Copy (or \(lqyank\(rq) +a text region specified by the +.I count +and motion into a buffer. +.TP +.B "[count1] z [count2] \-|.|+|^|" +Redraw, optionally repositioning and resizing the screen. +.TP +.B "[count] {" +Move backward +.I count +paragraphs. +.TP +.B "[count] |" +Move to a specific +.I column +position on the current line. +.TP +.B "[count] }" +Move forward +.I count +paragraphs. +.TP +.B "[count] ~" +Reverse the case of the next +.I count +character(s), if the +.B tildeop +option is +.IR unset . +.TP +.B "[count] ~ motion" +Reverse the case of the characters in a text region specified by the +.I count +and +.IR motion , +if the +.B tildeop +option is +.IR set . +.TP +.B "" +Interrupt the current operation. +.SH VI TEXT INPUT COMMANDS +The following section describes the commands available in the text +input mode of the +.I \&vi +editor. +.PP +.TP +.B "" +Replay the previous input. +.TP +.B "" +Erase to the previous +.B shiftwidth +column boundary. +.TP +.B "^" +Erase all of the autoindent characters, and reset the autoindent level. +.TP +.B "0" +Erase all of the autoindent characters. +.TP +.B "" +Insert sufficient +.I +and +.I +characters to move forward to the next +.B shiftwidth +column boundary. +.TP +.B " +.TP +.B "" +Erase the last character. +.TP +.B "" +Quote the next character. +.TP +.B " +Resolve all text input into the file, and return to command mode. +.TP +.B "" +Erase the current line. +.TP +.B "" +.TP +.B "" +Erase the last word. +The definition of word is dependent on the +.B altwerase +and +.B ttywerase +options. +.TP +.B "[0\-9A\-Fa\-f]+" +Insert a character with the specified hexadecimal value into the text. +.TP +.B "" +Interrupt text input mode, returning to command mode. +.SH EX COMMANDS +The following section describes the commands available in the +.I \&ex +editor. +In each entry below, the tag line is a usage synopsis for the command. +.PP +.TP +.B "" +Scroll the screen. +.TP +.B "! argument(s)" +.TP +.B "[range]! argument(s)" +Execute a shell command, or filter lines through a shell command. +.TP +.B \&" +A comment. +.TP +.B "[range] nu[mber] [count] [flags]" +.TP +.B "[range] # [count] [flags]" +Display the selected lines, each preceded with its line number. +.TP +.B "@ buffer" +.TP +.B "* buffer" +Execute a buffer. +.TP +.B "[line] a[ppend][!]" +The input text is appended after the specified line. +.TP +.B "[range] c[hange][!] [count]" +The input text replaces the specified range. +.TP +.B "cs[cope] add | find | help | kill | reset" +Execute a Cscope command. +.TP +.B "[range] d[elete] [buffer] [count] [flags]" +Delete the lines from the file. +.TP +.B "di[splay] b[uffers] | c[onnections] | s[creens] | t[ags]" +Display buffers, Cscope connections, screens or tags. +.TP +.B "[Ee][dit][!] [+cmd] [file]" +.TP +.B "[Ee]x[!] [+cmd] [file]" +Edit a different file. +.TP +.B "exu[sage] [command]" +Display usage for an +.I \&ex +command. +.TP +.B "f[ile] [file]" +Display and optionally change the file name. +.TP +.B "[Ff]g [name]" +.I \&Vi +mode only. +Foreground the specified screen. +.TP +.B "[range] g[lobal] /pattern/ [commands]" +.TP +.B "[range] v /pattern/ [commands]" +Apply commands to lines matching (or not matching) a pattern. +.TP +.B "he[lp]" +Display a help message. +.TP +.B "[line] i[nsert][!]" +The input text is inserted before the specified line. +.TP +.B "[range] j[oin][!] [count] [flags]" +Join lines of text together. +.TP +.B "[range] l[ist] [count] [flags]" +Display the lines unambiguously. +.TP +.B "map[!] [lhs rhs]" +Define or display maps (for +.I \&vi +only). +.TP +.B "[line] ma[rk] " +.TP +.B "[line] k " +Mark the line with the mark +.IR . +.TP +.B "[range] m[ove] line" +Move the specified lines after the target line. +.TP +.B "mk[exrc][!] file" +Write the abbreviations, editor options and maps to the specified +file. +.TP +.B "[Nn][ext][!] [file ...]" +Edit the next file from the argument list. +.TP +.B "[line] o[pen] /pattern/ [flags]" +Enter open mode. +.TP +.B "pre[serve]" +Save the file in a form that can later be recovered using the +.I \&ex +.B \-r +option. +.TP +.B "[Pp]rev[ious][!]" +Edit the previous file from the argument list. +.TP +.B "[range] p[rint] [count] [flags]" +Display the specified lines. +.TP +.B "[line] pu[t] [buffer]" +Append buffer contents to the current line. +.TP +.B "q[uit][!]" +End the editing session. +.TP +.B "[line] r[ead][!] [file]" +Read a file. +.TP +.B "rec[over] file" +Recover +.I file +if it was previously saved. +.TP +.B "res[ize] [+|\-]size" +.I \&Vi +mode only. +Grow or shrink the current screen. +.TP +.B "rew[ind][!]" +Rewind the argument list. +.TP +.B "se[t] [option[=[value]] ...] [nooption ...] [option? ...] [all]" +Display or set editor options. +.TP +.B "sh[ell]" +Run a shell program. +.TP +.B "so[urce] file" +Read and execute +.I \&ex +commands from a file. +.TP +.B "[range] s[ubstitute] [/pattern/replace/] [options] [count] [flags]" +.TP +.B "[range] & [options] [count] [flags]" +.TP +.B "[range] ~ [options] [count] [flags]" +Make substitutions. +.TP +.B "su[spend][!]" +.TP +.B "st[op][!]" +.TP +.B +Suspend the edit session. +.TP +.B "[Tt]a[g][!] tagstring" +Edit the file containing the specified tag. +.TP +.B "tagn[ext][!]" +Edit the file containing the next context for the current tag. +.TP +.B "tagp[op][!] [file | number]" +Pop to the specified tag in the tags stack. +.TP +.B "tagp[rev][!]" +Edit the file containing the previous context for the current tag. +.TP +.B "unm[ap][!] lhs" +Unmap a mapped string. +.TP +.B "ve[rsion]" +Display the version of the +.I \&ex/vi +editor. +.TP +.B "[line] vi[sual] [type] [count] [flags]" +.I \&Ex +mode only. +Enter +.IR \&vi . +.TP +.B "[Vi]i[sual][!] [+cmd] [file]" +.I \&Vi +mode only. +Edit a new file. +.TP +.B "viu[sage] [command]" +Display usage for a +.I \&vi +command. +.TP +.B "[range] w[rite][!] [>>] [file]" +.TP +.B "[range] w[rite] [!] [file]" +.TP +.B "[range] wn[!] [>>] [file]" +.TP +.B "[range] wq[!] [>>] [file]" +Write the file. +.TP +.B "[range] x[it][!] [file]" +Write the file if it has been modified. +.TP +.B "[range] ya[nk] [buffer] [count]" +Copy the specified lines to a buffer. +.TP +.B "[line] z [type] [count] [flags]" +Adjust the window. +.SH SET OPTIONS +There are a large number of options that may be set (or unset) to +change the editor's behavior. +This section describes the options, their abbreviations and their +default values. +.PP +In each entry below, the first part of the tag line is the full name +of the option, followed by any equivalent abbreviations. +The part in square brackets is the default value of the option. +Most of the options are boolean, i.e. they are either on or off, +and do not have an associated value. +.PP +Options apply to both +.I \&ex +and +.I \&vi +modes, unless otherwise specified. Multiple options can be given in +one set or unset, separated by spaces or tabs. Spaces and tabs can be +included in string options (eg. tags or filec) by preceding each with +a backslash. There's no way to get backslash itself into an option. +.PP +.TP +.B "altwerase [off]" +.I \&Vi +only. +Select an alternate word erase algorithm. +.TP +.B "autoindent, ai [off]" +Automatically indent new lines. +.TP +.B "autoprint, ap [off]" +.I \&Ex +only. +Display the current line automatically. +.TP +.B "autowrite, aw [off]" +Write modified files automatically when changing files. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms backup [QQ] +.TP +.B "\*(ms" +.tr QQ +Backup files before they are overwritten. +.TP +.B "beautify, bf [off]" +Discard control characters. +.TP +.B "cdpath [environment variable CDPATH, or current directory]" +The directory paths used as path prefixes for the +.B cd +command. +.TP +.B "cedit [no default]" +Set the character to edit the colon command\(hyline history. +.TP +.B "columns, co [80]" +Set the number of columns in the screen. +.TP +.B "comment [off]" +.I \&Vi +only. +Skip leading comments in shell, C and C++ language files. +.TP +.B "directory, dir [environment variable TMPDIR, or /tmp]" +The directory where temporary files are created. +.TP +.B "edcompatible, ed [off]" +Remember the values of the \(lqc\(rq and \(lqg\(rq suffices to the +.B substitute +commands, instead of initializing them as unset for each new +command. +.TP +.B "errorbells, eb [off]" +.I \&Ex +only. +Announce error messages with a bell. +.TP +.B "exrc, ex [off]" +Read the startup files in the local directory. +.TP +.B "extended [off]" +Regular expressions are extended (i.e. +.IR egrep (1)\-\c +style) expressions. +.TP +.B "filec [no default]" +Set the character to perform file path completion on the colon +command line. +.TP +.B "flash [on]" +Flash the screen instead of beeping the keyboard on error. +.TP +.B "hardtabs, ht [8]" +Set the spacing between hardware tab settings. +.TP +.B "iclower [off]" +Makes all Regular Expressions case\(hyinsensitive, +as long as an upper\(hycase letter does not appear in the search string. +.TP +.B "ignorecase, ic [off]" +Ignore case differences in regular expressions. +.TP +.B "keytime [6]" +The 10th's of a second +.I ex/vi +waits for a subsequent key to complete a key mapping. +.TP +.B "leftright [off]" +.I \&Vi +only. +Do left\(hyright scrolling. +.TP +.B "lines, li [24]" +.I \&Vi +only. +Set the number of lines in the screen. +.TP +.B "lisp [off]" +.I \&Vi +only. +Modify various search commands and options to work with Lisp. +.I "This option is not yet implemented." +.TP +.B "list [off]" +Display lines in an unambiguous fashion. +.TP +.B "lock [on]" +Attempt to get an exclusive lock on any file being edited, +read or written. +.TP +.B "magic [on]" +Treat certain characters specially in regular expressions. +.TP +.B "matchtime [7]" +.I \&Vi +only. +The 10th's of a second +.I ex/vi +pauses on the matching character when the +.B showmatch +option is set. +.TP +.B "mesg [on]" +Permit messages from other users. +.TP +.B "modelines, modeline [off]" +Read the first and last few lines of each file for +.I ex +commands. +.I "This option will never be implemented." +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms noprint [QQ] +.TP +.B "\*(ms" +.tr QQ +Characters that are never handled as printable characters. +.TP +.B "number, nu [off]" +Precede each line displayed with its current line number. +.TP +.B "octal [off]" +Display unknown characters as octal numbers, instead of the default +hexadecimal. +.TP +.B "open [on]" +.I \&Ex +only. +If this option is not set, the +.B open +and +.B visual +commands are disallowed. +.TP +.B "optimize, opt [on]" +.I \&Vi +only. +Optimize text throughput to dumb terminals. +.I "This option is not yet implemented." +.TP +.B "paragraphs, para [IPLPPPQPP LIpplpipbp]" +.I \&Vi +only. +Define additional paragraph boundaries for the +.B \&{ +and +.B \&} +commands. +.TP +.B "path []" +Define additional directories to search for files being edited. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms print [QQ] +.TP +.B "\*(ms" +.tr QQ +Characters that are always handled as printable characters. +.TP +.B "prompt [on]" +.I \&Ex +only. +Display a command prompt. +.TP +.B "readonly, ro [off]" +Mark the file and session as read\(hyonly. +.TP +.B "recdir [/var/tmp/vi.recover]" +The directory where recovery files are stored. +.TP +.B "redraw, re [off]" +.I \&Vi +only. +Simulate an intelligent terminal on a dumb one. +.I "This option is not yet implemented." +.TP +.B "remap [on]" +Remap keys until resolved. +.TP +.B "report [5]" +Set the number of lines about which the editor reports changes +or yanks. +.TP +.B "ruler [off]" +.I \&Vi +only. +Display a row/column ruler on the colon command line. +.TP +.B "scroll, scr [window / 2]" +Set the number of lines scrolled. +.TP +.B "searchincr [off]" +Makes the +.B \&/ +and +.B \&? +commands incremental. +.TP +.B "sections, sect [NHSHH HUnhsh]" +.I \&Vi +only. +Define additional section boundaries for the +.B \&[[ +and +.B \&]] +commands. +.TP +.B "secure [off]" +Turns off all access to external programs. +.TP +.B "shell, sh [environment variable SHELL, or /bin/sh]" +Select the shell used by the editor. +.\" I cannot get a double quote to print between the square brackets +.\" to save my life. The ONLY way I've been able to get this to work +.\" is with the .tr command. +.tr Q" +.ds ms shellmeta [~{[*?$\`'Q\e] +.TP +.B "\*(ms" +.tr QQ +Set the meta characters checked to determine if file name expansion +is necessary. +.TP +.B "shiftwidth, sw [8]" +Set the autoindent and shift command indentation width. +.TP +.B "showmatch, sm [off]" +.I \&Vi +only. +Note matching \(lq{\(rq and \(lq(\(rq for \(lq}\(rq and \(lq)\(rq characters. +.TP +.B "showmode, smd [off]" +.I \&Vi +only. +Display the current editor mode and a \(lqmodified\(rq flag. +.TP +.B "sidescroll [16]" +.I \&Vi +only. +Set the amount a left\(hyright scroll will shift. +.TP +.B "slowopen, slow [off]" +Delay display updating during text input. +.I "This option is not yet implemented." +.TP +.B "sourceany [off]" +Read startup files not owned by the current user. +.I "This option will never be implemented." +.TP +.B "tabstop, ts [8]" +This option sets tab widths for the editor display. +.TP +.B "taglength, tl [0]" +Set the number of significant characters in tag names. +.TP +.B "tags, tag [tags /var/db/libc.tags /sys/kern/tags]" +Set the list of tags files. +.TP +.B "term, ttytype, tty [environment variable TERM]" +Set the terminal type. +.TP +.B "terse [off]" +This option has historically made editor messages less verbose. +It has no effect in this implementation. +.TP +.B "tildeop [off]" +Modify the +.B \&~ +command to take an associated motion. +.TP +.B "timeout, to [on]" +Time out on keys which may be mapped. +.TP +.B "ttywerase [off]" +.I \&Vi +only. +Select an alternate erase algorithm. +.TP +.B "verbose [off]" +.I \&Vi +only. +Display an error message for every error. +.TP +.B "w300 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is less than 1200 baud. +.TP +.B "w1200 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is equal to 1200 baud. +.TP +.B "w9600 [no default]" +.I \&Vi +only. +Set the window size if the baud rate is greater than 1200 baud. +.TP +.B "warn [on]" +.I \&Ex +only. +This option causes a warning message to the terminal if the file has +been modified, since it was last written, before a +.B \&! +command. +.TP +.B "window, w, wi [environment variable LINES]" +Set the window size for the screen. +.TP +.B "windowname [off]" +Change the icon/window name to the current file name even if it can't +be restored on editor exit. +.TP +.B "wraplen, wl [0]" +.I \&Vi +only. +Break lines automatically, the specified number of columns from the +left\(hyhand margin. +If both the +.B wraplen +and +.B wrapmargin +edit options are set, the +.B wrapmargin +value is used. +.TP +.B "wrapmargin, wm [0]" +.I \&Vi +only. +Break lines automatically, the specified number of columns from the +right\(hyhand margin. +If both the +.B wraplen +and +.B wrapmargin +edit options are set, the +.B wrapmargin +value is used. +.TP +.B "wrapscan, ws [on]" +Set searches to wrap around the end or beginning of the file. +.TP +.B "writeany, wa [off]" +Turn off file\(hyoverwriting checks. +.SH "ENVIRONMENT VARIABLES +.TP +.I COLUMNS +The number of columns on the screen. +This value overrides any system or terminal specific values. +If the +.I COLUMNS +environmental variable is not set when +.I ex/vi +runs, or the +.B columns +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I EXINIT +A list of +.I \&ex +startup commands, read if the variable +.I NEXINIT +is not set. +.TP +.I HOME +The user's home directory, used as the initial directory path +for the startup \(lq$\fIHOME\fP/.nexrc\(rq and \(lq$\fIHOME\fP/.exrc\(rq +files. +This value is also used as the default directory for the +.I \&vi +.B \&cd +command. +.TP +.I LINES +The number of rows on the screen. +This value overrides any system or terminal specific values. +If the +.I LINES +environmental variable is not set when +.I ex/vi +runs, or the +.B lines +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I NEXINIT +A list of +.I \&ex +startup commands. +.TP +.I SHELL +The user's shell of choice (see also the +.B shell +option). +.TP +.I TERM +The user's terminal type. +The default is the type \(lqunknown\(rq. +If the +.I TERM +environmental variable is not set when +.I ex/vi +runs, or the +.B term +option is explicitly reset by the user, +.I ex/vi +enters the value into the environment. +.TP +.I TMPDIR +The location used to stored temporary files (see also the +.B directory +edit option). +.SH ASYNCHRONOUS EVENTS +.TP +SIGALRM +.I \&Vi/ex +uses this signal for periodic backups of file modifications and to +display \(lqbusy\(rq messages when operations are likely to take a long time. +.TP +SIGHUP +.TP +SIGTERM +If the current buffer has changed since it was last written in its +entirety, the editor attempts to save the modified file so it can +be later recovered. +See the +.I \&vi/ex +Reference manual section entitled \(lqRecovery\(rq for more information. +.TP +SIGINT +When an interrupt occurs, +the current operation is halted, +and the editor returns to the command level. +If interrupted during text input, +the text already input is resolved into the file as if the text +input had been normally terminated. +.TP +SIGWINCH +The screen is resized. +See the +.I \&vi/ex +Reference manual section entitled \(lqSizing the Screen\(rq for more information. +.TP +SIGCONT +.TP +SIGQUIT +.TP +SIGTSTP +.I \&Vi/ex +ignores these signals. +.SH FILES +.TP +/bin/sh +The default user shell. +.TP +/etc/vi.exrc +System\(hywide vi startup file. +.TP +/tmp +Temporary file directory. +.TP +/var/tmp/vi.recover +The default recovery file directory. +.TP +$HOME/.nexrc +1st choice for user's home directory startup file. +.TP +$HOME/.exrc +2nd choice for user's home directory startup file. +.TP +\&.nexrc +1st choice for local directory startup file. +.TP +\&.exrc +2nd choice for local directory startup file. +.SH SEE ALSO +.IR ctags (1), +.IR more (1), +.IR curses (3), +.IR dbopen (3) +.sp +The \(lqVi Quick Reference\(rq card. +.sp +\(lqAn Introduction to Display Editing with Vi\(rq, found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of both the 4.3BSD and 4.4BSD manual sets. +This document is the closest thing available to an introduction to the +.I \&vi +screen editor. +.sp +\(lqEx Reference Manual (Version 3.7)\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of both the 4.3BSD and 4.4BSD manual sets. +This document is the final reference for the +.I \&ex +editor, as distributed in most historic 4BSD and System V systems. +.sp +\(lqEdit: A tutorial\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of the 4.3BSD manual set. +This document is an introduction to a simple version of the +.I \&ex +screen editor. +.sp +\(lqEx/Vi Reference Manual\(rq, +found in the +\(lqUNIX User's Manual Supplementary Documents\(rq +section of the 4.4BSD manual set. +This document is the final reference for the +.I \&nex/nvi +text editors, as distributed in 4.4BSD and 4.4BSD\(hyLite. +.PP +.I Roff +source for all of these documents is distributed with +.I nex/nvi +in the +.I nvi/USD.doc +directory of the +.I nex/nvi +source code. +.sp +The files \(lqautowrite\(rq, \(lqinput\(rq, \(lqquoting\(rq and \(lqstructures\(rq +found in the +.I nvi/docs/internals +directory of the +.I nex/nvi +source code. +.SH HISTORY +The +.I nex/nvi +replacements for the +.I ex/vi +editor first appeared in 4.4BSD. +.SH STANDARDS +.I \&Nex/nvi +is close to IEEE Std1003.2 (\(lqPOSIX\(rq). +That document differs from historical +.I ex/vi +practice in several places; there are changes to be made on both sides. diff --git a/pkin/meson.build b/pkin/meson.build index 2b4245e..35850ad 100644 --- a/pkin/meson.build +++ b/pkin/meson.build @@ -11,14 +11,30 @@ deps = [ cc.find_library('libowfat'), ] +add_project_arguments( + '-DPATH_BIN_INTERNAL="'+get_option('path_bin_internal')+'"', + language: 'c', +) +add_project_arguments( + '-DPATH_CACHE="'+get_option('path_cache')+'"', + language: 'c', +) + executable('pkin', files( - './pkin.c', - './pkin-search.c', - './pkin-fetch.c', - './pkin/pkin_repo_iter_init.c', - './pkin/pkin_repo_iter_read.c', - './pkin/pkin_pkg_fetch_prepare.c', - './pkin/pkin_pkg_fetch_add.c', - './pkin/pkin_pkg_fetch_start.c', - './pkin_internal/pkin__spawn.c', + './src/bin/pkin.c', + './src/bin/pkin-search.c', + './src/bin/pkin-fetch.c', + './src/pkin/pkin_repo_iter_init.c', + './src/pkin/pkin_repo_iter_read.c', + './src/pkin/pkin_queue_prepare.c', + './src/pkin/pkin_queue_extract_add.c', + './src/pkin/pkin_queue_extract_start.c', + './src/pkin/pkin_queue_fetch_add.c', + './src/pkin/pkin_queue_fetch_start.c', + './src/pkin_internal/pkin__spawn.c', + './src/pkin_internal/pkin__mkpath.c', ), dependencies:deps) + +executable('extraction-worker', files( + './src/bin-internal/extraction-worker.c', +), dependencies:deps + dependency('libarchive')) diff --git a/pkin/meson.options b/pkin/meson.options new file mode 100644 index 0000000..fa44b36 --- /dev/null +++ b/pkin/meson.options @@ -0,0 +1,13 @@ +option( + 'path_bin_internal', + type : 'string', + value : '/usr/libexec/pkin', + description : 'path to internal binaries', +) + +option( + 'path_cache', + type : 'string', + value : '/var/cache/pkin', + description : 'path to cache', +) diff --git a/pkin/pkin/pkin_pkg_fetch_add.c b/pkin/pkin/pkin_pkg_fetch_add.c deleted file mode 100644 index 640c62f..0000000 --- a/pkin/pkin/pkin_pkg_fetch_add.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "../pkin.h" - -void pkin_fetch_add(pkin_fetch_queue *queue, char *url, char *output) -{ - buffer_puts(&queue->writeb, url); - buffer_puts(&queue->writeb, "\n out="); - buffer_puts(&queue->writeb, output); - buffer_puts(&queue->writeb, "\n user-agent=pkin "); - buffer_puts(&queue->writeb, "\n"); -} diff --git a/pkin/pkin/pkin_pkg_fetch_start.c b/pkin/pkin/pkin_pkg_fetch_start.c deleted file mode 100644 index 887bad3..0000000 --- a/pkin/pkin/pkin_pkg_fetch_start.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include -#include "../pkin.h" -#include "../pkin_internal.h" - -int pkin_fetch_start(pkin_fetch_queue *queue) -{ - char **fetchcmd; - int nullfd; - pid_t pid; - if (buffer_flush(&queue->writeb) < 0) { - carpsys("write to pipe"); - return 0; - } - close(queue->pipefd[1]); - - fetchcmd = (char *[]){"aria2c", "-i", "-", NULL}; - nullfd = open_write("/dev/null"); - pid = pkin__spawn(fetchcmd, queue->pipefd[0], nullfd < 0 ? 1 : nullfd, 2); - if (pid < 0) { - close(nullfd); - carp("failed spawning aria2c to fetch files"); - return 0; - } - - if (waitpid(pid, NULL, 0) < 0) { - close(nullfd); - carp("waitpid"); - return 0; - } - return 1; -} diff --git a/pkin/src/bin-internal/extraction-worker.c b/pkin/src/bin-internal/extraction-worker.c new file mode 100644 index 0000000..90bbacc --- /dev/null +++ b/pkin/src/bin-internal/extraction-worker.c @@ -0,0 +1,125 @@ +/* + * see also: https://github.com/libarchive/libarchive/blob/master/examples/untar.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#define errstr(a) archive_error_string(a) + +static int copy_data(struct archive *reader, struct archive *writer) +{ + int r; + const void *buf; + size_t size; +#if ARCHIVE_VERSION_NUMBER >= 3000000 + int64_t offset; +#else + off_t offset; +#endif + for (;;) { + r = archive_read_data_block(reader,&buf,&size,&offset); + if (r == ARCHIVE_EOF) return 1; + if (r != 0) { + carpsys("archive_read_data_block: ", errstr(reader)); + return 0; + } + r = archive_write_data_block(writer,buf,size,offset); + if (r != 0) { + carpsys("archive_write_data_block: ", errstr(reader)); + return 0; + } + } + return 1; +} + +int extract(char *in, const char *out) +{ + struct archive *reader = NULL, *writer = NULL; + struct archive_entry *ent; + int ret = 0; + int r; + size_t l; + const char *oldpath; + char *newpath; + + reader = archive_read_new(); + archive_read_support_filter_all(reader); + archive_read_support_format_all(reader); + writer = archive_write_disk_new(); + archive_write_disk_set_options(writer, + ARCHIVE_EXTRACT_PERM|ARCHIVE_EXTRACT_ACL|ARCHIVE_EXTRACT_FFLAGS); + + if (archive_read_open_filename(reader, in, 8192) != 0) { + carp("open archive ", in, " for reading: ", errstr(reader)); + goto done; + } + + for (;;) { + r = archive_read_next_header(reader, &ent); + if (r == ARCHIVE_EOF) break; + if (r != 0) { + carp("failed to read archive header: ", errstr(reader)); + goto done; + } + + oldpath = archive_entry_pathname(ent); + newpath = alloca(str_len(oldpath) + str_len(out) + 1); + l = str_copy(newpath, out); + l += str_copy(newpath + l, "/"); + str_copy(newpath + l, oldpath); + msg(oldpath, " -> ", newpath); + archive_entry_set_pathname(ent, newpath); + + if (archive_write_header(writer, ent) != 0) { + carp("failed to write header ", errstr(writer)); + continue; + } + if (!copy_data(reader, writer)) { + carp("failed to copy archive data"); + goto done; + } + if (archive_write_finish_entry(writer) != 0) { + carp("archive_write_finish_entry: ", errstr(writer)); + goto done; + } + } + + ret = 1; +done: + if (reader) { + archive_read_close(reader); + archive_read_free(reader); + } + if (writer) { + archive_write_close(writer); + archive_write_free(writer); + } + return ret; +} + +int main() +{ + stralloc line; + int r; + size_t l; + + for (;;) { + r = buffer_getnewline_sa(buffer_0, &line); + if (r == 0) break; + if (r < 0) diesys(111, "failed to read stdin"); + stralloc_chomp(&line); + stralloc_0(&line); + /* separate by space, first part is archive, rest is output dir */ + l = str_chr(line.s, ' '); + if (l == str_len(line.s)) + die(100, "malformed entry in stdin: missing separator(space)"); + line.s[l] = 0; + extract(line.s, line.s + l + 1); + } +} diff --git a/pkin/src/bin-internal/meson.build b/pkin/src/bin-internal/meson.build new file mode 100644 index 0000000..f13fca9 --- /dev/null +++ b/pkin/src/bin-internal/meson.build @@ -0,0 +1,17 @@ +cc = meson.get_compiler('c') +deps = [ + cc.find_library('libowfat'), + dependency("libarchive"), +] + +executable('pkin', files( + './pkin.c', + './pkin-search.c', + './pkin-fetch.c', + './pkin/pkin_repo_iter_init.c', + './pkin/pkin_repo_iter_read.c', + './pkin/pkin_pkg_fetch_prepare.c', + './pkin/pkin_pkg_fetch_add.c', + './pkin/pkin_pkg_fetch_start.c', + './pkin_internal/pkin__spawn.c', +), dependencies:deps) diff --git a/pkin/command.h b/pkin/src/bin/command.h similarity index 100% rename from pkin/command.h rename to pkin/src/bin/command.h diff --git a/pkin/src/bin/meson.build b/pkin/src/bin/meson.build new file mode 100644 index 0000000..93774e1 --- /dev/null +++ b/pkin/src/bin/meson.build @@ -0,0 +1,16 @@ +cc = meson.get_compiler('c') +deps = [ + cc.find_library('libowfat'), +] + +executable('pkin', files( + './pkin.c', + './pkin-search.c', + './pkin-fetch.c', + '../pkin_repo_iter_init.c', + '../pkin/pkin_repo_iter_read.c', + '../pkin/pkin_pkg_fetch_prepare.c', + '../pkin/pkin_pkg_fetch_add.c', + '../pkin/pkin_pkg_fetch_start.c', + '../pkin_internal/pkin__spawn.c', +), dependencies:deps) diff --git a/pkin/pkin-fetch.c b/pkin/src/bin/pkin-fetch.c similarity index 57% rename from pkin/pkin-fetch.c rename to pkin/src/bin/pkin-fetch.c index da9cb94..e1b0e50 100644 --- a/pkin/pkin-fetch.c +++ b/pkin/src/bin/pkin-fetch.c @@ -22,18 +22,31 @@ static void run(int argc, char **argv) { int i; pkin_pkgmeta pkgmeta; - pkin_fetch_queue queue; - if (!pkin_fetch_prepare(&queue)) - die(111, "failed to create package fetch queue"); + pkin_queue fetchq, extractq; + stralloc archivename; + if (!pkin_queue_prepare(&fetchq) + || !pkin_queue_prepare(&extractq) + ) die(111, "failed to create queue"); for (i = 0; i < argc; i++) { if (!find_package(argv[i], &pkgmeta)) die(100, "package '", argv[i], "' not found "); - pkin_fetch_add(&queue, pkgmeta.url, pkgmeta.name); + stralloc_copys(&archivename, pkgmeta.name); + stralloc_cats(&archivename, ".archive"); + stralloc_0(&archivename); + pkin_queue_fetch_add(&fetchq, pkgmeta.url, archivename.s); + pkin_queue_extract_add(&extractq, archivename.s, pkgmeta.name); + if (pkin_verbose) + msg("queueing fetch/extract: ", pkgmeta.url); } + stralloc_free(&archivename); - if (!pkin_fetch_start(&queue)) + msg("fetching binary packages"); + if (!pkin_queue_fetch_start(&fetchq)) die(111, "failed fetching packages"); + msg("extracting fetched packages"); + if (!pkin_queue_extract_start(&extractq)) + die(111, "failed extracting packages"); } void command_fetch(int argc, char **argv) diff --git a/pkin/pkin-search.c b/pkin/src/bin/pkin-search.c similarity index 100% rename from pkin/pkin-search.c rename to pkin/src/bin/pkin-search.c diff --git a/pkin/pkin.c b/pkin/src/bin/pkin.c similarity index 92% rename from pkin/pkin.c rename to pkin/src/bin/pkin.c index 7fb92d9..986e6c8 100644 --- a/pkin/pkin.c +++ b/pkin/src/bin/pkin.c @@ -5,6 +5,7 @@ #include #include "../pkin.h" +#include "../pkin_internal.h" #include "command.h" #define dienoarg(OPT) \ @@ -13,6 +14,7 @@ dieusage(); \ } while(0) +int pkin_extractjobs = 5; int pkin_verbose = 0; array pkin_repos; @@ -61,7 +63,7 @@ static void dieusage() int main(int argc, char **argv) { int i; - errmsg_iam(*argv); + errmsg_iam("pkin"); for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; if (argv[i][1] == '-' && !argv[i][2]) break; @@ -82,6 +84,9 @@ int main(int argc, char **argv) if (argc == 0) dieusage(); env_import_repos(); + if (!pkin__mkpath(PATH_CACHE, 0755)) + die(111, "failed creating cache ", PATH_CACHE); + if (str_equal(*argv, "search")) command_search(argc, argv); else if (str_equal(*argv, "fetch")) diff --git a/pkin/pkin.h b/pkin/src/pkin.h similarity index 74% rename from pkin/pkin.h rename to pkin/src/pkin.h index c29776b..e6da3d6 100644 --- a/pkin/pkin.h +++ b/pkin/src/pkin.h @@ -17,6 +17,7 @@ #define PKIN_PKGMETA_URL_MAX 2048 extern int pkin_verbose; +extern int pkin_extractjobs; extern array pkin_repos; /* of char * */ typedef struct { @@ -49,17 +50,16 @@ void pkin_repo_iter_init(pkin_repo_iter *); int pkin_repo_iter_read(pkin_repo_iter *, pkin_pkgmeta *res); typedef struct { - buffer writeb; - char writebuf[1024]; + buffer b; + char buf[1024]; int pipefd[2]; -} pkin_fetch_queue; +} pkin_queue; +int pkin_queue_prepare(pkin_queue *queue); -int pkin_fetch_prepare(pkin_fetch_queue *queue); -void pkin_fetch_add(pkin_fetch_queue *queue, char *url, char *output); -/* - * downloads the binary package from url to the given - * directory and writes the resulting path to rest - */ -int pkin_fetch_start(pkin_fetch_queue *queue); +void pkin_queue_fetch_add(pkin_queue *fetchqueue, char *url, char *output); +int pkin_queue_fetch_start(pkin_queue *fetchqueue); + +void pkin_queue_extract_add(pkin_queue *extractqueue, char *src, char *dest); +int pkin_queue_extract_start(pkin_queue *extractqueue); #endif diff --git a/pkin/src/pkin/pkin_queue_extract_add.c b/pkin/src/pkin/pkin_queue_extract_add.c new file mode 100644 index 0000000..bc01ff5 --- /dev/null +++ b/pkin/src/pkin/pkin_queue_extract_add.c @@ -0,0 +1,9 @@ +#include "../pkin.h" + +void pkin_queue_extract_add(pkin_queue *queue, char *src, char *dest) +{ + buffer_puts(&queue->b, src); + buffer_puts(&queue->b, " "); + buffer_puts(&queue->b, dest); + buffer_puts(&queue->b, "\n"); +} diff --git a/pkin/src/pkin/pkin_queue_extract_start.c b/pkin/src/pkin/pkin_queue_extract_start.c new file mode 100644 index 0000000..be03639 --- /dev/null +++ b/pkin/src/pkin/pkin_queue_extract_start.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +#include "../pkin_internal.h" +#include "../pkin.h" + +/* + * given a queue of files to extract + * and the destination for the extracted file, + * this shall extract it in parallell. + * + * basically: + * spawn n extraction processes that consume queue + * where n is pkin_extractjobs. + */ + +int pkin_queue_extract_start(pkin_queue *queue) +{ + pid_t *pids; + int pids_len; + char **cmd; + + if (buffer_flush(&queue->b) < 0) { + carpsys("write to pipe"); + return 0; + } + close(queue->pipefd[1]); + + pids = alloca(pkin_extractjobs); + pids_len = 0; + cmd = (char *[]){PATH_BIN_INTERNAL"/extraction-worker", NULL}; + for (pids_len = 0; pids_len < pkin_extractjobs; pids_len++) { + pids[pids_len] = pkin__spawn(cmd, queue->pipefd[0], 1, 2); + /* TODO improve error handling(?) */ + if (pids[pids_len] < 0) return 0; + } + + for (pids_len = 0; pids_len < pkin_extractjobs; pids_len++) + waitpid(pids[pids_len], NULL, 0); + return 1; +} diff --git a/pkin/src/pkin/pkin_queue_fetch_add.c b/pkin/src/pkin/pkin_queue_fetch_add.c new file mode 100644 index 0000000..bed9e44 --- /dev/null +++ b/pkin/src/pkin/pkin_queue_fetch_add.c @@ -0,0 +1,10 @@ +#include "../pkin.h" + +void pkin_queue_fetch_add(pkin_queue *queue, char *url, char *output) +{ + buffer_puts(&queue->b, url); + buffer_puts(&queue->b, "\n out="); + buffer_puts(&queue->b, output); + buffer_puts(&queue->b, "\n user-agent=pkin "); + buffer_puts(&queue->b, "\n"); +} diff --git a/pkin/src/pkin/pkin_queue_fetch_start.c b/pkin/src/pkin/pkin_queue_fetch_start.c new file mode 100644 index 0000000..920fa3c --- /dev/null +++ b/pkin/src/pkin/pkin_queue_fetch_start.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include "../pkin.h" +#include "../pkin_internal.h" + +int pkin_queue_fetch_start(pkin_queue *queue) +{ + char **cmd; + pid_t pid; + int status; + if (buffer_flush(&queue->b) < 0) { + carpsys("write to pipe"); + return 0; + } + close(queue->pipefd[1]); + + /* we use aria2c to process our queue using the -i option. + * aria2c logs errors to stdout(wtf???) and requires these options + * to not flood the terminal. It will still always send the + * "Download Results"-report. */ + cmd = (char *[]){"aria2c", "--console-log-level=warn", + "--enable-color=false", "--allow-overwrite=true", "-i", "-", NULL}; + pid = pkin__spawn(cmd, queue->pipefd[0], 1, 2); + if (pid < 0) { + carp("failed spawning aria2c to fetch files"); + return 0; + } + + if (waitpid(pid, &status, 0) < 0) { + carp("waitpid"); + return 0; + } + if (WEXITSTATUS(status) != 0) { + buffer_puts(buffer_2, "aria2c exited with non-zero exitcode: "); + buffer_putlong(buffer_2, WEXITSTATUS(status)); + buffer_putsflush(buffer_2, "\n"); + return 0; + } + return 1; +} diff --git a/pkin/pkin/pkin_pkg_fetch_prepare.c b/pkin/src/pkin/pkin_queue_prepare.c similarity index 51% rename from pkin/pkin/pkin_pkg_fetch_prepare.c rename to pkin/src/pkin/pkin_queue_prepare.c index f28d836..87cc45f 100644 --- a/pkin/pkin/pkin_pkg_fetch_prepare.c +++ b/pkin/src/pkin/pkin_queue_prepare.c @@ -3,13 +3,13 @@ #include "../pkin.h" -int pkin_fetch_prepare(pkin_fetch_queue *queue) +int pkin_queue_prepare(pkin_queue *queue) { if (pipe(queue->pipefd) < 0) { carpsys("pipe"); return 0; } - buffer_init_write(&queue->writeb, queue->pipefd[1], - queue->writebuf, sizeof(queue->writebuf)); + buffer_init_write(&queue->b, queue->pipefd[1], + queue->buf, sizeof(queue->buf)); return 1; } diff --git a/pkin/pkin/pkin_repo_iter_init.c b/pkin/src/pkin/pkin_repo_iter_init.c similarity index 100% rename from pkin/pkin/pkin_repo_iter_init.c rename to pkin/src/pkin/pkin_repo_iter_init.c diff --git a/pkin/pkin/pkin_repo_iter_read.c b/pkin/src/pkin/pkin_repo_iter_read.c similarity index 100% rename from pkin/pkin/pkin_repo_iter_read.c rename to pkin/src/pkin/pkin_repo_iter_read.c diff --git a/pkin/pkin_internal.h b/pkin/src/pkin_internal.h similarity index 54% rename from pkin/pkin_internal.h rename to pkin/src/pkin_internal.h index f5b6eb1..76fe5b3 100644 --- a/pkin/pkin_internal.h +++ b/pkin/src/pkin_internal.h @@ -5,4 +5,10 @@ pid_t pkin__spawn(char *args[], int infd, int outfd, int errfd); +/* + * makes sure path exist. + * return: 1 on success, 0 on error. + */ +int pkin__mkpath(const char *path, mode_t mode); + #endif diff --git a/pkin/src/pkin_internal/pkin__mkpath.c b/pkin/src/pkin_internal/pkin__mkpath.c new file mode 100644 index 0000000..c5f62cb --- /dev/null +++ b/pkin/src/pkin_internal/pkin__mkpath.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../pkin_internal.h" +#include "src/pkin.h" + +int pkin__mkpath(const char *_path, mode_t mode) +{ + char *path; + size_t pathlen, l, off; + off = 0; + pathlen = str_len(_path); + /* copy path to make it writable */ + path = alloca(pathlen + 1); + byte_copy(path, pathlen + 1, _path); + + if (pkin_verbose) + msg("creating directory ", path); + for (;;) { + l = str_chr(path + off, '/'); + if (l == 0) { + off++; + continue; + } + (path+off)[l] = 0; + if (mkdir(path, mode) < 0 && errno != EEXIST) { + carpsys("mkdir ", path); + return 0; + } + if (l == pathlen - off) break; + (path+off)[l] = '/'; + off += l + 1; + } + + return 1; +} diff --git a/pkin/pkin_internal/pkin__spawn.c b/pkin/src/pkin_internal/pkin__spawn.c similarity index 95% rename from pkin/pkin_internal/pkin__spawn.c rename to pkin/src/pkin_internal/pkin__spawn.c index 856c6e6..b7d61eb 100644 --- a/pkin/pkin_internal/pkin__spawn.c +++ b/pkin/src/pkin_internal/pkin__spawn.c @@ -28,9 +28,7 @@ pid_t pkin__spawn(char *args[], int infd, int outfd, int errfd) if (dup2(infd, 0)<0 || dup2(outfd, 1)<0 || dup2(errfd, 2)<0 - ) { - diesys(111, "dup2"); - } + ) diesys(111, "dup2"); if (infd != 0) close(infd); if (outfd != 1) close(outfd); if (errfd != 2) close(errfd);