home *** CD-ROM | disk | FTP | other *** search
- INTERNAL TEXT REPRESENTATION
- When vi starts up, the file is copied into a temporary file. Small
- amounts of extra space are inserted into the temporary file to insure
- that no text lines cross block boundaries; this speeds up processing.
- The "extra space" is filled with NUL charcters; the input file must
- not contain any NULs, to avoid confusion.
-
- The first block of the temporary file is an array of shorts which
- describe the order of the blocks; i.e. header[1] is the block number
- of the first block, and so on. This limits the temporary file to
- 512 active blocks, so the largest file you can edit is about 400K
- bytes long. I hope that's enough!
-
- When blocks are altered, they are rewritten to a *different* block
- in the file, and the in-core version of the header block is updated
- accordingly. The in-core header block will be copied to the temp
- file immediately before the next change... or, to undo this change,
- swap the old header (from the temp file) with the new (in-core)
- header.
-
- Vi maintains another in-core array which contains the line-number of
- the last line in every block. This allows you to go directly to a
- line, given its line number.
-
- IMPLEMENTATION OF EDITING
- There are three basic operations which affect text:
-
- * delete text - delete(from, to)
- * add text - add(at, text)
- * yank text - cut(from, to)
-
- To yank text, all text between two text positions is copied into
- a cut buffer. The original text is not changed. To copy the text
- into a cut buffer, you need only remember which physical blocks that
- contain the cut text, the offset into the first block of the start of
- the cut, the offset into the last block of the end of the cut, and
- what kind of cut it was. (Cuts may be either character cuts or line
- cuts; the kind of a cut affects the way it is later "put".)
-
- To delete text, you must modify the first and last blocks, and remove
- any reference to the intervening blocks in the header's list. The
- text to be deleted is specified by two marks.
-
- To add text, you must specify the text to insert (as a NUL-terminated
- string) and the place to insert it (as a mark). The block into which
- the text is to be inserted may need to be split into as many as four
- blocks, with new intervening blocks needed as well... or it could be
- as simple as modifying the block.
-
- When text is deleted or added, an internal file-revision counter,
- called "changes", is incremented. This counter is used to detect
- when certain caches are out of date. (The "changes" counter is
- also incremented when we switch to a different file, and also in
- one or two similar situations -- all related to invalidating caches.)
-
- MARKS AND THE CURSOR
- Marks are places within the text. They are represented internally
- as a long variable which is split into two bitfields: a line number
- and a character index. Line numbers start with 1, and character
- indexes start with 0.
-
- Since line numbers start with 1, it is impossible for a set mark to
- have a value of 0L. 0L is therefore used to represent unset marks.
-
- When you do the "delete text" change, any marks that were part of
- the deleted text are unset, and any marks that were set to points
- after it are adjusted. Similarly, marks are adjusted after new text
- is inserted.
-
- The cursor is represented as a mark.
-
- EX COMMAND INTERPRETATION
- EX commands are parsed, and the command name is looked up in an array
- of structures which also contain a pointer to the function that
- implements the command, and a description of the arguments that the
- command can take. If the command is recognized and its arguments
- are legal, then the function is called.
-
- Each function performs its task; this may cause the cursor to be moved
- to a different line, or whatever.
-
- SCREEN CONTROL
- The screen is updated via a package which looks like the "curses"
- library, but which is actually implemented in a simpler, faster way.
- Most curses operations are implemented as macros which copy characters
- into a large I/O buffer, which is then written with a single large
- write() call as part of the refresh() operation.
-
- The functions which modify text remember where text has been modified;
- the screen redrawing function needs this information to help it reduce
- the amount of text that is redrawn each time.
-