Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v44i019: vim - Vi IMproved editor, v3.0, Part00/26

27 views
Skip to first unread message

Bram Moolenaar

unread,
Aug 16, 1994, 10:16:55 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 19
Archive-name: vim/part00
Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

Version 3.0 of Vim: Vi IMproved. Vim is an almost compatible version of
the UNIX editor vi. Only the 'Q' command is missing (you don't need it).
Many new features have been added: multi level undo, command line history,
filename completion, block operations, etc. See difference.doc.

This editor is very useful for editing programs and other plain ASCII files.
All commands are given with normal keyboard characters, so those who can type
with ten fingers can work very fast. Additionally function keys can be defined
by the user.

Vim currently runs under Amiga DOS, MSDOS, Windows NT and many UNIX versions.
There are some things included for the Archimedes, but it does not work yet.
Porting to other systems should not be very difficult.

Documentation:

tutor/readme - one hour training course for beginners
reference.doc - complete reference of all Vim commands
difference.doc - summarizes the differences with UNIX vi
windows.doc - reference for the multi windows and buffer commands
index - alfabetical list of commands
amiga.doc - remarks for Amiga
unix.doc - remarks for unix
msdos.doc - remarks for MSDOS
winnt.doc - remarks for Windows NT
archie.doc - remarks for Archimedes

Big improvements
================

Added multiple windows and multiple buffers! See doc/windows.doc for an
overview of the new and changed commands.

Added hidden buffers. 'hidden' option can be set to create a hidden buffer
instead of abandoning a buffer. Added ":bnext", ":bprev", ":bNext" and
"brewind" commands to go to other buffer. Added ":buffers" command to show all
buffers. Added ":bmod" command: go to next modified buffer. Added ":bdelete"
command: delete buffer from list.

Added a lot of commands to manipulate buffers:
- Added commands to open a window for all arguments, all active buffers, all
buffers: ":all", ":sall", ":unhide", ":sunhide", ":ball", ":sball".
- Added ":bunload" command: Unload buffer from memory. The ":bdelete" command
does the same plus deletes the buffer from the buffer list.
- Arguments from command line are always put in buffer list.
- Added ":sbuffer", ":sbnext", ":sbNext", ":sbprevious", ":sbmodified",
":sbrewind", ":sblast": split window and go to specified buffer.
- Added ":wNext" and ":wprevious": write file and go back in argument list.
- Added ":wqall" and ":xall", write all change buffers and exit.

When all changes have been undone the buffer is not considered to be changed.
Vim can then be exit with ":q" instead of ":q!".

Added simple "more" facility to listings. Can be switched on/off with the
'more' option.

Added Robert Webb's code for command line completion, with
"#ifdef WEBB_COMPLETE".


See the file reade3.0 for a complete set of changes in this version.

Vim is Charityware. You can copy it as much as you like. Please read
uganda.txt for details.

Please send comments, bug reports and suggestions to:

stable address: Bram Moolenaar UUCP E-mail: mo...@oce.nl
molenstraat 2
2162 HP Lisse Fax: +31 2521 16381
The Netherlands Tel: +31 2521 13037

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:10 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 20
Archive-name: vim/part01

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: vim vim/doc vim/doc/reference.doc.D vim/macros
# vim/macros/hanoi vim/macros/maze vim/macros/urm vim/src
# vim/src/addcr.bat vim/src/proto vim/tools vim/tutor
# Wrapped by kent@sparky on Mon Aug 15 21:43:56 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 26)."'
if test ! -d 'vim' ; then
echo shar: Creating directory \"'vim'\"
mkdir 'vim'
fi
if test ! -d 'vim/doc' ; then
echo shar: Creating directory \"'vim/doc'\"
mkdir 'vim/doc'
fi
if test -f 'vim/doc/reference.doc.D' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/reference.doc.D'\"
else
echo shar: Extracting \"'vim/doc/reference.doc.D'\" \(59796 characters\)
sed "s/^X//" >'vim/doc/reference.doc.D' <<'END_OF_FILE'
X Command_line mode.
X
X:noremap {lhs} {rhs} Map the key sequence {lhs} to {rhs} in Command mode.
X Disallow remapping of {rhs}. {not in Vi}
X
X:noremap! {lhs} {rhs} Map the key sequence {lhs} to {rhs} in insert and
X Command_line mode. Disallow remapping of {rhs}. {not
X in Vi}
X
X:unm[ap] {lhs} Remove the mapping of {lhs} for Command mode.
X
X:unm[ap]! {lhs} Remove the mapping of {lhs} for Insert and
X Command_line mode.
X
X:map List all key mappings for Command mode.
X
X:map! List all key mappings for Insert and Command_line
X mode.
X
X:map {lhs} List the key mappings for the key sequences starting
X with {lhs} in Command mode. {not in Vi}
X
X:map! {lhs} List the key mappings for the key sequences starting
X with {lhs} in insert and Command_line mode. {not in Vi}
X
X:cm[ap] Same as :map, but for Command_line mode only. {not
X in Vi}
X
X:cu[nmap] Same as :unmap, but for Command_line mode only.
X {not in Vi}
X
X:cno[remap] Same as :noremap, but for Command_line mode only.
X {not in Vi}
X
X:im[ap] Same as :map, but for Insert mode only. {not in Vi}
X
X:iu[nmap] Same as :unmap, but for Insert mode only. {not in
X Vi}
X
X:ino[remap] Same as :noremap, but for Insert mode only. {not in
X Vi}
X
XThese commands are used to map a key or key sequence to a string of
Xcharacters. You can use this to put command sequences under function keys,
Xtranslate one key into another, etc. See the "Options" chapter below for how
Xto save and restore the current mapping.
X
XThere are three sets of mappings
X- For Insert mode. These are also used in Replace mode.
X- For Command_line mode: When entering a ":" or "/" command.
X- For Command mode: When typing commands.
X
XThe original vi did not have separate mappings for Insert mode and
XCommand_line mode. Therefore the ":map!" command enters and displays
Xmappings for both. In Vim you can use the ":cmap" and ":imap" commands to
Xenter mappings for each mode separately. When listing mappings with ":map!",
X":cmap" or ":imap" the character in column 1 is <!> for mappings in both
XInsert and Command_line mode, <i> for Insert mode only and <c> for
XCommand_line mode only.
X
XEverything from the first non-blank after {lhs} up to the end of the line
X(or <|>) is considered to be part of {rhs}. This allows the {rhs} to end
Xwith a space.
X
XTo include a space in {lhs} precede it with a CTRL-V (type two CTRL-Vs for
Xeach space). If you want a {rhs} that starts with a space, precede {rhs}
Xwith a single CTRL-V (You have to type CTRL-V two times). You can create an
Xempty {rhs} by typing nothing after the two CTRL-Vs.
X
XIt is not possible to put a comment after this command, because the <">
Xcharacter is considered to be part of the {rhs}. To put a <|> in {rhs}
Xescape it with a backslash or a CTRL-V (to get one CTRL-V you have to type
Xit twice).
X
XTo avoid mapping of the characters you type in insert or Command_line mode,
Xtype a CTRL-V first. The mapping in Insert mode is disabled if the 'paste'
Xoption is set.
X
XNote that the second character (argument) of the commands @zZtTfF[]rm'`"v is
Xnot mapped. This was done to be able to use all the named registers and
Xmarks, even when the command with the same name has been mapped.
X
XSome examples (given as you type them; e.g. the "^V" is CTRL-V which you
Xtype, but will not show up on the screen):
X
X :map g /foo^V^Mcwbar^V^[ (replace next "foo" by "bar")
X :map! qq quadrillion questions
X
XVim will compare what you type with the start of a mapped sequence. If there
Xis an incomplete match, it will get more characters until there either is a
Xcomplete match or until there is no match at all. Example: If you map! "qq",
Xthe first <q> will not appear on the screen until you type another
Xcharacter. This is because Vim cannot know if the next character will be a
X<q> or not. If you set the 'timeout' option (which is the default) Vim will
Xonly wait for one second (or as long as specified with the 'timeoutlen'
Xoption). After that it assumes that the <q> is to be interpreted as such. If
Xtype slowly, or your system is slow, reset the 'timeout' option. Then you
Xmight want to set the 'ttimeout' option. See the "Options" chapter.
X
XIf you want to exchange the meaning of two keys you should use the :noremap
Xcommand. For example:
X :noremap k j
X :noremap j k
XThis will exchange the cursor up and down commands. With the normal :map
Xcommand, when the 'remap' option is set, mapping takes place until the text
Xis found not to be a part of a {lhs}. For example, if you use:
X :map x y
X :map y x
XVim will replace x by y, and then y by x, etc. When this has happened 1000
Xtimes, Vim will give an error message.
X
XSee the file "index" for keys that are not used and thus can be mapped
Xwithout losing any builtin function.
X
XIf you include an undo command inside a mapped sequence, this will bring the
Xtext back in the state before executing the macro. This is compatible with
Xthe original vi, as long as there is only one undo command in the mapped
Xsequence (having two undo commands in a mapped sequence did not make sense
Xin the original vi, you would get back the text before the first undo).
X
XThere are two ways to map a function key:
X1. The vi-compatible method: Map the key code. Often this is a sequence that
X starts with <ESC>. To enter a mapping like this you type ":map " and then
X you have to type CTRL-V before hitting the function key.
X2. The second method is to use the internal code for the function key. To
X enter such a mapping just hit the function key, without CTRL-V, or use
X the form "#1", "#2", .. "#9", "#0". Only the first ten function keys can
X be used this way ("#0" refers to function key 10, defined with option
X 't_f10', which may be function key zero on some keyboards).
XThe advantage of the second method is that the mapping will mostly work on
Xdifferent terminals without modification (the function key will be
Xtranslated into the same internal code, no matter what terminal you are
Xusing. The termcap must be correct for this to work, and you must use the
Xsame mappings).
X
XDETAIL: Vim first checks if a sequence from the keyboard is mapped. If it
Xisn't the terminal key codes are tried (see section 20.2). If a terminal
Xcode is found it is replaced by the internal code. Then the check for a
Xmapping is done again (so you can map an internal code to something else).
XWhat is written into the script file depends on what is recognized. If the
Xterminal key code was recognized as a mapping the key code itself is written
Xto the script file. If it was recognized as a terminal code the internal
Xcode is written to the script file.
X
X
X 18. Recovery after a crash.
X
XYou have spent several hours typing in that text that has to be finished
Xnext morning, and then disaster strikes: Your computer crashes.
X
X DON'T PANIC!
X
X
X18.1 The swap file
X
XVim stores the things you changed in a swap file. Using the original file
Xyou started from plus the swap file you can mostly recover your work. You
Xcan see the name of the current swap file being used with the command:
X
X :sw[apname]
X
XThe name of the swap file is normally the same as the file you are editing,
Xwith the extension ".swp". On MSDOS machines and when the 'shortname' option
Xis set, any <.> in the original file name is replaced by <_>. If this file
Xalready exists (e.g. when you are recovering from a crash) a warning is
Xgiven and another extension is used, ".swo", ".swn", etc. An existing file
Xwill never be overwritten. The swap file is deleted as soon as Vim stops
Xediting the file.
X
XTechnical: The replacement of <.> by <_> is done to avoid problems with
X MSDOS compatible filesystems (e.g. crossdos, multidos). If Vim is
X able to detect that the file is on an MSDOS-like filesystem, a
X flag is set that has the same effect as the 'shortname' option.
X This flag is reset when you start editing another file.
X
X If the ".swp" filename already exists, the last character is
X decremented until there is no file with that name or ".swa" is
X reached. In the last case, no swap file is created.
X
XBy setting the 'directory' option you can place the swap file in
Xanother place than where the edited file is. The advantage is that you will
Xnot pollute the directories with ".swp" files and, when the 'directory' is
Xon another partition, reduce the risk of damaging the file system where the
Xfile is (in a crash). The tradeoff is that you can get name collisions from
Xfiles with the same name but in different directories. You can also use a
Xrecoverable ram disk, but there is no 100% guarantee that this works.
XPutting swap files in a normal ram disk (like RAM: on the Amiga) makes no
Xsense, you will loose them in a crash. If you want to put swap files in
Xanother place, put a command resembling the following one in your .vimrc:
X :set dir=dh2:tmp
XThis is also very handy when editing files on floppy.
X
XThe swap file is updated after typing 200 characters or when you have
Xnot typed anything for four seconds. This only happens if the buffer was
Xchanged, not when you only moved around. The reason why it is not kept up to
Xdate all the time is that this would slow down normal work too much. You can
Xchange the 200 character count with the 'updatecount' option. You can set
Xthe time with the 'updatetime' option. The time is given in milliseconds.
X
XIf the writing to the swap file is not wanted, it can be switched off by
Xsetting the 'updatecount' option to 0. The same is done when starting Vim
Xwith the "-n" or "-v" option. Writing can be switched back on by setting the
X'updatecount' option to non-zero. But this will only affect files that will
Xbe opened after this.
X
XIf you want to make sure that your changes are in the swap file use this
Xcommand:
X
X:pres[erve] Write all text for all buffers into swap file. {Vi:
X emergency exit}
X
XA Vim swap file can be recognized by the first six characters: "b0VIM ".
XAfter that comes the version number, e.g. "3.0".
X
X
X18.2 Recovery
X
XIn most cases recovery is quite easy: Start Vim on the same file you were
Xediting when the crash happened, with the "-r" option added. Vim will read
Xthe ".swp" file and may read bits and pieces of the original file.
X
XExample: vim -r reference.doc
X
XIf the swap file does not end in ".swp" but in something else, you can
Xrecover by giving the swap file name. Vim will then find out the name of the
Xoriginal file from the swap file.
X
XExample: Vim -r reference.doc.swp
X
XThis is also handy when the swap file is in another directory than expected.
XIf this still does not work, see what file names Vim reports and rename the
Xfiles accordingly.
X
XThere is some intelligence about what to do if the swap file is corrupt in
Xsome way. If Vim has doubt about what it found, it will give an error
Xmessage and insert lines with "???" in the text. If you see an error message
Xwhile recovering, search in the file for "???" to see what is wrong. You may
Xwant to cut and paste to get the text you need.
X
XBe sure that the recovery was successful before overwriting the original
Xfile or deleting the swap file. It is good practice to write the recovered
Xfile elsewhere and execute 'diff' to find out if the changes you want are in
Xthe recovered file.
X
XOnce you are sure the recovery is ok delete the swap file. Otherwise, you
Xwill continue to get warning messages that the ".swp" file already exists.
X
X{Vi: recovers in another way and sends mail if there is something to recover}
X
X
X 19. Options
X
XVi has a number of internal variables and switches which can be set to
Xachieve special effects. These options come in three forms, those that are
Xswitches, which toggle from off to on and back, those that require a numeric
Xvalue, and those that require an alphanumeric string value.
X
X
X19.1 Setting options
X
X:se[t] Show all modified options. {Vi: non-default options}
X
X:se[t] all Show all but terminal options.
X
X:se[t] termcap Show all terminal options.
X
X:se[t] {option} Set toggle option on, show value of string or number
X option.
X
X:se[t] no{option} Set toggle option off.
X
X:se[t] inv{option} Invert toggle option. {not in Vi}
X
X:se[t] {option}={value} Set string or number option to {value}.
X
X:se[t] {option}? Show value of {option}.
X
XThe {option} arguments to ":set" may be repeated. For example:
X ":set ai nosi sw=3 ts=3".
XIf you make an error in one of the arguments an error message will be given
Xand the text up to the next space will be skipped. Thus following arguments
Xwill be processed.
X
XThe listing from ":set" looks different from vi. Long string options are put
Xat the end of the list. The number of options is quite large. The output of
X"set all" probably does not fit on the screen, causing Vim to give the
X"--more--" message. See the 'more' option.
X
XAn environment variable in most string options will be expanded. This
Xhappens only when the string starts with a <$>. If the environment variable
Xexists the <$> and the following environment variable name is replaced by
Xits value. If it does not exist the <$> and the name are not modified. Any
Xnon-id character (not a letter, digit or <_>) may follow the environment
Xvariable name. That character and what follows is appended to the value of
Xthe environment variable. Example:
X :set term=$TERM.new
X
XUsing "~/" is like using "$HOME".
X
XBesides changing options with the ":set" command, there are four
Xalternatives to set options automatically for one or more files. The first
Xand second ones are used for all files. The third is used to set options for
Xthe files in one directory. The last is used to set options for a single
Xfile. The first three are done when you start Vim, in the given order. The
Xlast is done whenever you start editing a new file.
X
X1. The environment variable VIMINIT is read for an Ex command. You can set
X VIMINIT to something like "set noai sw=3" to set options.
X2. Only if there is no VIMINIT environment variable, the file
X "s:.vimrc" is read for Ex commands. You can include set commands in this
X file. (see below for how to automatically create a file with set commands).
X3. If VIMINIT is not found and "s:.vimrc" does not exist, EXINIT is used,
X in the same way as VIMINIT.
X4. If VIMINIT is not found, "s:.vimrc" does not exist and EXINIT is not found,
X the file "s:.exrc" is read for Ex commands.
X5. If the 'exrc' option is set, the file ".vimrc" in the current directory is
X read for Ex commands. You can include set commands in this file. If this
X file is not found the file ".exrc" is tried.
X6. If you start editing a new file, and the 'modeline' option is set, a
X number of lines at the beginning and end of the file are checked for the
X string "vi:", "vim:" or "ex:". The text after it is considered to be the
X arguments for a ":set" command, separated with colons or spaces. For
X example:
X "vi:noai:sw=3 ts=6"
X The number of lines that are checked can be set with the 'modelines'
X option. If 'modeline' is not set or 'modelines' is 0 no lines are
X checked.
X The string "vi:", "vim:" or "ex:" must be preceded with a blank or begin
X at the start of a line. This minimizes the chance that a normal word like
X "lex:" is caught.
X Note that all of the rest of the line is used, thus a line like:
X "/* vi:ts=4: */"
X will give an error message for the trailing "*/".
X If an error is detected the rest of the line is skipped.
X One other form of modelines is recognized that has the "set" command
X after "vi:", "vim:" or "ex:" (this is compatible with some versions of
X vi). In this case the characters up to the first <:> are executed as an
X ex command. Anything following it is ignored. Thus a line like:
X "/* vi:set ts=4: */"
X is OK. If you want to include a <:> in a set command precede it with a
X <\>.
X
X
X19.2 Saving settings
X
X:mkexrc [file] Write current key mappings and changed options to
X [file] (default ".exrc"), unless it already exists.
X {not in Vi}
X
X:mkexrc! [file] Always write current key mappings and changed
X options to [file] (default ".exrc"). {not in Vi}
X
X:mkvimrc[!] [file] Same as :mkexrc, but default is ".vimrc". {not in
X Vi}
X
XThese commands will write ":map" and ":set" commands to a file, in such a
Xway that when these commands are executed, the current key mappings and
Xoptions will be set again. A common method is to use a default ".exrc" file
Xby first reading one in with ":source s:.exrc.Cprogs", change the settings
Xand then save them in the current directory with ":mkexrc!".
X
X
X19.3 Options summary
X
XIn the list below all the options are mentioned with their full name and some
Xwith an abbreviation between parens. Both forms may be used. In this
Xdocument when an option that can be toggled is "set" that means that ":set
Xoption" is entered. When an option is "reset", ":set nooption" is used.
X
Xautoindent (ai) toggle (default off)
X Copy indent from current line when starting a new line (typing <CR>
X in Insert mode or when using the "o" or "O" command). If you do not
X type anything on the new line except <BS> and then type <ESC> or
X <CR>, the indent is deleted again. When autoindent is set,
X formatting (with the "Q" command or when you reach 'textwidth' in
X Insert mode) uses the indentation of the first line. The 'autoindent'
X option is reset when the 'paste' option is set.
X
Xautowrite (aw) toggle (default off)
X Write the contents of the file, if it has been modified, on each
X :next, :rewind, :previous, :stop, :suspend, :tag, :!, :make, CTRL-]
X and CTRL-^ command; and when a CTRL-O, CTRL-I, '<A-Z>, or `<A-Z>
X command takes one to another file.
X
Xbackspace (bs) number (default 0)
X Influences the working of <BS>, <DEL>, CTRL-W and CTRL-U in Insert
X mode. If set to 0 Vi compatible backspacing is used. When 1 allow
X backspacing over newlines. When larger than 1 allow backspacing over
X the start of insert. In the last case CTRL-W and CTRL-U stop once at
X the start of insert. {not in Vi}
X
Xbackup (bk) toggle (default on)
X Make a backup before overwriting a file. Leave it around after the
X file has been successfully written. If you do not want to keep the
X backup file, but you do want a backup while the file is being
X written, reset this option and set the 'writebackup' option. If you
X do not want a backup file at all reset both options (See the table
X in section 5.4 for another explanation.). {not in Vi}
X
Xbackupdir (bdir) string (default "$HOME")
X Directory name for the backup file. Empty means in same directory as
X the edited file. If the directory name starts with <>>, only the
X specified directory will be used. If there is a directory name but
X it does not start with <>>, the current directory is tried first.
X The specified directory is used only if that fails. The name may end
X in an <:> or </>. Environment variables are expanded. {not in Vi}
X
Xbinary (bin) toggle (default off)
X This option should be set before editing a binary file. You can also
X use the "-b" command line option. When this option is set the
X 'textwidth' option will set to 0, the 'textmode' and 'textauto'
X options will be reset and 'modelines' will be set to 0. When writing
X a file the end-of-line for the last line is only written if there
X was one in the original file (normally Vim appends an end-of-line to
X the last line if there is none; this would make the file longer). See
X the 'endofline' option. {not in Vi}
X
Xbioskey (bk) toggle (default on)
X For MSDOS only: When set the bios is called to obtain a keyboard
X character. This works better to detect CTRL-C, but only works for
X the console. When using a terminal over a serial port reset this
X option. {not in Vi}
X
Xcmdheight (ch) number (default 1)
X Number of lines to use for the command line. If you are annoyed by
X "hit return to continue" or "--more--" caused by long messages, set
X this option to a larger value. {not in Vi}
X
Xcolumns number (default 80 or terminal width)
X Number of columns in the display. Normally this is set by the
X terminal initialization and does not have to be set by hand. {not in
X Vi}
X
Xcompatible (cp) toggle (default off)
X At the moment this option is set, several other options will be set
X or reset to make Vim vi-compatible. Switching this option off has no
X effect. {not in Vi}
X
X option new value effect
X
X backspace 0 normal backspace
X backup off no backup file
X digraph off no digraphs
X esckeys off no <ESC>-keys in Insert mode
X expandtab off tabs not expanded to spaces
X history 0 no commandline history
X insertmode off do not start in Insert mode
X joinspaces on insert 2 spaces after period
X modelines 0 no modelines
X more off no pauses in listings
X revins off no reverse insert
X ruler off no ruler
X scrolljump 0 no jump scroll
X shiftround off indent not rounded to shiftwidth
X showcmd off command characters not shown
X showmode off current mode not shown
X smartindent off no smart indentation
X textauto off no automatic textmode detection
X textwidth 0 no automatic line wrap
X tildeop off tilde is not an operator
X ttimeout off no terminal timeout
X undolevels 0 no multilevel undo
X updatecount 0 no swap file
X writebackup off no backup file written
X yankendofline off do not Yank to end of line
X
Xdigraph (dg) toggle (default off)
X Enable the entering of digraphs in Insert mode with {char1} <BS>
X {char2}. Only works if Vim was compiled with digraphs enabled. {not
X in Vi}
X
Xdirectory (dir) string (default for Amiga: "t:", for MSDOS:
X "c:\tmp", for unix: "/tmp")
X Directory name for the swap file. Empty means in same directory as the
X edited file. If the directory name starts with <>>, only the
X specified directory will be used. If there is a directory name but
X it does not start with <>>, the current directory is tried first.
X The specified directory is used only if that fails. The name may end
X in an <:> or </>. Environment variables are expanded. Careful with
X <\> characters, type two to get one in the option, ":set
X dir=c:\\tmp". {Vi: directory to put temp file in, defaults to
X "/tmp"}
X
Xedcompatible toggle (default off)
X Makes the 'g' and 'c' flags of the ":substitute" command to be
X toggled each time the flag is given. See 11.3. See also 'gdefault'
X option.
X
Xendofline (eol) toggle (default on)
X When writing a file and this option is off and the 'binary' option is
X set, no end of line (newline) character will be written for the last
X line in the file. This option is automatically set when starting to
X edit a new file, unless the 'binary' options is set and the file does
X not have an end of line (newline) for the last line in the file, in
X which case it is reset. Normally you don't have to set or reset this
X option. When 'binary' is not set the value is not used. When 'binary'
X is set it is used to remember the presence of a newline for the last
X line in the file, so that when you write the file the situation from
X the original file can be kept. But you can change it when you want to.
X {not in Vi}
X
Xequalalways (ea) toggle (default on)
X When set all the windows are automatically made the same size after
X splitting or closing a window. If you don't set this option, splitting
X a window will reduce the size of the current window and leave the
X other windows the same. When closing a window the extra lines are
X given the the window above it. {not in Vi}
X
Xequalprg (ep) string (default "indent")
X External program to use for "=" command. Environment variables are
X expanded. {not in Vi}
X
Xerrorbells (eb) toggle (default off)
X Ring the bell for error messages. Does not work on the Amiga, you
X always get a screen flash.
X
Xerrorfile (ef) string (default "AztecC.Err" or "errors")
X Name of the error file for the QuickFix mode (see 5.5). Environment
X variables are expanded. {not in Vi}
X
Xerrorformat (efm) string (default "%f>%l:%c:%t:%n:%m" or
X ""%f",%*[^0-9]%l %m")
X Scanf-like description of the format for the lines in the error file
X (see 5.5). {not in Vi}
X
Xesckeys (ek) toggle (default on)
X Function keys that start with an <ESC> are recognized in Insert
X mode. When this option is off, the cursor and function keys cannot be
X used in Insert mode if they start with an <ESC>. The advantage of this
X is that the single <ESC> is recognized immediately, instead of after
X one second.
X
Xexpandtab (et) toggle (default off)
X In Insert mode: Use the appropriate number of spaces to insert a
X <TAB>. Spaces are used in indents with the '>' and '<' commands and
X when 'autoindent' is set. To insert a real tab when expandtab is
X set, use CTRL-V<TAB>. {not in Vi}
X
Xexrc toggle (default off)
X Enables the reading of .vimrc and .exrc in the current directory. If
X you switch this option on you should also consider setting the
X 'secure' option (see 3.4). {not in Vi}
X
Xformatprg (fp) string (default "")
X The name of an external program that will be used to format the
X lines selected with the "Q" command. The program must take the input
X on stdin and produce the output on stdout. The unix program 'fmt' is
X such a program. If this option is an empty string, the internal
X format function will be used. Environment variables are expanded.
X {not in Vi}
X
Xgdefault (gd) toggle (default off)
X When set, the ":substitute" flag 'g' is default on. This means that
X all matches in a line are substituted instead of one. See 11.3. {not
X in Vi}
X
Xgraphic (gr) toggle (default off, MSDOS: on)
X When off characters between <~> and 0xa0 are displayed as "~?",
X "~@", "~A", etc.. When on the characters are sent to the display
X directly. This will allow for graphic characters to be shown on some
X terminals (e.g. MSDOS console) and mess up the display on others
X (e.g. Amiga).
X
Xhelpfile (hf) string (default (Amiga) "vim:vim.hlp"
X (unix) "/usr/local/lib/vim.hlp")
X Name of the help file. It may start with an environment variable.
X For example: "$VIM/doc/vim.hlp". Environment variables are expanded.
X {not in Vi}
X
Xhidden (hid) toggle (default off)
X When off the current buffer is unloaded when it is abandoned. When
X on the current buffer becomes hidden when starting to edit another
X buffer. If the current buffer is also displayed in another window it
X does not become hidden. The commands that move through the buffer
X list make the current buffer hidden although the 'hidden' option is
X not set. See also 'windows.doc'. {not in Vi}
X
Xhighlight (hl) string (default "db,es,hs,rs,vi,si")
X This option can be used to set highlighting mode for various
X occasions. It is a comma separated list of character pairs. The first
X character in a pair gives the occasion, the second the mode to use for
X that occasion. The occasions are:
X v visual mode
X d directories in CTRL-D listing
X e error messages
X s status lines
X h help file headers
X r return to continue message and yes/no questions
X The display modes are:
X i invert (termcap entry "mr")
X b bold (termcap entry "md")
X s standout (termcap entry "so")
X n no highlighting
X The default is to use bold for directories, standout for error
X messages, help file headers and return, invert for visual mode and
X status lines.
X Invert is used for occasions that are not included. {not in Vi}
X
Xhistory (hi) number (default 20)
X Number of command lines that are remembered. {not in Vi}
X
Xicon toggle (default off)
X When set the icon of the window will be set to the name of the file
X currently being edited. Only the last part of the name is used. Only
X works if the terminal supports setting window icons (currently only
X Unix xterm and iris-ansi). When Vim was compiled with USE_X11
X defined, the original icon will be restored if possible. {not in Vi}
X
Xignorecase (ic) toggle (default off)
X Ignore case in search patterns. Also used when searching in the tags
X file.
X
Xinsertmode (im) toggle (default off)
X Start the edit of a file in Insert mode. {not in Vi}
X
Xjoinspaces (js) toggle (default on)
X Insert two spaces after a period with a join command. {not in Vi}
X
Xkeywordprg (kp) string (default "ref")
X Program to use for the "K" command. Environment variables are
X expanded. {not in Vi}
X
Xlaststatus (ls) number (default 1)
X The value of this option influences when the last window will have a
X status line:
X 0: never
X 1: only if there are at least two windows
X 2: always
X The screen looks nicer with a status line if you have several
X windows, but it takes another screen line. {not in Vi}
X
Xlines number (default 24 or terminal height)
X Number of lines in the display. Normally you don't need to set this.
X That is done automatically by the terminal initialization code.
X
Xlist toggle (default off)
X List mode: Show tabs as CTRL-I, show end of line with $. Useful to
X see the difference between tabs and spaces and for trailing blanks.
X
Xmagic toggle (default on)
X Changes the special characters that can be used in search patterns.
X See section "Pattern searches".
X
Xmakeprg (mp) string (default "make")
X Program to use for the ":make" command. This option may contain
X <%> and <#> characters, which are expanded like when used in a
X command line. Environment variables are expanded. {not in Vi}
X
Xmaxmem (mm) number (default 512)
X Maximum amount of memory (in Kbyte) to use for one buffer. When this
X limit is reached allocating extra memory for a buffer will cause
X other memory to be freed. See also 'maxmemtot'. {not in Vi}
X
Xmaxmemtot (mmt) number (default 512)
X Maximum amount of memory (in Kbyte) to use for all buffers together.
X Added 'maxmemtot' option ('mmt'), maximal Kbyte to use for
X all buffers.
X
Xmodeline (ml) toggle (default on)
Xmodelines (mls) number (default 5)
X If 'modeline' is set 'modelines' gives the number of lines that is
X checked for set commands. If 'modeline' is not set or 'modelines' is
X 0 no lines are checked. See 19.1. {not in Vi}
X
Xmore toggle (default on)
X Listings pause when the whole screen is filled. Type <CR> for one
X more line. Type <SPACE> for the next page. Type 'q' to stop the
X listing. When this option is off there are no pauses, the listing
X continues until finished. When Vim was compiled with COMPATIBLE
X defined this option is default off. When 'compatible' is set this
X option is off. {not in Vi}
X
Xnobuf (nb) toggle (default off)
X When set characters are send to the terminal one by one. For MSDOS
X pcterm this does not work. For debugging purposes. {not in Vi}
X
Xnumber (nu) toggle (default off)
X Print the line number in front of each line.
X
Xparagraphs (para) string (default "IPLPPPQPP LIpplpipbp")
X Specifies the nroff macros that separate paragraphs. These are pairs
X of two letters (see section 6.4).
X
Xpaste toggle (default off)
X Put Vim in Paste mode. This is useful if you want to cut or copy
X some text from one window and paste it in Vim. This will avoid
X unexpected effects. When the 'paste' option is set mapping in Insert
X mode is disabled, abbreviations are disabled and some options are
X reset ('textwidth', 'autoindent', 'smartindent', 'revins', 'ruler'
X and 'showmatch'). When the 'paste' option is reset the mentioned
X options are restored to the value before the moment 'paste' was
X set. Resetting 'paste' before ever setting it does not have any
X effect. If you use this often, you could map a function key to the
X command ":set invpaste^V^M". {not in Vi}
X
Xpatchmode (pm) string (default "")
X Only for Unix: When set the oldest version of a file is kept. This can
X be used to keep the original version of a file if you are changing
X files in a source distribution. Only the first time that a file is
X edited a copy of the original file will be kept. The name of the copy
X is the name of the original file with the string in the 'patchmode'
X option appended. This option should start with a dot. Use a string
X like ".org". Only works properly if the 'backup' or the 'writebackup'
X option is set. If both are not set, an empty file is created with the
X 'patchmode' option appended to the name of the original file. This
X means that you can only see which files where changed. {not in Vi}
X
Xreadonly (ro) toggle (default off)
X If set, writes fail unless you use an !. Protects you from
X accidentally overwriting a file. Also, sets 'updatecount' to zero so
X that no ".swp" swap file is created. Default on when vim is started
X in view mode ("vim -v") or when the executable is called "view". It
X is reset if you overwrite the current file (e.g. with ":w!").
X
Xremap toggle (default on)
X Allows for :map command to work recursively. If you do not want this
X for a single entry, use the :noremap[!] command.
X
Xreport number (default 2)
X Threshold for reporting number of lines changed.
X
Xrevins toggle (default off)
X Inserting characters in Insert mode will work backwards. See "typing
X backwards". Can be toggled with the CTRL-B command in Insert mode.
X This option is reset when 'compatible' or 'paste' is set. {not in Vi}
X
Xruler (ru) toggle (default off)
X Show the line and column number of the cursor position in the status
X line, separated by a comma. If there are characters in the line that
X take two positions on the screen, both the "real" column and the
X screen column are shown, separated with a dash. This option is reset
X when the 'paste' option is set. {not in Vi}
X
Xscroll number (default 'lines' / 2)
X Number of lines to scroll with CTRL-U and CTRL-D commands. Will be
X set to half the number of lines in the window when the window size
X changes. If you give a count to the CTRL-U or CTRL-D command it will
X be used as the new value for 'scroll'. Reset to 'lines' / 2 with
X ":set scroll=0".
X
Xscrolljump number (default 1)
X Minimal number of lines to scroll when the cursor gets off the
X screen (e.g. with "j"). Not used for scroll commands (e.g. CTRL-E,
X CTRL-D). Useful if your terminal scrolls very slowly. {not in Vi}
X
Xsections (sect) string (default "SHNHH HUnhsh")
X Specifies the nroff macros that separate sections. These are pairs of
X two letters (See section 6.4).
X
Xsecure toggle (default off)
X When on, shell and write commands are not allowed in ".vimrc" and
X ".exrc" in the current directory and map commands are displayed.
X Switch it off only if you know that you will not run into problems,
X or when the 'exrc' option is off. On unix this option is only used
X if the ".vimrc" or ".exrc" is not owned by you.
X
Xshell (sh) string (default $SHELL or "sh", MSDOS: "command")
X Name of the shell to use for ! and :! commands. See also the
X 'shelltype' option. It is allowed to give an argument to the
X command, e.g. "csh -f". If you type this in the command line you
X will have to put a backslash in front of the space. Environment
X variables are expanded.
X
Xshellpipe (sp) string (default ">", "| tee", "|& tee" or "2>&1| tee")
X String to be used to put the output of the ":make" command in the
X error file. For the Amiga and MSDOS the default is ">". The output
X is directly saved in a file and not echoed to the screen. For Unix
X the default it "| tee". The stdout of the compiler is saved in a
X file and echoed to the screen. If the 'shell' option is "csh" during
X initializations, the default becomes "|& tee". If the 'shell' option
X is "sh", "ksh" or "bash" the default becomes "2>&1| tee". This means
X that stderr is also included. Setting the 'shell' option does not
X automatically change the 'shellpipe' option.
X
Xshelltype (st) number (default 0)
X On the Amiga this option influences the way how the commands work
X which use a shell.
X 0 and 1: always use the shell
X 2 and 3: use the shell only to filter lines
X 4 and 5: use shell only for ':sh' command
X When not using the shell, the command is executed directly.
X
X 0 and 2: use 'shell -c cmd' to start external commands
X 1 and 3: use 'shell cmd' to start external commands
X
Xshiftround (sr) toggle (default off)
X Round indent to multiple of shiftwidth. Applies to > and < commands
X and to CTRL-T and CTRL-D in Insert mode. {not in Vi}
X
Xshiftwidth (sw) number (default 8)
X Number of spaces to use for (auto)indent.
X
Xshortname (sn) toggle (default off)
X Filenames can be 8 characters plus one extension of 3 characters.
X Multiple dots in file names are not allowed. When this option is on,
X dots in filenames are replaced by underscores when adding an
X extension (".bak" or ".swp"). This option is not available for
X MSDOS, because then it would always be on. This option is useful
X when editing files on an MSDOS compatible filesystem, e.g. messydos
X or crossdos. {not in Vi}
X
Xshowcmd (sc) toggle (default on, off for unix)
X show command in status line. Set this option off if your terminal
X is slow. {not in Vi}
X
Xshowmatch (sm) toggle (default off)
X When a bracket is inserted, briefly jump to the matching one. This
X option is reset when the 'paste' option is set.
X
Xshowmode (smd) toggle (default on)
X If in Insert or Replace mode, put a message on the last line.
X
Xsidescroll (ss) number (default 0)
X The minimal number of columns to scroll horizontally. Used only when
X the 'wrap' option is on and the cursor is moved off of the screen.
X When set to zero the cursor will be put in the middle of the screen.
X When using a slow terminal set it to a large number or 0. When using
X a fast terminal use a small number or 1. {not in Vi}
X
Xsmartindent (si) toggle (default off)
X Do smart autoindenting for C programs in Insert mode and with the
X "o" and "O" commands. An indent is automatically inserted:
X - After a line ending in <{>.
X - After a line starting with "if", "for", "while", "else" or "do".
X If you type a <{> as the first character in the new line, the
X indent is deleted.
X - Before a line starting with <}> (only with the "O" command).
X When typing <}> as the first character in a new line, that line is
X given the same indent as the matching <{>.
X When typing <#> as the first character in a new line, the indent for
X that line is removed, the <#> is put in the first column. The indent
X is restored for the next line.
X When using the ">>" command, lines starting with <#> are not shifted
X right.
X 'smartindent' is reset when the 'paste' option is set. {not in Vi}
X
Xsmarttab (sta) toggle (default off)
X When set a TAB in front of a line inserts 'shiftwidth' positions,
X 'tabstop' in other places. When not set a TAB always inserts 'tabstop'
X positions, 'shiftwidth' is only used for ">>" and the like. {not in
X Vi}
X
Xsplitbelow (sb) toggle (default off)
X When set new window from split is below the current one. {not in Vi}
X
Xsuffixes (su) string (default ".bak.o.h.info.swp")
X Files with these suffixes are ignored when multiple files match a
X wildcard. {not in Vi}
X
Xtabstop (ts) number (default 8)
X Number of spaces that a <TAB> in the file counts for.
X
Xtaglength (tl) number (default 0)
X If non-zero, tags are significant up to this number of characters.
X
Xtagrelative (tr) toggle (default on)
X If set and using a tag file in another directory, file names in that
X tag file are relative to the directory where the tag file is. If Vim
X was compiled with COMPATIBLE defined, or when the 'compatible' option
X is set, this option is reset. {not in Vi}
X
Xtags string (default "tags")
X Filenames for the tag command, separated by spaces. Environment
X variables are expanded for the first name. {Vi: default is "tags
X /usr/lib/tags"}
X
Xterm string (default $TERM or "amiga" on Amiga, "pcterm"
X on MSDOS)
X Name of the terminal. Used for choosing the terminal control
X characters. Environment variables are expanded.
X
Xterse toggle (default off)
X Shorten some of the messages. {Vi shortens a lot more messages}
X
Xtextauto (ta) toggle (default on)
X When a new file is edited the first line is checked for the line
X separator. If it is a single <LF> 'textmode' is reset. If it is a
X <CR><LF> pair 'textmode' is set. {not in Vi}
X
Xtextmode (tx) toggle (MSDOS: default on, others: default off)
X When off, <LF> separates lines. When on, <CR><LF> separates lines
X and CTRL-Z at end of file is ignored. Only used when reading and
X writing files. Set automatically when reading a file and 'textauto'
X is on. {not in Vi}
X
Xtextwidth number (default 0)
X Maximum width of text that is being inserted. A longer line will be
X broken after white space to get this width. A zero value disables
X this. 'textwidth' is set to 0 when the 'paste' option is set. When
X 'textwidth' is zero, 'wrapmargin' may be used. {not in Vi}
X
Xtildeop (to) toggle (default off)
X The tilde command <~> behaves like an operator. {not in Vi}
X
Xtimeout toggle (default on)
Xttimeout toggle (default off)
X These two options together determine the behaviour when part of a
X mapped key sequence or keyboard code has been received:
X
X timeout ttimeout action
X off off no time out
X on on or off time out on :mappings and key codes
X off on time out on key codes
X
X If there is no time out, Vim will wait until either the complete
X mapping or key sequence has been received, or it is clear that there
X is no mapping or key sequence for the received characters. For
X example: if you have mapped "vl" and Vim has received <v>, the next
X character is needed to see if the <v> is followed by an <l>. With a
X time out Vim will wait for about 1 second for the next character to
X arrive. After that the already received characters are interpreted
X as single characters. The time can be set with the 'timeoutlen'
X option.
X On slow terminals or very busy systems time out may cause
X malfunctioning cursor keys. If both options are off, Vim waits
X forever after an entered <ESC> if there are key codes that start
X with <ESC>. You will have to type <ESC> twice. If you do not have
X problems with key codes, but would like to have :mapped key
X sequences not time out in 1 second, set the ttimeout option and
X reset the timeout option. {the ttimeout option is not in Vi}
X
Xtimeoutlen (tm) number (default 1000)
X The time in milliseconds that is waited for a key code or mapped key
X sequence to complete. {only in some versions of Vi}
X
Xtitle toggle (default on)
X When set the title of the window will be set to "VIM - filename",
X where filename is the name of the file currently being edited. Only
X works if the terminal supports setting window titles (currently Amiga
X console, Unix xterm and iris-ansi). When Vim was compiled with NOTITLE
X defined the default is off. When Vim was compiled with USE_X11
X defined, the original title will be restored if possible. {not in Vi}
X
Xttyfast (tf) toggle (default off)
X Indicates a fast terminal connection. More characters will be send
X to the screen for redrawing, instead of using insert/delete line
X commands. Improves smoothness of redrawing when there are multiple
X windows and the terminal does not support a scrolling region. {not
X in Vi}
X
Xundolevels (ul) number (default 100)
X Maximum number of changes that can be undone. Set to 0 for Vi
X compatibility: one level of undo and 'u' undoes itself. Set to a
X negative number for no undo at all (saves memory). {not in Vi}
X
Xupdatecount (uc) number (default 200)
X After this many characters typed the swap file will be written to
X disk. When zero the swap script will not be written at all (see
X chapter on recovery). {not in Vi}
X
Xupdatetime (ut) number (default 4000)
X If this many milliseconds nothing is typed the swap file will be
X written to disk (see chapter on recovery). {not in Vi}
X
Xvisualbell (vb) toggle (default off)
X Use (sort of) visual bell for AUX device. {not in Vi}
X
Xwarn toggle (default on)
X Give a warning message when a shell command is used while the buffer
X has been changed.
X
Xweirdinvert (wi) toggle (default off)
X Set this option for terminals that have a weird inversion method.
X Makes the start/end invert code outputted before every character.
X Slows down terminal I/O a lot, but it makes Visual mode work.
X {not in Vi}
X
Xwhichwrap (ww) number (default 3)
X Allow specified keys that move the cursor left/right to wrap to the
X previous/next line when the cursor is on the first/last character in
X the line. Add numbers to allow this for these keys:
X 1 for backspace in command mode
X 2 for space in command mode
X 4 for 'h' and 'l' in command mode
X 8 for cursor left/right in command mode
X 16 for cursor left/right in insert mode
X For example: ":set ww=24" allows wrap only when cursor keys are used.
X When compiled with COMPATIBLE defined or when 'compatible' option set,
X 'whichwrap' is set to 0.
X {not in Vi}
X
Xwildchar (wc) number (default <TAB> or CTRL-E)
X Character you have to type to start wildcard expansion in the
X command line. CTRL-E is used when Vim was compiled with COMPATIBLE
X or when the 'compatible' option is set. The character is not
X recognized when used inside a macro. {not in Vi}
X
Xwinheight (wh) number (default 0)
X Minimal number of lines for the current window. If the current
X window is smaller, its size is increased, at the cost of the height
X of other windows. Set it to 999 to make the current window always
X fill the screen. Set it to a small number for normal editing. The
X height is not adjusted after one of the commands to change the
X height of the current window. {not in Vi}
X
Xwrap toggle (default on)
X When on, long lines will wrap and continue on the next line. When
X off long lines will not wrap and only part of them will be shown.
X When the cursor is moved to a part that is not shown, the screen
X will scroll horizontally (also see 'sidescroll' option. {not in Vi}
X
Xwrapmargin (wm) number (default 0)
X Number of characters from the right window border where wrapping
X starts. When 'textwidth' is set, this option is not used. {Vi: works
X differently and less useful}
X
Xwrapscan (ws) toggle (default on)
X Searches wrap around the end of the file.
X
Xwriteany (wa) toggle (default off)
X Allows writing to any file with no need for "!" override.
X
Xwritebackup (wb) toggle (default on)
X Make a backup before overwriting a file. The backup is removed after
X the file was successfully written, unless the 'backup' option is also
X on. {not in Vi}
X
Xyankendofline (ye) toggle (default off)
X The Y command yanks from the cursor until the end of the line instead
X of whole lines. {not in Vi}
X
X
X 20. Terminal information
X
XVim uses information about the terminal you are using to fill the screen and
Xrecognize what keys you hit. If this information is not correct the screen
Xmay be messed up or keys may not be recognized. The actions which have to be
Xperformed on the screen are accomplished by outputting a string of
Xcharacters. Special keys produce a string of characters. These strings are
Xstored in the terminal options, see section 20.2.
X
X
X20.1 startup
X
XWhen Vim is started a default terminal type is assumed. For the Amiga this
Xis a standard CLI window, for MSDOS the pc terminal, for Unix an ansi
Xterminal. A few other terminal types are always available. Use the command
X"set term=xxx" to find out which ones are builtin.
X
XYou can give the terminal name with the '-T' command line option. If it is
Xnot given Vim will try to get the name from the TERM environment variable.
X
XOn Unix the termcap file is used. On Amiga and MSDOS this is only available
Xif Vim was compiled with TERMCAP defined. If the termcap code is included
XVim will try to get the strings for the terminal you are using from the
Xtermcap file.
X
XFor normal editing the terminal will be put into "raw" mode. The strings
Xdefined with 't_ts' and 't_ks' will be sent to the terminal. Normally this
Xputs the terminal in a state where the termcap codes are valid and activates
Xthe cursor and function keys. When Vim exits the terminal will be put back
Xinto the mode it was before Vim started. The strings defined with 't_te' and
X't_ke' will be sent to the terminal. On the Amiga with commands that execute
Xan external command (e.g. "!!") the terminal will be put into normal mode
Xfor a moment. This means that you can stop the output to the screen by
Xhitting a printing key. Output resumes when you hit <BS>.
X
XSome termcap entries are wrong in the sense that after sending 't_ks' the
Xcursor keys send codes different from the codes defined in the termcap. To
Xavoid this you can set 't_ks' (and 't_ke') to empty strings. This must be
Xdone during initialization (see 3.4), otherwise its too late.
X
XSome termcap entries assume that the highest bit is always reset. For
Xexample: The cursor-up entry for the amiga could be ":ku=\EA:". But the
XAmiga really sends "\233A". This works fine if the highest bit is reset,
Xe.g. when using an Amiga over a serial line. If the cursor keys don't work,
Xtry the entry ":ku=\233A:".
X
XSome termcap entries have the entry ":ku=\E[A:". But the Amiga really sends
X"\233A". On output "\E[" and "\233" are often equivalent, on input they
Xaren't. You will have to change the termcap entry, or change the key code
Xwith the :set command to fix this.
X
XMany cursor key codes start with an <ESC>. Vim must find out if this a
Xsingle hit of the <ESC> key or the start of a cursor key sequence. It waits
Xfor a next character to arrive. If it does not arrive within one second a
Xsingle <ESC> is assumed. On very slow systems this may fail, causing cursor
Xkeys not to work sometimes. If you discover this problem reset the 'timeout'
Xoption. Vim will wait for the next character to arrive after an <ESC>. If
Xyou want to enter a single <ESC> you must type it twice. Resetting the
X'esckeys' option avoids this problems in Insert mode, but you lose the
Xpossibility to use cursor and function keys in Insert mode.
X
XOn the Amiga the recognition of window resizing is activated only when the
Xterminal name is "amiga" or "builtin_amiga".
X
XSome terminals have confusing codes for the cursor keys. The televideo 925
Xis such a terminal. It sends a CTRL-H for cursor-left. This would make it
Ximpossible to distinguish a backspace and cursor-left. To avoid this problem
XCTRL-H is never recognized as cursor-left.
X
X
X20.2 terminal options
X
XThe terminal options can be set just like normal options. But they are not
Xshown with the ":set all" command. Instead use ":set termcap".
X
XIt is always possible to change individual strings by setting the
Xappropriate option. For example:
X
X :set t_el=^V^[[K (CTRL-V, ESC, [, K)
X
X{Vi: no terminal options. You have to exit vi, edit the termcap entry and
Xtry again}
X
XThe options are listed below along with the associated termcap code. Two of
Xthem are required: Cursor positioning and clear screen. The others are used
Xto minimize the screen updating overhead and to recognize special keys.
X
X
X option termcap meaning
X
XOUTPUT CODES
X t_name (name) name of current terminal entry
X t_el ce clear to end of line
X t_il al add new blank line
X t_cil AL add number of blank lines
X t_dl dl delete line
X t_cdl DL delete number of lines
X t_cs cs define scrolling region
X t_ed cl clear screen (required!)
X t_ci vi cursor invisible
X t_cv ve cursor visible
X t_cvv cvv cursor very visible
X t_tp me normal mode (undoes t_ti and t_tb)
X t_ti mr reverse (invert) mode
X t_tb md bold mode
X t_se se standout end
X t_so so standout mode
X t_ms ms if set, cursor can be moved in standout/inverse mode
X t_cm cm cursor motion (required!)
X t_sr sr scroll reverse (backward)
X t_cri RI cursor number of chars right
X t_vb vb visual bell
X t_ks ks put terminal in "keypad transmit" mode
X t_ke ke out of "keypad transmit" mode
X t_ts ti put terminal in "termcap" mode
X t_te te out of "termcap" mode
X
XKEY CODES
X t_ku ku arrow up
X t_kd kd arrow down
X t_kr kr arrow right
X t_kl kl arrow left
X t_sku (none) shift arrow up
X t_skd (none) shift arrow down
X t_skr %i shift arrow right
X t_skl #4 shift arrow left
X t_f1 k1 function key 1
X t_f2 k2 function key 2
X t_f3 k3 function key 3
X t_f4 k4 function key 4
X t_f5 k5 function key 5
X t_f6 k6 function key 6
X t_f7 k7 function key 7
X t_f8 k8 function key 8
X t_f9 k9 function key 9
X t_f10 k; function key 10
X t_sf1 F1 function key 11 or shifted function key 1
X t_sf2 F2 function key 12 or shifted function key 2
X t_sf3 F3 function key 13 or shifted function key 3
X t_sf4 F4 function key 14 or shifted function key 4
X t_sf5 F5 function key 15 or shifted function key 5
X t_sf6 F6 function key 16 or shifted function key 6
X t_sf7 F7 function key 17 or shifted function key 7
X t_sf8 F8 function key 18 or shifted function key 8
X t_sf9 F9 function key 19 or shifted function key 9
X t_sf10 FA function key 20 or shifted function key 10
X t_help %1 help key
X t_undo &8 undo key
X
XNote about t_so and t_ti: When the termcap entry "so" is not present the
Xentry for "mr" is used. And visa versa. The same is done for "se" and "me".
XIf your terminal supports both inversion and standout mode, you can see two
Xdifferent modes. If you terminal supports only one of the modes, both will
Xlook the same.
X
XIf inversion or other highlighting does not work correctly, try setting the
X'weirdinvert' option. This makes the start-highlight or end-highlight termcap
Xcode to be outputted before every character. This slows down terminal I/O a
Xlot, but it makes inversion work on some terminals.
X
XSome termcaps do not include an entry for 'cs' (scroll region), although the
Xterminal does support it. For example: xterm on a sun. You can use the
Xbuiltin_xterm or define t_cs yourself. For example:
X
X :set t_cs=^V^[[%i%d;%dr
X
XWhere ^V is CTRL-V and ^[ is <ESC>.
X
XUnfortunately it is not possible to deduct from the termcap how cursor
Xpositioning should be done when using a scrolling region: Relative to the
Xbeginning of the screen or relative to the beginning of the scrolling region.
XMost terminals use the first method. A know exception is the MSDOS console
X(pcterm). The 't_csc' option should be set to any string when cursor
Xpositioning is relative to the start of the scrolling region. It should be set
Xto an empty string otherwise. It is default "yes" when 'term' is "pcterm".
X
XNote for xterm users: The shifted cursor keys normally don't work. You can
X make them work with the xmodmap command and some mappings in Vim.
X
X Give these commands in the xterm:
X xmodmap -e "keysym Up = Up F16"
X xmodmap -e "keysym Down = Down F17"
X xmodmap -e "keysym Left = Left F18"
X xmodmap -e "keycode Right = Right F19"
X
X And use these mappings in Vim:
X :map CTRL-V 151 CTRL-V 132
X :map! CTRL-V 151 CTRL-V 132
X :map CTRL-V 152 CTRL-V 133
X :map! CTRL-V 152 CTRL-V 133
X :map CTRL-V 153 CTRL-V 134
X :map! CTRL-V 153 CTRL-V 134
X :map CTRL-V 154 CTRL-V 135
X :map! CTRL-V 154 CTRL-V 135
X
XWhere 151-154 are the internal vim decimal codes for function keys F16 to
XF19 and 132-135 are the codes for the shifted arrow keys.
X
X
X20.3 Window size
X
X[This is about the size of the whole window Vim is using, not a window that is
Xcreated with the :split command]
X
XIf you are running Vim on an Amiga and the terminal name is "amiga" or
X"builtin_amiga", the amiga-specific window resizing will be enabled. On Unix
Xsystems three methods are tried to get the window size:
X
X- an ioctl call (TIOCGSIZE or TIOCGWINSZ, depends on your system)
X- the environment variables "LINES" and "COLUMNS"
X- from the termcap entries "li" and "co"
X
XIf everything fails a default size of 24 lines and 80 columns is assumed. If
Xa window-resize signal is received the size will be set again. If the window
Xsize is wrong you can use the 'lines' and 'columns' options to set the
Xcorrect values.
X
XOne command can be used to set the screen size:
X
X:mode [mode]
X
XWithout argument this only detects the screen size. With MSDOS it is possible
Xto switch screen mode. [mode] can be one of these values:
X "bw40" 40 columns black&white
X "c40" 40 columns color
X "bw80" 80 columns black&white
X "c80" 80 columns black&white (most people use this)
X "mono" 80 columns monochrome
X "c4350" 43 or 50 lines EGA/VGA mode
X number mode number to use, depends on your video card
X
X
X20.4 slow and fast terminals
X
XIf you have a fast terminal you may like to set the 'ruler' option. The
Xcursor position is shown in the status line. If you are using horizontal
Xscrolling ('wrap' option off) consider setting 'sidescroll' to a small
Xnumber.
X
XIf you have a slow terminal you may want to reset the 'showcmd' option.
XThe command characters will not be shown in the status line. If the terminal
Xscrolls very slowly, set the 'scrolljump' to 5 or so. If the cursor is moved
Xoff the screen (e.g. with "j") Vim will scroll 5 lines at a time. Another
Xpossibility is to reduce the number of lines that Vim uses with the command
X"z<height><CR>".
X
XIf the characters from the terminal are arriving with more than 1 second
Xbetween them you might want to set the 'timeout' and/or 'ttimeout' option.
XSee the "Options" chapter.
X
XIf your terminal does not support a scrolling region, but it does support
Xinsert/delete line commands, scrolling with multiple windows may make the
Xlines jump up and down. If you don't want this set the 'ttyfast' option.
XThis will redraw the window instead of scroll it.
X
XIf you are testing termcap options, but you cannot see what is happening,
Xyou might want to set the 'nobuf' option ('nb'). When set one character is
Xsend to the terminal at a time (does not work for MSDOS). This makes the
Xscreen updating a lot slower, making it possible to see what is happening.
X
X
X 21. Differences from Vi and Ex
X
XThroughout this document differences between Vim and Vi/Ex are given in
Xcurly braces. This chapter only lists what has not been mentioned in
Xprevious chapters. Also see "difference.doc" for an overview.
X
X
X21.1 Missing commands
X
XA large number of the "Ex" commands (the commands that start with a colon)
Xare included. However, there is no Ex mode.
X
XThese commands are in Vi, but not in Vim.
X
XQ {Vi: go to Ex mode}
X
X:a[ppend] {Vi: append text}
X:c[hange] {Vi: replace lines}
X:i[nsert] {Vi: insert text}
X:o[pen] {Vi: start editing in open mode}
X:rec[over] {Vi: recover a file after a crash or :preserve}
X:z {Vi: print some lines}
X
X
X21.2 Missing options
X
XThese options are in the unix Vi, but not in Vim. If you try to set one of
Xthem you won't get an error message, but the value is not used and cannot be
Xprinted.
X
Xautoprint (ap) toggle (default on)
Xbeautify (bf) toggle (default off)
Xhardtabs (ht) number (default 8)
X number of spaces that a <TAB> moves on the display
Xlisp toggle (default off)
Xmesg toggle (default on)
Xopen toggle (default on)
Xoptimize (op) toggle (default on)
Xprompt toggle (default on)
Xredraw toggle (default off)
Xslowopen (slow) toggle (default off)
Xsourceany toggle (default not documented)
Xttytype string
Xwindow number (default 24)
Xw300 number (default 24)
Xw1200 number (default 24)
Xw9600 number (default 24)
X
X
X
XCONTENTS
X
X[Note: The commands for multiple windows and buffers are explained in
Xwindows.doc]
X
X 1. Introduction
X 2. Notation
X 3. Starting Vim
X 3.1 Command line
X 3.2 Workbench (Amiga only)
X 3.3 Vim window (Amiga only)
X 3.4 Initialization
X 3.5 Suspending
X 4. Modes
X 4.1 Introduction
X 4.2 Switching from mode to mode
X 4.3 Insert and Replace mode
X 4.3.1 special keys
X 4.3.2 special special keys
X 4.3.3 'textwidth' option
X 4.3.4 'expandtab' option
X 4.3.5 typing backwards
X 4.3.6 Replace mode
X 4.3.7 Keyword completion
X 4.4 Command_line mode
X 4.4.1 Command line editing
X 4.4.2 Command line completion
X 4.4.3 Ex command lines
X 4.4.4 Ex command line ranges
X 4.5 The window contents
X 4.6 Abbreviations
X 4.7 Digraphs
X 5. Editing files
X 5.1 Introduction
X 5.2 Editing a file
X 5.3 The argument list
X 5.4 Writing and quitting
X 5.5 Using the QuickFix mode
X 5.6 Editing binary files
X 6. Cursor motions
X 6.1 Left-right motions
X 6.2 Up-down motions
X 6.3 Word motions
X 6.4 Text object motions
X 6.5 Pattern searches
X 6.6 Various motions
X 7. Scrolling
X 8. Tags
X 9. Inserting text
X10. Deleting text
X11. Changing text
X 11.1 Delete and insert
X 11.2 Simple changes
X 11.3 Complex changes
X12. Copying and moving text
X13. Visual mode
X14. Various commands
X15. Repeating commands
X 15.1 Single repeats
X 15.2 Multiple repeats
X 15.3 Complex repeats
X16. Undo and redo
X17. Key mapping
X18. Recovery after a crash
X 18.1 The swap file
X 18.2 Recovery
X19. Options
X 19.1 Setting options
X 19.2 Saving settings
X 19.3 Options summary
X20. Terminal information
X 20.1 startup
X 20.2 terminal options
X 20.3 Window size
X 20.4 slow and fast terminals
X21. Differences from Vi and Ex
X 21.1 Missing commands
X 21.2 Missing options
X
Xvim:tw=76:ts=8:sw=8
END_OF_FILE
if test 59796 -ne `wc -c <'vim/doc/reference.doc.D'`; then
echo shar: \"'vim/doc/reference.doc.D'\" unpacked with wrong size!
elif test -f 'vim/doc/reference.doc.A' && test -f 'vim/doc/reference.doc.B' && test -f 'vim/doc/reference.doc.C'; then
echo shar: Combining \"'vim/doc/reference.doc'\" \(210836 characters\)
cat 'vim/doc/reference.doc.A' 'vim/doc/reference.doc.B' 'vim/doc/reference.doc.C' 'vim/doc/reference.doc.D' > 'vim/doc/reference.doc'
if test 210836 -ne `wc -c <'vim/doc/reference.doc'`; then
echo shar: \"'vim/doc/reference.doc'\" combined with wrong size!
else
rm vim/doc/reference.doc.A vim/doc/reference.doc.B vim/doc/reference.doc.C vim/doc/reference.doc.D
fi
fi
# end of 'vim/doc/reference.doc.D'
fi
if test ! -d 'vim/macros' ; then
echo shar: Creating directory \"'vim/macros'\"
mkdir 'vim/macros'
fi
if test ! -d 'vim/macros/hanoi' ; then
echo shar: Creating directory \"'vim/macros/hanoi'\"
mkdir 'vim/macros/hanoi'
fi
if test ! -d 'vim/macros/maze' ; then
echo shar: Creating directory \"'vim/macros/maze'\"
mkdir 'vim/macros/maze'
fi
if test ! -d 'vim/macros/urm' ; then
echo shar: Creating directory \"'vim/macros/urm'\"
mkdir 'vim/macros/urm'
fi
if test ! -d 'vim/src' ; then
echo shar: Creating directory \"'vim/src'\"
mkdir 'vim/src'
fi
if test -f 'vim/src/addcr.bat' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/addcr.bat'\"
else
echo shar: Extracting \"'vim/src/addcr.bat'\" \(3578 characters\)
sed "s/^X//" >'vim/src/addcr.bat' <<'END_OF_FILE'
Xaddcr <addcr.c >tmp
Xcp tmp addcr.c
Xaddcr <alloc.c >tmp
Xcp tmp alloc.c
Xaddcr <ascii.h >tmp
Xcp tmp ascii.h
Xaddcr <charset.c >tmp
Xcp tmp charset.c
Xaddcr <cmdline.c >tmp
Xcp tmp cmdline.c
Xaddcr <cmdtab.h >tmp
Xcp tmp cmdtab.h
Xaddcr <cmdtab.tab >tmp
Xcp tmp cmdtab.tab
Xaddcr <csearch.c >tmp
Xcp tmp csearch.c
Xaddcr <debug.h >tmp
Xcp tmp debug.h
Xaddcr <digraph.c >tmp
Xcp tmp digraph.c
Xaddcr <edit.c >tmp
Xcp tmp edit.c
Xaddcr <env.h >tmp
Xcp tmp env.h
Xaddcr <fileio.c >tmp
Xcp tmp fileio.c
Xaddcr <getchar.c >tmp
Xcp tmp getchar.c
Xaddcr <globals.h >tmp
Xcp tmp globals.h
Xaddcr <help.c >tmp
Xcp tmp help.c
Xaddcr <keymap.h >tmp
Xcp tmp keymap.h
Xaddcr <linefunc.c >tmp
Xcp tmp linefunc.c
Xaddcr <macros.h >tmp
Xcp tmp macros.h
Xaddcr <main.c >tmp
Xcp tmp main.c
Xaddcr <makefile >tmp
Xcp tmp makefile
Xaddcr <mark.c >tmp
Xcp tmp mark.c
Xaddcr <memfile.c >tmp
Xcp tmp memfile.c
Xaddcr <memline.c >tmp
Xcp tmp memline.c
Xaddcr <message.c >tmp
Xcp tmp message.c
Xaddcr <misccmds.c >tmp
Xcp tmp misccmds.c
Xaddcr <mkcmdtab.c >tmp
Xcp tmp mkcmdtab.c
Xaddcr <msdos.c >tmp
Xcp tmp msdos.c
Xaddcr <msdos.h >tmp
Xcp tmp msdos.h
Xaddcr <normal.c >tmp
Xcp tmp normal.c
Xaddcr <ops.c >tmp
Xcp tmp ops.c
Xaddcr <ops.h >tmp
Xcp tmp ops.h
Xaddcr <param.c >tmp
Xcp tmp param.c
Xaddcr <param.h >tmp
Xcp tmp param.h
Xaddcr <proto.h >tmp
Xcp tmp proto.h
Xaddcr <quickfix.c >tmp
Xcp tmp quickfix.c
Xaddcr <regexp.c >tmp
Xcp tmp regexp.c
Xaddcr <regexp.h >tmp
Xcp tmp regexp.h
Xaddcr <regmagic.h >tmp
Xcp tmp regmagic.h
Xaddcr <regsub.c >tmp
Xcp tmp regsub.c
Xaddcr <screen.c >tmp
Xcp tmp screen.c
Xaddcr <search.c >tmp
Xcp tmp search.c
Xaddcr <storage.c >tmp
Xcp tmp storage.c
Xaddcr <tag.c >tmp
Xcp tmp tag.c
Xaddcr <tags >tmp
Xcp tmp tags
Xaddcr <term.c >tmp
Xcp tmp term.c
Xaddcr <term.h >tmp
Xcp tmp term.h
Xaddcr <termlib.c >tmp
Xcp tmp termlib.c
Xaddcr <termlib.fix >tmp
Xcp tmp termlib.fix
Xaddcr <undo.c >tmp
Xcp tmp undo.c
Xaddcr <version.c >tmp
Xcp tmp version.c
Xaddcr <vim.h >tmp
Xcp tmp vim.h
Xaddcr <vim.prj >tmp
Xcp tmp vim.prj
Xaddcr <vimresp >tmp
Xcp tmp vimresp
Xaddcr <proto\alloc.pro >tmp
Xcp tmp proto\alloc.pro
Xaddcr <proto\amiga.pro >tmp
Xcp tmp proto\amiga.pro
Xaddcr <proto\buffers.pro >tmp
Xcp tmp proto\buffers.pro
Xaddcr <proto\charset.pro >tmp
Xcp tmp proto\charset.pro
Xaddcr <proto\cmdline.pro >tmp
Xcp tmp proto\cmdline.pro
Xaddcr <proto\csearch.pro >tmp
Xcp tmp proto\csearch.pro
Xaddcr <proto\digraph.pro >tmp
Xcp tmp proto\digraph.pro
Xaddcr <proto\edit.pro >tmp
Xcp tmp proto\edit.pro
Xaddcr <proto\fileio.pro >tmp
Xcp tmp proto\fileio.pro
Xaddcr <proto\help.pro >tmp
Xcp tmp proto\help.pro
Xaddcr <proto\linefunc.pro >tmp
Xcp tmp proto\linefunc.pro
Xaddcr <proto\main.pro >tmp
Xcp tmp proto\main.pro
Xaddcr <proto\mark.pro >tmp
Xcp tmp proto\mark.pro
Xaddcr <proto\message.pro >tmp
Xcp tmp proto\message.pro
Xaddcr <proto\misccmds.pro >tmp
Xcp tmp proto\misccmds.pro
Xaddcr <proto\normal.pro >tmp
Xcp tmp proto\normal.pro
Xaddcr <proto\ops.pro >tmp
Xcp tmp proto\ops.pro
Xaddcr <proto\param.pro >tmp
Xcp tmp proto\param.pro
Xaddcr <proto\quickfix.pro >tmp
Xcp tmp proto\quickfix.pro
Xaddcr <proto\regexp.pro >tmp
Xcp tmp proto\regexp.pro
Xaddcr <proto\regsub.pro >tmp
Xcp tmp proto\regsub.pro
Xaddcr <proto\screen.pro >tmp
Xcp tmp proto\screen.pro
Xaddcr <proto\script.pro >tmp
Xcp tmp proto\script.pro
Xaddcr <proto\search.pro >tmp
Xcp tmp proto\search.pro
Xaddcr <proto\storage.pro >tmp
Xcp tmp proto\storage.pro
Xaddcr <proto\tag.pro >tmp
Xcp tmp proto\tag.pro
Xaddcr <proto\term.pro >tmp
Xcp tmp proto\term.pro
Xaddcr <proto\termlib.pro >tmp
Xcp tmp proto\termlib.pro
Xaddcr <proto\undo.pro >tmp
Xcp tmp proto\undo.pro
Xdel tmp
END_OF_FILE
if test 3578 -ne `wc -c <'vim/src/addcr.bat'`; then
echo shar: \"'vim/src/addcr.bat'\" unpacked with wrong size!
fi
# end of 'vim/src/addcr.bat'
fi
if test ! -d 'vim/src/proto' ; then
echo shar: Creating directory \"'vim/src/proto'\"
mkdir 'vim/src/proto'
fi
if test ! -d 'vim/tools' ; then
echo shar: Creating directory \"'vim/tools'\"
mkdir 'vim/tools'
fi
if test ! -d 'vim/tutor' ; then
echo shar: Creating directory \"'vim/tutor'\"
mkdir 'vim/tutor'
fi
echo shar: End of archive 1 \(of 26\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 26 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:16 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 21
Archive-name: vim/part02

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/memline.c vim/src/vimresp


# Wrapped by kent@sparky on Mon Aug 15 21:43:56 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 2 (of 26)."'
if test -f 'vim/src/memline.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/memline.c'\"
else
echo shar: Extracting \"'vim/src/memline.c'\" \(64654 characters\)
sed "s/^X//" >'vim/src/memline.c' <<'END_OF_FILE'
X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/* for debugging */
X/* #define CHECK(c, s) if (c) EMSG(s) */
X#define CHECK(c, s)
X
X/*
X * memline.c: Contains the functions for appending, deleting and changing the
X * text lines. The memfile functions are used to store the information in blocks
X * of memory, backed up by a file. The structure of the information is a tree.
X * The root of the tree is a pointer block. The leaves of the tree are data
X * blocks. In between may be several layers of pointer blocks, forming branches.
X *
X * Three types of blocks are used:
X * - Block nr 0 contains information for recovery
X * - Pointer blocks contain list of pointers to other blocks.
X * - Data blocks contain the actual text.
X *
X * Block nr 0 contains the block0 structure (see below).
X *
X * Block nr 1 is the first pointer block. It is the root of the tree.
X * Other pointer blocks are branches.
X *
X * If a line is too big to fit in a single page, the block
X * containing that line is made big enough to hold the line. It may span
X * several pages. Otherwise all blocks are one page.
X *
X * A data block that was filled when starting to edit a file and was not
X * changed since then, can have a negative block number. This means that it
X * has not yet been assigned a place in the file. When recovering, the lines
X * in this data block can be read from the original file. When the block is
X * changed (lines appended/deleted/changd) or when it is flushed it gets
X * a positive number. Use mf_trans_del() to get the new number, before
X * calling mf_get().
X */
X
X/*
X * The following functions are available to work with a memline:
X *
X * ml_open() open a new memline for a buffer
X * ml_close() close the memline for a buffer
X * ml_close_all() close all memlines
X * ml_recover() read a memline for recovery
X * ml_sync_all() flush changed blocks to file for all files
X * ml_preserve() flush everything into the file for one file
X * ml_get() get a pointer to a line
X * ml_get_pos() get a pointer to a position in a line
X * ml_get_cursor() get a pointer to the char under the cursor
X * ml_get_buf() get a pointer to a line in a specific buffer
X * ml_line_alloced() return TRUE if line was allocated
X * ml_append() append a new line
X * ml_replace() replace a line
X * ml_delete() delete a line
X * ml_setmarked() set mark for a line (for :global command)
X * ml_firstmarked() get first line with a mark (for :global command)
X * ml_clearmarked() clear all line marks (for :global command)
X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X#include <fcntl.h>
X
X#ifdef SASC
X# include <proto/dos.h> /* for Open() and Close() */
X#endif
X
Xtypedef struct block0 ZERO_BL; /* contents of the first block */
Xtypedef struct pointer_block PTR_BL; /* contents of a pointer block */
Xtypedef struct data_block DATA_BL; /* contents of a data block */
Xtypedef struct pointer_entry PTR_EN; /* block/line-count pair */
X
X#define DATA_ID (('d' << 8) + 'a') /* data block id */
X#define PTR_ID (('p' << 8) + 't') /* pointer block id */
X#define BLOCK0_ID (('b' << 8) + '0') /* block 0 id */
X
X/*
X * pointer to a block, used in a pointer block
X */
Xstruct pointer_entry
X{
X blocknr_t pe_bnum; /* block number */
X linenr_t pe_line_count; /* number of lines in this branch */
X linenr_t pe_old_lnum; /* lnum for this block (for recovery) */
X int pe_page_count; /* number of pages in block pe_bnum */
X};
X
X/*
X * A pointer block contains a list of branches in the tree.
X */
Xstruct pointer_block
X{
X short_u pb_id; /* id for pointer block: PBL_ID */
X short_u pb_count; /* number of pointer in this block */
X short_u pb_count_max; /* maximum value for pb_count */
X PTR_EN pb_pointer[1]; /* list of pointers to blocks (actually longer)
X * followed by empty space until end of page */
X};
X
X/*
X * A data block is a leaf in the tree.
X *
X * The text of the lines is at the end of the block. The text of the first line
X * in the block is put at the end, the text of the second line in front of it,
X * etc. Thus the order of the lines is the opposite of the line number.
X */
Xstruct data_block
X{
X short_u db_id; /* id for data block: DBL_ID */
X unsigned db_free; /* free space available */
X unsigned db_txt_start; /* byte where text starts */
X unsigned db_txt_end; /* byte just after data block */
X linenr_t db_line_count; /* number of lines in this block */
X unsigned db_index[1]; /* index for start of line (actually bigger)
X * followed by empty space upto db_txt_start
X * followed by the text in the lines until
X * end of page */
X};
X
X/*
X * The low bits of db_index hold the actual index. The topmost bit is
X * used for the global command to be able to mark a line.
X * This method is not clean, but otherwise there would be at least one extra
X * byte used for each line.
X * The mark has to be in this place to keep it with the correct line when other
X * lines are inserted or deleted.
X */
X#define DB_MARKED (1 << ((sizeof(unsigned) * 8) - 1))
X#define DB_INDEX_MASK (~DB_MARKED)
X
X#define INDEX_SIZE (sizeof(unsigned)) /* size of one db_index entry */
X#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE) /* size of data block header */
X
Xstruct block0
X{
X short_u b0_id; /* id for block 0: BLOCK0_ID */
X char_u b0_version[10]; /* Vim version string */
X int b0_page_size; /* number of bytes per page */
X long b0_mtime; /* last modification time of file */
X char_u b0_fname[1000]; /* file name of file being edited */
X};
X
X/* NOTE: if size of block0 changes, adjust minimal block size in mf_open()!! */
X
X#define STACK_INCR 5 /* number of entries added to ml_stack at a time */
X
X/*
X * The line number where the first mark may be is remembered.
X * If it is 0 there are no marks at all.
X * (always used for the current buffer only, no buffer change possible while
X * executing a global command).
X */
Xstatic linenr_t lowest_marked = 0;
X
X/*
X * arguments for ml_find_line()
X */
X#define ML_DELETE 0x11 /* delete line */
X#define ML_INSERT 0x12 /* insert line */
X#define ML_FIND 0x13 /* just find the line */
X#define ML_FLUSH 0x02 /* flush locked block */
X#define ML_SIMPLE(x) (x & 0x10) /* DEL, INS or FIND */
X
Xstatic int ml_append_int __ARGS((BUF *, linenr_t, char_u *, colnr_t, int));
Xstatic int ml_delete_int __ARGS((BUF *, linenr_t));
Xstatic char_u *findswapname __ARGS((BUF *, int));
Xstatic void ml_flush_line __ARGS((BUF *));
Xstatic BHDR *ml_new_data __ARGS((MEMFILE *, int, int));
Xstatic BHDR *ml_new_ptr __ARGS((MEMFILE *));
Xstatic BHDR *ml_find_line __ARGS((BUF *, linenr_t, int));
Xstatic int ml_add_stack __ARGS((BUF *));
Xstatic char_u *makeswapname __ARGS((BUF *, int));
Xstatic void ml_lineadd __ARGS((BUF *, int));
X
X/*
X * open a new memline for 'curbuf'
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xml_open()
X{
X MEMFILE *mfp = NULL;
X char_u *fname = NULL;
X BHDR *hp = NULL;
X ZERO_BL *b0p;
X struct stat st;
X int i;
X
X/*
X * init fields in memline struct
X */
X curbuf->b_ml.ml_stack_size = 0; /* no stack yet */
X curbuf->b_ml.ml_stack = NULL; /* no stack yet */
X curbuf->b_ml.ml_stack_top = 0; /* nothing in the stack */
X curbuf->b_ml.ml_locked = NULL; /* no cached block */
X curbuf->b_ml.ml_line_lnum = 0; /* no cached line */
X
X/*
X * make fname for swap file
X * If we are unable to find a file name, mf_fname will be NULL
X * and the memfile will be in memory only (no recovery possible).
X * When 'updatecount' is 0 there is never a swap file.
X */
X if (p_uc == 0)
X fname = NULL;
X else
X fname = findswapname(curbuf, FALSE); /* NULL detected below */
X
X/*
X * open the memfile
X *
X * If a file name given, 'directory' option is set and does not start with '>'
X * may try twice: first in current dir and if that fails in 'directory'.
X */
X if (fname != NULL && *p_dir != NUL && *p_dir != '>')
X i = 0; /* try twice */
X else
X i = 1; /* try once */
X for ( ; i < 2 && (mfp = mf_open(fname, TRUE, i == 0)) == NULL; ++i)
X {
X fname = findswapname(curbuf, TRUE); /* NULL detected below */
X }
X if (mfp == NULL)
X goto error;
X curbuf->b_ml.ml_mfp = mfp;
X curbuf->b_neverloaded = FALSE;
X if (p_uc != 0 && mfp->mf_fname == NULL)
X {
X /* call wait_return if not done by emsg() */
X if (EMSG("Unable to open swap file, recovery impossible"))
X {
X msg_outchar('\n');
X wait_return(FALSE);
X }
X }
X
X/*
X * fill block0 struct and write page 0
X */
X if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
X goto error;
X if (hp->bh_bnum != 0)
X {
X EMSG("didn't get block nr 0?");
X goto error;
X }
X b0p = (ZERO_BL *)(hp->bh_data);
X b0p->b0_id = BLOCK0_ID;
X STRNCPY(b0p->b0_version, Version, (size_t)10);
X if (curbuf->b_filename != NULL)
X {
X STRNCPY(b0p->b0_fname, curbuf->b_filename, (size_t)1000);
X if (stat((char *)curbuf->b_filename, &st) != -1)
X b0p->b0_mtime = st.st_mtime;
X else
X b0p->b0_mtime = 0;
X }
X else
X b0p->b0_fname[0] = NUL;
X b0p->b0_page_size = mfp->mf_page_size;
X mf_put(mfp, hp, TRUE, FALSE);
X
X/*
X * fill in root pointer block and write page 1
X */
X if ((hp = ml_new_ptr(mfp)) == NULL)
X goto error;
X if (hp->bh_bnum != 1)
X {
X EMSG("didn't get block nr 1?");
X goto error;
X }
X mf_put(mfp, hp, TRUE, FALSE);
X curbuf->b_ml.ml_flags = ML_EMPTY;
X
X return OK;
X
Xerror:
X if (mfp != NULL)
X {
X if (hp)
X mf_put(mfp, hp, FALSE, FALSE);
X mf_close(mfp, TRUE); /* will also free(fname) */
X }
X else
X free(fname);
X curbuf->b_ml.ml_mfp = NULL;
X return FAIL;
X}
X
X/*
X * Open a file for the memfile for all buffers.
X * Used when 'updatecount' changes from zero to non-zero.
X */
X void
Xml_open_files()
X{
X BUF *buf;
X MEMFILE *mfp;
X char_u *fname;
X int i;
X
X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X {
X mfp = buf->b_ml.ml_mfp;
X if (mfp == NULL || mfp->mf_fd >= 0) /* nothing to do */
X continue;
X
X /*
X * make fname for swap file
X * If we are unable to find a file name, mf_fname will be NULL
X * and the memfile will remain in memory only (no recovery possible).
X */
X fname = findswapname(buf, FALSE); /* NULL detected below */
X
X /*
X * open the memfile
X *
X * If a file name given, 'directory' option is set and does not start with '>'
X * may try twice: first in current dir and if that fails in 'directory'.
X */
X if (fname != NULL && *p_dir != NUL && *p_dir != '>')
X i = 0; /* try twice */
X else
X i = 1; /* try once */
X for ( ; i < 2 && mf_open_file(mfp, fname) == FAIL; ++i)
X {
X fname = findswapname(buf, TRUE); /* NULL detected below */
X }
X if (mfp->mf_fname == NULL)
X {
X /* call wait_return if not done by emsg() */
X if (EMSG2("Unable to open swap file for \"%s\", recovery impossible",
X buf->b_xfilename == NULL ? (char_u *)"No File"
X : buf->b_xfilename))
X {
X msg_outchar('\n');
X wait_return(FALSE);
X }
X }
X }
X}
X
X/*
X * close memline for buffer 'buf' and delete the swap file
X */
X void
Xml_close(buf)
X BUF *buf;
X{
X if (buf->b_ml.ml_mfp == NULL) /* not open */
X return;
X mf_close(buf->b_ml.ml_mfp, TRUE); /* delete the .swp file */
X if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
X free(buf->b_ml.ml_line_ptr);
X free(buf->b_ml.ml_stack);
X buf->b_ml.ml_mfp = NULL;
X}
X
X/*
X * Close all existing memlines and memfiles.
X * Used when exiting.
X */
X void
Xml_close_all()
X{
X BUF *buf;
X
X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X ml_close(buf);
X}
X
X/*
X * Update the timestamp in the .swp file.
X * Used when the file has been written.
X */
X void
Xml_timestamp(buf)
X BUF *buf;
X{
X MEMFILE *mfp = NULL;
X BHDR *hp = NULL;
X ZERO_BL *b0p;
X struct stat st;
X
X mfp = buf->b_ml.ml_mfp;
X
X if (mfp == NULL || (hp = mf_get(mfp, (blocknr_t)0, 1)) == NULL)
X return;
X b0p = (ZERO_BL *)(hp->bh_data);
X if (b0p->b0_id != BLOCK0_ID)
X {
X EMSG("ml_timestamp: Didn't get block 0??");
X goto error;
X }
X /* copy filename again, it may have been changed */
X STRNCPY(b0p->b0_fname, buf->b_filename, (size_t)1000);
X if (stat((char *)buf->b_filename, &st) != -1)
X b0p->b0_mtime = st.st_mtime;
Xerror:
X mf_put(mfp, hp, TRUE, FALSE);
X}
X
X/*
X * try to recover curbuf from the .swp file
X */
X void
Xml_recover()
X{
X BUF *buf = NULL;
X MEMFILE *mfp = NULL;
X char_u *fname = NULL;
X BHDR *hp = NULL;
X ZERO_BL *b0p;
X PTR_BL *pp;
X DATA_BL *dp;
X IPTR *ip;
X blocknr_t bnum;
X int page_count;
X struct stat org_stat, swp_stat;
X int len;
X int directly;
X linenr_t lnum;
X char_u *p;
X int i;
X long error;
X int cannot_open;
X linenr_t line_count;
X int has_error;
X int idx;
X int top;
X int txt_start;
X long size;
X
X/*
X * If the file name ends in ".sw?" we use it directly.
X * Otherwise ".swp" is appended.
X */
X fname = curbuf->b_xfilename;
X len = STRLEN(fname);
X if (len >= 4 && vim_strnicmp(fname + len - 4, (char_u *)".sw", (size_t)3) == 0)
X {
X fname = strsave(fname); /* make a copy for mf_open */
X directly = TRUE;
X }
X else
X {
X fname = makeswapname(curbuf, FALSE);
X directly = FALSE;
X }
X if (fname == NULL)
X goto theend; /* out of memory */
X
X/*
X * allocate a buffer structure (only the memline in it is really used)
X */
X buf = (BUF *)alloc((unsigned)sizeof(BUF));
X if (buf == NULL)
X goto theend;
X
X/*
X * init fields in memline struct
X */
X buf->b_ml.ml_stack_size = 0; /* no stack yet */
X buf->b_ml.ml_stack = NULL; /* no stack yet */
X buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
X buf->b_ml.ml_line_lnum = 0; /* no cached line */
X buf->b_ml.ml_locked = NULL; /* no locked block */
X buf->b_ml.ml_flags = 0;
X
X/*
X * open the memfile
X *
X * If swap file name not given directly, 'directory' option is set and
X * does not start with '>' may try twice: first in current dir and if that
X * fails in 'directory'.
X */
X if (!directly && *p_dir != NUL && *p_dir != '>')
X i = 0; /* try twice */
X else
X i = 1; /* try once */
X for ( ; i < 2 && (mfp = mf_open(fname, FALSE, i == 0)) == NULL; i++)
X {
X fname = makeswapname(curbuf, TRUE);
X if (fname == NULL)
X goto theend;
X }
X if (mfp == NULL || mfp->mf_fd < 0)
X {
X EMSG2("Cannot open %s", fname);
X goto theend;
X }
X buf->b_ml.ml_mfp = mfp;
X
X/*
X * try to read block 0
X */
X if ((hp = mf_get(mfp, (blocknr_t)0, 1)) == NULL)
X {
X msg_start();
X msg_outstr((char_u *)"Unable to read block 0 from ");
X msg_outstr(fname);
X msg_outstr((char_u *)"\nMaybe no changes were made or Vim did not update the .swp file");
X msg_end();
X goto theend;
X }
X b0p = (ZERO_BL *)(hp->bh_data);
X if (b0p->b0_id != BLOCK0_ID)
X {
X EMSG2("%s is not a swap file", fname);
X goto theend;
X }
X /*
X * If we guessed the wrong page size, we have to recalculate the
X * hightest block number in the file
X */
X if (mfp->mf_page_size != b0p->b0_page_size)
X {
X mfp->mf_page_size = b0p->b0_page_size;
X if ((size = lseek(mfp->mf_fd, 0L, SEEK_END)) <= 0)
X mfp->mf_blocknr_max = 0; /* no file or empty file */
X else
X mfp->mf_blocknr_max = size / mfp->mf_page_size;
X mfp->mf_infile_count = mfp->mf_blocknr_max;
X }
X
X/*
X * If .swp file name given directly, use name from swap file for buffer
X */
X if (directly && setfname(b0p->b0_fname, NULL, TRUE) == FAIL)
X goto theend;
X
X smsg((char_u *)"Using swap file \"%s\", original file \"%s\"", fname,
X curbuf->b_filename == NULL ? "No File" : (char *)curbuf->b_filename);
X
X/*
X * check date of swap file and original file
X */
X if (curbuf->b_filename != NULL &&
X stat((char *)curbuf->b_filename, &org_stat) != -1 &&
X ((stat((char *)fname, &swp_stat) != -1 &&
X org_stat.st_mtime > swp_stat.st_mtime) ||
X org_stat.st_mtime != b0p->b0_mtime))
X {
X MSG("Warning: Original file may have been changed");
X }
X mf_put(mfp, hp, FALSE, FALSE); /* release block 0 */
X hp = NULL;
X
X bnum = 1; /* start with block 1 */
X page_count = 1; /* which is 1 page */
X lnum = 0; /* append after line 0 in curbuf */
X line_count = 0;
X idx = 0; /* start with first index in block 1 */
X error = 0;
X buf->b_ml.ml_stack_top = 0;
X buf->b_ml.ml_stack = NULL;
X buf->b_ml.ml_stack_size = 0; /* no stack yet */
X
X if (curbuf->b_filename == NULL)
X cannot_open = TRUE;
X else
X cannot_open = FALSE;
X
X for (;;)
X {
X if ((lnum & 15) == 0) /* check for interrupt now and then */
X {
X breakcheck();
X if (got_int)
X break;
X }
X
X if (hp != NULL)
X mf_put(mfp, hp, FALSE, FALSE); /* release previous block */
X
X /*
X * get block
X */
X if ((hp = mf_get(mfp, (blocknr_t)bnum, page_count)) == NULL)
X {
X if (bnum == 1)
X {
X EMSG2("Unable to read block 1 from %s", fname);
X goto theend;
X }
X ++error;
X ml_append(lnum++, (char_u *)"???MANY LINES MISSING", (colnr_t)0, TRUE);
X }
X else /* there is a block */
X {
X pp = (PTR_BL *)(hp->bh_data);
X if (pp->pb_id == PTR_ID) /* it is a pointer block */
X {
X /* check line count when using pointer block first time */
X if (idx == 0 && line_count != 0)
X {
X for (i = 0; i < (int)pp->pb_count; ++i)
X line_count -= pp->pb_pointer[i].pe_line_count;
X if (line_count != 0)
X {
X ++error;
X ml_append(lnum++, (char_u *)"???LINE COUNT WRONG", (colnr_t)0, TRUE);
X }
X }
X
X if (pp->pb_count == 0)
X {
X ml_append(lnum++, (char_u *)"???EMPTY BLOCK", (colnr_t)0, TRUE);
X ++error;
X }
X else if (idx < (int)pp->pb_count) /* go a block deeper */
X {
X if (pp->pb_pointer[idx].pe_bnum < 0)
X {
X /*
X * data block with negative block number
X * Try to read lines from the original file.
X * This is slow, but it works.
X */
X if (!cannot_open)
X {
X line_count = pp->pb_pointer[idx].pe_line_count;
X if (readfile(curbuf->b_filename, NULL, lnum, FALSE,
X pp->pb_pointer[idx].pe_old_lnum - 1,
X line_count) == FAIL)
X cannot_open = TRUE;
X else
X lnum += line_count;
X }
X if (cannot_open)
X {
X ++error;
X ml_append(lnum++, (char_u *)"???LINES MISSING", (colnr_t)0, TRUE);
X }
X ++idx; /* get same block again for next index */
X continue;
X }
X
X /*
X * going one block deeper in the tree
X */
X if ((top = ml_add_stack(buf)) < 0) /* new entry in stack */
X {
X ++error;
X break; /* out of memory */
X }
X ip = &(buf->b_ml.ml_stack[top]);
X ip->ip_bnum = bnum;
X ip->ip_index = idx;
X
X bnum = pp->pb_pointer[idx].pe_bnum;
X line_count = pp->pb_pointer[idx].pe_line_count;
X page_count = pp->pb_pointer[idx].pe_page_count;
X continue;
X }
X }
X else /* not a pointer block */
X {
X dp = (DATA_BL *)(hp->bh_data);
X if (dp->db_id != DATA_ID) /* block id wrong */
X {
X if (bnum == 1)
X {
X EMSG2("Block 1 ID wrong (%s not a .swp file?)", fname);
X goto theend;
X }
X ++error;
X ml_append(lnum++, (char_u *)"???BLOCK MISSING", (colnr_t)0, TRUE);
X }
X else
X {
X /*
X * it is a data block
X * Append all the lines in this block
X */
X has_error = FALSE;
X /*
X * check length of block
X * if wrong, use length in pointer block
X */
X if (page_count * mfp->mf_page_size != dp->db_txt_end)
X {
X ml_append(lnum++, (char_u *)"???until END lines may be messed up", (colnr_t)0, TRUE);
X ++error;
X has_error = TRUE;
X dp->db_txt_end = page_count * mfp->mf_page_size;
X }
X
X /* make sure there is a NUL at the end of the block */
X *((char_u *)dp + dp->db_txt_end - 1) = NUL;
X
X /*
X * check number of lines in block
X * if wrong, use count in data block
X */
X if (line_count != dp->db_line_count)
X {
X ml_append(lnum++, (char_u *)"???until END lines may have been inserted/deleted", (colnr_t)0, TRUE);
X ++error;
X has_error = TRUE;
X }
X
X for (i = 0; i < dp->db_line_count; ++i)
X {
X txt_start = (dp->db_index[i] & DB_INDEX_MASK);
X if (txt_start <= HEADER_SIZE || txt_start >= (int)dp->db_txt_end)
X {
X p = (char_u *)"???";
X ++error;
X }
X else
X p = (char_u *)dp + txt_start;
X ml_append(lnum++, p, (colnr_t)0, TRUE);
X }
X if (has_error)
X ml_append(lnum++, (char_u *)"???END", (colnr_t)0, TRUE);
X }
X }
X }
X
X if (buf->b_ml.ml_stack_top == 0) /* finished */
X break;
X
X /*
X * go one block up in the tree
X */
X ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
X bnum = ip->ip_bnum;
X idx = ip->ip_index + 1; /* go to next index */
X page_count = 1;
X }
X
X recoverymode = 0;
X if (got_int)
X EMSG("Recovery Interrupted");
X else if (error)
X EMSG("Errors detected while recovering; look for lines starting with ???");
X else
X MSG("Recovery completed; If everything is OK: Save this file and delete the .swp file");
X
Xtheend:
X if (mfp != NULL)
X {
X if (hp != NULL)
X mf_put(mfp, hp, FALSE, FALSE);
X mf_close(mfp, FALSE); /* will also free(fname) */
X }
X else
X free(fname);
X free(buf);
X return;
X}
X
X/*
X * sync all memlines
X *
X * Stop syncing when character becomes available, but always sync at
X * least one block.
X * If 'check_file' is TRUE, check if original file exists and was not changed.
X */
X void
Xml_sync_all(check_file)
X int check_file;
X{
X BUF *buf;
X struct stat st;
X
X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X {
X if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
X continue; /* no file */
X
X ml_flush_line(buf); /* flush buffered line */
X (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH); /* flush locked block */
X if (buf->b_changed && check_file && mf_need_trans(buf->b_ml.ml_mfp) &&
X buf->b_filename != NULL)
X {
X /*
X * if original file does not exist anymore or has been changed
X * call ml_preserve to get rid of all negative numbered blocks
X */
X if (stat((char *)buf->b_filename, &st) == -1 ||
X st.st_mtime != buf->b_mtime)
X ml_preserve(buf, FALSE);
X }
X if (buf->b_ml.ml_mfp->mf_dirty)
X {
X mf_sync(buf->b_ml.ml_mfp, FALSE, TRUE);
X if (mch_char_avail()) /* character available now */
X break;
X }
X }
X}
X
X/*
X * sync one buffer, including negative blocks
X *
X * after this all the blocks are in the swap file
X *
X * Used for the :preserve command and when the original file has been
X * changed or deleted.
X *
X * when message is TRUE the success of preserving is reported
X */
X void
Xml_preserve(buf, message)
X BUF *buf;
X int message;
X{
X BHDR *hp;
X linenr_t lnum;
X MEMFILE *mfp = buf->b_ml.ml_mfp;
X int status;
X
X if (mfp == NULL || mfp->mf_fname == NULL)
X {
X if (message)
X EMSG("Cannot preserve, there is no swap file");
X return;
X }
X
X ml_flush_line(buf); /* flush buffered line */
X (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH); /* flush locked block */
X status = mf_sync(mfp, TRUE, FALSE);
X
X /* stack is invalid after mf_sync(.., TRUE, ..) */
X buf->b_ml.ml_stack_top = 0;
X
X /*
X * Some of the data blocks may have been changed from negative to
X * positive block number. In that case the pointer blocks need to be updated.
X *
X * We don't know in which pointer block the references are, so we visit
X * all data blocks until there are no more translations to be done.
X * ml_find_line() does the work by translating the negative block numbers
X * when getting the first line of each data block.
X */
X if (mf_need_trans(mfp))
X {
X lnum = 1;
X while (mf_need_trans(mfp))
X {
X hp = ml_find_line(buf, lnum, ML_FIND);
X if (hp == NULL)
X {
X status = FAIL;
X goto theend;
X }
X CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
X lnum = buf->b_ml.ml_locked_high + 1;
X }
X (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH); /* flush locked block */
X if (mf_sync(mfp, TRUE, FALSE) == FAIL) /* sync the updated pointer blocks */
X status = FAIL;
X buf->b_ml.ml_stack_top = 0; /* stack is invalid now */
X }
Xtheend:
X if (message)
X {
X if (status == OK)
X MSG("File preserved");
X else
X EMSG("Preserve failed");
X }
X}
X
X/*
X * get a pointer to a (read-only copy of a) line
X *
X * On failure an error message is given and IObuff is returned (to avoid
X * having to check for error everywhere).
X */
X char_u *
Xml_get(lnum)
X linenr_t lnum;
X{
X return ml_get_buf(curbuf, lnum, FALSE);
X}
X
X/*
X * ml_get_pos: get pointer to position 'pos'
X */
X char_u *
Xml_get_pos(pos)
X FPOS *pos;
X{
X return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
X}
X
X char_u *
Xml_get_cursor()
X{
X return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) + curwin->w_cursor.col);
X}
X
X/*
X * get a pointer to a line in a specific buffer
X *
X * will_change: if TRUE mark the buffer dirty (chars in the line will be changed)
X */
X char_u *
Xml_get_buf(buf, lnum, will_change)
X BUF *buf;
X linenr_t lnum;
X int will_change; /* line will be changed */
X{
X BHDR *hp;
X DATA_BL *dp;
X char_u *ptr;
X
X if (lnum < 1 || lnum > buf->b_ml.ml_line_count) /* invalid line number */
X {
X emsg2((char_u *)"ml_get: invalid lnum: %ld", (char_u *)lnum);
Xerrorret:
X STRCPY(IObuff, "???");
X return IObuff;
X }
X
X/*
X * See if it is the same line as requested last time.
X * Otherwise may need to flush last used line.
X */
X if (buf->b_ml.ml_line_lnum != lnum)
X {
X ml_flush_line(buf);
X
X if (buf->b_ml.ml_flags & ML_EMPTY) /* empty buffer */
X return (char_u *)"";
X
X /*
X * find the data block containing the line
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
X {
X emsg2((char_u *)"ml_get: cannot find line %ld", (char_u *)lnum);
X goto errorret;
X }
X
X dp = (DATA_BL *)(hp->bh_data);
X
X ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
X buf->b_ml.ml_line_ptr = ptr;
X buf->b_ml.ml_line_lnum = lnum;
X buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
X }
X if (will_change)
X buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
X
X return buf->b_ml.ml_line_ptr;
X}
X
X/*
X * Check if a line that was just obtained by a call to ml_get
X * is in allocated memory.
X */
X int
Xml_line_alloced()
X{
X return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
X}
X
X/*
X * append a line after lnum (may be 0 to insert a line in front of the file)
X *
X * newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
X * will be set for recovery
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xml_append(lnum, line, len, newfile)
X linenr_t lnum; /* append after this line (can be 0) */
X char_u *line; /* text of the new line */
X colnr_t len; /* length of new line, including NUL, or 0 */
X int newfile; /* flag, see above */
X{
X if (curbuf->b_ml.ml_line_lnum != 0)
X ml_flush_line(curbuf);
X return ml_append_int(curbuf, lnum, line, len, newfile);
X}
X
X static int
Xml_append_int(buf, lnum, line, len, newfile)
X BUF *buf;
X linenr_t lnum; /* append after this line (can be 0) */
X char_u *line; /* text of the new line */
X colnr_t len; /* length of line, including NUL, or 0 */
X int newfile; /* flag, see above */
X{
X int i;
X int line_count; /* number of indexes in current block */
X int offset;
X int from, to;
X int space_needed; /* space needed for new line */
X int page_size;
X int page_count;
X int db_idx; /* index for lnum in data block */
X BHDR *hp = NULL;
X BHDR *hp2;
X MEMFILE *mfp;
X DATA_BL *dp;
X PTR_BL *pp;
X IPTR *ip;
X
X if (lnum > buf->b_ml.ml_line_count) /* lnum out of range */
X return FAIL;
X
X if (lowest_marked && lowest_marked > lnum)
X lowest_marked = lnum + 1;
X
X if (len == 0)
X len = STRLEN(line) + 1; /* space needed for the text */
X space_needed = len + INDEX_SIZE; /* space needed for text + index */
X
X mfp = buf->b_ml.ml_mfp;
X page_size = mfp->mf_page_size;
X
X if (buf->b_ml.ml_flags & ML_EMPTY) /* empty file */
X {
X/*
X * Special case: Add first line to empty file.
X * Create the first data block.
X * If lnum == 0, line 1 is inserted below.
X * If lnum == 1, insert an empty line 1 and insert line 2 below.
X */
X /*
X * allocate the first data block
X */
X if (lnum == 1) /* reserve space for line 1 */
X space_needed += 1 + INDEX_SIZE;
X page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
X if ((hp = ml_new_data(mfp, newfile, page_count)) == NULL)
X return FAIL;
X
X if (lnum == 1) /* insert line 1 here, empty */
X {
X dp = (DATA_BL *)(hp->bh_data);
X dp->db_index[0] = --dp->db_txt_start; /* at end of block */
X dp->db_free -= 1 + INDEX_SIZE;
X dp->db_line_count = 1;
X *((char_u *)dp + dp->db_txt_start) = NUL; /* emtpy line */
X space_needed -= 1 + INDEX_SIZE; /* space for line 1 */
X }
X
X /*
X * update the first pointer block
X */
X if ((hp2 = mf_get(mfp, (blocknr_t)1, 1)) == NULL)
X {
X mf_free(mfp, hp);
X return FAIL;
X }
X pp = (PTR_BL *)(hp2->bh_data); /* must be pointer block */
X if (pp->pb_id != PTR_ID)
X {
X EMSG("pointer block id wrong 5");
X mf_free(mfp, hp);
X mf_put(mfp, hp2, FALSE, FALSE);
X return FAIL;
X }
X pp->pb_count = 1;
X pp->pb_pointer[0].pe_bnum = hp->bh_bnum;
X pp->pb_pointer[0].pe_page_count = page_count;
X pp->pb_pointer[0].pe_old_lnum = 1;
X pp->pb_pointer[0].pe_line_count = lnum + 1; /* line count after insertion */
X mf_put(mfp, hp2, TRUE, FALSE);
X
X buf->b_ml.ml_flags &= ~ML_EMPTY;
X line_count = lnum; /* 0 or 1 line in block before insertion */
X buf->b_ml.ml_line_count = lnum;
X db_idx = lnum - 1; /* append new line after -1 or 0 */
X }
X else /* not empty file */
X {
X/*
X * find the data block containing the previous line
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_t)1 : lnum, ML_INSERT)) == NULL)
X return FAIL;
X
X if (lnum == 0) /* got line one instead, correct db_idx */
X db_idx = -1; /* careful, it is negative! */
X else
X db_idx = lnum - buf->b_ml.ml_locked_low;
X /* get line count before the insertion */
X line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
X }
X
X dp = (DATA_BL *)(hp->bh_data);
X
X/*
X * If
X * - there is not enough room in the current block
X * - appending to the last line in the block
X * - not appending to the last line in the file
X * insert in front of the next block.
X */
X if ((int)dp->db_free < space_needed && db_idx == line_count - 1 &&
X lnum < buf->b_ml.ml_line_count)
X {
X /*
X * Now that the line is not going to be inserted in the block that we
X * expected, the line count has to be adjusted in the pointer blocks
X * by using ml_locked_lineadd.
X */
X --(buf->b_ml.ml_locked_lineadd);
X --(buf->b_ml.ml_locked_high);
X if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
X return FAIL;
X
X db_idx = -1; /* careful, it is negative! */
X /* get line count before the insertion */
X line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
X CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
X
X dp = (DATA_BL *)(hp->bh_data);
X }
X
X ++buf->b_ml.ml_line_count;
X
X if ((int)dp->db_free >= space_needed) /* enough room in data block */
X {
X/*
X * Insert new line in existing data block, or in data block allocated above.
X */
X dp->db_txt_start -= len;
X dp->db_free -= space_needed;
X ++(dp->db_line_count);
X
X /*
X * move the text of the lines that follow to the front
X * adjust the indexes of the lines that follow
X */
X if (line_count > db_idx + 1) /* if there are following lines */
X {
X /*
X * Offset is the start of the previous line.
X * This will become the character just after the new line.
X */
X if (db_idx < 0)
X offset = dp->db_txt_end;
X else
X offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
X memmove((char *)dp + dp->db_txt_start,
X (char *)dp + dp->db_txt_start + len,
X (size_t)(offset - (dp->db_txt_start + len)));
X for (i = line_count - 1; i > db_idx; --i)
X dp->db_index[i + 1] = dp->db_index[i] - len;
X dp->db_index[db_idx + 1] = offset - len;
X }
X else /* add line at the end */
X dp->db_index[db_idx + 1] = dp->db_txt_start;
X
X /*
X * copy the text into the block
X */
X memmove((char *)dp + dp->db_index[db_idx + 1], (char *)line, (size_t)len);
X
X /*
X * Mark the block dirty.
X */
X buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
X if (!newfile)
X buf->b_ml.ml_flags |= ML_LOCKED_POS;
X }
X else /* not enough space in data block */
X {
X/*
X * If there is not enough room we have to create a new data block and copy some
X * lines into it.
X * Then we have to insert an entry in the pointer block.
X * If this pointer block also is full, we go up another block, and so on, up
X * to the root if necessary.
X * The line counts in the pointer blocks have already been adjusted by
X * ml_find_line().
X */
X int line_count_left, line_count_right;
X int page_count_left, page_count_right;
X BHDR *hp_left;
X BHDR *hp_right;
X BHDR *hp_new;
X int lines_moved;
X int data_moved = 0; /* init to shut up gcc */
X int total_moved = 0; /* init to shut up gcc */
X DATA_BL *dp_right, *dp_left;
X int stack_idx;
X int in_left;
X int lineadd;
X blocknr_t bnum_left, bnum_right;
X linenr_t lnum_left, lnum_right;
X int pb_idx;
X PTR_BL *pp_new;
X
X /*
X * We are going to allocate a new data block. Depending on the situation
X * it will be put to the left or right of the existing block.
X * If possible we put the new line in the left block and move the
X * lines after it to the right block. Otherwise the new line is also put
X * in the right block. This method is more efficient when inserting a lot
X * of lines at one place.
X */
X if (db_idx < 0) /* left block is new, right block is existing */
X {
X lines_moved = 0;
X in_left = TRUE;
X /* space_needed does not change */
X }
X else /* left block is existing, right block is new */
X {
X lines_moved = line_count - db_idx - 1;
X if (lines_moved == 0)
X in_left = FALSE; /* put new line in right block */
X /* space_needed does not change */
X else
X {
X data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) - dp->db_txt_start;
X total_moved = data_moved + lines_moved * INDEX_SIZE;
X if ((int)dp->db_free + total_moved >= space_needed)
X {
X in_left = TRUE; /* put new line in left block */
X space_needed = total_moved;
X }
X else
X {
X in_left = FALSE; /* put new line in right block */
X space_needed += total_moved;
X }
X }
X }
X
X page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
X if ((hp_new = ml_new_data(mfp, newfile, page_count)) == 0)
X {
X /* correct line counts in pointer blocks */
X --(buf->b_ml.ml_locked_lineadd);
X --(buf->b_ml.ml_locked_high);
X return FAIL;
X }
X if (db_idx < 0) /* left block is new */
X {
X hp_left = hp_new;
X hp_right = hp;
X line_count_left = 0;
X line_count_right = line_count;
X }
X else /* right block is new */
X {
X hp_left = hp;
X hp_right = hp_new;
X line_count_left = line_count;
X line_count_right = 0;
X }
X dp_right = (DATA_BL *)(hp_right->bh_data);
X dp_left = (DATA_BL *)(hp_left->bh_data);
X bnum_left = hp_left->bh_bnum;
X bnum_right = hp_right->bh_bnum;
X page_count_left = hp_left->bh_page_count;
X page_count_right = hp_right->bh_page_count;
X
X /*
X * May move the new line into the right/new block.
X */
X if (!in_left)
X {
X dp_right->db_txt_start -= len;
X dp_right->db_free -= len + INDEX_SIZE;
X dp_right->db_index[0] = dp_right->db_txt_start;
X memmove((char *)dp_right + dp_right->db_txt_start, (char *)line, (size_t)len);
X ++line_count_right;
X }
X /*
X * may move lines from the left/old block to the right/new one.
X */
X if (lines_moved)
X {
X /*
X */
X dp_right->db_txt_start -= data_moved;
X dp_right->db_free -= total_moved;
X memmove((char *)dp_right + dp_right->db_txt_start,
X (char *)dp_left + dp_left->db_txt_start,
X (size_t)data_moved);
X offset = dp_right->db_txt_start - dp_left->db_txt_start;
X dp_left->db_txt_start += data_moved;
X dp_left->db_free += total_moved;
X
X /*
X * update indexes in the new block
X */
X for (to = line_count_right, from = db_idx + 1; from < line_count_left; ++from, ++to)
X dp_right->db_index[to] = dp->db_index[from] + offset;
X line_count_right += lines_moved;
X line_count_left -= lines_moved;
X }
X
X /*
X * May move the new line into the left (old or new) block.
X */
X if (in_left)
X {
X dp_left->db_txt_start -= len;
X dp_left->db_free -= len + INDEX_SIZE;
X dp_left->db_index[line_count_left] = dp_left->db_txt_start;
X memmove((char *)dp_left + dp_left->db_txt_start, (char *)line,
X (size_t)len);
X ++line_count_left;
X }
X
X if (db_idx < 0) /* left block is new */
X {
X lnum_left = lnum + 1;
X lnum_right = 0;
X }
X else /* right block is new */
X {
X lnum_left = 0;
X if (in_left)
X lnum_right = lnum + 2;
X else
X lnum_right = lnum + 1;
X }
X dp_left->db_line_count = line_count_left;
X dp_right->db_line_count = line_count_right;
X
X /*
X * release the two data blocks
X * The new one (hp_new) already has a correct blocknumber.
X * The old one (hp, in ml_locked) gets a positive blocknumber if
X * we changed it and we are not editing a new file.
X */
X if (lines_moved || in_left)
X buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
X if (!newfile && db_idx >= 0 && in_left)
X buf->b_ml.ml_flags |= ML_LOCKED_POS;
X mf_put(mfp, hp_new, TRUE, FALSE);
X
X /*
X * flush the old data block
X * set ml_locked_lineadd to 0, because the updating of the
X * pointer blocks is done below
X */
X lineadd = buf->b_ml.ml_locked_lineadd;
X buf->b_ml.ml_locked_lineadd = 0;
X ml_find_line(buf, (linenr_t)0, ML_FLUSH); /* flush data block */
X
X /*
X * update pointer blocks for the new data block
X */
X for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
X {
X ip = &(buf->b_ml.ml_stack[stack_idx]);
X pb_idx = ip->ip_index;
X if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
X return FAIL;
X pp = (PTR_BL *)(hp->bh_data); /* must be pointer block */
X if (pp->pb_id != PTR_ID)
X {
X EMSG("pointer block id wrong 3");
X mf_put(mfp, hp, FALSE, FALSE);
X return FAIL;
X }
X /*
X * TODO: If the pointer block is full and we are adding at the end
X * try to insert in front of the next block
X */
X if (pp->pb_count < pp->pb_count_max) /* block not full, add one entry */
X {
X if (pb_idx + 1 < (int)pp->pb_count)
X memmove((char *)&pp->pb_pointer[pb_idx + 2],
X (char *)&pp->pb_pointer[pb_idx + 1],
X (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
X ++pp->pb_count;
X pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
X pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
X pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
X pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
X pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
X pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
X
X if (lnum_left != 0)
X pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
X if (lnum_right != 0)
X pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
X
X mf_put(mfp, hp, TRUE, FALSE);
X buf->b_ml.ml_stack_top = stack_idx + 1; /* truncate stack */
X
X if (lineadd)
X {
X --(buf->b_ml.ml_stack_top);
X /* fix line count for rest of blocks in the stack */
X ml_lineadd(buf, lineadd);
X /* fix stack itself */
X buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high += lineadd;
X ++(buf->b_ml.ml_stack_top);
X }
X
X return OK;
X }
X else /* pointer block full */
X {
X /*
X * split the pointer block
X * allocate a new pointer block
X * move some of the pointer into the new block
X * prepare for updating the parent block
X */
X for (;;) /* do this twice when splitting block 1 */
X {
X hp_new = ml_new_ptr(mfp);
X if (hp_new == NULL) /* TODO: try to fix tree */
X return FAIL;
X pp_new = (PTR_BL *)(hp_new->bh_data);
X
X if (hp->bh_bnum != 1)
X break;
X
X /*
X * if block 1 becomes full the tree is given an extra level
X * The pointers from block 1 are moved into the new block.
X * block 1 is updated to point to the new block
X * then continue to split the new block
X */
X memmove((char *)pp_new, (char *)pp, (size_t)page_size);
X pp->pb_count = 1;
X pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
X pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
X pp->pb_pointer[0].pe_old_lnum = 1;
X pp->pb_pointer[0].pe_page_count = 1;
X mf_put(mfp, hp, TRUE, FALSE); /* release block 1 */
X hp = hp_new; /* new block is to be split */
X pp = pp_new;
X CHECK(stack_idx != 0, "stack_idx should be 0");
X ip->ip_index = 0;
X ++stack_idx; /* do block 1 again later */
X }
X /*
X * move the pointers after the current one to the new block
X * If there are none, the new entry will be in the new block.
X */
X total_moved = pp->pb_count - pb_idx - 1;
X if (total_moved)
X {
X memmove((char *)&pp_new->pb_pointer[0],
X (char *)&pp->pb_pointer[pb_idx + 1],
X (size_t)(total_moved) * sizeof(PTR_EN));
X pp_new->pb_count = total_moved;
X pp->pb_count -= total_moved - 1;
X pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
X pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
X pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
X if (lnum_right)
X pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
X }
X else
X {
X pp_new->pb_count = 1;
X pp_new->pb_pointer[0].pe_bnum = bnum_right;
X pp_new->pb_pointer[0].pe_line_count = line_count_right;
X pp_new->pb_pointer[0].pe_page_count = page_count_right;
X pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
X }
X pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
X pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
X pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
X if (lnum_left)
X pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
X lnum_left = 0;
X lnum_right = 0;
X
X /*
X * recompute line counts
X */
X line_count_right = 0;
X for (i = 0; i < (int)pp_new->pb_count; ++i)
X line_count_right += pp_new->pb_pointer[i].pe_line_count;
X line_count_left = 0;
X for (i = 0; i < (int)pp->pb_count; ++i)
X line_count_left += pp->pb_pointer[i].pe_line_count;
X
X bnum_left = hp->bh_bnum;
X bnum_right = hp_new->bh_bnum;
X page_count_left = 1;
X page_count_right = 1;
X mf_put(mfp, hp, TRUE, FALSE);
X mf_put(mfp, hp_new, TRUE, FALSE);
X }
X }
X EMSG("Updated too many blocks?");
X buf->b_ml.ml_stack_top = 0; /* invalidate stack */
X }
X return OK;
X}
X
X/*
X * replace line lnum, with buffering, in current buffer
X *
X * If copy is TRUE, make a copy of the line, otherwise the line has been
X * copied to allocated memory already.
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xml_replace(lnum, line, copy)
X linenr_t lnum;
X char_u *line;
X int copy;
X{
X int status;
X
X if (line == NULL) /* just checking... */
X return FAIL;
X
X /*
X * if empty file simply append the one and only line
X */
X if (curbuf->b_ml.ml_flags & ML_EMPTY)
X {
X if (*line == NUL) /* nothing to do */
X return OK;
X status = ml_append_int(curbuf, lnum - 1, line, (colnr_t)0, FALSE);
X if (!copy)
X free(line);
X return status;
X }
X
X /*
X * if only line replaced by empty line, buffer becomes empty
X */
X if (lnum == 1 && *line == NUL && curbuf->b_ml.ml_line_count == 1)
X {
X status = ml_delete(lnum);
X if (!copy)
X free(line);
X return status;
X }
X
X if (curbuf->b_ml.ml_line_lnum != lnum) /* other line currently buffered */
X ml_flush_line(curbuf); /* flush it */
X else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line has been allocated */
X free(curbuf->b_ml.ml_line_ptr); /* free it */
X if (copy && (line = strsave(line)) == NULL) /* allocate memory for the line */
X return FAIL;
X curbuf->b_ml.ml_line_ptr = line;
X curbuf->b_ml.ml_line_lnum = lnum;
X curbuf->b_ml.ml_flags |= ML_LINE_DIRTY;
X
X return OK;
X}
X
X/*
X * delete line 'lnum'
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xml_delete(lnum)
X linenr_t lnum;
X{
X ml_flush_line(curbuf);
X return ml_delete_int(curbuf, lnum);
X}
X
X static int
Xml_delete_int(buf, lnum)
X BUF *buf;
X linenr_t lnum;
X{
X BHDR *hp;
X MEMFILE *mfp;
X DATA_BL *dp;
X PTR_BL *pp;
X IPTR *ip;
X int count; /* number of entries in block */
X int idx;
X int stack_idx;
X int text_start;
X int line_start;
X int line_size;
X int i;
X
X if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
X return FAIL;
X
X if (lowest_marked && lowest_marked > lnum)
X lowest_marked--;
X
X if (buf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
X return FAIL;
X
X /*
X * find the data block containing the line
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X mfp = buf->b_ml.ml_mfp;
X
X if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
X return FAIL;
X
X dp = (DATA_BL *)(hp->bh_data);
X /* compute line count before the delete */
X count = (long)(buf->b_ml.ml_locked_high) - (long)(buf->b_ml.ml_locked_low) + 2;
X idx = lnum - buf->b_ml.ml_locked_low;
X
X/*
X * If the file becomes empty the data block is freed.
X * The pointer blocks will be updated when the first line is appended.
X */
X if (--buf->b_ml.ml_line_count == 0) /* file becomes empty */
X {
X CHECK(count != 1, "ml_delete: count not 1");
X CHECK(idx != 0, "ml_delete: idx not 0");
X buf->b_ml.ml_line_count = 1;
X buf->b_ml.ml_flags |= ML_EMPTY;
X mf_free(mfp, hp); /* free the data block */
X buf->b_ml.ml_locked = NULL;
X buf->b_ml.ml_stack_top = 0; /* flush stack */
X return OK;
X }
X
X/*
X * special case: If there is only one line in the data block it becomes empty.
X * Then we have to remove the entry, pointing to this data block, from the
X * pointer block. If this pointer block also becomes empty, we go up another
X * block, and so on, up to the root if necessary.
X * The line counts in the pointer blocks have already been adjusted by
X * ml_find_line().
X */
X if (count == 1)
X {
X mf_free(mfp, hp); /* free the data block */
X buf->b_ml.ml_locked = NULL;
X
X for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
X {
X buf->b_ml.ml_stack_top = 0; /* stack is invalid when failing */
X ip = &(buf->b_ml.ml_stack[stack_idx]);
X idx = ip->ip_index;
X if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
X return FAIL;
X pp = (PTR_BL *)(hp->bh_data); /* must be pointer block */
X if (pp->pb_id != PTR_ID)
X {
X EMSG("pointer block id wrong 4");
X mf_put(mfp, hp, FALSE, FALSE);
X return FAIL;
X }
X count = --(pp->pb_count);
X if (count == 0) /* the pointer block becomes empty! */
X mf_free(mfp, hp);
X else
X {
X if (count != idx) /* move entries after the deleted one */
X memmove((char *)&pp->pb_pointer[idx],
X (char *)&pp->pb_pointer[idx + 1],
X (size_t)(count - idx) * sizeof(PTR_EN));
X mf_put(mfp, hp, TRUE, FALSE);
X
X buf->b_ml.ml_stack_top = stack_idx; /* truncate stack */
X /* fix line count for rest of blocks in the stack */
X if (buf->b_ml.ml_locked_lineadd)
X {
X ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
X buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
X buf->b_ml.ml_locked_lineadd;
X }
X ++(buf->b_ml.ml_stack_top);
X
X return OK;
X }
X }
X CHECK(1, "deleted block 1?");
X
X return OK;
X }
X
X /*
X * delete the text by moving the next lines forwards
X */
X text_start = dp->db_txt_start;
X line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
X if (idx == 0) /* first line in block, text at the end */
X line_size = dp->db_txt_end - line_start;
X else
X line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
X memmove((char *)dp + text_start + line_size, (char *)dp + text_start,
X (size_t)(line_start - text_start));
X
X /*
X * delete the index by moving the next indexes backwards
X * Adjust the indexes for the text movement.
X */
X for (i = idx; i < count - 1; ++i)
X dp->db_index[i] = dp->db_index[i + 1] + line_size;
X
X dp->db_free += line_size + INDEX_SIZE;
X dp->db_txt_start += line_size;
X --(dp->db_line_count);
X
X /*
X * mark the block dirty and make sure it is in the file (for recovery)
X */
X buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
X
X return OK;
X}
X
X/*
X * set the B_MARKED flag for line 'lnum'
X */
X void
Xml_setmarked(lnum)
X linenr_t lnum;
X{
X BHDR *hp;
X DATA_BL *dp;
X
X if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* invalid line number */
X return; /* give error message? */
X
X if (lowest_marked == 0 || lowest_marked > lnum)
X lowest_marked = lnum;
X
X /*
X * find the data block containing the line
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
X return; /* give error message? */
X
X dp = (DATA_BL *)(hp->bh_data);
X dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
X curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
X}
X
X/*
X * find the first line with its B_MARKED flag set
X */
X linenr_t
Xml_firstmarked()
X{
X BHDR *hp;
X DATA_BL *dp;
X linenr_t lnum;
X int i;
X
X /*
X * The search starts with lowest_marked line. This is the last line where
X * a mark was found, adjusted by inserting/deleting lines.
X */
X for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
X {
X /*
X * Find the data block containing the line.
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
X return (linenr_t)0; /* give error message? */
X
X dp = (DATA_BL *)(hp->bh_data);
X
X for (i = lnum - curbuf->b_ml.ml_locked_low;
X lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
X if ((dp->db_index[i]) & DB_MARKED)
X {
X (dp->db_index[i]) &= DB_INDEX_MASK;
X curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
X lowest_marked = lnum + 1;
X return lnum;
X }
X }
X
X return (linenr_t) 0;
X}
X
X/*
X * return TRUE if line 'lnum' has a mark
X */
X int
Xml_has_mark(lnum)
X linenr_t lnum;
X{
X BHDR *hp;
X DATA_BL *dp;
X
X if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
X return FALSE;
X
X dp = (DATA_BL *)(hp->bh_data);
X return (int)((dp->db_index[lnum - curbuf->b_ml.ml_locked_low]) & DB_MARKED);
X}
X
X/*
X * clear all DB_MARKED flags
X */
X void
Xml_clearmarked()
X{
X BHDR *hp;
X DATA_BL *dp;
X linenr_t lnum;
X int i;
X
X /*
X * The search starts with line lowest_marked.
X */
X for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
X {
X /*
X * Find the data block containing the line.
X * This also fills the stack with the blocks from the root to the data block
X * This also releases any locked block.
X */
X if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
X return; /* give error message? */
X
X dp = (DATA_BL *)(hp->bh_data);
X
X for (i = lnum - curbuf->b_ml.ml_locked_low;
X lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
X if ((dp->db_index[i]) & DB_MARKED)
X {
X (dp->db_index[i]) &= DB_INDEX_MASK;
X curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
X }
X }
X
X lowest_marked = 0;
X return;
X}
X
X/*
X * flush ml_line if necessary
X */
X static void
Xml_flush_line(buf)
X BUF *buf;
X{
X BHDR *hp;
X DATA_BL *dp;
X linenr_t lnum;
X char_u *new_line;
X char_u *old_line;
X colnr_t new_len;
X int old_len;
X int extra;
X int idx;
X int start;
X int count;
X int i;
X
X if (buf->b_ml.ml_line_lnum == 0) /* nothing to do */
X return;
X
X if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
X {
X lnum = buf->b_ml.ml_line_lnum;
X new_line = buf->b_ml.ml_line_ptr;
X
X hp = ml_find_line(buf, lnum, ML_FIND);
X if (hp == NULL)
X EMSG2("Cannot fine line %ld", (char_u *)lnum);
X else
X {
X dp = (DATA_BL *)(hp->bh_data);
X idx = lnum - buf->b_ml.ml_locked_low;
X start = ((dp->db_index[idx]) & DB_INDEX_MASK);
X old_line = (char_u *)dp + start;
X if (idx == 0) /* line is last in block */
X old_len = dp->db_txt_end - start;
X else /* text of previous line follows */
X old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
X new_len = STRLEN(new_line) + 1;
X extra = new_len - old_len; /* negative if lines gets smaller */
X
X /*
X * if new line fits in data block, replace directly
X */
X if ((int)dp->db_free >= extra)
X {
X /* if the length changes and there are following lines */
X count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
X if (extra != 0 && idx < count - 1)
X {
X /* move text of following lines */
X memmove((char *)dp + dp->db_txt_start - extra,
X (char *)dp + dp->db_txt_start,
X (size_t)(start - dp->db_txt_start));
X
X /* adjust pointers of this and following lines */
X for (i = idx + 1; i < count; ++i)
X dp->db_index[i] -= extra;
X }
X dp->db_index[idx] -= extra;
X
X /* adjust free space */
X dp->db_free -= extra;
X dp->db_txt_start -= extra;
X
X /* copy new line into the data block */
X memmove((char *)old_line - extra, (char *)new_line, (size_t)new_len);
X buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
X }
X else
X {
X /*
X * Cannot do it in one data block: delete and append.
X */
X /* How about handling errors??? */
X (void)ml_delete_int(buf, lnum);
X (void)ml_append_int(buf, lnum - 1, new_line, new_len, FALSE);
X }
X }
X free(new_line);
X }
X
X buf->b_ml.ml_line_lnum = 0;
X}
X
X/*
X * create a new, empty, data block
X */
X static BHDR *
Xml_new_data(mfp, negative, page_count)
X MEMFILE *mfp;
X int negative;
X int page_count;
X{
X BHDR *hp;
X DATA_BL *dp;
X
X if ((hp = mf_new(mfp, negative, page_count)) == NULL)
X return NULL;
X
X dp = (DATA_BL *)(hp->bh_data);
X dp->db_id = DATA_ID;
X dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
X dp->db_free = dp->db_txt_start - HEADER_SIZE;
X dp->db_line_count = 0;
X
X return hp;
X}
X
X/*
X * create a new, empty, pointer block
X */
X static BHDR *
Xml_new_ptr(mfp)
X MEMFILE *mfp;
X{
X BHDR *hp;
X PTR_BL *pp;
X
X if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
X return NULL;
X
X pp = (PTR_BL *)(hp->bh_data);
X pp->pb_id = PTR_ID;
X pp->pb_count = 0;
X pp->pb_count_max = (mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1;
X
X return hp;
X}
X
X/*
X * lookup line 'lnum' in a memline
X *
X * action: if ML_DELETE or ML_INSERT the line count is updated while searching
X * if ML_FLUSH only flush a locked block
X * if ML_FIND just find the line
X *
X * If the block was found it is locked and put in ml_locked.
X * The stack is updated to lead to the locked block. The ip_high field in
X * the stack is updated to reflect the last line in the block AFTER the
X * insert or delete, also if the pointer block has not been updated yet. But
X * if if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
X *
X * return: NULL for failure, pointer to block header otherwise
X */
X static BHDR *
Xml_find_line(buf, lnum, action)
X BUF *buf;
X linenr_t lnum;
X int action;
X{
X DATA_BL *dp;
X PTR_BL *pp;
X IPTR *ip;
X BHDR *hp;
X MEMFILE *mfp;
X linenr_t t;
X blocknr_t bnum, bnum2;
X int dirty;
X linenr_t low, high;
X int top;
X int page_count;
X int idx;
X
X mfp = buf->b_ml.ml_mfp;
X
X /*
X * If there is a locked block check if the wanted line is in it.
X * If not, flush and release the locked block.
X * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
X * Don't do this for ML_FLUSH, because we want to flush the locked block.
X */
X if (buf->b_ml.ml_locked)
X {
X if (ML_SIMPLE(action) && buf->b_ml.ml_locked_low <= lnum &&
X buf->b_ml.ml_locked_high >= lnum)
X {
X /* remember to update pointer blocks and stack later */
X if (action == ML_INSERT)
X {
X ++(buf->b_ml.ml_locked_lineadd);
X ++(buf->b_ml.ml_locked_high);
X }
X else if (action == ML_DELETE)
X {
X --(buf->b_ml.ml_locked_lineadd);
X --(buf->b_ml.ml_locked_high);
X }
X return (buf->b_ml.ml_locked);
X }
X
X mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
X buf->b_ml.ml_flags & ML_LOCKED_POS);
X buf->b_ml.ml_locked = NULL;
X
X /*
X * if lines have been added or deleted in the locked block, need to
X * update the line count in pointer blocks
X */
X if (buf->b_ml.ml_locked_lineadd)
X ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
X }
X
X if (action == ML_FLUSH) /* nothing else to do */
X return NULL;
X
X bnum = 1; /* start at the root of the tree */
X page_count = 1;
X low = 1;
X high = buf->b_ml.ml_line_count;
X
X if (action == ML_FIND) /* first try stack entries */
X {
X for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
X {
X ip = &(buf->b_ml.ml_stack[top]);
X if (ip->ip_low <= lnum && ip->ip_high >= lnum)
X {
X bnum = ip->ip_bnum;
X low = ip->ip_low;
X high = ip->ip_high;
X buf->b_ml.ml_stack_top = top; /* truncate stack at prev entry */
X break;
X }
X }
X if (top < 0)
X buf->b_ml.ml_stack_top = 0; /* not found, start at the root */
X }
X else /* ML_DELETE or ML_INSERT */
X buf->b_ml.ml_stack_top = 0; /* start at the root */
X
X/*
X * search downwards in the tree until a data block is found
X */
X for (;;)
X {
X if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
X goto error_noblock;
X
X /*
X * update high for insert/delete
X */
X if (action == ML_INSERT)
X ++high;
X else if (action == ML_DELETE)
X --high;
X
X dp = (DATA_BL *)(hp->bh_data);
X if (dp->db_id == DATA_ID) /* data block */
X {
X buf->b_ml.ml_locked = hp;
X buf->b_ml.ml_locked_low = low;
X buf->b_ml.ml_locked_high = high;
X buf->b_ml.ml_locked_lineadd = 0;
X buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
X return hp;
X }
X
X pp = (PTR_BL *)(dp); /* must be pointer block */
X if (pp->pb_id != PTR_ID)
X {
X EMSG("pointer block id wrong");
X goto error_block;
X }
X
X if ((top = ml_add_stack(buf)) < 0) /* add new entry to stack */
X goto error_block;
X ip = &(buf->b_ml.ml_stack[top]);
X ip->ip_bnum = bnum;
X ip->ip_low = low;
X ip->ip_high = high;
X ip->ip_index = -1; /* index not known yet */
X
X dirty = FALSE;
X for (idx = 0; idx < (int)pp->pb_count; ++idx)
X {
X t = pp->pb_pointer[idx].pe_line_count;
X CHECK(t == 0, "pe_line_count is zero");
X if ((low += t) > lnum)
X {
X ip->ip_index = idx;
X bnum = pp->pb_pointer[idx].pe_bnum;
X page_count = pp->pb_pointer[idx].pe_page_count;
X high = low - 1;
X low -= t;
X
X /*
X * a negative block number may have been changed
X */
X if (bnum < 0)
X {
X bnum2 = mf_trans_del(mfp, bnum);
X if (bnum != bnum2)
X {
X bnum = bnum2;
X pp->pb_pointer[idx].pe_bnum = bnum;
X dirty = TRUE;
X }
X }
X
X break;
X }
X }
X if (idx >= (int)pp->pb_count) /* past the end: something wrong! */
X {
X if (lnum > buf->b_ml.ml_line_count)
X emsg2((char_u *)"line number out of range: %ld past the end", (char_u *)(lnum - buf->b_ml.ml_line_count));
X
X else
X emsg2((char_u *)"line count wrong in block %ld", (char_u *)(bnum));
X goto error_block;
X }
X if (action == ML_DELETE)
X {
X pp->pb_pointer[idx].pe_line_count--;
X dirty = TRUE;
X }
X else if (action == ML_INSERT)
X {
X pp->pb_pointer[idx].pe_line_count++;
X dirty = TRUE;
X }
X mf_put(mfp, hp, dirty, FALSE);
X }
X
Xerror_block:
X mf_put(mfp, hp, FALSE, FALSE);
Xerror_noblock:
X/*
X * If action is ML_DELETE or ML_INSERT we have to correct the tree for
X * the incremented/decremented line counts, because there won't be a line
X * inserted/deleted after all.
X */
X if (action == ML_DELETE)
X ml_lineadd(buf, 1);
X else if (action == ML_INSERT)
X ml_lineadd(buf, -1);
X buf->b_ml.ml_stack_top = 0;
X return NULL;
X}
X
X/*
X * add an entry to the info pointer stack
X *
X * return -1 for failure, number of the new entry otherwise
X */
X static int
Xml_add_stack(buf)
X BUF *buf;
X{
X int top;
X IPTR *newstack;
X
X top = buf->b_ml.ml_stack_top;
X
X /* may have to increase the stack size */
X if (top == buf->b_ml.ml_stack_size)
X {
X CHECK(top > 0, "Stack size increases"); /* more than 5 levels??? */
X
X newstack = (IPTR *)alloc((unsigned)sizeof(IPTR) * (buf->b_ml.ml_stack_size + STACK_INCR));
X if (newstack == NULL)
X return -1;
X memmove((char *)newstack, (char *)buf->b_ml.ml_stack, (size_t)top * sizeof(IPTR));
X free(buf->b_ml.ml_stack);
X buf->b_ml.ml_stack = newstack;
X buf->b_ml.ml_stack_size += STACK_INCR;
X }
X
X buf->b_ml.ml_stack_top++;
X return top;
X}
X
X/*
X * Update the pointer blocks on the stack for inserted/deleted lines.
X * The stack itself is also updated.
X *
X * When a insert/delete line action fails, the line is not inserted/deleted,
X * but the pointer blocks have already been updated. That is fixed here by
X * walking through the stack.
X *
X * Count is the number of lines added, negative if lines have been deleted.
X */
X static void
Xml_lineadd(buf, count)
X BUF *buf;
X int count;
X{
X int idx;
X IPTR *ip;
X PTR_BL *pp;
X MEMFILE *mfp = buf->b_ml.ml_mfp;
X BHDR *hp;
X
X for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
X {
X ip = &(buf->b_ml.ml_stack[idx]);
X if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
X break;
X pp = (PTR_BL *)(hp->bh_data); /* must be pointer block */
X if (pp->pb_id != PTR_ID)
X {
X mf_put(mfp, hp, FALSE, FALSE);
X EMSG("pointer block id wrong 2");
X break;
X }
X pp->pb_pointer[ip->ip_index].pe_line_count += count;
X ip->ip_high += count;
X mf_put(mfp, hp, TRUE, FALSE);
X }
X}
X
X/*
X * make swap file name out of the filename
X */
X static char_u *
Xmakeswapname(buf, second_try)
X BUF *buf;
X int second_try;
X{
X char_u *r, *s, *fname;
X char_u *pdir;
X
X r = modname(curbuf->b_xfilename, (char_u *)".swp");
X /*
X * do not try to use 'directory' option
X * - if 'directory' option not set
X * - if out of memory
X * - not a second try and 'directory' option does not start with '>'
X */
X if (*p_dir == NUL || r == NULL || (!second_try && *p_dir != '>'))
X return r;
X
X fname = gettail(r);
X if (*p_dir == '>') /* skip '>' in front of dir name */
X pdir = p_dir + 1;
X else
X pdir = p_dir;
X s = alloc((unsigned)(STRLEN(pdir) + STRLEN(fname) + 2));
X if (s != NULL)
X {
X STRCPY(s, pdir);
X if (*s && !ispathsep(*(s + STRLEN(s) - 1))) /* don't add '/' after ':' */
X STRCAT(s, PATHSEPSTR);
X STRCAT(s, fname);
X }
X free(r);
X return s;
X}
X
X/*
X * Find out what name to use for the swap file for buffer 'buf'.
X *
X * Several names are tried to find one that does not exist
X */
X static char_u *
Xfindswapname(buf, second_try)
X BUF *buf;
X int second_try;
X{
X char_u *fname;
X int n;
X
X#ifdef AMIGA
X int r;
X BPTR fh;
X FILE *dummyfd = NULL;
X
X/*
X * If we start editing a new file, e.g. "test.doc", which resides on an MSDOS
X * compatible filesystem, it is possible that the file "test.doc.swp" which we
X * create will be exactly the same file. To avoid this problem we temporarily
X * create "test.doc".
X */
X if (!(buf->b_p_sn || buf->b_shortname) && buf->b_xfilename &&
X getperm(buf->b_xfilename) < 0)
X dummyfd = fopen((char *)buf->b_xfilename, "w");
X#endif
X
X/*
X * we try different names until we find one that does not exist yet
X */
X fname = makeswapname(buf, second_try);
X for (;;)
X {
X if (fname == NULL) /* must be out of memory */
X break;
X if ((n = STRLEN(fname)) == 0) /* safety check */
X {
X free(fname);
X fname = NULL;
X break;
X }
X
X /*
X * check if the scriptfile already exists
X */
X if (getperm(fname) < 0) /* it does not exist */
X {
X#ifdef AMIGA
X fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
X /*
X * on the Amiga getperm() will return -1 when the file exists but
X * is being used by another program. This happens if you edit
X * a file twice.
X */
X if (fh != (BPTR)NULL) /* can open file, OK */
X {
X Close(fh);
X break;
X }
X if (IoErr() != ERROR_OBJECT_IN_USE && IoErr() != ERROR_OBJECT_EXISTS)
X#endif
X break;
X }
X /*
X * get here when file already exists
X */
X if (fname[n - 1] == 'p') /* first try */
X {
X#ifdef AMIGA
X /*
X * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
X * and file.doc are the same file. To guess if this problem is
X * present try if file.doc.swx exists. If it does, we set
X * buf->b_shortname and try file_doc.swp (dots replaced by
X * underscores for this file), and try again. If it doesn't we
X * assume that "file.doc.swp" already exists.
X */
X if (!(buf->b_p_sn || buf->b_shortname)) /* not tried yet */
X {
X fname[n - 1] = 'x';
X r = getperm(fname); /* try "file.swx" */
X fname[n - 1] = 'p';
X if (r >= 0) /* it seems to exist */
X {
X buf->b_shortname = TRUE;
X free(fname);
X fname = makeswapname(buf, second_try); /* '.' replaced by '_' */
X continue; /* try again */
X }
X }
X#endif
X /*
X * If we get here ".swp" file really exists.
X * Give an error message, unless recovering or no file name.
X */
X if (!recoverymode && buf->b_xfilename != NULL)
X {
X /* call wait_return if not done by emsg() */
X if (EMSG2(".swp file exists: An edit of file \"%s\" may not have been finished", buf->b_xfilename))
X {
X msg_outchar('\n');
X wait_return(FALSE); /* do call wait_return now */
X }
X }
X }
X
X if (fname[n - 1] == 'a') /* tried enough names, give up */
X {
X free(fname);
X fname = NULL;
X break;
X }
X --fname[n - 1]; /* change last char of the name */
X }
X
X#ifdef AMIGA
X if (dummyfd) /* file has been created temporarily */
X {
X fclose(dummyfd);
X remove((char *)buf->b_xfilename);
X }
X#endif
X return fname;
X}
END_OF_FILE
if test 64654 -ne `wc -c <'vim/src/memline.c'`; then
echo shar: \"'vim/src/memline.c'\" unpacked with wrong size!
fi
# end of 'vim/src/memline.c'
fi
if test -f 'vim/src/vimresp' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/vimresp'\"
else
echo shar: Extracting \"'vim/src/vimresp'\" \(438 characters\)
sed "s/^X//" >'vim/src/vimresp' <<'END_OF_FILE'
Xobj/alloc.obj obj/msdos.obj obj/buffers.obj obj/charset.obj obj/cmdline.obj +
Xobj/csearch.obj obj/digraph.obj obj/edit.obj obj/fileio.obj obj/help.obj +
Xobj/linefunc.obj obj/main.obj obj/mark.obj obj/message.obj obj/misccmds.obj +
Xobj/normal.obj obj/ops.obj obj/param.obj obj/quickfix.obj obj/regexp.obj +
Xobj/regsub.obj obj/screen.obj obj/script.obj obj/search.obj obj/storage.obj +
Xobj/tag.obj obj/term.obj obj/undo.obj obj/version.obj
END_OF_FILE
if test 438 -ne `wc -c <'vim/src/vimresp'`; then
echo shar: \"'vim/src/vimresp'\" unpacked with wrong size!
fi
# end of 'vim/src/vimresp'
fi
echo shar: End of archive 2 \(of 26\).
cp /dev/null ark2isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:21 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 22
Archive-name: vim/part03

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/reference.doc.A vim/src/archie.c vim/src/archie.h
# Wrapped by kent@sparky on Mon Aug 15 21:43:58 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 3 (of 26)."'
if test -f 'vim/doc/reference.doc.A' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/reference.doc.A'\"
else
echo shar: Extracting \"'vim/doc/reference.doc.A'\" \(52085 characters\)
sed "s/^X//" >'vim/doc/reference.doc.A' <<'END_OF_FILE'
X
X
X
X Vim reference manual
X
X By Bram Moolenaar
X
X version 3.0
X
X
XThere is a contents listing at the end of this document.
X
XThe commands and options for multiple windows and buffers are explained in a
Xseparate document: windows.doc
X
X


X
X 1. Introduction
X

XVim stands for Vi IMproved. It used to be Vi IMitation, but that does not
Xreally cover it anymore. Vim is a text editor which includes almost all the
Xcommands from the Unix program "Vi" (and a lot new ones). It is very useful
Xfor editing programs and other ASCII text. All commands are given with the
Xkeyboard. There is no mouse support and there are no menus. This gives the
Xadvantage that you can keep your fingers on the keyboard and your eyes on
Xthe screen.
X
XThroughout this manual the differences between Vi and Vim are mentioned in
Xcurly braces. Read the file "difference.doc" for a summary of the
Xdifferences.
X
XThis manual refers to Vim on the Commodore Amiga computer. On other
Xcomputers and on terminals there may be small differences. For MSDOS this
Xis documented in msdos.doc. For UNIX this is in unix.doc.
X
XThis manual is a reference for all the Vim commands and options. A basic
Xknowledge of "Vi" is assumed. A summary of this manual can be found in the
Xfile vim.hlp. It can be accessed from within Vim with the <HELP> key (in
XMSDOS <F1>) and with the command ":help". The 'helpfile' option can be
Xset to the name of the help file, so you can put it in any place you like.
X
X
X 2. Notation
X
X[] Characters in square brackets are optional.
X
X[count] An optional number that may precede the command to multiply
X or iterate the command. If no number is given a count of one
X is used, unless otherwise noted. Note that in this manual
X the [count] is not mentioned in the description of the
X command, but only in the explanation. This was done to make
X the commands easier to lookup. If the "sc" option is on, the
X (partially) entered count is shown at the bottom of the
X window. You can use <DEL> to erase the last digit.
X
X["x] An optional register designation where text can be stored.
X The x is a single character between <a> and <z> or <A> and
X <Z> or <">, and in some cases (with the put command) between
X <0> and <9>, <%>, <:> or <.>. The uppercase and lower case
X letter designate the same register, but the lower case letter
X is used to overwrite the previous register contents, while the
X uppercase letter is used to append to the previous register
X contents. Without the ""x" or with """" the stored text is
X put into the unnamed register. See also "Copying and moving
X text".
X
X{} Curly braces denote parts of the command which must appear,
X but can take a number of different values. The differences
X between Vim and Vi are also given in curly braces (this will
X be clear from the context).
X
X{motion} A command that moves the cursor. They are listed in chapter
X 6. This is used after an "operator" command to move over the
X text that is to be operated upon. If the motion includes a
X count and the operator also had a count, the two counts are
X multiplied. For example: "2d3w" deletes six words.
X
X{visual} A piece of text that is started with the "v", "V" or CTRL-V
X command and ended by the cursor position. This is used
X before an "operator" to highlight the text that is to be
X operated upon. See the chapter on Visual mode.
X
X<character> A special character from the table below or a single ASCII
X character.
X
X<char1-char2> A single character from the range <char1> to <char2>. For
X example: <a-z> is a lower case letter. Multiple ranges may be
X concatenated. For example: <a-zA-Z0-9> is any alphanumeric
X character.
X
XCTRL-<char> <char> typed as a control character, that is, typing <char>
X while holding the CTRL key down. The case of <char> does not
X matter, thus CTRL-A and CTRL-a are equivalent.
X
X'option' An option, or parameter, that can be set to a value is
X enclosed in single quotes. See chapter 19.
X
X"command" In examples the commands you can type are enclosed in double
X quotes.
X
X
Xnotation meaning equivalent decimal value
X-----------------------------------------------------------------------
X<NUL> zero CTRL_@ 000 (internally 010)
X<BELL> bell CTRL-G 007
X<BS> backspace CTRL-H 008
X<TAB> tab CTRL-I 009
X<LF> linefeed CTRL-J 010
X<FF> formfeed CTRL-L 012
X<CR> carriage return CTRL-M 013
X<ESC> escape CTRL-[ 027
X<SPACE> space 032
X<DEL> delete 127
X<C_UP> cursor-up 128 (msdos: 176)
X<C_DOWN> cursor-down 129 (msdos: 177)
X<C_LEFT> cursor-left 130 (msdos: 178)
X<C_RIGHT> cursor-right 131 (msdos: 179)
X<SC_UP> shift-cursor-up 132 (msdos: 180)
X<SC_DOWN> shift-cursor-down 133 (msdos: 181)
X<SC_LEFT> shift-cursor-left 134 (msdos: 182)
X<SC_RIGHT> shift-cursor-right 135 (msdos: 183)
X<F1> - <F10> function keys 1 to 10 136 - 145 (msdos: 184 - 193)
X<SF1> - <SF10> shift-function keys 1 to 10 146 - 155 (msdos: 194 - 203)
XHELP> help key 156 (msdos: 204)
X<UNDO> undo key 157 (msdos: 205)
X-----------------------------------------------------------------------
XNote: The shifted cursor keys, the help key and the undo key are only
Xavailable on a few terminals. On some terminals the function keys 11 to 20
Xare used instead of the shifted function keys. On the Amiga shifted function
Xkey 10 produces a code (CSI) that is also used by key sequences. It will be
Xrecognized only after typing another key.
X
X


X 3. Starting Vim
X

X3.1 Command line
X
XMost often Vim is started to edit a single file with the command
X
X vim file
X
XMore generally Vim is started with:
X
X vim [options] [filelist]
X
XIf the filelist is missing, the editor will start with an empty buffer.
XOtherwise exactly one out of the following three may be used to choose one
Xor more files to be edited.
X
Xfile .. A list of file names. The first one will be the current file
X and read into the buffer. The cursor will be positioned on
X the first line of the buffer.
X
X-t {tag} A tag. "tag" is looked up in the tags file, the associated
X file becomes the current file and the associated command is
X executed. Mostly this is used for C programs. In that case
X "tag" should be a function name. The effect is that the file
X containing that function becomes the current file and the
X cursor is positioned on the start of the function (see the
X section "tag searches").
X
X-e [errorfile] QuickFix mode. The file with the name [errorfile] is read
X and the first error is displayed. If [errorfile] is not
X given, the 'errorfile' option is used for the file name
X (default "AztecC.Err" for the Amiga, "errors" for other
X systems). See section 5.5: "using the QuickFix mode".
X
XThe options, if present, must precede the filelist. The options may be given
Xin any order.
X
X+[num] The cursor will be positioned on line "num" for the first
X file being edited. If "num" is missing, the cursor will be
X positioned on the last line.
X
X+/{pat} The cursor will be positioned on the first line containing
X "pat" in the first file being edited (see the section
X "pattern searches" for the available search patterns).
X
X+{command}
X-c {command} "command" will be executed after the first file has been
X read. "command" is interpreted as an Ex command. If the
X "command" contains spaces it must be enclosed in double
X quotes (this depends on the shell that is used). Example:
X vim "+set si" main.c
X
X-r Recovery mode. The swap file is read to recover a
X crashed editing session. See the chapter "Recovery after a
X crash".
X
X-v View mode. The 'readonly' option will be set and no
X swap file will be written (see -n below). You can
X still edit the buffer, but will be prevented from
X accidentally overwriting a file. If you forgot that you are
X in View mode and did make some changes, you can overwrite
X a file by adding an exclamation mark to the Ex command, as in
X ":w!". The 'readonly' option can be reset with ":set noro"
X (see the options chapter). Calling the executable "view"
X has the same effect as the -v option. If your system does
X not support links and you do not want to have the executable
X twice you could make an alias: "alias view vim -v".
X
X-b Binary mode. The 'textauto', 'textmode' and 'expandtab'
X options will be reset. The 'textwidth' option is set to 0.
X 'modelines' is set to 0. The 'binary' option is set. This is
X done after reading the .vimrc/.exrc files but before reading
X a file. See also 5.6: "Editing binary files".
X
X-n No swap file will be used. Recovery after a crash will be
X impossible. Handy if you want to view or edit a file on a
X very slow medium (e.g. floppy). Can also be done with ":set
X uc=0". You can switch it on again by setting the 'uc' option
X to some value, e.g. ":set uc=100". Any files already being
X edited will not be affected by this.
X
X-o[N] Open N windows. If [N] is not given, one window is opened
X for every file given as argument. If there is not enough
X room, only the first few files get a window. If there are
X more windows than arguments, the last few windows will be
X editing an empty file.
X
X-T {terminal} Set the terminal type to "terminal". This influences the
X codes that Vim will send to your terminal. This is normally
X not needed, because Vim will be able to find out what type
X of terminal you are using (See chapter 20).
X
X-d {device} Amiga only: The "device" is opened to be used for editing.
X Normally you would use this to set the window position and
X size: "-d con:x/y/width/height", e.g.
X "-d con:30/10/600/150". But you can also use it to start
X editing on another device, e.g. AUX:.
X
X-x Amiga only: Do not restart Vim to open a new window. This
X option should be used when Vim is started by a program that
X will wait for the edit session to finish (e.g. mail or
X readnews). See section 3.3.
X
X-s {scriptin} The script file "scriptin" is read. The characters in the
X file are interpreted as if you had typed them. The same can
X be done with the command ":source! {scriptin}". If the end
X of the file is reached before the editor exits, further
X characters are read from the keyboard. See also the section
X "complex repeats".
X
X-w {scriptout} All the characters that you type are recorded in the file
X "scriptout", until you exit Vim. This is useful if you want
X to create a script file to be used with "vim -s" or
X ":source!". See also the section "complex repeats".
X
XExample for using a script file to change a name in several files:
X Create a file "subs.vi" containing substitute commands and a :wq
X command:
X
X :%s/Jones/Smith/g
X :%s/Allen/Peter/g
X :wq
X
X Execute Vim on all files you want to change:
X
X foreach i ( *.let ) vim -s subs.vi $i
X
XIf the executable is called "view" Vim will start in Readonly mode. This is
Xuseful if you can make a hard or symbolic link from "view" to "vim".
XStarting in Readonly mode can also be done with "vim -v".
X
X
X3.2 Workbench (Amiga only)
X
XVim can be started from the workbench by clicking on its icon twice. It will
Xthen start with an empty buffer.
X
XVim can be started to edit one or more files by using a "Project" icon. The
X"Default Tool" of the icon must be the full pathname of the Vim executable.
XThe name of the ".info" file must be the same as the name of the text file.
XBy clicking on this icon twice, Vim will be started with the filename as
Xcurrent filename, which will be read into the buffer (if it exists). You can
Xedit multiple files by pressing the shift key while clicking on icons, and
Xclicking twice on the last one. The "Default Tool" for all these icons must
Xbe the same.
X
XIt is not possible to give arguments to Vim, other than filenames, from the
Xworkbench.
X
X
X3.3 Vim window (Amiga only)
X
XVim will run in the CLI window where it was started. If Vim was started with
Xthe "run" or "runback" command, or if Vim was started from the workbench, it
Xwill open a window of its own.
X
XTechnical detail:
X To open the new window a little trick is used. As soon as Vim
X recognizes that it does not run in a normal CLI window, it will
X create a script file in t:. This script file contains the same
X command as how Vim was started, and an "endcli" command. This script
X file is then executed with a "newcli" command (the "c:run" and
X "c:newcli" commands are required for this to work). The script file
X will hang around until reboot, or until you delete it. This method
X is required to get the ":sh" and ":!" commands to work correctly.
X But when Vim was started with the -e option (Quickfix mode) or with
X the -x option, this method is not used. The reason for this is that
X when a compiler starts Vim with the -e option it will wait for a
X return code. With the script trick the compiler cannot get the
X return code. The -x option can be used when Vim is started by a mail
X program which also waits for the edit session to finish. As a
X consequence the ":sh" and ":!" commands are not available when the
X -e or -x option is used.
X
XVim will automatically recognize the window size and react to window
Xresizing. Under Amiga DOS 1.3 it is advised to use the fastfonts program
X"FF" to speed up display redrawing.
X
X
X3.4 Initialization
X
XWhen Vim starts running it does initializations in the following order. If
Xan environment variable is used, it is executed as a single Ex command line.
XMultiple commands must be separated with <|> or <LF>. If a file is used,
Xeach line is executed as an Ex command line.
X
X1. Four places are searched for initializations. The first that exists is
X used, the others are ignored.
X 1. The environment variable VIMINIT
X 2. The file "s:.vimrc" (for Unix: "$HOME/.vimrc")
X 3. The environment variable EXINIT
X 4. The file "s:.exrc" (for Unix: "$HOME/.exrc")
X
X2. If the 'exrc' option is set (default is 'noexrc'), the current directory
X is searched for two files. The first that exists is used, the other is
X ignored.
X 1. The file ".vimrc"
X 2. The file ".exrc"
X
X3. The environment variable SHELL, if it exists, is used to set the
X 'shell' option. With MSDOS the COMPSPEC variable is used if SHELL does
X not exist. The 'shellpipe' option is set according to the name of the
X shell.
X
X4. The environment variable TERM, if it exists, is used to set the 'term'
X option.
X
XThe first can be used to set your default settings and mappings for all edit
Xsessions. The second one for sessions in a certain directory (note that the
X'exrc' option is default off). See the section "Saving settings" for how to
Xcreate a file with commands to recreate the current settings.
X
XIf the VIMINIT environment variable or ".vimrc" exist the EXINIT and ".exrc"
Xare skipped. This can be used to initialize Vim without interfering with
Xanother version of Vi.
X
XOn the Amiga two types of environment variables exist. The ones set with the
XDOS 1.3 (or later) setenv command are recognized. See the AmigaDos 1.3
Xmanual. The environment variables set with the old Manx Set command (before
Xversion 5.0) are not recognized.
X
XOn MS-DOS systems Vim assumes that all the "_vimrc" and "_exrc" files have
X<CR><LF> pairs as line separators. This will give problems if you have a
Xfile with only <LF>s and have a line like ":map xx yy^M". The trailing ^M
Xwill be ignored.
X
XWhile reading the ".vimrc" or the ".exrc" file in the current directory some
Xcommands can be disabled for security reasons by setting the 'secure'
Xoption. Otherwise it would be possible to create a .exrc that contains nasty
Xcommands, which another user may automatically execute when he starts Vim it
Xthat directory. The disabled commands are the ones that start a shell and
Xthe ones that write to a file. The ":map" commands are echoed, so you can
Xsee which keys are being mapped.
X
XYou can reset the 'secure' option in the EXINIT or VIMINIT environment
Xvariable or in the global ".exrc" or ".vimrc" file. This is not possible in
X".vimrc" or ".exrc" in the current directory, for obvious reasons.
X
XOn unix systems this only happens if you are not the owner of the ".vimrc"
Xor ".exrc" file. Warning: If you unpack an archive that contains a .exrc
Xfile, it will be owned by you. You won't have the security protection. Check
Xthe .exrc file before you start Vim in that directory, or reset the 'exrc'
Xoption.
X
X
X3.5 Suspending
X
XCTRL-Z Suspend the editor. Same as ":stop".
X
X:sus[pend][!] or
X:st[op][!] Suspend the editor. If the <!> is not given,
X the buffer was changed, autowrite is set and
X a filename is known, the buffer will be
X written.
X
XOn many UNIX systems it is possible to suspend Vim with CTRL-Z. This is only
Xpossible in Command mode (see next chapter). Vim will continue if you make it
Xthe foreground job again. On other systems CTRL-Z will start a new shell.
XThis is the same as the ":sh" command. Vim will continue if you exit from the
Xshell.
X
X
X 4. Modes
X
X4.1 Introduction
X
XVim has four basic modes:
X
XCommand mode In Command mode you can enter all the editor
X commands. If you start the editor you are in this
X mode (unless you have set the 'insertmode' option,
X see below).
X
XInsert mode In Insert mode the text you type is inserted into the
X buffer. If the 'showmode' option is set (which is
X default), the string "-- INSERT --" is shown at the
X bottom of the window.
X
XReplace mode Replace mode is a special case of Insert mode. You
X can do the same things as in Insert mode, but for
X each character you enter (except some special
X characters) one character of the existing text is
X deleted. If the 'showmode' option is set (which is
X default), the string "-- REPLACE --" is shown at the
X bottom of the window.
X
XCommand_line mode In Command_line mode you can enter one line of text
X at the bottom of the window. This is for the Ex
X commands <:>, the pattern search commands <?></> and
X the filter command <!>.
X
XMore explanation on the insert, replace and Command_line mode is further on
Xin this chapter.
X
X
X4.2 Switching from mode to mode
X
XIf for any reason you do not know in which mode you are, you can always get
Xback to Command mode by typing <ESC> twice. You will know you are back in
XCommand mode when you see the screen flash or hear the bell after you type
X<ESC>.
X
X- go from Command mode to Insert mode by giving one of the commands
X "iIaAoOcCsS".
X- go from Command mode to Replace mode with the "R" command (not the "r"
X command!).
X- go from Command mode to Command_line mode with the one of the commands
X ":/?!".
X
X- go from insert or Replace mode to Command mode with <ESC> (twice in some
X rare cases).
X- go from Command_line mode to Command mode by:
X - hitting <CR> or <LF>, which causes the entered command to be executed
X - deleting the complete line (e.g. with CTRL-U) and giving a final <BS>
X - hitting CTRL-C or <ESC>, which quits the command line without executing
X the command.
X In the last case <ESC> may be the character defined with the 'wildchar'
X option, and start command line completion. You can ignore that and type
X <ESC> again. {vi: when hitting <ESC> the command line is executed. This is
X unexpected for most people, therefore it was changed in Vim. But when the
X <ESC> is part of a mapping the command line is executed. If you want the
X vi behaviour also when typing <ESC> use ":cmap ^V<ESC> ^V^M"}
X
XIf the 'insertmode' option is set, editing a file will start in Insert mode.
X
X
X4.3 Insert and Replace mode
X
X4.3.1 special keys
X
XIn insert and Replace mode the following characters have a special meaning,
Xother characters are inserted directly. To insert one of these special
Xcharacters into the buffer, precede it with CTRL-V. To insert a <NUL>
Xcharacter use "CTRL-V CTRL-@" or "CTRL-V 000". On some systems you have to
Xuse "CTRL-V 003" to insert a CTRL-C.
X
Xchar action
X-----------------------------------------------------------------------
XCTRL-@ Insert previously inserted text and stop insert. {Vi: only
X when typed as first char, only up to 128 chars}
XCTRL-A Insert previously inserted text. {not in Vi}
XCTRL-B Toggle the 'revins' option (B for Backwards). {not in Vi}
XCTRL-C Quit insert mode, back to command mode. Do not check for
X abbreviations.
XCTRL-D Delete one shiftwidth of indent at the start of the current
X line. See also 'shiftround' option. When preceded with <^>
X or <0> delete all indent in the current line. With <^> the
X indent is restored in the next line. This is useful when
X inserting a label. {Vi: CTRL-D works only when used after
X autoindent}
XCTRL-E Insert the character which is below the cursor. {not in Vi}
XCTRL-H <BS> Delete the character before the cursor (see below). {Vi:
X does not delete autoindents}
XCTRL-I <TAB> Insert a tab. If the 'expandtab' option is on, the
X equivalent number of spaces is inserted (use CTRL-V <TAB> to
X avoid the expansion). See also the 'smarttab' option, section
X 4.3.4.
XCTRL-J <LF> Begin new line.
XCTRL-K {char1} {char2}
X Enter digraph (see 4.7). {not in Vi}
XCTRL-M <CR> Begin new line.
XCTRL-N Find next keyword (see 4.3.7). {not in Vi}
XCTRL-O Execute one Command mode command. See below. {not in Vi}
XCTRL-P Find previous keyword (see 4.3.7). {not in Vi}
XCTRL-R <0-9a-z"%:>
X Insert the contents of a numbered or named register. The
X text is inserted as if you typed it, but mappings and
X abbreviations are not used. If you have options like
X 'textwidht' or 'autoindent' set, this will influence what
X will be inserted. Use <"> for the unnamed register,
X containing the text of the last delete or yank. Use <%> for
X the current file name. Use <:> for the last command line. See
X the chapter on copying and moving text about registers. {<%>,
X <"> and <:> not in Vi}
XCTRL-T Insert one shiftwidth of indent at the start of the current
X line. See also 'shiftround' option. {Vi: only when in
X autoindent}
XCTRL-U Delete all entered characters in the current line (see
X below).
XCTRL-V Insert next non-digit literally. Up to three digits form the
X decimal value of a single byte. The non-digit and the three
X digits are not considered for mapping. {Vi: no decimal byte
X entry}
XCTRL-W Delete the word before the cursor (see below). See the
X section "word motions" for the definition of a word.
XCTRL-Y Insert the character which is above the cursor. {not in Vi}
XCTRL-[ or <ESC> End insert or Replace mode, back to Command mode.
X<DEL> Same as CTRL-H <BS>
X-----------------------------------------------------------------------
X
XThe effect of the <BS>, <DEL>, CTRL-W and CTRL-U depends on the 'backspace'
Xoption (unless 'revins' is set):
X
Xbackspace action
X option
X 0 delete stops in column 1 and start position of insert
X 1 delete stops at start position of insert
X 2 delete always, CTRL-W and CTRL-U stop once at start position of
X insert
X
XIf the 'backspace' option is non-zero and the cursor is in column 1 when one
Xof the three keys is used, the current line is joined with the previous
Xline. This effectively deletes the newline in front of the cursor. {Vi: does
Xnot cross lines, does not delete past start position of insert}
X
XWith CTRL-V followed by one, two or three digits you can enter the decimal
Xvalue of a byte, except 10. Normally CTRL-V is followed by three digits. The
Xformed byte is inserted as soon as you type the third digit. If you type
Xonly one or two digits and then a non-digit, the decimal value of those one
Xor two digits form the byte. After that the non-digit is dealt with in the
Xnormal way. If you enter a value of 10, it will end up in the file as a 0.
XThe 10 is a <LF>, which is used internally to represent the <NUL> character.
XWhen writing the buffer to a file the <LF> character is translated into
X<NUL>. The <LF> character is written at the end of each line. Thus if you
Xwant to insert a <LF> character in a file you will have to make a line
Xbreak.
X
X
X4.3.2 special special keys
X
XThe following keys are special. They stop the current insert, do something
Xand then restart insertion. This means you can do something without getting
Xout of Insert mode. This is very handy if you prefer to use the Insert mode
Xall the time, just like editors that don't have a separate Command mode. You
Xmay also want to set the 'backspace' option to 2 and set the 'insertmode'
Xoption. You can use CTRL-O if you want to map a function key to a command.
X
XThe changes (inserted or deleted characters) before and after these keys can
Xbe undone separately. Only the last change can be redone and always behaves
Xlike an "i" command.
X
Xchar action
X-----------------------------------------------------------------------
X<C_UP> cursor one line up
X<C_DOWN> cursor one line down
X<C_LEFT> cursor one character left
X<C_RIGHT> cursor one character right
X<SC_UP> move window one page up
X<SC_DOWN> move window one page down
X<SC_LEFT> cursor one word back (like "b" command)
X<SC_RIGHT> cursor one word forward (like "w" command)
XCTRL-O execute one command and return to Insert mode
X-----------------------------------------------------------------------
X
XThe CTRL-O command has one side effect: If the cursor was beyond the end of
Xthe line it will be put on the last character in the line.
XThe shifted cursor keys are not available on all terminals.
X
XWhen the 'whichwrap' option is set appropriately, the <C_LEFT> and <C_RIGHT>
Xkeys on the first/last character in the line make the cursor wrap to the
Xprevious/next line.
X
X
X4.3.3 'textwidth' and 'wrapmargin' option
X
XThe 'textwidth' option can be used to automatically break a line before it
Xgets too long. Set the 'textwidth' option to the desired maximum line
Xlength. If you then type more characters (not spaces or tabs), the
Xlast word will be put on a new line (unless it is the only word on the
Xline). If you set 'textwidth' to 0, this feature is disabled.
X
XThe 'wrapmargin' option does almost the same. The difference is that
X'textwidth' has a fixed width while 'wrapmargin' depends on the width of the
Xscreen. When using 'wrapmargin' this is equal to using 'textwidth' with a
Xvalue equal to (columns - 'wrapmargin'), where columns is the width of the
Xscreen.
X
XWhen 'textwidth' and 'wrapmargin' are both set, 'textwidth' is used.
X
XThe line is only broken automatically when using insert mode, or when
Xappending to a line. When in replace mode and the line length is not
Xchanged, the line will not be broken.
X
XIf you want to format a block of text you can use the "Q" operator. Type "Q"
Xand a movement command to move the cursor to the end of the block. In many
Xcases the command "Q}" will do what you want (format until the end of
Xparagraph). Or you can use visual mode: hit "v", move to the end of the
Xblock and hit "Q".
X
X
X4.3.4 'expandtab' and 'smarttab' options
X
XIf the 'expandtab' option is set, spaces will be used to fill the amount of
Xwhitespace of the tab. If you want to enter a real <TAB> type CTRL-V first.
XThe 'expandtab' option is default off. Note that in Replace mode a single
Xcharacter is replaced by several spaces. The result of this is that the
Xnumber of characters in the line increases. Backspacing will delete one
Xspace at a time. The original text will be put back in a place where you
Xwould not expect it. {not in Vi}
X
XWhen the 'smarttab' option is set a TAB in front of a line inserts
X'shiftwidth' positions, 'tabstop' in other places. This means that often
Xspaces instead of a TAB character is inserted. When not set a TAB always
Xinserts 'tabstop' positions, 'shiftwidth' is only used for ">>" and the like.


X{not in Vi}
X
X

X4.3.5 typing backwards
X
XIf the 'revins' (reverse insert) option is set, inserting happens backwards.
XThis can be used to type Hebrew. When inserting characters the cursor is not
Xmoved and the text moves rightwards. A <BS> deletes the character under the
Xcursor. CTRL-W and CTRL-U also work in the opposite direction. <BS>, CTRL-W
Xand CTRL-U do not stop at the start of insert or end of line, no matter how
Xthe 'backspace' option is set.
X
XIn Replace mode the cursor is moved leftwards. <BS> will restore the
Xcharacter right of the cursor.
X
XIn insert or Replace mode the 'revins' option can be toggled with CTRL-B.
X
XIf the 'showmode' option is set, "-- REVERSE INSERT --" or
X"-- REVERSE REPLACE --" will be shown in the status line.
X
X
X4.3.6 Replace mode
X
XIn Replace mode one character in the line is deleted for every character you
Xtype. If there is no character to delete (at the end of the line), the
Xtyped character is appended (as in Insert mode). Thus the number of
Xcharacters in a line stays the same until you get to the end of the line.
X
XBe careful with <TAB> characters. If you type a normal printing character in
Xits place, the number of characters is still the same, but the number of
Xcolumns will become smaller.
X
XIf you delete characters in Replace mode (with <BS>, <DEL>, CTRL-W or
XCTRL-U), you really delete your changes. The characters that were replaced
Xare restored. If you had typed past the existing text, the characters you
Xadded are deleted.
X All this only works in the current line. If you have started a new line
X(replaced a character with a <CR>) Vim no longer remembers what happened in
Xthe previous line. If you backspace over the newline (only possible if the
X'backspace' option is non-zero), the two lines will be joined again, but
Xtyping further backspaces will not restore the original text. Only the
Xcursor is moved.
X If the 'expandtab' option is set, a <TAB> will replace one character
Xwith several spaces. When backspacing over these spaces, the original text
Xwill appear in a position where you would not expect it.
X
X
X4.3.7 Keyword completion
X
XIn insert and replace mode the keys CTRL-N and CTRL-P can be used to
Xcomplete the keyword that is in front of the cursor. This is useful if you
Xare writing a program that has complicated variable names, and you want to
Xcopy a name from the text before of after the cursor.
X
XIf there is an identifier in front of the cursor (a name made out of
Xalphanumeric characters and <_>) it is used as the search pattern, with "\<"
Xprepended (meaning: start of a word). Otherwise "\<[a-zA-Z_]" is used as
Xsearch pattern (start of any identifier).
X
XWith CTRL-N (next) the search goes forward, with CTRL-P (previous) the
Xsearch goes backward. The first time the search starts where the cursor is.
XThe next times the search starts at the last found position. If you type any
Xother character than CTRL-P or CTRL-N the current text is accepted and the
Xsearch pattern is forgotten.
X
XIf the search found a match, it is inserted at the cursor position. Any
Xprevious match is replaced. If no match was found, Vim will beep.
X
XIf there is not a valid identifier character before the cursor, any
Xidentifier is matched.
X eg. to get:
X printf("(%g, %g, %g)", vector[0], vector[1], vector[2]);
X just type:
X printf("(%g, %g, %g)", vector[0], ^P[1], ^P[2]);
X
XMultiple repeats of the same completion are skipped.
X
XIf there is only one completion found, then a second CTRL-P or CTRL-N will
Xgive the message 'No other matches'.
X
XIf the only match in the file is an exact match, where no extra characters
Xwould be typed, then the message 'Exact match only' is given (this is also
Xuseful for checking that you typed the symbol correctly).
X
XThe mode (--INSERT--) is shown, unless there is another more important
Xmessage (eg Pattern not found). This other message will stay until another
Xkey is hit, and then the mode is shown again.
X
XOnly matches where something extra will be added are used.
X eg. to get:
X printf("name = %s\n", name);
X just type:
X printf("name = %s\n", n^P);
XThe 'n' in '\n' is skipped.
X
X
X4.4 Command_line mode
X
XCommand_line mode is used to enter Ex commands <:>, search patterns </><?>
Xand filter commands <!>.
X
X
X4.4.1 Command line editing
X
XNormal characters are inserted in front of the cursor position. You can move
Xaround in the command line with the left and right cursor keys. {Vi: can
Xonly alter the last character in the line}
X
XThe command lines that you enter are remembered in a history table. You can
Xrecall them with the up and down cursor keys. Use the 'history' option to
Xset the number of lines that are remembered (default 20).
X
XThere is an automatic completion of names on the command line, see 4.4.2.
X
XCTRL-V Insert next non-digit literally. Up to three digits form the
X decimal value of a single byte. The non-digit and the three
X digits are not considered for mapping. This works the same
X way as in Insert mode (see above).
X<C_LEFT> cursor left
X<C_RIGHT> cursor right
X<SC_LEFT> cursor one word left
X<SC_RIGHT> cursor one word right
XCTRL-B cursor to begin of command line
XCTRL-E cursor to end of command line
X
X<BS> delete the character in front of the cursor
X<DEL> delete the character under the cursor (at end of line:
X character in front of the cursor)
XCTRL-W delete the word in front of the cursor
XCTRL-U remove all characters
X
X Note: if the command line becomes empty with one of the
X delete commands, command line mode is quit.
X
X{char1} <BS> {char2} or
XCTRL-K {char1} {char2}
X enter digraph (see 4.7). {not in Vi}
X
X<CR> or <LF> start entered command
X<ESC> when typed: quit command line without executing
X in macros: start entered command
XCTRL-C quit command line without executing
X
X<C_UP> recall older command line from history
X<C_DOWN> recall more recent command line from history
X
X<SC_UP> recall older command line from history, which begin matches
X the current command line (see below).
X<SC_DOWN> recall more recent command line from history, which begin
X matches the current command line (see below).
X
XCTRL-D command line completion (see 4.4.2)
X'wildchar' option
X command line completion (see 4.4.2)
XCTRL-N command line completion (see 4.4.2)
XCTRL-P command line completion (see 4.4.2)
XCTRL-A command line completion (see 4.4.2)
XCTRL-L command line completion (see 4.4.2)
X
XThe <SC_UP> and <SC_DOWN> keys take the current command line as search
Xstring. The beginning of the next/previous command lines are compared against
Xthis string. The fist line that matches is the new command line. When typing
Xthese two keys repeatedly, the same string is used again. For example this
Xcan be used to find the previous substitute command: Type ":s" and then
X<SC_UP>. The same could be done by typing <C_UP> a number of times until the
Xdesired command line is shown. (Note: the shifted arrow keys do not work on
Xall terminals)
X
X
X4.4.2 Command line completion
X
XWhen editing the command line a few commands can be used to complete the
Xword before the cursor. This is available for:
X
X- Command names, at the start of the command line. Works always.
X- tags, only after the ":tag" command.
X- file names, only after a command that accepts a file name or a setting for
X an option that can be set to a file name. This is called file name
X completion.
X- options, only after the ":set" command.
X
XThese are the commands that can be used:
X
XCTRL-D List names that match the pattern in front of the cursor.
X When showing file names, directories are highlighted (see
X 'highlight' option)
X'wildchar' option
X A match is done on the pattern in front of the cursor. The
X match, or if there are several, the first match, is inserted
X in place of the pattern. (Note: does not work inside a
X macro, because TAB or ESC is mostly used as 'wildchar', and
X these have a special meaning in some macros)
X When typed again, and there were multiple matches, the next
X match is inserted. After the last match the first is used
X again (wrap around).
XCTRL-N After using 'wildchar' which got multiple matches: go to next
X match. Otherwise: Recall more recent command line from history.
XCTRL-P After using 'wildchar' which got multiple matches: go to
X previous match. Otherwise: Recall older command line from
X history.
XCTRL-A All names that match the pattern in front of the cursor are
X inserted.
XCTRL-L A match is done on the pattern in front of the cursor. If
X there is one match, it is inserted in place of the pattern.
X If there are multiple matches the longest common part is
X inserted in place of the pattern.
X
XThe 'wildchar' option defaults to <TAB> (CTRL-E when compiled with
XCOMPATIBLE; in a previous version <ESC> was used). In the pattern standard
Xwildcards <*> and <?> are accepted. <*> matches any string, <?> matches
Xexactly one character.
X
XFor filename completion you can use the 'suffixes' option to set a priority
Xbetween files with almost the same name. If there are multiple matches,
Xthose files with an extension that is in the 'suffixes' option are ignored.
XThe default is ".bak.o.h.info.swp", which means that files with the
Xextensions ".bak", ".o", ".h", ".info" and ".swp" are sometimes ignored. It
Xis impossible to ignore suffixes with two dots. Examples:
X
Xpattern: files: match:
Xtest* test.c test.h test.o test.c
Xtest* test.h test.o test.h and test.o
Xtest* test.i test.h test.c test.i and test.c
X
XIf there is more than one matching file (after ignoring the ones matching
Xthe 'suffixes' option) the first file name is inserted. You can see that
Xthere is only one match when you type 'wildchar' twice and the completed
Xmatch stays the same. You can get to the other matches by entering
X'wildchar', CTRL-N or CTRL-P. All files are included, also the ones with
Xextensions matching the 'suffixes' option.
X
X
X4.4.3 Ex command lines
X
XThe Ex commands have a few specialties:
X
X<"> at the start of a line causes the whole line to be ignored. <">
Xafter a command causes the rest of the line to be ignored. This can be used
Xto add comments. Example:
X :set ai "set 'autoindent' option
XIt is not possible to add a comment to a shell command ":!cmd" or to the
X":map" command and friends, because they see the <"> as part of their
Xargument.
X
X<|> can be used to separate commands, so you can give multiple commands in
Xone line. The commands ":global", "vglobal" and ":!" see the <|> as their
Xargument, and can therefore not be followed by another command. If you want
X<|> to be included in a command, precede it with <\>. Note that this is
Xconfusing (inherited from vi). If you give a command with ":!" you don't
Xhave to use a backslash, with ":r !" you have to. And with ":g" the <|> is
Xincluded in the command, with ":s" it is not. Examples:
X :!ls | wc view the output of two commands
X :r !ls \| wc insert the same output in the text
X :%g/foo/p|> moves all matching lines one shiftwidth
X :%s/foo/bar/|> moves one line one shiftwidth
XYou can also use <LF> to separate commands in the same way as with <|>. But
Xusing <|> is the preferred method.
X
XWhen the character <%> or <#> is used where a filename is expected, they are
Xexpanded to the current and alternate filename (see the chapter "editing
Xfiles").
X
XEmbedded spaces in filenames are allowed if one filename is expected as
Xargument. Trailing spaces will be ignored, unless escaped with a backslash
Xor CTRL-V. Note that the ":next" command uses spaces to separate file names.
XEscape the spaces to include them in a file name. Example:
X :next foo\ bar goes\ to school\
Xstarts editing the three files "foo bar", "goes to" and "school ".
X
XWhen you want to use the special characters <"> or <|> in a command, or want
Xto use <%> or <#> in a filename, precede them with a backslash. The backslash
Xis not required in a range and in the ":substitute" command.
X
X
X4.4.4 Ex command line ranges
X
XSome Ex commands accept a line range in front of them. This is noted as
X[range]. It consists of one or more line specifiers, separated with <,> or
X<;>. When separated with <;> the cursor position will be set to that line
Xbefore interpreting the next line specifier. The default line specifier for
Xmost commands is the cursor position, but the commands ":write" and
X":global" have the whole file (1,$) as default. If more line specifiers are
Xgiven than required for the command, the first one(s) will be ignored.
X
XLine numbers may be specified with:
X {number} an absolute line number
X . the current line
X $ the last line in the file
X % equal to 1,$ (the entire file)
X 't position of mark t (lower case)
X /{pattern}[/] the next line where {pattern} matches
X ?{pattern}[?] the previous line where {pattern} matches
X
XEach may be followed (several times) by <+> or <-> and an optional number.
XThis number is added or subtracted from the preceding line number. If the
Xnumber is omitted, 1 is used.
X
XThe "/" and "?" may be preceded with another address. The search starts from
Xthere. The "/" and "?" after {pattern} are required to separate the pattern
Xfrom anything that follows.
X
XThe {number} must be between 0 and the number of lines in the file. A 0 is
Xinterpreted as a 1, except with the commands tag, pop and read.
X
XExamples:
X .+3 three lines below the cursor
X /that/+1 the line below the next line containing "that"
X .,$ from current line until end of file
X 0/that the first line containing "that"
X
XSome commands allow for a count after the command. This count is used as the
Xnumber of lines to be used, starting with the line given in the last line
Xspecifier (the default is the cursor line). The commands that accept a count
Xare the ones that use a range but do not have a file name argument (because
Xa file name can also be a number).
X
XExamples:
X :s/x/X/g 5 substitute <x> by <X> in the current line and four
X following lines
X :23d 4 delete lines 23, 24, 25 and 26
X
XA range should have the lower line number first. If this is not the case, Vim
Xwill ask you if it should swap the line numbers. This is not done within the
Xglobal command ":g".
X
XWhen giving a count before entering ":", this is translated into:
X :.,.+(count - 1)
XIn words: The 'count' lines at and after the cursor. Example: To delete
Xthree lines:
X 3:d<CR> is translated into: .,.+2d<CR>
X
X
X4.5 The window contents
X
XIn command and Insert/Replace mode the screen window will show the current
Xcontents of the buffer: What You See Is What You Get. {Vi: when changing
Xtext a <$> is placed on the last changed character; The window is not always
Xupdated on slow terminals} Lines longer than the window width will wrap,
Xunless the 'wrap' option is off (see below). The bottom lines in the window
Xmay start with one of these two characters:
X
X<@> The next line is too long to fit in the window.
X<~> Below the last line in the buffer.
X
XIf the bottom line is completely filled with <@>, the line that is at the
Xtop of the window is too long to fit in the window. If the cursor is on this
Xline you can't see what you are doing, because this part of the line is not
Xshown. However, the part of the line before the <@>s can be edited normally.
X{Vi: gives an "internal error" on lines that do not fit in the window}
X
XIf the 'wrap' option is off, long lines will not wrap. Only the part that
Xfits on the screen is shown. If the cursor is moved to a part of the line
Xthat is not shown, the screen is scrolled horizontally. The advantage of
Xthis method is that columns are shown as they are and lines that cannot fit
Xon the screen can be edited. The disadvantage is that you cannot see all the
Xcharacters of a line at once. The 'sidescroll' option can be set to the
Xminimal number of columns to scroll. {Vi: has no 'wrap' option}
X
XAll normal ASCII characters are displayed directly on the screen. The <TAB>
Xis replaced by the number of spaces that it represents. Other non-printing
Xcharacters are replaced by "^<char>", where <char> is the non-printing
Xcharacter with 64 added. Thus character 7 (bell) will be shown as "^G".
XCharacters between 127 and 160 are replaced by "~<char>", where <char> is
Xthe character with 64 subtracted. These characters occupy more than one
Xposition on the screen. The cursor can only be positioned on the first one.
X
XIf you set the 'number' option, all lines will be preceded with their
Xnumber.
X
XIf you set the 'list' option, <TAB> characters will not be shown as several
Xspaces, but as "^I". A <$> will be placed at the end of the line, so you can
Xfind trailing blanks.
X
XIn Command_line mode only the command line itself is shown correctly. The
Xdisplay of the buffer contents is updated as soon as you go back to Command
Xmode.
X
XSome commands hand over the window to external commands (e.g. ":shell" and
X"="). After these commands are finished the window may be clobbered with
Xoutput from the external command, so it needs to be redrawn. This is also
Xthe case if something is displayed on the status line that is longer than
Xthe width of the window. If you are expected to have a look at the screen
Xbefore it is redrawn, you get this message:
X
X Press RETURN or enter command to continue
X
XAfter you type a key the screen will be redrawn and Vim continues. If you
Xtype <CR>, <SP> or <LF> nothing else happens. If you type any other key, it
Xwill be interpreted as (the start of) a new command. {Vi: only <:> commands
Xare interpreted}
X
XThe last line of the window is used for status and other messages. The
Xstatus messages will only be used if an option is on:
X
Xstatus message option default unix default
Xcurrent mode 'showmode' on on
Xcommand characters 'showcmd' on off
Xcursor position 'ruler' off off
X
XThe current mode is "-- INSERT --" or "-- REPLACE --". The command
Xcharacters are those that you typed but were not used yet. {Vi: does not
Xshow the characters you typed or the cursor position}
X
XIf you have a slow terminal you can switch off the status messages to speed
Xup editing:
X :set nosc noru nosm
X
XIf there is an error, an error message will be shown for at least one second
X(in reverse video). {Vi: error messages may be overwritten with other
Xmessages before you have a chance to read them}
X
XSome commands show how many lines were affected. Above which threshold this
Xhappens can be controlled with the 'report' option (default 2).
X
XOn the Amiga Vim will run in a CLI window. The name Vim and the full name of
Xthe current filename will be shown in the title bar. When the window is
Xresized, Vim will automatically redraw the window. You may make the window as
Xsmall as you like, but if it gets too small not a single line will fit in it.
XMake it at least 40 characters wide to be able to read most messages on the
Xlast line.
X
XOn most Unix systems window resize works ok. {Vi: not ok}
X
X
X4.6 Abbreviations
X
XAbbreviations are used in insert mode, Replace mode and Command_line mode.
XIf you enter a word that is an abbreviation, it is replaced by the word it
Xstands for. This can be used to save typing for often used long words.
X
XThere are two types of abbreviations: The "full-id" type consists entirely
Xof id characters (letters, digits and <_> characters). This is the most
Xcommon abbreviation. The "non-id" type ends in an id character, but all the
Xother characters are not id characters. Examples of a "full-id" type are
X"foo" and "c_1". Examples of a "non-id" type are "#i" and "$/7". Examples of
Xstrings that will not be recognized as an abbreviation are "a.b", "a b" and
X"_$ar".
X
XThe "full-id" abbreviation is recognized if:
X- A character is typed that is not an id character. This can also be
X the <ESC> that ends insert mode or the <CR> that ends a command.
X- The characters in front of the cursor match the abbreviation.
X- In front of the match is a non-id character, or this is where the line or
X insertion starts. Exception: when the abbreviation is only one character,
X it is not recognized if there is a non-id character in front of it, other
X than a space or a TAB.
X
XThe "non-id" abbreviation is recognized if:
X- A character is typed that is not an id character. This can also be
X the <ESC> that ends insert mode or the <CR> that ends a command.
X- The characters in front of the cursor match the abbreviation.
X- In front of the match is an id character, or a space or a TAB, or this is
X where the line or insertion starts.
X
XExample: ":ab foo four old otters". Note that spaces in the <rhs> are
Xallowed and included in the replacement string. If you now insert the word
X"foo" with a space before and after it, it will be replaced by "four old
Xotters". If you would type "foobar" or "barfoo" nothing happens.
X
XTo avoid the abbreviation in insert mode type part of the abbreviation, exit
Xinsert mode with <ESC>, re-enter insert mode with "a" and type the rest. In
XCommand_line mode you can type CTRL-V twice somewhere in the abbreviation to
Xavoid it to be replaced. A CTRL-V in front of a normal character is mostly
Xignored otherwise.
X
XThere are no default abbreviations.
X
XAbbreviations are never recursive. You can use ":ab f f-o-o" without any
Xproblem. But abbreviations can be mapped. {some versions of vi support
Xrecursive abbreviations, for no apparent reason}
X
XAbbreviations are disabled if the 'paste' option is set.
X
X:ab[breviate] list all abbreviations. The character in the first
X column indicates the mode where the abbreviation is
X used: 'i' for insert mode, 'c' for Command_line
X mode, '!' for both.
X
X:ab[breviate] <lhs> list the abbreviations that start with <lhs>
X
X:ab[breviate] <lhs> <rhs>
X add abbreviation for <lhs> to <rhs>. If <lhs> already
X existed it is replaced with the new <rhs>. <rhs> may
X contain spaces.
X
X:una[bbreviate] <lhs> remove abbreviation for <lhs> from the list
X
X:norea[bbrev] [lhs] [rhs]
X same as ":ab", but no remapping for this <rhs> {not
X in Vi}
X
X:ca[bbrev] [lhs] [rhs] same as ":ab", but for Command_line mode only. {not
X in Vi}
X
X:cuna[bbrev] <lhs> same as ":una", but for Command_line mode only. {not
X in Vi}
X
X:cnorea[bbrev] [lhs] [rhs]
X same as ":ab", but for Command_line mode only and no
X remapping for this <rhs> {not in Vi}
X
X:ia[bbrev] [lhs] [rhs] same as ":ab", but for insert mode only. {not in Vi}
X
X:iuna[bbrev] <lhs> same as ":una", but for insert mode only. {not in
X Vi}
X
X:inorea[bbrev] [lhs] [rhs]
X same as ":ab", but for insert mode only and no
X remapping for this <rhs> {not in Vi}
X
X
X4.7 Digraphs
X
X:dig[raphs] show currently defined digraphs. {not in Vi}
X
X:dig[raphs] {char1}{char2} {number} ...
X Add digraph {char1}{char2} to the list. {number} is
X the decimal representation of the character.
X
XDigraphs are used to enter characters that normally cannot be entered by
Xan ordinary keyboard. These are mostly accented characters which have the
Xeighth bit set. The digraphs are easier to remember than the decimal number
Xthat can be entered with CTRL-V (see above).
X
XVim must have been compiled with the 'digraphs' option enabled. If not, the
X":digraph" command will display an error message.
X
XThere are two methods to enter digraphs:
X CTRL-K {char1} {char2} or
X {char1} <BS> {char2}
XThe first is always available. The second only when the 'digraph' option is
Xset.
X
XOnce you have entered the digraph the character is treated like a normal
Xcharacter, taking up only one character in the file and on the screen.
XExample:
X <|> <BS> <|> will enter the double <|> character (166)
X <a> <BS> <^> will enter an <a> with a hat (226)
X CTRL-K <-> <-> will enter a minus sign (173)
X
XThe default digraphs are listed in the file digraph.doc. They are meant for
Xthe Amiga character set, which is some international standard. With another
Xcharacter set they may be illogical.
X
XFor CTRL-K there is one general digraph: CTRL-K <SPACE> {char} will enter
X{char} with the highest bit set. This can be used to enter meta-characters.
X
XThe <ESC> character cannot be part of a digraph. When hitting <ESC> entering
Xthe digraph is aborted and insert mode too.
X
XIf you accidently typed an <a> that should be an <e>, you will type <a> <BS>
X<e>. But that is a digraph, so you will not get what you want. To avoid this,
Xuse <DEL> instead of <BS>. Or don't set the 'digraph' option and use CTRL-K
Xto enter digraphs.
X
X


X 5. Editing files
X

X5.1 Introduction
X
XEditing a file with Vim means:
X
X1. reading the file into the internal buffer
X2. changing the buffer with editor commands
X3. writing the buffer into a file
X
XAs long as you don't write the buffer, the original file remains unchanged.
XIf you start editing a file (read a file into the buffer), the file name is
Xremembered as the "current filename".
X
XIf there already was a current filename, then that one becomes the alternate
Xfile name. All filenames are remembered in the file list. When you enter a
Xfilename, for editing (e.g. with ":e filename") or writing (e.g. with (:w
END_OF_FILE
if test 52085 -ne `wc -c <'vim/doc/reference.doc.A'`; then
echo shar: \"'vim/doc/reference.doc.A'\" unpacked with wrong size!
elif test -f 'vim/doc/reference.doc.B' && test -f 'vim/doc/reference.doc.C' && test -f 'vim/doc/reference.doc.D'; then


echo shar: Combining \"'vim/doc/reference.doc'\" \(210836 characters\)
cat 'vim/doc/reference.doc.A' 'vim/doc/reference.doc.B' 'vim/doc/reference.doc.C' 'vim/doc/reference.doc.D' > 'vim/doc/reference.doc'
if test 210836 -ne `wc -c <'vim/doc/reference.doc'`; then
echo shar: \"'vim/doc/reference.doc'\" combined with wrong size!
else
rm vim/doc/reference.doc.A vim/doc/reference.doc.B vim/doc/reference.doc.C vim/doc/reference.doc.D
fi
fi

# end of 'vim/doc/reference.doc.A'
fi
if test -f 'vim/src/archie.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/archie.c'\"
else
echo shar: Extracting \"'vim/src/archie.c'\" \(13434 characters\)
sed "s/^X//" >'vim/src/archie.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X *
X * VIM - Vi IMproved

X *
X * Code Contributions By: Bram Moolenaar mo...@oce.nl
X * Tim Thompson twitch!tjt
X * Tony Andrews onecom!wldrdg!tony
X * G. R. (Fred) Walter watmath!watcgl!grwalter
X */
X/*
X * archie.c -- RISC OS + UnixLib specific code.
X *
X * A lot of this file was written by Juergen Weigert.
X *
X * It was then hacked to pieces by Alun Jones to work on the Acorn
X * Archimedes!


X */
X
X#include "vim.h"
X#include "globals.h"

X#include "param.h"
X#include "proto.h"
X
X#include <fcntl.h>
X#include <time.h>
X#include <unistd.h>
X#include <sys/types.h>
X#include <sys/os.h>
X#include <signal.h>
X
X#include <termio.h>
X
Xstatic int Read __ARGS((char *, long));
Xstatic int WaitForChar __ARGS((int));
Xstatic int RealWaitForChar __ARGS((int));
Xstatic void fill_inbuf __ARGS((void));
X
Xstatic int do_resize = FALSE;
X
X/* I'm sure this should be defined in UnixLib, but it ain't!
X */
Xshort ospeed;
X
X void
Xmch_write(s, len)
X char *s;
X int len;
X{
X int i;
X for (i=0; i<len; i++)
X {
X os_vdu(s[i]);
X }
X}
X
X/*
X * GetChars(): low level input funcion.
X * Get a characters from the keyboard.
X * If time == 0 do not wait for characters.
X * If time == n wait a short time for characters.
X * If time == -1 wait forever for characters.
X */
X int
XGetChars(buf, maxlen, time)
X char *buf;
X int maxlen;
X int time;
X{
X if (time >= 0)
X {
X if (WaitForChar(time) == 0) /* no character available */
X return 0;
X }
X else /* time == -1 */
X {
X /*
X * If there is no character available within 2 seconds (default)
X * write the autoscript file to disk
X */
X if (WaitForChar((int)p_ut) == 0)
X updatescript(0);
X }
X
X WaitForChar(-1);
X return Read(buf, (long)maxlen);
X}
X
X void
Xvim_delay()
X{
X clock_t now;
X
X now = clock();
X while (clock() < now + CLOCKS_PER_SEC/2);
X}
X
X/*
X * No job control. Fake it by starting a new shell.
X */
X void
Xmch_suspend()
X{
X outstr("new shell started\n");
X call_shell(NULL, 0, 1);
X}
X
X void
Xmch_windinit()
X{
X Columns = 80;
X Rows = 24;
X
X flushbuf();
X
X mch_get_winsize();
X}
X
X/*
X * Check_win checks whether we have an interactive window.
X */
X
X void
Xcheck_win(argc, argv)
X int argc;
X char **argv;
X{
X if (!isatty(0) || !isatty(1))
X {
X fprintf(stderr, "VIM: no controlling terminal\n");
X exit(2);
X }
X}
X
X/*
X * fname_case(): Set the case of the filename, if it already exists.
X * This will cause the filename to remain exactly the same.
X */
X void
Xfname_case(name)
X char *name;
X{
X}
X
X void
Xsettitle(str)
X char *str;
X{
X}
X
X void
Xresettitle()
X{
X}
X
X/*
X * Get name of current directory into buffer 'buf' of length 'len' bytes.
X * Return non-zero for success.
X */
X int
Xdirname(buf, len)
X char *buf;
X int len;
X{
X extern int errno;
X extern char *sys_errlist[];
X
X if (getcwd(buf,len) == NULL)
X {
X strcpy(buf, sys_errlist[errno]);
X return 0;
X }
X return 1;
X}
X
X/*
X * get absolute filename into buffer 'buf' of length 'len' bytes
X */
X int
XFullName(fname, buf, len)
X char *fname, *buf;
X int len;
X{
X int l;
X char olddir[MAXPATHL];
X char *p;
X int c;
X int retval = 1;
X
X if (fname == NULL) /* always fail */
X return 0;
X
X *buf = 0;
X if (*fname != '/')
X {
X /*
X * If the file name has a path, change to that directory for a moment,
X * and then do the getwd() (and get back to where we were).
X * This will get the correct path name with "../" things.
X */
X if ((p = strrchr(fname, '/')) != NULL)
X {
X if (getcwd(olddir, MAXPATHL) == NULL)
X {
X p = NULL; /* can't get current dir: don't chdir */
X retval = 0;
X }
X else
X {
X c = *p;
X *p = NUL;
X chdir("\\"); /* Try to maintain PSD */
X if (chdir(fname))
X retval = 0;
X else
X fname = p + 1;
X *p = c;
X }
X }
X if (getcwd(buf, len) == NULL)
X {
X retval = 0;
X *buf = NUL;
X }
X l = strlen(buf);
X if (l && buf[l - 1] != '/')
X strcat(buf, "/");
X if (p)
X {
X chdir("\\"); /* Maintain PSD */
X chdir(olddir);
X }
X }
X strcat(buf, fname);
X return retval;
X}
X
X/*
X * get file permissions for 'name'
X */
X long
Xgetperm(name)
X char *name;
X{
X struct stat statb;
X
X if (stat(name, &statb))
X return -1;
X return statb.st_mode;
X}
X
X/*
X * set file permission for 'name' to 'perm'
X */
X int
Xsetperm(name, perm)
X char *name;
X int perm;
X{
X return chmod(name, perm);
X}
X
X/*
X * check if "name" is a directory
X */
X int
Xisdir(name)
X char *name;
X{
X struct stat statb;
X
X if (stat(name, &statb))
X return -1;
X return (statb.st_mode & S_IFMT) == S_IFDIR;
X}
X
X void
Xmch_windexit(r)
X int r;
X{
X settmode(0);
X stoptermcap();
X flushbuf();
X stopscript(); /* remove autoscript file */
X exit(r);
X}
X
X void
Xmch_settmode(raw)
X int raw;
X{
X static int old225, old226, old4;
X int retvals[3];
X static struct termio told;
X struct termio tnew;
X
X if (raw)
X {
X /* Make arrow keys act as function keys.
X */
X os_byte(4, 2, 0, retvals);
X old4 = retvals[1];
X /* Now make function keys return NULL followed by a character.
X * Remember the old value for resetting.
X */
X os_byte(225, 0xC0, 0, retvals);
X old225 = retvals[1];
X os_byte(226, 0xD0, 0, retvals);
X old226 = retvals[1];
X
X ioctl(0, TCGETA, &told);
X tnew = told;
X tnew.c_iflag &= ~(ICRNL | IXON); /* ICRNL enables typing ^V^M */
X /* IXON enables typing ^S/^Q */
X tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE);
X tnew.c_cc[VMIN] = 1; /* return after 1 char */
X tnew.c_cc[VTIME] = 0; /* don't wait */
X ioctl(0, TCSETA, &tnew);
X }
X else
X {
X os_byte(4, old4, 0, retvals);
X os_byte(225, old225, 0, retvals);
X os_byte(226, old226, 0, retvals);
X ioctl(0, TCSETA, &told);
X }
X}
X
X/*
X * Try to get the current window size:
X * 1. with an ioctl(), most accurate method
X * 2. from the environment variables LINES and COLUMNS
X * 3. from the termcap
X * 4. keep using the old values
X */
X int
Xmch_get_winsize()
X{
X int old_Rows = Rows;
X int old_Columns = Columns;
X char *p;
X
X Columns = 0;
X Rows = 0;
X
X/*
X * 1. try using an ioctl. It is the most accurate method.
X */
X {
X struct winsize ws;
X
X if (ioctl(0, TIOCGWINSZ, &ws) == 0)
X {
X Columns = ws.ws_col;
X Rows = ws.ws_row;
X }
X }
X
X/*
X * 2. get size from environment
X */
X if (Columns == 0 || Rows == 0)
X {
X if ((p = (char *)getenv("LINES")))
X Rows = atoi(p);
X if ((p = (char *)getenv("COLUMNS")))
X Columns = atoi(p);
X }
X
X/*
X * 3. try reading the termcap
X */
X if (Columns == 0 || Rows == 0)
X {
X extern void getlinecol();
X
X getlinecol(); /* get "co" and "li" entries from termcap */
X }
X
X/*
X * 4. If everything fails, use the old values
X */
X if (Columns <= 0 || Rows <= 0)
X {
X Columns = old_Columns;
X Rows = old_Rows;
X return 1;
X }
X debug2("mch_get_winsize: %dx%d\n", (int)Columns, (int)Rows);
X
X Rows_max = Rows; /* remember physical max height */
X
X check_winsize();
X script_winsize();
X
X/* if size changed: screenalloc will allocate new screen buffers */
X return (0);
X}
X
X void
Xmch_set_winsize()
X{
X /* should try to set the window size to Rows and Columns */
X}
X
X int
Xcall_shell(cmd, dummy, cooked)
X char *cmd;
X int dummy;
X int cooked;
X{
X int x;
X char newcmd[1024];
X
X flushbuf();
X
X if (cooked)
X settmode(0); /* set to cooked mode */
X
X if (cmd == NULL)
X x = system(p_sh);
X else
X {
X sprintf(newcmd, "*%s", cmd);
X x = system(newcmd);
X }
X if (x == 127)
X {
X emsg("Cannot execute shell sh");
X outchar('\n');
X }
X else if (x)
X {
X smsg("%d returned", x);
X outchar('\n');
X }
X
X if (cooked)
X settmode(1); /* set to raw mode */
X return x;
X
X}
X
X/*
X * The input characters are buffered to be able to check for a CTRL-C.
X * This should be done with signals, but I don't know how to do that in
X * a portable way for a tty in RAW mode.
X */
X
X#define INBUFLEN 50
Xstatic unsigned char inbuf[INBUFLEN]; /* internal typeahead buffer */
Xstatic int inbufcount = 0; /* number of chars in inbuf[] */
X
X static int
XRead(buf, maxlen)
X char *buf;
X long maxlen;
X{
X if (inbufcount == 0) /* if the buffer is empty, fill it */
X fill_inbuf();
X if (maxlen > inbufcount)
X maxlen = inbufcount;
X memmove(buf, inbuf, maxlen);
X inbufcount -= maxlen;
X if (inbufcount)
X memmove(inbuf, inbuf + maxlen, inbufcount);
X return (int)maxlen;
X}
X
X void
Xbreakcheck()
X{
X/*
X * check for CTRL-C typed by reading all available characters
X */
X if (RealWaitForChar(0)) /* if characters available */
X fill_inbuf();
X}
X
X static void
Xfill_inbuf()
X{
X int len;
X
X if (inbufcount >= INBUFLEN) /* buffer full */
X return;
X
X for (len=0; len < INBUFLEN-inbufcount; len++)
X {
X int key;
X
X key = os_inkey(0);
X if (key==-1)
X {
X break;
X }
X inbuf[inbufcount+len] = key;
X }
X
X while (len-- > 0)
X {
X /*
X * if a CTRL-C was typed, remove it from the buffer and set got_int
X */
X if (inbuf[inbufcount] == 3)
X {
X /* remove everything typed before the CTRL-C */
X memmove(inbuf, inbuf + inbufcount, len + 1);
X inbufcount = 0;
X got_int = TRUE;
X }
X ++inbufcount;
X }
X}
X
X/*
X * Wait "ticks" until a character is available from the keyboard or from inbuf[]
X * ticks = -1 will block forever
X */
X
X static int
XWaitForChar(ticks)
X int ticks;
X{
X if (inbufcount) /* something in inbuf[] */
X return 1;
X return RealWaitForChar(ticks);
X}
X
X/*
X * Wait "ticks" until a character is available from the keyboard
X * ticks = -1 will block forever


X */
X static int

XRealWaitForChar(ticks)
X int ticks;
X{
X int key;
X
X if (ticks == -1)
X {
X key = os_get();
X }
X else
X {
X key = os_inkey(ticks/10);
X }
Xdebug3("RWFC(%d) got %d (%c)\n", ticks, key, key);
X
X if (key != -1)
X {
X /* Unfortunately the key has now been taken from the
X * buffer, so we need to put it in outselves. It's a
X * shame, but the other way I can think of involves a
X * keyboard scan, and this would return for SHIFT, etc.
X */
X if (inbufcount < INBUFLEN)
X {
X inbuf[inbufcount++] = key;
X }
X }
X return (key != -1);
X}
X
X/*
X * ExpandWildCard() - this code does wild-card pattern matching using the shell
X *
X * Mool: return 0 for success, 1 for error (you may loose some memory) and
X * put an error message in *file.
X *
X * num_pat is number of input patterns
X * pat is array of pointers to input patterns
X * num_file is pointer to number of matched file names
X * file is pointer to array of pointers to matched file names
X * On Unix we do not check for files only yet
X * list_notfound is ignored
X */
X
Xextern char *mktemp __ARGS((char *));
X#ifndef SEEK_SET
X# define SEEK_SET 0
X#endif
X#ifndef SEEK_END
X# define SEEK_END 2
X#endif
X
X int
XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
X int num_pat;
X char **pat;
X int *num_file;
X char ***file;
X int files_only;
X int list_notfound;
X{
X char tmpname[TMPNAMELEN];
X char *command;
X int i;
X int dir;
X size_t len;
X FILE *fd;
X char *buffer;
X char *p;
X
X *num_file = 0; /* default: no files found */
X *file = (char **)"";
X
X /*
X * If there are no wildcards, just copy the names to allocated memory.
X * Saves a lot of time, because we don't have to run glob.
X */
X if (!have_wildcard(num_pat, pat))
X {
X *file = (char **)alloc(num_pat * sizeof(char *));
X if (*file == NULL)
X {
X *file = (char **)"";
X return 1;
X }
X for (i = 0; i < num_pat; i++)
X (*file)[i] = strsave(pat[i]);
X *num_file = num_pat;
X return 0;
X }
X
X/*
X * get a name for the temp file
X */
X strcpy(tmpname, TMPNAME2);
X if (*mktemp(tmpname) == NUL)
X {
X emsg(e_notmp);
X return 1;
X }
X
X len = TMPNAMELEN + 10;
X for (i = 0; i < num_pat; ++i) /* count the length of the patterns */
X len += strlen(pat[i]) + 1;
X command = (char *)alloc(len);
X if (command == NULL)
X return 1;
X strcpy(command, "glob >"); /* built the shell command */
X strcat(command, tmpname);
X for (i = 0; i < num_pat; ++i)
X {
X strcat(command, " ");
X strcat(command, pat[i]);
X }
X i = call_shell(command, 0, FALSE); /* execute it */
X free(command);
X if (i) /* call_shell failed */
X {
X remove(tmpname);
X sleep(1); /* give the user a chance to read error messages */
X must_redraw = CLEAR; /* probably messed up screen */
X return 1;
X }
X
X/*
X * read the names from the file into memory
X */
X fd = fopen(tmpname, "r");
X if (fd == NULL)
X {
X emsg(e_notopen);
X return 1;
X }
X
X fseek(fd, 0L, SEEK_END);
X len = ftell(fd); /* get size of temp file */
X fseek(fd, 0L, SEEK_SET);
X buffer = (char *)alloc(len + 1);
X if (buffer == NULL)
X {
X remove(tmpname);
X fclose(fd);
X return 1;
X }
X i = fread(buffer, 1, len, fd);
X fclose(fd);
X remove(tmpname);
X if (i != len)
X {
X emsg(e_notread);
X free(buffer);
X return 1;
X }
X
X buffer[len] = NUL; /* make sure the buffers ends in NUL */
X i = 0;
X for (p = buffer; p < buffer + len; ++p)
X if (*p == NUL) /* count entry */
X ++i;
X if (len)
X ++i; /* count last entry */
X
X *num_file = i;
X *file = (char **)alloc(sizeof(char *) * i);
X if (*file == NULL)
X {
X free(buffer);
X *file = (char **)"";
X return 1;
X }
X p = buffer;
X
X for (i = 0; i < *num_file; ++i)
X {
X (*file)[i] = p;
X while (*p && p < buffer + len) /* skip entry */
X ++p;
X ++p; /* skip NUL */
X }
X for (i = 0; i < *num_file; ++i)
X {
X dir = (isdir((*file)[i]) > 0);
X if (dir < 0) /* if file doesn't exist don't add '.' */
X dir = 0;
X p = alloc((unsigned)(strlen((*file)[i]) + 1 + dir));
X if (p)
X {
X strcpy(p, (*file)[i]);
X if (dir)
X strcat(p, ".");
X }
X (*file)[i] = p;
X }
X free(buffer);
X return 0;
X}
X
X void
XFreeWild(num, file)
X int num;
X char **file;
X{
X if (file == NULL || num == 0)
X return;
X while (num--)
X free(file[num]);
X free(file);
X}
X
X int
Xhas_wildcard(p)
X char *p;
X{
X return strpbrk(p, "*#") != NULL;
X}
X
X int
Xhave_wildcard(num, file)
X int num;
X char **file;
X{
X register int i;
X
X for (i = 0; i < num; i++)
X if (has_wildcard(file[i]))
X return 1;
X return 0;
X}
END_OF_FILE
if test 13434 -ne `wc -c <'vim/src/archie.c'`; then
echo shar: \"'vim/src/archie.c'\" unpacked with wrong size!
fi
# end of 'vim/src/archie.c'
fi
if test -f 'vim/src/archie.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/archie.h'\"
else
echo shar: Extracting \"'vim/src/archie.h'\" \(285 characters\)
sed "s/^X//" >'vim/src/archie.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Archimedes Machine-dependent things
X */
X
X/*
X * sorry, this file is missing
X */
END_OF_FILE
if test 285 -ne `wc -c <'vim/src/archie.h'`; then
echo shar: \"'vim/src/archie.h'\" unpacked with wrong size!
fi
# end of 'vim/src/archie.h'
fi
echo shar: End of archive 3 \(of 26\).
cp /dev/null ark3isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:29 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 23
Archive-name: vim/part04

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/reference.doc.B vim/src/termlib.c
# Wrapped by kent@sparky on Mon Aug 15 21:43:59 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 4 (of 26)."'
if test -f 'vim/doc/reference.doc.B' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/reference.doc.B'\"
else
echo shar: Extracting \"'vim/doc/reference.doc.B'\" \(50511 characters\)
sed "s/^X//" >'vim/doc/reference.doc.B' <<'END_OF_FILE'
Xfilename"), the filename is added to the list. You can use this list to
Xremember which files you edited and to quickly switch from one file to
Xanother with the CTRL-^ command (e.g. to copy text). First type the number
Xof the file and then hit CTRL-^. {Vi: only one alternate filename}
X
XIn Ex commands (the ones that start with a colon) <%> is replaced by the
Xcurrent filename and <#> is replaced by the alternate filename. The older
Xalternate filenames are "#1", "#2", etc. "#0" is the same as "#". If a
X"<" is appended to <%>, <#> or "#n" the extension of the file name is
Xremoved (everything after and including the last '.' in the file name).
X
X % current file name
X %< current file name without extension
X # alternate file name for current window
X #< idem, without extension
X #31 alternate file number 31
X #31< idem, without extension
X
XCTRL-G or
X:f[ile] Prints the current filename (as typed) and the
X cursor position. {vi does not include column number}
X
X{count}CTRL-G Prints the current filename with full path and the
X cursor position.
X
X:f[ile] {name} Sets the current filename to {name}.
X
X:buffers
X:files List all the currently known file names. See
X 'windows.doc'. {not in vi}
X
XVim will remember the full path name of a file name that you enter. In most
Xcases when the file name is displayed only the name you typed is shown, but
Xthe full path name is being used if you used the ":cd" command.
X
XIf the environment variable 'HOME' is set, and the file name starts with
Xthat string, it is often displayed with HOME replaced by "~". This was done
Xto keep file names short. When reading or writing files the full name is
Xstill used, the "~" is only used when displaying file names.
X
XWhen writing the buffer, the default is to use the current filename. Thus
Xwhen you give the "ZZ" or ":wq" command, the original file will be
Xoverwritten. If you do not want this, the buffer can be written into another
Xfile by giving a filename argument to the ":write" command. For example:
X
X vim testfile
X [change the buffer with editor commands]
X :w newfile
X :q
X
XThis will create a file "newfile", that is a modified copy of "testfile".
XThe file "testfile" will remain unchanged. Anyway, if the 'backup' option is
Xset, Vim renames the original file before it will be overwritten. You can
Xuse this file if you discover that you need the original file. See also the
X'patchmode' option. The name of the backup file is the same as the original
Xfile with ".bak" appended. Any <.> is replaced by <_> on MSDOS machines, when
XVim has detected that an MSDOS-like filesystem is being used (e.g. messydos or
Xcrossdos) and when the 'shortname' option is set.
X
XTechnical: On the Amiga you can use 30 characters for a file name. But on an
X MSDOS-compatible filesystem only 8 plus 3 characters are
X available. Vim tries to detect the type of filesystem when it is
X creating the .swp file. If an MSDOS-like filesystem is suspected,
X a flag is set that has the same effect as setting the 'shortname'
X option. This flag will be reset as soon as you start editing a
X new file. The flag will be used when making the filename for the
X ".swp" and ".bak" files for the current file. But when you are
X editing a file in a normal filesystem and write to an MSDOS-like
X filesystem the flag will not have been set. In that case the
X creation of the ".bak" file may fail and you will get an error
X message. Use the 'shortname' option in this case.
X
XWhen you started editing without giving a file name, "No File" is displayed in
Xmessages. If a ":write file" or ":read file" command is used, the file name
Xfor the current file is set to the file name in that command. This is useful
Xwhen starting Vim without an argument and then doing ":read file" to start
Xediting a file. Or when entering text in an empty buffer and then writing it
Xto a file. Because the file name was set without really starting to edit that
Xfile, you are protected from overwriting that file. This is done by setting
Xthe "notedited" flag. You can see if this flag is set with the CTRL-G or
X":file" command. It will include "[Not edited]" when the "notedited" flag is
Xset. When writing the buffer to the current file name (with ":w!"), the
X"notedited" flag is reset.
X
XVim remembers whether you have changed the buffer. You are protected from
Xlosing the changes you made. If you try to quit without writing, or want to
Xstart editing another file, this will be refused. In order to overrule this
Xprotection add a <!> to the command. The changes will then be lost. For
Xexample: ":q" will not work if the buffer was changed, but ":q!" will. To see
Xwhether the buffer was changed use the "CTRL-G" command. The message includes
Xthe string "[Modified]" if the buffer has been changed.
X
X
X5.2 Editing a file
X
X:e[dit] [+cmd] Edit the current file, unless changes have been made.
X
X:e[dit]! [+cmd] Edit the current file always. Discard any changes to
X the buffer.
X
X:e[dit] [+cmd] {file} Edit {file}, unless changes have been made.
X
X:e[dit]! [+cmd] {file} Edit {file} always. Discard any changes to the
X buffer.
X
X:e[dit] #[count] Edit the [count]th alternate filename (as shown by
X :files). This command does the same as [count] CTRL-^.
X
X:ex [+cmd] [file] Same as :edit. {Vi: go from visual to Ex mode}
X
X:vi[sual] [+cmd] [file] Same as :edit. {Vi: go from Ex to Visual mode}
X
X[count]CTRL-^ Edit [count]th alternate file (equivalent to ":e
X #[count]"). Without count this gets you to the
X previously edited file. This is a quick way to
X toggle between two (or more) files. If the
X 'autowrite' option is set and the buffer was
X changed, write it.
X
X]f
X[f
Xgf Edit the file whose name is under or after the
X cursor. Mnemonic: "goto file". This fails if the
X current file cannot be abandoned. {not in Vi}
X
X:cd On non-Unix systems: Print the current directory
X name. On Unix systems: Change the current directory
X to the home directory.
X
X:cd {path} Change the current directory to {path}. Does not
X change the meaning of an already entered file name,
X because its full path name is remembered.
X
X:chd[ir] [path] Same as :cd.
X
X:pwd Print the current directory name. {Vi: no pwd}
X
XThese commands are used to start editing a single file. This means that the
Xfile is read into the buffer and the current filename is set. You may use the
X":cd" command to get to another directory, so you will not have to type that
Xdirectory name in front of the filenames. One warning: After using ":cd" the
Xfull path name will be used for reading and writing files. On some networked
Xfile systems this may cause problems. The result of using the full path name
Xis that the file names currently in use will remain referring to the same
Xfile. Example: If you have a file a:test and a directory a:vim the commands
X":e test" ":cd vim" ":w" will overwrite the file a:test and not write
Xa:vim/test. But if you do ":w test" the file a:vim/test will be written,
Xbecause you gave a new file name and did not refer to a file name before the
X":cd".
X
XYou can use the ":e!" command if you messed up the buffer and want to start
Xall over again. The ":e" command is only useful if you have changed the
Xcurrent filename.
X
XThe [+cmd] can be used to position the cursor in the newly opened file:
X + Start at the last line.
X +{num} Start at line {num}.
X +/{pat} Start at first line containing {pat}. {pat} must not
X contain any spaces.
X +{command} Execute {command} after opening the new file.
X {command} is an Ex command. It must not contain
X spaces.
X
XWhen reading a file when the 'textmode' option is off (default for
Xnon-MSDOS) the <LF> character is interpreted as end-of-line. If 'textmode'
Xis on (default for MSDOS), <CR><LF> is also interpreted as end-of-line.
X
XWhen writing a file when the 'textmode' option is off a <LF> character is
Xused to separate lines. When the 'textmode' option is on <CR><LF> is used.
X
XYou can read a file with 'textmode' set and write it with 'textmode' reset.
XThis will replace all <CR><LF> pairs by <LF>. If you read a file with
X'textmode' reset and write with 'textmode' set, all <LF> characters will be
Xreplaced by <CR><LF>.
X
XIf you start editing a new file and the 'textauto' option is set, Vim will
Xtry to detect whether the lines in the file are separated by a single <LF>
X(as used on Unix and Amiga) or by a <CR><LF> pair (MSDOS). It reads up to
Xthe first <LF> and checks if there is a <CR> in front of it. If there is the
X'textmode' option is set, otherwise it is reset. If the 'textmode' option is
Xset on non-MSDOS systems the message "[textmode]" is shown to remind you
Xthat something unusual is happening. On MSDOS systems you get the message
X"[notextmode]" if the 'textmode' option is not set.
X
XBefore editing binary, executable or Vim script files you should set the
X'textmode' and 'textauto' options off. With 'textmode' on you risk that
Xsingle <LF> characters are unexpectedly replaced with <CR><LF>. A simple way
Xto do this is by starting Vim with the "-b" option.
X
X
X5.3 The argument list
X
XIf you give more than one filename when starting Vim, this list is
Xremembered as the argument list. Do not confuse this with the file list,
Xwhich you can see with the ":files" command. The argument list was already
Xpresent in vi, the file list is new in Vim. The file names in the argument
Xlist will also be present in the file list (unless they were deleted with
X":bdel").
X
XYou can use the argument list with the following commands:
X
X:ar[gs] Print the argument list, with the current file in
X square brackets.
X
X:[count]argu[ment] [count] [+cmd]
X Edit file [count] in the argument list, unless
X changes have been made and the 'autowrite' option is
X off. {Vi: no such command}
X
X:[count]argu[ment]! [count] [+cmd]
X Edit file [count] in the argument list, discard any
X changes to the current buffer. {Vi: no such command}
X
X:[count]n[ext] [+cmd] Edit [count] next file, unless changes have been
X made and the 'autowrite' option is off {Vi: no
X count}.
X
X:[count]n[ext]! [+cmd] Edit [count] next file, discard any changes to the
X buffer {Vi: no count}.
X
X:ar[gs] [+cmd] {filelist}
X:n[ext] [+cmd] {filelist}
X Define {filelist} as the new argument list and edit
X the first one, unless changes have been made and the
X 'autowrite' option is off.
X
X:ar[gs]! [+cmd] {filelist}
X:n[ext]! [+cmd] {filelist}
X Define {filelist} as the new argument list and edit
X the first one. Discard any changes to the buffer.
X
X:[count]N[ext] [count] [+cmd]
X Edit [count] previous file in argument list, unless
X changes have been made and the 'autowrite' option is
X off {Vi: no count}.
X
X:[count]N[ext]! [count] [+cmd]
X Edit [count] previous file in argument list. Discard
X any changes to the buffer {Vi: no count}.
X
X:[count]pre[vious] [count] [+cmd]
X Same as :Next {Vi: only in some versions}
X
X:rew[ind] [+cmd] Start editing the first file in the argument list,
X unless changes have been made and the 'autowrite'
X option is off.
X
X:rew[ind]! [+cmd] Start editing the first file in the argument list.
X Discard any changes to the buffer.
X
X:la[st] [+cmd] Start editing the last file in the argument list, unless
X changes have been made and the 'autowrite' option is
X off. {not in Vi}
X
X:la[st]! [+cmd] Start editing the last file in the argument list.
X Discard any changes to the buffer. {not in Vi}
X
X:[count]wn[ext] [+cmd] Write current file and start editing the [count]
X next file. {not in Vi}
X
X:[count]wn[ext] [+cmd] {file}
X Write current file to {file} and start editing the
X [count] next file, unless {file} already exists and
X the 'writeany' option is off. {not in Vi}
X
X:[count]wn[ext]! [+cmd] {file}
X Write current file to {file} and start editing the
X [count] next file. {not in Vi}
X
X:[count]wN[ext][!] [+cmd] [file]
X:[count]wp[revous][!] [+cmd] [file]
X Same as :wnext, but go to previous file instead of
X next. {not in Vi}
X
XThe [count] in the commands above defaults to one. For some commands it is
Xpossible to use two counts. The last one (rightmost one) is used.
X
XFor [+cmd] see 5.2.
X
XThe wildcards in the argument list are expanded and the filenames are sorted.
XThus you can use the command "vim *.c" to edit all the C files. From within
XVim the command ":n *.c" does the same.
X
XYou are protected from leaving Vim if you are not editing the last file in
Xthe argument list. This prevents you from forgetting that you were editing one
Xout of several files. To exit anyway try to exit twice. If there are changes
Xin the current buffer this will fail. You can exit anyway, and save any
Xchanges, with the ":wq!" command. To lose any changes use the ":q!" command.
X
X
X5.4 Writing and quitting
X
X:[range]w[rite][!] Write the specified lines to the current file.
X
X:[range]w[rite] {file} Write the specified lines to {file}, unless it
X already exists and the 'writeany' option is off.
X
X:[range]w[rite]! {file} Write the specified lines to {file}. Overwrite an
X existing file.
X
X:[range]w[rite][!] >> Append the specified lines to the current file.
X
X:[range]w[rite][!] >> {file}
X Append the specified lines to {file}. <!> forces the
X write even if file does not exist.
X
X:[range]w[rite] !{cmd} Execute {cmd} with [range] lines as standard input
X (note the space in front of the <!>).
X
XThe default [range] for the ":w" command is the whole buffer (1,$).
XIf a file name is give with ":w" it becomes the alternate file. This can be
Xused when the write fails and you want to try again later with ":w #".
X
X
X:q[uit] Quit, unless changes have been made or not editing
X the last file in the argument list.
X
X:q[uit]! Quit always, without writing.
X
X:cq Quit always, without writing, and return an error
X code. Used for Manx's QuickFix mode (see 5.5).
X
X:wq Write the current file. Exit if not editing the
X last file in the argument list.
X
X:wq! Write the current file and exit.
X
X:wq {file} Write to {file}. Exit if not editing the last
X file in the argument list.
X
X:wq! {file} Write to {file} and exit.
X
X:x[it][!] [file] Like ":wq", but write only when changes have been
X made.
X
X:exi[t][!] [file] Same as :xit.
X
XZZ Write current file, if modified, and exit (same as
X ":x").
X
XIf you write to an existing file (but do not append) while the 'backup' or
X'writebackup' option is on, a backup of the original file is made. On Unix
Xsystems the file is copied, on other systems the file is renamed. After the
Xfile has been successfully written and when the 'writebackup' option is on
Xand the 'backup' option is off, the backup file is deleted.
X
X'backup' 'writebackup' action
X off off no backup made
X off on backup made, deleted afterwards
X on off backup made, not deleted
X on on backup made, not deleted (default)
X
XOn Unix systems:
XWhen you write to an existing file, that file is truncated and then filled
Xwith the new text. This means that protection bits, owner and symbolic links
Xare unmodified. The backup file however, is a new file, owned by the user
Xwho edited the file. If it is not possible to create the backup file in the
Xsame directory as the original file, the directory given with the
X'backupdir' option is used (default: home directory).
X
XIf the creation of a backup file fails, the write is not done. If you want
Xto write anyway add a <!> to the command.
X
XIf the 'textmode' option is set <CR><LF> is used for end-of-line. This is
Xdefault for MSDOS. On other systems the message "[textmode]" is shown to
Xremind you that an usual end-of-line marker was used. If the 'textmode' is
Xnot set LF is used for end-of-line. On MSDOS the message "[notextmode]" is
Xshown. See also the 'textmode' and 'textauto' options.
X
X
X5.5 Using the QuickFix mode
X
XVim has a special mode to speedup the edit-compile-edit cycle. This is
Xinspired by the quickfix option of the Manx's Aztec C compiler on the Amiga.
XThe idea is to save the error messages from the compiler in a file and use
XVim to jump to the errors one by one. You can then examine each problem and
Xfix it, without having to remember all the error messages.
X
XIf you are using Manx's Aztec C compiler on the Amiga you should do the
Xfollowing:
X- Set the CCEDIT environment variable with the command
X mset "CCEDIT=vim -e"
X- Compile with the -qf option. If the compiler finds any errors, Vim is
X started and the cursor is positioned on the first error. The error message
X will be displayed on the last line. You can go to other errors with the
X commands mentioned below. You can fix the errors and write the file(s).
X- If you exit Vim normally the compiler will re-compile the same file. If you
X exit with the :cq command, the compiler will terminate. Do this if you
X cannot fix the error, or if another file needs to be compiled first.
X
XIf you are using another compiler you should save the error messages in a
Xfile and start Vim with "vim -e filename". An easy way to do this is with
Xthe ":make" command (see below). The 'errorformat' option should be set to
Xmatch the error messages from your compiler (see below).
X
XThe following commands can be used if you are in QuickFix mode:
X
X:cc [nr] Display error [nr]. If [nr] is omitted, the same
X error is displayed again. {not in Vi}
X
X:[count]cn Display the [count] next error in the list that
X includes a file name. If there are no file names at
X all, go the the [count] next error. {not in Vi}
X
X:[count]cp Display the [count] previous error in the list that
X includes a file name. If there are no file names at
X all, go the the [count] previous error. {not in Vi}
X
X:cq Quit Vim with an error code, so that the compiler
X will not compile the same file again. {not in Vi}
X
X:cf [errorfile] Read the error file and jump to the first error.
X This is done automatically when Vim is started with
X the -e option. You can use this command when you
X keep Vim running while compiling. If you give the
X name of the errorfile, the 'errorfile' option will
X be set to [errorfile] {not in Vi}
X
X:cl List all errors. {not in Vi}
X
X:make [arguments] 1. If the 'autowrite' option is set and the buffer
X was changed, write it.
X 2. Any existing 'errorfile' is deleted.
X 3. The program given with the 'makeprg' option is
X started (default "make") with the optional
X [arguments] and the output is saved in
X 'errorfile' (for Unix it is also echoed on the
X screen).
X 4. The 'errorfile' is then read and the first error
X is jumped to.
X 5. The 'errorfile' is deleted.


X {not in Vi}
X

XThe name of the file can be set with the 'errorfile' option. The default is
X"AztecC.Err" for the Amiga and "errors" for other systems. The format of the
Xfile from the Aztec compiler is:
X
X filename>linenumber:columnnumber:errortype:errornumber:errormessage
X
X filename name of the file in which the error was detected
X linenumber line number where the error was detected
X columnnumber column number where the error was detected
X errortype type of the error, normally a single <E> or <W>
X errornumber number of the error (for lookup in the manual)
X errormessage description of the error
X
XAnother compiler is likely to use a different format. You should set the
X'errorformat' option to a scanf-like string that describes the format. First
Xyou need to know how scanf works. Look in the documentation of your C
Xcompiler. Vim will understand eight conversion characters. Others are invalid.
X %f file name (finds a string)
X %l line number (finds a number)
X %c column number (finds a number)
X %t error type (finds a single character)
X %n error number (finds a number)
X %m error message (finds a string)
X %*<conv> any scanf non-assignable conversion
X %% the single <%> character
X
XExamples:
X"%f>%l:%c:%t:%n:%m" for the AztecC.Err file
X"%f:%l:\ %t%*[^0123456789]%n:\ %m" for Aztec C error messages
X"%f\ %l\ %t%*[^0123456789]%n:\ %m" for SAS C
X"\"%f\",%*[^0123456789]%l:\ %m" default for generic C compilers
X"%f:%l:%m" for GCC
X
XNote the backslash in front of a space and double quote. It is required for
Xthe :set command.
X
XThe "%f" and "%m" conversions have to detect the end of the string. They
Xshould be followed by a character that cannot be in the string. Everything
Xup to that character is included in the string. Be careful: "%f%l" will
Xinclude everything up to the first <%> in the file name. If the "%f" or "%m"
Xis at the end, everything up to the end of the line is included.
X
XIf a line is detected that does not completely match the 'errorformat', the
Xwhole line is put in the error message and the entry is marked "not valid"
XThese lines are skipped with the ":cn" and ":cp" commands (unless there is
Xno valid line at all). You can use ":cl" to display all the error messages.
X
XIf the error format does not contain a file name Vim cannot switch to the
Xcorrect file. You will have to do this by hand.
X
XIf you have a compiler that produces error messages that do not fit in the
Xformat string, you could write a program that translates the error messages
Xinto this format. You can use this program with the ":make" command by
Xchanging the 'makeprg' option. For example:
X ":set mp=make\ \\\|&\ error_filter".
XThe backslashes before the pipe character are required to avoid it to be
Xrecognized as a command separator. The backslash before each space is
Xrequired for the set command.
X
XThe ":make" command executes the command given with the 'makeprg' option.
XThis is done by passing the command to the shell given with the 'shell'
Xoption. This works almost like typing
X
X ":!{makeprg} [arguments] {shellpipe} {errorfile}".
X
X{makeprg} is the string given with the 'makeprg' option. Any command can be
Xused, not just "make". Characters <%> and <#> are expanded as usual on a
Xcommand line. You can use "#<" to insert the current filename without
Xextension, for example ":set makeprg=make\ #<.o".
X
X[arguments] is anything that is typed after ":make".
X{shellpipe} is the 'shellpipe' option.
X{errorfile} is the 'errorfile' option.
X
XThe 'shellpipe' option defaults to ">" for the Amiga and MSDOS. This means
Xthat the output of the compiler is saved in a file and not shown on the
Xscreen directly. For Unix "| tee" is used. The compiler output is shown on
Xthe screen and saved in a file the same time. Depending on the shell used
X"|& tee" or "2>&1| tee" is the default, so stderr output will be included.
X
XThere are some restrictions to the Quickfix mode on the Amiga. The
Xcompiler only writes the first 25 errors to the errorfile (Manx's
Xdocumentation does not say how to get more). If you want to find the others,
Xyou will have to fix a few errors and exit the editor. After recompiling,
Xup to 25 remaining errors will be found.
X
XOn the Amiga, if Vim was started from the compiler, the :sh and :! commands
Xwill not work, because Vim is then running in the same process as the
Xcompiler and these two commands may guru the machine then.
X
XIf you insert or delete lines, mostly the correct error location is still
Xfound because hidden marks are used (Manx's Z editor does not do this).
XSometimes, when the mark has been deleted for some reason, the message "line
Xchanged" is shown to warn you that the error location may not be correct. If
Xyou quit Vim and start again the marks are lost and the error locations may
Xnot be correct anymore.
X
X
X5.6 Editing binary files
X
XAlthough Vim was made to edit text files, it is possible to edit binary
Xfiles. The "-b" command line option (b for binary) sets some options for
Xediting binary files ('binary' on, 'textwidth' to 0, 'textmode' and
X'textauto' off, 'modelines' to 0, 'expandtab' off). Setting the 'binary'
Xoption has the same effect. Don't forget to do this before reading the file.
X
XThere are a few things to remember when editing binary files:
X- When editing executable files the number of characters must not change.
X Use only the "R" or "r" command to change text. Do not delete characters
X with "x" or by backspacing.
X- Set the 'textwidth' option to 0. Otherwise lines will unexpectedly be
X split in two.
X- When there are not many end-of-line characters, the lines will become very
X long. If you want to edit a line that does not fit on the screen reset the
X 'wrap' option. Horizontal scrolling is used then. If a line becomes too
X long (more than about 32767 characters on the Amiga, much more on 32-bit
X systems) you cannot edit that line. The line will be split when reading
X the file. It is also possible that you get an "out of memory" error when
X reading the file.
X- Make sure the 'textmode' and 'textauto' options are off before loading the
X file. In 'textmode' both <CR><LF> and <LF> are considered to end a line
X and when the file is written the <LF> will be replaced by <CR><LF>. The
X 'modelines' option should also be off, because there may be a string like
X ":vi:" in the file that would give unpredictable results.
X- <NUL> characters are shown on the screen as ^@. You can enter them with
X "CTRL-V CTRL-@" or "CTRL-V 000" {vi cannot handle <NUL> characters in the
X file}
X- To insert a <LF> character in the file split up a line. When writing the
X buffer to a file a <LF> will be written for the end of line.
X- Vim normally appends an end-of-line character at the end of the file if
X there is none. Setting the 'binary' option prevents this. If you want to
X add the final end-of-line, set the 'endofline' option. You can also read the
X value of this option to see if there was an end-of-line character for the
X last line (you cannot see this in the text).
X
X


X 6. Cursor motions
X

XThese commands move the cursor position. If the new position is off of the
Xscreen, the screen is scrolled to show the cursor (see also 'scrolljump'
Xoption).
X
XThe motion commands can be used after other commands, called operators, to
Xhave the command operate on the text that was moved over. That is the text
Xbetween the cursor position before and after the motion. If the motion
Xincludes a count and the operator also had a count, the two counts are
Xmultiplied. For example: "2d3w" deletes six words.
X The operator either affects whole lines, or the characters between
Xthe start and end position. Generally, motions that move between lines
Xaffect lines (are linewise), and motions that move within a line affect
Xcharacters. However, there are some exceptions.
X A character motion is either inclusive or exclusive. When inclusive,
Xthe start and end position of the motion are included in the operation.
XWhen exclusive, the last character towards the end of the buffer is not
Xincluded. Linewise motions always include the start and end position.
X Which motions are linewise, inclusive or exclusive is mentioned
Xbelow. There are however, two general exceptions:
X1. If the motion is exclusive and the end of the motion is in column 1, the
X end of the motion is moved to the end of the previous line and the motion
X becomes inclusive. Example: "}" ends at the first line after a paragraph,
X but "V}" will not include that line.
X2. If the motion is exclusive, the end of the motion is in column 1 and the
X start of the motion was at or before the first non-blank in the line, the
X motion becomes linewise. Example: If a paragraph begins with some blanks
X and you do "d}" while standing on the first non-blank, all the lines of
X the paragraph are deleted, including the blanks. If you do a put now, the
X deleted lines will be inserted below the cursor position.
X
XInstead of first giving the operator and then a motion you can use Visual
Xmode: mark the start of the text with <v>, move the cursor to the end of the
Xtext that is to be affected and then hit the operator. The text between the
Xstart and the cursor position is highlighted, so you can see what text will
Xbe operated upon. This allows much more freedom, but requires more key
Xstrokes and has limited redo functionality. See the chapter on Visual mode.
X
XIf you want to know where you are in the file use the "CTRL-G" command. If
Xyou set the 'ruler' option, the cursor position is continuously shown in the
Xstatus line (which slows down Vim a little).
X
XNOTE: Experienced users prefer the hjkl keys because they are always right
Xunder their fingers. Beginners often prefer the arrow keys, because they
Xdo not know what the hjkl keys do. The mnemonic value of hjkl is clear from
Xlooking at the keyboard. Think of j as an arrow pointing downwards.
X
X6.1 Left-right motions
X
Xh or
X<C_LEFT> or
XCTRL-H or
X<BS> [count] characters to the left (exclusive).
X
Xl or
X<C_RIGHT> or
X<SPACE> [count] characters to the right (exclusive).
X
X0 To the first character of the line (exclusive).
X
X^ To the first non-blank character of the line
X (exclusive).
X
X$ To the end of line [count] from the cursor
X (inclusive).
X
X| To column [count] (inclusive).
X
Xf<char> To [count]'th occurrence of <char> to the right. The
X cursor is placed on <char> (inclusive).
X
XF<char> To the [count]'th occurrence of <char> to the left.
X The cursor is placed on <char> (inclusive).
X
Xt<char> Till before [count]'th occurrence of <char> to the
X right. The cursor is placed on the character left of
X <char> (inclusive).
X
XT<char> Till after [count]'th occurrence of <char> to the
X left. The cursor is placed on the character right of
X <char> (inclusive).
X
X; Repeat latest f, t, F or T [count] times.
X
X, Repeat latest f, t, F or T in opposite direction
X [count] times.
X
XThese commands move the cursor to the specified column in the current line.
XThey stop at the first column and at the end of the line, except "$", which
Xmay move to one of the next lines.
X
X
X6.2 Up-down motions
X
Xk or
X<C_UP> or
XCTRL-P [count] lines upward (linewise).
X
Xj or
X<C_DOWN> or
XCTRL-J or
X<LF> or
XCTRL-N [count] lines downward (linewise).
X
X- <minus> [count] lines upward, on the first non-blank
X character (linewise).
X
X+ or
XCTRL-M or
X<CR> [count] lines downward, on the first non-blank
X character (linewise).
X
X_ <underscore> [count] - 1 lines downward, on the first non-blank
X character (linewise).
X
XG Goto line [count], default last line, on the first
X non-blank character (linewise).
X
X:[range] Set the cursor on the (last) specified line number
X (cannot be used with an operator).
X
X{count}% Go to {count} percentage in the file, on the first
X non-blank in the line (linewise). To compute the new
X line number this formula is used: {count} *
X number-of-lines / 100. {not in Vi}
X
XThese commands move to the specified line. They stop when reaching the first
Xor the last line. The first two commands put the cursor in the same column
X(if possible) as it was after the last command that changed the column,
Xexcept after the "$" command, then the cursor will be put on the last
Xcharacter of the line.
X
X
X6.3 Word motions
X
X<SC_RIGHT> or
Xw [count] words forward (exclusive).
X
XW [count] WORDS forward (exclusive).
X
Xe Forward to the end of word [count] (inclusive).
X
XE Forward to the end of WORD [count] (inclusive).
X
X<SC_LEFT> or
Xb [count] words backward (exclusive).
X
XB [count] WORDS backward (exclusive).
X
XThese commands move over words or WORDS. A word consists of a sequence of
Xletters, digits and underscores, or a sequence of other non-blank
Xcharacters, separated with white space (spaces, tabs, end of line). A WORD
Xconsists of a sequence of non-blank characters, separated with white space.
XAn empty line is also considered to be a word and a WORD.
X
XSpecial case: "cw" and "cW" are treated like "ce" and "cE" if the cursor is
Xon a non-blank. This is because "cw" is interpreted as change-word, and a
Xword does not include the following white space. {Vi: "cw" when on a blank
Xfollowed by other blanks changes only the first blank; this is probably a
Xbug, because "dw" deletes all the blanks}
X
XAnother special case: When using the "w" motion in combination with an
Xoperator and the last word moved over is at the end of a line, the end of
Xthat word becomes the end of the operated text, not the first word in the
Xnext line.
X
XThe original vi implementation of "e" is buggy. For example, the "e" command
Xwill stop on the first character of a line if the previous line was empty.
XBut when you use "2e" this does not happen. In Vim "ee" and "2e" are the
Xsame, which is more logical. However, this causes a small incompatibility
Xbetween vi and Vim.
X
X
X6.4 Text object motions
X
X( [count] sentences backward (exclusive).
X
X) [count] sentences forward (exclusive).
X
X{ [count] paragraphs backward (exclusive).
X
X} [count] paragraphs forward (exclusive).
X
X]] [count] sections forward or to the next <{> in the
X first column. When used after an operator, then the
X <}> in the first column. (linewise).
X
X][ [count] sections forward or to the next <}> in the
X first column (linewise).
X
X[[ [count] sections backward or to the previous <{> in
X the first column (linewise).
X
X[] [count] sections backward or to the previous <}> in
X the first column (linewise).
X
XThese commands move over three kinds of text objects.
X
XA sentence is defined as ending at a <.>, <!> or <?> followed by either the
Xend of a line, or by a space. {Vi: two spaces} Any number of closing <)>,
X<]>, <"> and <'> characters my appear after the <.>, <!> or <?> before the
Xspaces or end of line. A paragraph and section boundary is also a sentence
Xboundary.
X
XA paragraph begins after each empty line, and also at each of a set of
Xparagraph macros, specified by the pairs of characters in the 'paragraphs'
Xoption. The default is "IPLPPPQPP LIpplpipbp", which corresponds to the
Xmacros ".IP", ".LP", etc. (these are nroff macros, the dot must be in the
Xfirst column). A section boundary is also a paragraph boundary. Note that
Xthis does not include a <{> or <}> in the first column.
X
XA section begins after a form-feed in the first column and at each of a set
Xof section macros, specified by the pairs of characters in the 'sections'
Xoption. The default is "SHNHH HUnhsh".
X
XThe "]" and "[" commands stop at the <{> or <}" in the first column. This is
Xuseful to find the start or end of a function in a C program. Note that the
Xfirst character of the command determines the search direction and the
Xsecond character the type of brace found.
X
X
X6.5 Pattern searches
X
X/{pattern}[/] Search forward for the [count]'th occurrence of
X {pattern} (exclusive).
X
X/{pattern}/{offset} Search forward for the [count]'th occurrence of
X {pattern} and go {offset} lines up or down (see
X below). (linewise).
X
X/ Search forward for the [count]'th latest used
X pattern with latest used {offset}.
X
X//{offset} Search forward for the [count]'th latest used
X pattern with new {offset}. If {offset} is empty no
X offset is used.
X
X* Search forward for the [count]'th occurrence of the
X ident after or under the cursor (exclusive). Only
X whole words are search for, like with the command
X "/\<indent\>". If there is no identifier after or
X under the cursor, any non-blank word is used to
X search for. {not in Vi}
X
X# Same as "*", but search backward. {not in Vi}
X
X?{pattern}[?] Search backward for the [count]'th previous
X occurrence of {pattern} (exclusive).
X
X?{pattern}?{offset} Search backward for the [count]'th previous
X occurrence of {pattern} and go {offset} lines up or
X down (see below) (linewise).
X
X? Search backward for the [count]'th latest used
X pattern with latest used {offset}.
X
X??{offset} Search backward for the [count]'th latest used
X pattern with new {offset}. If {offset} is empty no
X offset is used.
X
Xn Repeat the latest "/" or "?" [count] times. {Vi: no
X count}
X
XN Repeat the latest "/" or "?" [count] times in
X opposite direction. {Vi: no count}
X
XCTRL-C Interrupt current (search) command.
X
XThese commands search for the specified pattern. With "/" and "?" an
Xadditional offset may be given. There are two types of offsets: line offsets
Xand character offsets. {the character offsets are not in Vi}
X
XThe offset gives the cursor position relative to the found match:
X [num] [num] lines downwards, in column 1
X +[num] [num] lines downwards, in column 1
X -[num] [num] lines upwards, in column 1
X e[+num] [num] characters to the right of the end of the match
X e[-num] [num] characters to the left of the end of the match
X s[+num] [num] characters to the right of the start of the match
X s[-num] [num] characters to the left of the start of the match
X b[+num] [num] characters to the right of the start (begin) of the match
X b[-num] [num] characters to the left of the start (begin) of the match
X
XIf a <-> or <+> is given but [num] is omitted, a count of one will be used.
XWhen including an offset with 'e', the search becomes inclusive (the
Xcharacter the cursor lands on is included in operations).
X
XExamples:
X
Xpattern cursor position
X/test/+1 one line below "test", in column 1
X/test/e on the last t of "test"
X/test/s+2 on the <s> of "test"
X/test/b-3 three characters before "test"
X
XIf one of these commands is used after an operator, the characters between
Xthe cursor position before and after the search is affected. However, if a
Xline offset is given, the whole lines between the two cursor positions are
Xaffected.
X
XThe last used <pattern> and <offset> are remembered. They can be used to
Xrepeat the search, possibly in another direction or with another count. Note
Xthat two patterns are remembered: one for 'normal' search commands and one
Xfor the substitute command ":s". Each time an empty <pattern> is given, the
Xpreviously used <pattern> is used.
X
X{In vi the :tag command sets a new search pattern when the tag is searched
Xfor. In Vim this is not done, the previous search pattern is still
Xremembered}.
X
XIf the 'wrapscan' option is set (which is the default), searches wrap around
Xthe end of the buffer. If 'wrapscan' is not set, the backward search stops
Xat the beginning and the forward search stops at the end of the buffer. If
X'wrapscan' is set and the pattern was not found the error message "pattern
Xnot found" is given, and the cursor will not be moved. If 'wrapscan' is not
Xset the message becomes "search hit BOTTOM without match" when searching
Xforward, or "search hit TOP without match" when searching backward. If
Xwrapscan is set and the search wraps around the end of the file the message
X"search hit TOP, continuing at BOTTOM" or "search hit BOTTOM, continuing at
XTOP" is given when searching backwards or forwards respectively.
X
XThe "*" and "#" commands search for the identifier currently under the
Xcursor. If there is no identifier under the cursor, the first one to the
Xright is used. This identifier may only contain letters, digits and
Xunderscores. Note that if you type with ten fingers, the characters are easy
Xto remember: the "#" is under your left hand middle finger (search to the
Xleft and up) and the "*" is under your right hand middle finger (search to
Xthe right and down). If there is no identifier under or after the cursor, a
Xsearch is done for any word under or after the cursor. Blanks (<TAB>s and/or
X<SPACE>s) are recognized as delimiters for this word.
X
X
XThe definition of a pattern:
X
XPatterns may contain special characters, depending on the setting of the
X'magic' option.
X
X1. A pattern is one or more branches, separated by '\|'. It matches anything
X that matches one of the branches. Example: "foo\|bar" matches "foo" and
X "bar.
X
X2. A branch is one or more pieces, concatenated. It matches a match for the
X first, followed by a match for the second, etc. Example: "foo[0-9]bar",
X first match "foo", then a digit and then "bar".
X
X3. A piece is an atom, possibly followed by:
X 'magic' 'nomagic'
X option option
X * \* matches 0 or more of the preceding atom
X \+ \+ matches 1 or more of the preceding atom {not
X in Vi}
X \= \= matches 0 or 1 of the preceding atom {not in
X Vi}
X Examples:
X .* .\* match anything, also empty string
X .\+ .\+ match any non-empty string
X foo\= foo\= match "fo" and "foo"
X
X
X4. An atom can be:
X - One of these five:
X magic nomagic
X . \. matches any single character
X \< \< matches the beginning of a word
X \> \> matches the end of a word
X ^ ^ at beginning of pattern, matches start of
X line
X $ $ at end of pattern or in front of '\|',
X matches end of line
X - A pattern enclosed by escaped parentheses (e.g. "\(^a\)").
X - A single character, with no special meaning, matches itself
X - A backslash followed by a single character, with no special meaning,
X matches the single character.
X - A range. This is a sequence of characters enclosed in '[]' with the
X 'magic' option, or enclosed in '\[]' with the 'nomagic' option. It
X normally matches any single character from the sequence. If the
X sequence begins with <^>, it matches any single character NOT in the
X sequence. If two characters in the sequence are separated by <->, this
X is shorthand for the full list of ASCII characters between them (e.g.
X '[0-9]' matches any decimal digit). To include a literal <]> in the
X sequence, make it the first character (following a possible <^>). To
X include a literal '\-', make it the first or last character.
X
XIf the 'ignorecase' option is set, the case of letters is ignored.
X
XIt is impossible to have a pattern that contains a line break.
X
XExamples:
X^beep( Probably the start of the C function "beep".
X
X[a-zA-Z]$ Any alphabetic character at the end of a line.
X
X\(^\|[^a-zA-Z0-9_]\)[a-zA-Z_]\+[a-zA-Z0-9_]*
X A C identifier (will stop in front of it).
X
X\(\.$\|\. \) A period followed by end-of-line or a space.
X Note that "\(\. \|\.$\)" does not do the same,
X because '$' is not end-of-line in front of '\)'.
X This was done to remain vi-compatible.
X
X[.!?][])"']*\($\|[ ]\) A search pattern that finds the end of a sentence,
X with almost the same definition as the <)> command.
X
XTechnical detail:
X<NUL> characters in the file are stored as <LF> in memory. In the display
Xthey are shown as "^@". The translation is done when reading and writing
Xfiles. To match a <NUL> with a search pattern you can just enter CTRL-@ or
X"CTRL-V 000". This is probably just what you expect. Internally the
Xcharacter is replaced by a <LF> in the search pattern. What is unusual is
Xthat typing CTRL_V CTRL_J also inserts a <LF>, thus also searches for a
X<NUL> in the file. {vi cannot handle <NUL> characters in the file at all}
X
X
X6.6 Various motions
X
Xm<a-zA-Z> Set mark <a-zA-Z> at cursor position (does not move
X the cursor, this is not a motion command).
X
X:[range]mar[k] <a-zA-Z> Set mark <a-zA-Z> at last line number in [range],
X column 0. Default is cursor line.
X
X:[range]k<a-zA-Z> Same as :mark, but the space before the mark name can
X be omitted.
X
X'<a-z> To the first non-blank character on the line with
X mark <a-z> (linewise).
X
X'<A-Z> To the first non-blank character on the line with
X mark <A-Z> in the correct file (linewise when in
X same file, not a motion command when in other file).

X {not in Vi}
X

X`<a-z> To the mark <a-z> (exclusive).
X
X`<A-Z> To the mark <A-Z> in the correct file (exclusive
X when in same file, not a motion command when in
X other file). {not in Vi}
X
X:marks List the current marks (not a motion command). {not
X in Vi}
X
XA mark is not visible in any way. It is just a position in the file that is
Xremembered. Do not confuse marks with named registers, they are totally
Xunrelated.
X
XLowercase marks are only remembered as long as the file remains loaded. If
Xyou quit editing the file, change a character in a line or delete a line
Xthat contains a mark, that mark is erased. Lowercase marks can be used
Xin combination with operators. For example: "d't" deletes the lines from the
Xcursor position to mark <t>. Hint: Use mark <t> for Top, <b> for Bottom,
Xetc..
X
XMarks are restored when using undo and redo.
X
XMarks are remembered as long as the file remains in the buffer list.
X
XUppercase marks include the file name. {Vi: no uppercase marks} You can use
Xthem to jump from file to file. You can only use an uppercase mark with
Xan operator if the mark is in the current file. The line number of the mark
Xremains correct, even if you insert/delete lines or edit another file for a
Xmoment.
X
X
X'[ To the first non-blank character on the first line
X of the previously operated text or start of the last
X putted text. {not in Vi}
X
X`[ To the first character of the previously operated
X text or start of the last putted text. {not in Vi}
X
X'] To the first non-blank character on the last line of
X the previously operated text or end of the last
X putted text. {not in Vi}
X
X`] To the last character of the previously operated
X text or end of the last putted text. {not in Vi}
X
XAfter executing an operator the Cursor is put at the beginning of the text
Xthat was operated upon. After a put command ("p" or "P") the cursor is
Xsometimes placed at the first inserted line and sometimes on the last
Xinserted character. The four commands above put the cursor at either
Xend. Example: After yanking 10 lines you want to go to the last one of them:
X"10Y']". After inserting several lines with the "p" command you want to jump
Xto the lowest inserted line: "p']".
X
XNote: After deleting text, the start and end positions are the same, except
Xwhen using blockwise Visual mode. These commands do not work when no
Xoperator or put command has been used yet in the current file. The position
Xmay be incorrect after inserting text and ".p.
X
X
X'' To the first non-blank character of the line where
X the cursor was before the latest jump (linewise).
X
X`` To the position before latest jump (exclusive).
X
XA "jump" is one of the following commands: "'", "`", "G", "/", "?", "n",
X"N", "%", "(", ")", "[[", "]]", "{", "}", ":s", ":tag", "L", "M", "H" and
Xthe commands that start editing a new file. If you make the cursor "jump"
Xwith one of these commands, the position of the cursor before the jump is
Xremembered. You can return to that position with the "''" and "``" command,
Xunless the line containing that position was changed or deleted.
X
XCTRL-O Go to [count] Older cursor position in jump list
X (not a motion command). {not in Vi}
X
XCTRL-I Go to [count] newer cursor position in jump list
X (not a motion command). {not in Vi}
X
X:jumps Print the jump list (not a motion command). {not in
X Vi}
X
XJumps are remembered in a jump list. With the CTRL-O and CTRL-I command you
Xcan go to cursor positions before older jumps, and back again. Thus you can
Xmove up and down the list.
X
XFor example, after three jump commands you have this jump list:
X
X jump line file
X 1 1 -current-
X 2 70 -current-
X 3 1154 -current-
X>
X
XYou are currently in line 1167. If you then use the CTRL-O command, the
Xcursor is put in line 1154. This results in:
X
X jump line file
X 1 1 -current-
X 2 70 -current-
X> 3 1154 -current-
X 4 1167 -current-
X
XThe pointer will be set at the last used jump position. The next CTRL-O
Xcommand will use the entry above it, the next CTRL-I command will use the
Xentry below it. If the pointer is below the last entry, this indicates that
Xyou did not use a CTRL-I or CTRL-O before. In this case the CTRL-O command
Xwill cause the cursor position to be added to the jump list, so you can get
Xback to the position before the CTRL-O. In this case this is line 1167.
X
XWith more CTRL-O commands you will go to lines 70 and 1. If you use CTRL-I
Xyou can go back to 1154 and 1167 again.
X
XIf you use a jump command, the current line number is inserted at the end of
Xthe jump list. If you used CTRL-O or CTRL-I just before that, the same line
Xmay be in the list twice. This may be a bit strange. Just try it and look at
Xthe jump list with the :jumps command. Note that this behaviour is different
Xfrom the tag stack.
X
XAfter the CTRL-O command that got you into line 1154 you could give another
Xjump command (e.g. "G"). The jump list would then become:
X
X jump line file
X 1 1 -current-
X 2 70 -current-
X 3 1154 -current-
X 4 1167 -current-
X 5 1154 -current-
X>
X
XAs long as you stay in the same file, the line numbers will be adjusted for
Xdeleted and inserted lines. If you go to another file the line numbers may
Xbe wrong (keeping them correct would take too much time). If you want to
Xavoid this use a :jumps command before changing files. This will update the
Xline numbers in the current file.
X
X% Find the next item in this line after or under the
X cursor and jump to its match (inclusive). Items can
X be:
X ([{}]) parenthesis or (curly/square) brackets
X /* */ start or end of C-style comment
X #if, #ifdef, #else, #elif, #endif
X C preprocessor conditionals
X Parens and braces preceded with a backslash are
X ignored. Parens and braces inside quotes are ignored,
X unless the number of parens/braces in a line is uneven
X and this line and the previous one does not end in a
X backslash. No count is allowed ({count}% jumps to a
X line {count} percentage down the file).
X Using '%' on #if/#else/#endif makes the movement
X linewise.
X
X[( go to [count] previous unmatched <(>. {not in Vi}
X
X[{ go to [count] previous unmatched <{>. {not in Vi}
X
X]) go to [count] next unmatched <)>. {not in Vi}
X
X]} go to [count] next unmatched <}>. {not in Vi}
X
XThe above four commands can be used to go to the start or end of the current
Xcode block. It is like doing "%" on the <(>, <)>, <{> or <}> at the other
Xend of the code block, but you can do this from anywhere in the code block.
XVery useful for C programs. Example: When standing on "case x:", "[{" will
Xbring you back to the switch statement.
X
XH To line [count] from top (Home) of screen (default:
X first line on the screen) on the first non-blank
X character (linewise).
X
XM To Middle line of screen, on the first non-blank
X character (linewise).
X
XL To line [count] from bottom of screen (default: Last
X line on the screen) on the first non-blank character
X (linewise).
X
X
X 7. Scrolling
X
XMove edit window downwards (this means that more lines downwards in the text
Xbuffer are seen):
X
XCTRL-E Window [count] lines downwards in the buffer
X
XCTRL-D Window Downwards in the buffer. The number of lines
X comes from the 'scroll' option (default: half a
X screen). If [count] given, first set 'scroll' option
X to [count].
X
X<SC_DOWN> or
XCTRL-F Window [count] pages Forwards (downwards) in the
X buffer.
X
XMove edit window upwards (this means that more lines upwards in the text
Xbuffer are seen):
X
XCTRL-Y Window [count] lines upwards in the buffer.
X
XCTRL-U Window Upwards in the buffer. The number of lines
END_OF_FILE
if test 50511 -ne `wc -c <'vim/doc/reference.doc.B'`; then
echo shar: \"'vim/doc/reference.doc.B'\" unpacked with wrong size!
elif test -f 'vim/doc/reference.doc.A' && test -f 'vim/doc/reference.doc.C' && test -f 'vim/doc/reference.doc.D'; then


echo shar: Combining \"'vim/doc/reference.doc'\" \(210836 characters\)
cat 'vim/doc/reference.doc.A' 'vim/doc/reference.doc.B' 'vim/doc/reference.doc.C' 'vim/doc/reference.doc.D' > 'vim/doc/reference.doc'
if test 210836 -ne `wc -c <'vim/doc/reference.doc'`; then
echo shar: \"'vim/doc/reference.doc'\" combined with wrong size!
else
rm vim/doc/reference.doc.A vim/doc/reference.doc.B vim/doc/reference.doc.C vim/doc/reference.doc.D
fi
fi

# end of 'vim/doc/reference.doc.B'
fi
if test -f 'vim/src/termlib.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/termlib.c'\"
else
echo shar: Extracting \"'vim/src/termlib.c'\" \(15559 characters\)
sed "s/^X//" >'vim/src/termlib.c' <<'END_OF_FILE'
X/* vi:sw=4:ts=4:
X The following software is (C) 1984 Peter da Silva,
X the Mad Australian, in the public domain. It may
X be re-distributed for any purpose with the inclusion
X of this notice. */
X
X/* modified by Bram Moolenaar for use with VIM - Vi Improved */
X
X/* TERMLIB: Terminal independant database. */
X
X#include "vim.h"
X#include "proto.h"
X#include "proto/termlib.pro"
X
X#ifndef AMIGA
X# include <sgtty.h>
X#endif
X
Xstatic int getent __PARMS((char *, char *, FILE *, int));
Xstatic int nextent __PARMS((char *, FILE *, int));
Xstatic int _match __PARMS((char *, char *));
Xstatic char *_addfmt __PARMS((char *, char *, int));
Xstatic char *_find __PARMS((char *, char *));
X
X/*
X * Global variables for termlib
X */
X
Xchar *tent; /* Pointer to terminal entry, set by tgetent */
Xchar PC = 0; /* Pad character, default NULL */
Xchar *UP = 0, *BC = 0; /* Pointers to UP and BC strings from database */
Xshort ospeed; /* Baud rate (1-16, 1=300, 16=19200), as in stty */
X
X/*
X * Module: tgetent
X *
X * Purpose: Get termcap entry for <term> into buffer at <tbuf>.
X *
X * Calling conventions: char tbuf[TBUFSZ+], term=canonical name for
X * terminal.
X *
X * Returned values: 1 = success, -1 = can't open file,
X * 0 = can't find terminal.
X *
X * Notes
X * Should probably supply static buffer.
X *
X * Uses environment variables "TERM" and
X * "TERMCAP". If TERM = term (that is, if the argument
X * matches the environment) then it looks at TERMCAP.
X * If TERMCAP begins with a slash, then it assumes
X * this is the file to search rather than /etc/termcap.
X * If TERMCAP does not begin with a slash, and it
X * matches TERM, then this is used as the entry.
X *
X * This could be simplified considerably for non-UNIX
X * systems.
X */
X
X#ifdef AMIGA
X# define TERMCAPFILE "s:termcap"
X#else
X# define TERMCAPFILE "/etc/termcap"
X#endif
X
Xtgetent(tbuf, term)
X char *tbuf; /* Buffer to hold termcap entry, TBUFSZ bytes max */
X char *term; /* Name of terminal */
X{
X char tcbuf[32]; /* Temp buffer to handle */
X char *tcptr = tcbuf; /* extended entries */
X char *tcap = TERMCAPFILE; /* Default termcap file */
X char *tmp;
X FILE *termcap;
X int retval = 0;
X int len;
X
X if ((tmp = (char *)vimgetenv("TERMCAP")) != NULL)
X {
X if (*tmp == '/') /* TERMCAP = name of termcap file */
X tcap = tmp ;
X else /* TERMCAP = termcap entry itself */
X {
X int tlen = strlen(term);
X
X while (*tmp && *tmp != ':') /* Check if TERM matches */
X {
X while (*tmp == '|')
X tmp++;
X if (_match(tmp, term) == tlen)
X {
X strcpy(tbuf, tmp);
X tent = tbuf;
X return 1;
X }
X else
X tmp = _find(tmp, ":|");
X }
X }
X }
X if (!(termcap = fopen(tcap, "r")))
X {
X strcpy(tbuf, tcap);
X return -1;
X }
X
X len = 0;
X while (getent(tbuf + len, term, termcap, TBUFSZ - len))
X {
X if ((term = tgetstr("tc", &tcptr))) /* extended entry */
X {
X rewind(termcap);
X len = strlen(tbuf);
X }
X else
X {
X retval = 1;
X tent = tbuf;
X break;
X }
X }
X fclose(termcap);


X return retval;
X}
X

X static int
Xgetent(tbuf, term, termcap, buflen)
X char *tbuf, *term;
X FILE *termcap;
X int buflen;
X{
X char *tptr;
X int tlen = strlen(term);
X
X while (nextent(tbuf, termcap, buflen)) /* For each possible entry */
X {
X tptr = tbuf;
X while (*tptr && *tptr != ':') /* : terminates name field */
X {
X while (*tptr == '|') /* | seperates names */
X tptr++;
X if (_match(tptr, term) == tlen) /* FOUND! */
X {
X tent = tbuf;
X return 1;
X }
X else /* Look for next name */
X tptr = _find(tptr, ":|");
X }
X }


X return 0;
X}
X

X static int
Xnextent(tbuf, termcap, buflen) /* Read 1 entry from TERMCAP file */
X char *tbuf;
X FILE *termcap;
X int buflen;
X{
X char *lbuf = tbuf; /* lbuf=line buffer */
X /* read lines straight into buffer */
X
X while (lbuf < tbuf+buflen && /* There's room and */
X fgets(lbuf, (int)(tbuf+buflen-lbuf), termcap)) /* another line */
X {
X int llen = strlen(lbuf);
X
X if (*lbuf == '#') /* eat comments */
X continue;
X if (lbuf[-1] == ':' && /* and whitespace */
X lbuf[0] == '\t' &&
X lbuf[1] == ':')
X {
X strcpy(lbuf, lbuf+2);
X llen -= 2;
X }
X if (lbuf[llen-2] == '\\') /* and continuations */
X lbuf += llen-2;
X else
X {
X lbuf[llen-1]=0; /* no continuation, return */


X return 1;
X }
X }
X

X return 0; /* ran into end of file */
X}
X
X/*
X * Module: tgetflag
X *
X * Purpose: returns flag true or false as to the existence of a given
X * entry. used with 'bs', 'am', etc...
X *
X * Calling conventions: id is the 2 character capability id.
X *
X * Returned values: 1 for success, 0 for failure.
X */
X
Xtgetflag(id)
X char *id;
X{
X char buf[256], *ptr = buf;
X
X return tgetstr(id, &ptr) ? 1 : 0;
X}
X
X/*
X * Module: tgetnum
X *
X * Purpose: get numeric value such as 'li' or 'co' from termcap.
X *
X * Calling conventions: id = 2 character id.
X *
X * Returned values: -1 for failure, else numerical value.
X */
X
Xtgetnum(id)
Xchar *id;
X{
X char *ptr, buf[256];
X ptr = buf;
X
X if (tgetstr(id, &ptr))
X return atoi(buf);
X else


X return 0;
X}
X
X/*

X * Module: tgetstr
X *
X * Purpose: get terminal capability string from database.
X *
X * Calling conventions: id is the two character capability id.
X * (*buf) points into a hold buffer for the
X * id. the capability is copied into the buffer
X * and (*buf) is advanced to point to the next
X * free byte in the buffer.
X *
X * Returned values: 0 = no such entry, otherwise returns original
X * (*buf) (now a pointer to the string).
X *
X * Notes
X * It also decodes certain escape sequences in the buffer.
X * they should be obvious from the code:
X * \E = escape.
X * \n, \r, \t, \f, \b match the 'c' escapes.
X * ^x matches control-x (^@...^_).
X * \nnn matches nnn octal.
X * \x, where x is anything else, matches x. I differ
X * from the standard library here, in that I allow ^: to match
X * :.
X *
X */
X
Xchar *
Xtgetstr(id, buf)
Xchar *id, **buf;
X{
X int len = strlen(id);
X char *tmp=tent;
X char *hold;
X int i;
X
X do {
X tmp = _find(tmp, ":"); /* For each field */
X while (*tmp == ':') /* skip empty fields */
X tmp++;
X if (!*tmp)
X break;
X
X if (_match(id, tmp) == len) {
X tmp += len; /* find '=' '@' or '#' */
X if (*tmp == '@') /* :xx@: entry for tc */
X return 0; /* deleted entry */
X hold= *buf;
X while (*++tmp && *tmp != ':') {/* not at end of field */
X switch(*tmp) {
X case '\\': /* Expand escapes here */
X switch(*++tmp) {
X case 0: /* ignore backslashes */
X tmp--; /* at end of entry */
X break; /* shouldn't happen */
X case 'e':
X case 'E': /* ESC */
X *(*buf)++ = '\033';
X break;
X case 'n': /* \n */
X *(*buf)++ = '\n';
X break;
X case 'r': /* \r */
X *(*buf)++ = '\r';
X break;
X case 't': /* \t */
X *(*buf)++ = '\t';
X break;
X case 'b': /* \b */
X *(*buf)++ = '\b';
X break;
X case 'f': /* \f */
X *(*buf)++ = '\f';
X break;
X case '0': /* \nnn */
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X **buf = 0;
X /* get up to three digits */
X for (i = 0; i < 3 && isdigit(*tmp); ++i)
X **buf = **buf * 8 + *tmp++ - '0';
X (*buf)++;
X tmp--;
X break;
X default: /* \x, for all other x */
X *(*buf)++= *tmp;
X }
X break;
X case '^': /* control characters */
X *(*buf)++ = *++tmp - '@';
X break;
X default:
X *(*buf)++ = *tmp;
X }
X }
X *(*buf)++ = 0;
X return hold;
X }
X } while (*tmp);
X


X return 0;
X}
X
X/*

X * Module: tgoto
X *
X * Purpose: decode cm cursor motion string.
X *
X * Calling conventions: cm is cursor motion string.
X * line, col, are the desired destination.
X *
X * Returned values: a string pointing to the decoded string, or
X * "OOPS" if it cannot be decoded.
X *
X * Notes
X * The accepted escapes are:
X * %d as in printf, 0 origin.
X * %2, %3 like %02d, %03d in printf.
X * %. like %c
X * %+x adds <x> to value, then %.
X * %>xy if value>x, adds y. No output.
X * %i increments line& col, no output.
X * %r reverses order of line&col. No output.
X * %% prints as a single %.
X * %n exclusive or row & col with 0140.
X * %B BCD, no output.
X * %D reverse coding (x-2*(x%16)), no output.
X */
X
Xchar *
Xtgoto(cm, col, line)
Xchar *cm; /* cm string, from termcap */
Xint col, /* column, x position */
X line; /* line, y position */
X{
X char gx, gy, /* x, y */
X *ptr, /* pointer in 'cm' */
X reverse = 0, /* reverse flag */
X *bufp, /* pointer in returned string */
X addup = 0, /* add upline */
X addbak = 0, /* add backup */
X c;
X static char buffer[32];
X
X if (!cm)
X return "OOPS"; /* Kludge, but standard */
X
X bufp = buffer;
X ptr = cm;
X
X while (*ptr) {
X if ((c = *ptr++) != '%') { /* normal char */
X *bufp++ = c;
X } else { /* % escape */
X switch(c = *ptr++) {
X case 'd': /* decimal */
X bufp = _addfmt(bufp, "%d", line);
X line = col;
X break;
X case '2': /* 2 digit decimal */
X bufp = _addfmt(bufp, "%02d", line);
X line = col;
X break;
X case '3': /* 3 digit decimal */
X bufp = _addfmt(bufp, "%03d", line);
X line = col;
X break;
X case '>': /* %>xy: if >x, add y */
X gx = *ptr++;
X gy = *ptr++;
X if (col>gx) col += gy;
X if (line>gx) line += gy;
X break;
X case '+': /* %+c: add c */
X line += *ptr++;
X case '.': /* print x/y */
X if (line == '\t' || /* these are */
X line == '\n' || /* chars that */
X line == '\004' || /* UNIX hates */
X line == '\0') {
X line++; /* so go to next pos */
X if (reverse == (line == col))
X addup=1; /* and mark UP */
X else
X addbak=1; /* or BC */
X }
X *bufp++=line;
X line = col;
X break;
X case 'r': /* r: reverse */
X gx = line;
X line = col;
X col = gx;
X reverse = 1;
X break;
X case 'i': /* increment (1-origin screen) */
X col++;
X line++;
X break;
X case '%': /* %%=% literally */
X *bufp++='%';
X break;
X case 'n': /* magic DM2500 code */
X line ^= 0140;
X col ^= 0140;
X break;
X case 'B': /* bcd encoding */
X line = line/10<<4+line%10;
X col = col/10<<4+col%10;
X break;
X case 'D': /* magic Delta Data code */
X line = line-2*(line&15);
X col = col-2*(col&15);
X break;
X default: /* Unknown escape */
X return "OOPS";
X }
X }
X }
X
X if (addup) /* add upline */
X if (UP) {
X ptr=UP;
X while (isdigit(*ptr) || *ptr == '.')
X ptr++;
X if (*ptr == '*')
X ptr++;
X while (*ptr)
X *bufp++ = *ptr++;
X }
X
X if (addbak) /* add backspace */
X if (BC) {
X ptr=BC;
X while (isdigit(*ptr) || *ptr == '.')
X ptr++;
X if (*ptr == '*')
X ptr++;
X while (*ptr)
X *bufp++ = *ptr++;
X }
X else
X *bufp++='\b';
X
X *bufp = 0;
X
X return(buffer);
X}
X
X/*
X * Module: tinit
X *
X * Purpose: simplified terminal initialisation.
X *
X * Calling conventions: name is name of terminal.
X *
X * Returned values: none.
X *
X * Notes
X * tinit calls tgetent, then sets up the global
X * variables PC, UP, BC, ospeed appropriately.
X *
X */
X
X#if 0 /* already included in term.c */
X
Xchar tbuf[TBUFSZ]; /* Buffer for termcap entry */
Xchar junkbuf[TBUFSZ]; /* Big buffer for junk */
Xchar *junkptr;
X
Xtinit(name)
Xchar *name;
X{
X#ifndef AMIGA
X struct sgttyb sgbuf;
X#endif
X char *ps;
X
X junkptr = junkbuf;
X
X tgetent(tbuf, name);
X
X ps = tgetstr("pc", &junkptr);
X if (ps) PC = *ps;
X UP = tgetstr("up", &junkptr);
X BC = tgetstr("bc", &junkptr);
X
X#ifdef AMIGA
X ospeed=0;
X#else
X gtty(1, &sgbuf);
X ospeed=sgbuf.sg_ospeed;
X#endif
X return 0;
X}
X#endif
X
X/*
X * Module: tputs
X *
X * Purpose: decode padding information
X *
X * Calling conventions: cp = string to be padded, affcnt = # of items
X * affected (lines, characters, whatever),
X * outc = routine to output 1 character.
X *
X * Returned values: none
X *
X * Notes
X * cp has padding information ahead of it, in the form
X * nnnTEXT or nnn*TEXT. nnn is the number of milliseconds to delay,
X * and may be a decimal (nnn.mmm). If the asterisk is given, then
X * the delay is multiplied by afcnt. The delay is produced by outputting
X * a number of nulls (or other padding char) after printing the
X * TEXT.
X *
X */
X
Xlong _bauds[16]={
X 0, 50, 75, 110,
X 134, 150, 200, 300,
X 600, 1200, 1800, 2400,
X 4800, 9600, 19200, 19200 };
X
Xtputs(cp, affcnt, outc)
Xchar *cp; /* string to print */
Xint affcnt; /* Number of lines affected */
Xvoid (*outc) __ARGS((unsigned int)); /* routine to output 1 character */
X{
X long frac, /* 10^(#digits after decimal point) */
X counter, /* digits */
X atol();
X
X if (isdigit(*cp)) {
X counter = 0;
X frac = 1000;
X while (isdigit(*cp))
X counter = counter * 10L + (long)(*cp++ - '0');
X if (*cp == '.')
X while (isdigit(*++cp)) {
X counter = counter * 10L + (long)(*cp++ - '0');
X frac = frac * 10;
X }
X if (*cp!='*') { /* multiply by affected lines */
X if (affcnt>1) affcnt = 1;
X }
X else
X cp++;
X
X /* Calculate number of characters for padding counter/frac ms delay */
X if (ospeed)
X counter = (counter * _bauds[ospeed] * (long)affcnt) / frac;
X
X while (*cp) /* output string */
X (*outc)(*cp++);
X if (ospeed)
X while (counter--) /* followed by pad characters */
X (*outc)(PC);
X }
X else
X while (*cp)
X (*outc)(*cp++);


X return 0;
X}
X
X/*

X * Module: tutil.c
X *
X * Purpose: Utility routines for TERMLIB functions.
X *


X */
X
X static int

X_match(s1, s2) /* returns length of text common to s1 and s2 */
Xchar *s1, *s2;
X{
X int i = 0;
X
X while (s1[i] && s1[i] == s2[i])
X i++;
X
X return i;
X}
X
X static char *
X_find(s, set) /* finds next c in s that's a member of set, returns pointer */
Xchar *s, *set;
X{
X for(; *s; s++) {
X char *ptr = set;
X
X while (*ptr && *s != *ptr)
X ptr++;
X
X if (*ptr)


X return s;
X }
X
X return s;
X}
X

X static char *
X_addfmt(buf, fmt, val) /* add val to buf according to format fmt */
Xchar *buf, *fmt;
Xint val;
X{
X sprintf(buf, fmt, val);
X while (*buf)
X buf++;
X return buf;
X}
END_OF_FILE
if test 15559 -ne `wc -c <'vim/src/termlib.c'`; then
echo shar: \"'vim/src/termlib.c'\" unpacked with wrong size!
fi
# end of 'vim/src/termlib.c'
fi
echo shar: End of archive 4 \(of 26\).
cp /dev/null ark4isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:39 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 24
Archive-name: vim/part05

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/arpbase.h vim/src/term.h vim/tools/ref
# Wrapped by kent@sparky on Mon Aug 15 21:44:00 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 5 (of 26)."'
if test -f 'vim/src/arpbase.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/arpbase.h'\"
else
echo shar: Extracting \"'vim/src/arpbase.h'\" \(49919 characters\)
sed "s/^X//" >'vim/src/arpbase.h' <<'END_OF_FILE'
X#ifndef LIBRARIES_ARPBASE_H
X#define LIBRARIES_ARPBASE_H 1
X
X/*
X ************************************************************************
X * *
X * 5/3/89 ARPbase.h by MKSoft from ARPbase.i by SDB *
X * *
X ************************************************************************
X * *
X * AmigaDOS Resource Project -- Library Include File *
X * for Lattice C 5.x or Manx C 5.x *
X * *
X ************************************************************************
X * *
X * Copyright (c) 1987/1988/1989 by Scott Ballantyne *
X * *
X * The arp.library, and related code and files may be freely used *
X * by supporters of ARP. Modules in the arp.library may not be *
X * extracted for use in independent code, but you are welcome to *
X * provide the arp.library with your work and call on it freely. *
X * *
X * You are equally welcome to add new functions, improve the ones *
X * within, or suggest additions. *
X * *
X * BCPL programs are not welcome to call on the arp.library. *
X * The welcome mat is out to all others. *
X * *
X ************************************************************************
X * *
X * N O T E ! You MUST! have IoErr() defined as LONG to use LastTracker *
X * If your compiler has other defines for this, you may wish *
X * to remove the prototype for IoErr() from this file. *
X * *
X ************************************************************************
X */
X
X/*
X ************************************************************************
X * First we need to include the Amiga Standard Include files... *
X ************************************************************************
X */
X#ifndef EXEC_TYPES_H
X#include <exec/types.h>
X#endif /* EXEC_TYPES_H */
X
X#ifndef EXEC_LISTS_H
X#include <exec/lists.h>
X#endif /* EXEC_LISTS_H */
X
X#ifndef EXEC_ALERTS_H
X#include <exec/alerts.h>
X#endif /* EXEC_ALERTS_H */
X
X#ifndef EXEC_LIBRARIES_H
X#include <exec/libraries.h>
X#endif /* EXEC_LIBRARIES_H */
X
X#ifndef EXEC_SEMAPHORES_H
X#include <exec/semaphores.h>
X#endif /* EXEC_SEMAPHORES_H */
X
X#ifndef LIBRARIES_DOS_H
X#include <libraries/dosextens.h>
X#endif /* LIBRARIES_DOS_H */
X
X/*
X ************************************************************************
X * Check for MANX/Lattice and define the differences... *
X ************************************************************************
X * At the moment MANX 3.6 does not have prototypes or the *
X * wonderful #pragma statements of Lattice 5.0... *
X * And, no __stdargs in MANX either... *
X ************************************************************************
X */
X#ifdef AZTEC_C
X
X /* Do we have an old 3.6a compiler? -olsen */
X
X#ifndef __VERSION
X#define __VERSION 360
X#endif /* __VERSION */
X
X /* If this is an old compiler, don't confuse it with
X * ANSI prototypes and pragmas. -olsen
X */
X
X#if __VERSION < 500
X#define NO_PRAGMAS 1
X#define NO_PROTOTYPES 1
X#endif /* __VERSION */
X
X#define C_Args
X
X#endif /* AZTEC_C */
X
X#ifdef LATTICE
X
X#define C_Args __stdargs
X
X#endif /* LATTICE */
X
X/*
X ************************************************************************
X * Standard definitions for arp library information *
X ************************************************************************
X */
X#define ArpName "arp.library" /* Name of library... */
X#define ArpVersion 39L /* Current version... */
X
X/*
X ************************************************************************
X * The current ARP library node... *
X ************************************************************************
X */
Xstruct ArpBase {
X struct Library LibNode; /* Standard library node */
X APTR DosRootNode; /* Copy of dl_Root */
X UBYTE Flags; /* See bitdefs below */
X UBYTE ESCChar; /* Character to be used for escaping */
X LONG ArpReserved1; /* ArpLib's use only!! */
X struct Library *EnvBase; /* Dummy library for MANX compatibility*/
X struct Library *DosBase; /* Cached DosBase */
X struct Library *GfxBase; /* Cached GfxBase */
X struct Library *IntuiBase; /* Cached IntuitionBase */
X struct MinList ResLists; /* Resource trackers */
X struct ResidentProgramNode *ResidentPrgList;/* Resident Programs. */
X struct SignalSemaphore ResPrgProtection;/* protection for above */
X BPTR SegList; /* Pointer to loaded libcode (a BPTR). */
X };
X
X/*
X ************************************************************************
X * The following is here *ONLY* for information and for *
X * compatibility with MANX. DO NOT use in new code! *
X ************************************************************************
X */
X#ifdef ARP_PRIVATE
Xstruct EnvBase {
X struct Library LibNode; /* Standard library node for linkage */
X BYTE *EnvSpace; /* Access only when Forbidden! */
X ULONG EnvSize; /* Total allocated mem for EnvSpace */
X struct ArpBase *ArpBase; /* Added in V32 for Resource Tracking */
X };
X#endif /* ARP_PRIVATE */
X
X/*
X ************************************************************************
X * These are used in release 33.4 but not by the library code. *
X * Instead, individual programs check for these flags. *
X ************************************************************************
X */
X#define ARPB_WILD_WORLD 0L ; Mixed BCPL/Normal wildcards.
X#define ARPB_WILD_BCPL 1L ; Pure BCPL wildcards.
X
X#define ARPF_WILD_WORLD (1L << ARPB_WILD_WORLD)
X#define ARPF_WILD_BCPL (1L << ARPB_WILD_BCPL)
X
X/*
X ************************************************************************
X * The alert object is what you use if you really must return an alert *
X * to the user. You would normally OR this with another alert number *
X * from the alerts.h file. Generally, should be NON deadend alerts. *
X * *
X * For example, if you can't open ArpLibrary: *
X * Alert( (AG_OpenLib|AO_ArpLib), 0L); *
X ************************************************************************
X */
X#define AO_ArpLib 0x00008036L /* Alert object */
X
X/*
X ************************************************************************
X * Alerts that arp.library may return... *
X ************************************************************************
X */
X#define AN_ArpLib 0x03600000L /* Alert number */
X#define AN_ArpNoMem 0x03610000L /* No more memory */
X#define AN_ArpInputMem 0x03610002L /* No memory for input buffer */
X#define AN_ArpNoMakeEnv 0x83610003L /* No memory to make EnvLib */
X
X#define AN_ArpNoDOS 0x83630001L /* Can't open dos.library */
X#define AN_ArpNoGfx 0x83630002L /* Can't open graphics.library */
X#define AN_ArpNoIntuit 0x83630003L /* Can't open intuition */
X#define AN_BadPackBlues 0x83640000L /* Bad packet returned to SendPacket() */
X#define AN_Zombie 0x83600003L /* Zombie roaming around system */
X
X#define AN_ArpScattered 0x83600002L /* Scatter loading not allowed for arp */
X
X
X/*
X ************************************************************************
X * Return codes you can get from calling ARP Assign()... *
X ************************************************************************
X */
X#define ASSIGN_OK 0L /* Everything is cool and groovey */
X#define ASSIGN_NODEV 1L /* "Physical" is not valid for assignment */
X#define ASSIGN_FATAL 2L /* Something really icky happened */
X#define ASSIGN_CANCEL 3L /* Tried to cancel something but it won't cancel */
X
X/*
X ************************************************************************
X * Size of buffer you need if you are going to call ReadLine() *
X ************************************************************************
X */
X#define MaxInputBuf 256L
X
X/*
X ************************************************************************
X * The ARP file requester data structure... *
X ************************************************************************
X */
X
X /* This whole part has to be skipped if libraries/asl.h is
X * pulled in before arpbase.h is included (which is the recommended
X * sequence). -olsen
X */
X
X#ifndef LIBRARIES_ASL_H
X#define LIBRARIES_ASL_H 1 /* mool: don't use libraries/asl.h */
X
X /* You know req.library? -olsen */
X
X#ifndef REQLIBRARY_H
X
Xstruct FileRequester {
X BYTE *fr_Hail; /* Hailing text */
X BYTE *fr_File; /* Filename array (FCHARS + 1) */
X BYTE *fr_Dir; /* Directory array (DSIZE + 1) */
X struct Window *fr_Window; /* Window requesting or NULL */
X UBYTE fr_FuncFlags; /* Set bitdef's below */
X UBYTE fr_Flags2; /* New flags... */
X VOID (*fr_Function)(); /* Your function, see bitdef's */
X WORD fr_LeftEdge; /* To be used later... */
X WORD fr_TopEdge;
X };
X
X#endif /* REQLIBRARY_H */
X
X/*
X ************************************************************************
X * The following are the defines for fr_FuncFlags. These bits tell *
X * FileRequest() what your fr_UserFunc is expecting, and what *
X * FileRequest() should call it for. *
X * *
X * You are called like so: *
X * fr_Function(Mask, Object) *
X * ULONG Mask; *
X * CPTR *Object; *
X * *
X * The Mask is a copy of the flag value that caused FileRequest() to *
X * call your function. You can use this to determine what action you *
X * need to perform, and exactly what Object is, so you know what to do *
X * and what to return. *
X ************************************************************************
X */
X#define FRB_DoWildFunc 7L /* Call me with a FIB and a name, ZERO return accepts. */
X#define FRB_DoMsgFunc 6L /* You get all IDCMP messages not for FileRequest() */
X#define FRB_DoColor 5L /* Set this bit for that new and different look */
X#define FRB_NewIDCMP 4L /* Force a new IDCMP (only if fr_Window != NULL) */
X#define FRB_NewWindFunc 3L /* You get to modify the newwindow structure. */
X#define FRB_AddGadFunc 2L /* You get to add gadgets. */
X#define FRB_GEventFunc 1L /* Function to call if one of your gadgets is selected. */
X#define FRB_ListFunc 0L /* Not implemented yet. */
X
X#define FRF_DoWildFunc (1L << FRB_DoWildFunc)
X#define FRF_DoMsgFunc (1L << FRB_DoMsgFunc)
X#define FRF_DoColor (1L << FRB_DoColor)
X#define FRF_NewIDCMP (1L << FRB_NewIDCMP)
X#define FRF_NewWindFunc (1L << FRB_NewWindFunc)
X#define FRF_AddGadFunc (1L << FRB_AddGadFunc)
X#define FRF_GEventFunc (1L << FRB_GEventFunc)
X#define FRF_ListFunc (1L << FRB_ListFunc)
X
X/*
X ************************************************************************
X * The FR2B_ bits are for fr_Flags2 in the file requester structure *
X ************************************************************************
X */
X#define FR2B_LongPath 0L /* Specify the fr_Dir buffer is 256 bytes long */
X
X#define FR2F_LongPath (1L << FR2B_LongPath)
X
X/*
X ************************************************************************
X * The sizes of the different buffers... *
X ************************************************************************
X */
X#define FCHARS 32L /* Filename size */
X#define DSIZE 33L /* Directory name size if not FR2B_LongPath */
X
X#define LONG_DSIZE 254L /* If FR2B_LongPath is set, use LONG_DSIZE */
X#define LONG_FSIZE 126L /* For compatibility with ARPbase.i */
X
X#define FR_FIRST_GADGET 0x7680L /* User gadgetID's must be less than this value */
X
X#endif /* LIBRARIES_ASL_H */
X
X#ifndef DOS_DOSASL_H /* mool: either this or dos/dosasl.h */
X#define DOS_DOSASL_H
X/*
X ************************************************************************
X * Structure expected by FindFirst()/FindNext() *
X * *
X * You need to allocate this structure and initialize it as follows: *
X * *
X * Set ap_BreakBits to the signal bits (CDEF) that you want to take a *
X * break on, or NULL, if you don't want to convenience the user. *
X * *
X * if you want to have the FULL PATH NAME of the files you found, *
X * allocate a buffer at the END of this structure, and put the size of *
X * it into ap_StrLen. If you don't want the full path name, make sure *
X * you set ap_StrLen to zero. In this case, the name of the file, and *
X * stats are available in the ap_Info, as per usual. *
X * *
X * Then call FindFirst() and then afterwards, FindNext() with this *
X * structure. You should check the return value each time (see below) *
X * and take the appropriate action, ultimately calling *
X * FreeAnchorChain() when there are no more files and you are done. *
X * You can tell when you are done by checking for the normal AmigaDOS *
X * return code ERROR_NO_MORE_ENTRIES. *
X * *
X * You will also have to check the DirEntryType variable in the ap_Info *
X * structure to determine what exactly you have received. *
X ************************************************************************
X */
Xstruct AnchorPath {
X struct AChain *ap_Base; /* Pointer to first anchor */
X struct AChain *ap_Last; /* Pointer to last anchor */
X LONG ap_BreakBits; /* Bits to break on */
X LONG ap_FoundBreak; /* Bits we broke on. Also returns ERROR_BREAK */
X BYTE ap_Flags; /* New use for the extra word... */
X BYTE ap_Reserved; /* To fill it out... */
X WORD ap_StrLen; /* This is what used to be ap_Length */
X struct FileInfoBlock ap_Info;
X BYTE ap_Buf[1]; /* Allocate a buffer here, if desired */
X };
X
X#define ap_Length ap_StrLen
X
X/*
X ************************************************************************
X * Bit definitions for the new ap_Flags... *
X ************************************************************************
X */
X#define APB_DoWild 0L /* User option ALL */
X#define APB_ItsWild 1L /* Set by FindFirst, used by FindNext */
X#define APB_DoDir 2L /* Bit is SET if a DIR node should be entered */
X /* Application can RESET this bit to AVOID */
X /* entering a dir. */
X#define APB_DidDir 3L /* Bit is set for an "expired" dir node */
X#define APB_NoMemErr 4L /* Set if there was not enough memory */
X#define APB_DoDot 5L /* If set, '.' (DOT) will convert to CurrentDir */
X
X#define APF_DoWild (1L << APB_DoWild)
X#define APF_ItsWild (1L << APB_ItsWild)
X#define APF_DoDir (1L << APB_DoDir)
X#define APF_DidDir (1L << APB_DidDir)
X#define APF_NoMemErr (1L << APB_NoMemErr)
X#define APF_DoDot (1L << APB_DoDot)
X
X/*
X ************************************************************************
X * Structure used by the pattern matching functions, no need to obtain, *
X * diddle or allocate this yourself. *
X * *
X * Note: If you did, you will now break as it has changed... *
X ************************************************************************
X */
X#ifdef ARP_PRIVATE
Xstruct AChain {
X struct AChain *an_Child;
X struct AChain *an_Parent;
X struct FileLock *an_Lock;
X struct FileInfoBlock *an_Info;
X BYTE an_Flags;
X char an_String[1]; /* Just as is .i file */
X }; /* ??? Don't use this! */
X#endif /* ARP_PRIVATE */
X
X#define DDB_PatternBit 0L
X#define DDB_ExaminedBit 1L
X#define DDB_Completed 2L
X#define DDB_AllBit 3L
X
X#define DDF_PatternBit (1L << DDB_PatternBit)
X#define DDF_ExaminedBit (1L << DDB_ExaminedBit)
X#define DDF_Completed (1L << DDB_Completed)
X#define DDF_AllBit (1L << DDB_AllBit)
X
X/*
X ************************************************************************
X * This structure takes a pointer, and returns FALSE if wildcard was *
X * not found by FindFirst() *
X ************************************************************************
X */
X#define IsWild( ptr ) ( *((LONG *)(ptr)) )
X
X/*
X ************************************************************************
X * Constants used by wildcard routines *
X * *
X * These are the pre-parsed tokens referred to by pattern match. It *
X * is not necessary for you to do anything about these, FindFirst() *
X * FindNext() handle all these for you. *
X ************************************************************************
X */
X#define P_ANY 0x80L /* Token for '*' | '#?' */
X#define P_SINGLE 0x81L /* Token for '?' */
X
X/*
X ************************************************************************
X * No need to muck with these as they may change... *
X ************************************************************************
X */
X#ifdef ARP_PRIVATE
X#define P_ORSTART 0x82L /* Token for '(' */
X#define P_ORNEXT 0x83L /* Token for '|' */
X#define P_OREND 0x84L /* Token for ')' */
X#define P_NOT 0x85L /* Token for '~' */
X#define P_NOTCLASS 0x87L /* Token for '^' */
X#define P_CLASS 0x88L /* Token for '[]' */
X#define P_REPBEG 0x89L /* Token for '[' */
X#define P_REPEND 0x8AL /* Token for ']' */
X#endif /* ARP_PRIVATE */
X
X#define ERROR_BUFFER_OVERFLOW 303L /* User or internal buffer overflow */
X#define ERROR_BREAK 304L /* A break character was received */
X#define ERROR_NOT_EXECUTABLE 305L /* A file has E bit cleared */
X /* dos/dosasl.h uses a good lot of the symbols and structures
X * defined here (AnchorPatch, AChain, ERROR_BREAK and the
X * like), so let's don't include it again.
X */
X
X/* #define DOS_DOSASL_H 1 */
X#endif /* added by mool */
X
X/*
X ************************************************************************
X * Structure used by AddDANode(), AddDADevs(), FreeDAList(). *
X * *
X * This structure is used to create lists of names, which normally *
X * are devices, assigns, volumes, files, or directories. *
X ************************************************************************
X */
Xstruct DirectoryEntry {
X struct DirectoryEntry *de_Next; /* Next in list */
X BYTE de_Type; /* DLX_mumble */
X BYTE de_Flags; /* For future expansion, DO NOT USE! */
X BYTE de_Name[1]; /* The name of the thing found */
X };
X
X/*
X ************************************************************************
X * Defines you use to get a list of the devices you want to look at. *
X * For example, to get a list of all directories and volumes, do: *
X * *
X * AddDADevs( mydalist, (DLF_DIRS | DLF_VOLUMES) ) *
X * *
X * After this, you can examine the de_type field of the elements added *
X * to your list (if any) to discover specifics about the objects added. *
X * *
X * Note that if you want only devices which are also disks, you must *
X * (DLF_DEVICES | DLF_DISKONLY). *
X ************************************************************************
X */
X#define DLB_DEVICES 0L /* Return devices */
X#define DLB_DISKONLY 1L /* Modifier for above: Return disk devices only */
X#define DLB_VOLUMES 2L /* Return volumes only */
X#define DLB_DIRS 3L /* Return assigned devices only */
X
X#define DLF_DEVICES (1L << DLB_DEVICES)
X#define DLF_DISKONLY (1L << DLB_DISKONLY)
X#define DLF_VOLUMES (1L << DLB_VOLUMES)
X#define DLF_DIRS (1L << DLB_DIRS)
X
X/*
X ************************************************************************
X * Legal de_Type values, check for these after a call to AddDADevs(), *
X * or use on your own as the ID values in AddDANode(). *
X ************************************************************************
X */
X#define DLX_FILE 0L /* AddDADevs() can't determine this */
X#define DLX_DIR 8L /* AddDADevs() can't determine this */
X#define DLX_DEVICE 16L /* It's a resident device */
X
X#define DLX_VOLUME 24L /* Device is a volume */
X#define DLX_UNMOUNTED 32L /* Device is not resident */
X
X#define DLX_ASSIGN 40L /* Device is a logical assignment */
X
X/*
X ************************************************************************
X * This macro is to check for an error return from the Atol() *
X * routine. If Errno is ERRBADINT, then there was an error... *
X * This was done to try to remain as close to source compatible *
X * as possible with the older (rel 1.1) ARPbase.h *
X ************************************************************************
X */
X#define ERRBADINT 1L
X#define Errno (IoErr() ? ERRBADINT : 0)
X
X/*
X ************************************************************************
X * Resource Tracking stuff... *
X ************************************************************************
X * *
X * There are a few things in arp.library that are only directly *
X * acessable from assembler. The glue routines provided by us for *
X * all 'C' compilers use the following conventions to make these *
X * available to C programs. The glue for other language's should use *
X * as similar a mechanism as possible, so that no matter what language *
X * or compiler we speak, when talk about arp, we will know what the *
X * other guy is saying. *
X * *
X * Here are the cases: *
X * *
X * Tracker calls... *
X * These calls return the Tracker pointer as a secondary *
X * result in the register A1. For C, there is no clean *
X * way to return more than one result so the tracker *
X * pointer is returned in IoErr(). For ease of use, *
X * there is a define that typecasts IoErr() to the correct *
X * pointer type. This is called LastTracker and should *
X * be source compatible with the earlier method of storing *
X * the secondary result. *
X * *
X * GetTracker() - *
X * Syntax is a bit different for C than the assembly call *
X * The C syntax is GetTracker(ID). The binding routines *
X * will store the ID into the tracker on return. Also, *
X * in an effort to remain consistant, the tracker will *
X * also be stored in LastTracker. *
X * *
X * In cases where you have allocated a tracker before you have obtained *
X * a resource (usually the most efficient method), and the resource has *
X * not been obtained, you will need to clear the tracker id. The macro *
X * CLEAR_ID() has been provided for that purpose. It expects a pointer *
X * to a DefaultTracker sort of struct. *
X ************************************************************************
X */
X#define CLEAR_ID(t) ((SHORT *) t)[-1]=NULL
X
X/*
X ************************************************************************
X * You MUST prototype IoErr() to prevent the possible error in defining *
X * IoErr() and thus causing LastTracker to give you trash... *
X * *
X * N O T E ! You MUST! have IoErr() defined as LONG to use LastTracker *
X * If your compiler has other defines for this, you may wish *
X * to remove the prototype for IoErr(). *
X ************************************************************************
X */
X#define LastTracker ((struct DefaultTracker *)IoErr())
X
X/*
X ************************************************************************
X * The rl_FirstItem list (ResList) is a list of TrackedResource (below) *
X * It is very important that nothing in this list depend on the task *
X * existing at resource freeing time (i.e., RemTask(0L) type stuff, *
X * DeletePort() and the rest). *
X * *
X * The tracking functions return a struct Tracker *Tracker to you, this *
X * is a pointer to whatever follows the tr_ID variable. *
X * The default case is reflected below, and you get it if you call *
X * GetTracker() ( see DefaultTracker below). *
X * *
X * NOTE: The two user variables mentioned in an earlier version don't *
X * exist, and never did. Sorry about that (SDB). *
X * *
X * However, you can still use ArpAlloc() to allocate your own tracking *
X * nodes and they can be any size or shape you like, as long as the *
X * base structure is preserved. They will be freed automagically just *
X * like the default trackers. *
X ************************************************************************
X */
Xstruct TrackedResource {
X struct MinNode tr_Node; /* Double linked pointer */
X BYTE tr_Flags; /* Don't touch */
X BYTE tr_Lock; /* Don't touch, for Get/FreeAccess() */
X SHORT tr_ID; /* Item's ID */
X
X/*
X ************************************************************************
X * The struct DefaultTracker *Tracker portion of the structure. *
X * The stuff below this point can conceivably vary, depending *
X * on user needs, etc. This reflects the default. *
X ************************************************************************
X */
X union {
X CPTR tr_Resource; /* Whatever */
X LONG tg_Verify; /* For use during TRAK_GENERIC */
X } tr_Object; /* The thing being tracked */
X union {
X VOID (*tg_Function)();/* Function to call for TRAK_GENERIC */
X struct Window *tr_Window2; /* For TRAK_WINDOW */
X } tr_Extra; /* Only needed sometimes */
X };
X
X#define tg_Value tg_Verify /* Ancient compatibility only! Do NOT use in new CODE!!! */
X
X/*
X ************************************************************************
X * You get a pointer to a struct of the following type when you call *
X * GetTracker(). You can change this, and use ArpAlloc() instead of *
X * GetTracker() to do tracking. Of course, you have to take a wee bit *
X * more responsibility if you do, as well as if you use TRAK_GENERIC *
X * stuff. *
X * *
X * TRAK_GENERIC folks need to set up a task function to be called when *
X * an item is freed. Some care is required to set this up properly. *
X * *
X * Some special cases are indicated by the unions below, for *
X * TRAK_WINDOW, if you have more than one window opened, and don't *
X * want the IDCMP closed particularly, you need to set a ptr to the *
X * other window in dt_Window2. See CloseWindowSafely() for more info. *
X * If only one window, set this to NULL. *
X ************************************************************************
X */
Xstruct DefaultTracker {
X union {
X CPTR dt_Resource; /* Whatever */
X LONG tg_Verify; /* For use during TRAK_GENERIC */
X } dt_Object; /* The object being tracked */
X union {
X VOID (*tg_Function)();/* Function to call for TRAK_GENERIC */
X struct Window *dt_Window2; /* For TRAK_WINDOW */
X } dt_Extra;
X };
X
X/*
X ************************************************************************
X * Items the tracker knows what to do about *
X ************************************************************************
X */
X#define TRAK_AAMEM 0L /* Default (ArpAlloc) element */
X#define TRAK_LOCK 1L /* File lock */
X#define TRAK_FILE 2L /* Opened file */
X#define TRAK_WINDOW 3L /* Window -- see docs */
X#define TRAK_SCREEN 4L /* Screen */
X#define TRAK_LIBRARY 5L /* Opened library */
X#define TRAK_DAMEM 6L /* Pointer to DosAllocMem block */
X#define TRAK_MEMNODE 7L /* AllocEntry() node */
X#define TRAK_SEGLIST 8L /* Program segment */
X#define TRAK_RESLIST 9L /* ARP (nested) ResList */
X#define TRAK_MEM 10L /* Memory ptr/length */
X#define TRAK_GENERIC 11L /* Generic Element, your choice */
X#define TRAK_DALIST 12L /* DAlist ( aka file request ) */
X#define TRAK_ANCHOR 13L /* Anchor chain (pattern matching) */
X#define TRAK_FREQ 14L /* FileRequest struct */
X#define TRAK_FONT 15L /* GfxBase CloseFont() */
X#define TRAK_MAX 15L /* Poof, anything higher is tossed */
X
X#define TRB_UNLINK 7L /* Free node bit */
X#define TRB_RELOC 6L /* This may be relocated (not used yet) */
X#define TRB_MOVED 5L /* Item moved */
X
X#define TRF_UNLINK (1L << TRB_UNLINK)
X#define TRF_RELOC (1L << TRB_RELOC)
X#define TRF_MOVED (1L << TRB_MOVED)
X
X/*
X ************************************************************************
X * Note: ResList MUST be a DosAllocMem'ed list!, this is done for *
X * you when you call CreateTaskResList(), typically, you won't need *
X * to access/allocate this structure. *
X ************************************************************************
X */
Xstruct ResList {
X struct MinNode rl_Node; /* Used by arplib to link reslists */
X struct Task *rl_TaskID; /* Owner of this list */
X struct MinList rl_FirstItem; /* List of Tracked Resources */
X struct ResList *rl_Link; /* SyncRun's use - hide list here */
X };
X
X/*
X ************************************************************************
X * Returns from CompareLock() *
X ************************************************************************
X */
X#define LCK_EQUAL 0L /* The two locks refer to the same object */
X#define LCK_VOLUME 1L /* Locks are on the same volume */
X#define LCK_DIFVOL1 2L /* Locks are on different volumes */
X#define LCK_DIFVOL2 3L /* Locks are on different volumes */
X
X/*
X ************************************************************************
X * ASyncRun() stuff... *
X ************************************************************************
X * Message sent back on your request by an exiting process. *
X * You request this by putting the address of your message in *
X * pcb_LastGasp, and initializing the ReplyPort variable of your *
X * ZombieMsg to the port you wish the message posted to. *
X ************************************************************************
X */
Xstruct ZombieMsg {
X struct Message zm_ExecMessage;
X ULONG zm_TaskNum; /* Task ID */
X LONG zm_ReturnCode; /* Process's return code */
X ULONG zm_Result2; /* System return code */
X struct DateStamp zm_ExitTime; /* Date stamp at time of exit */
X ULONG zm_UserInfo; /* For whatever you wish */
X };
X
X/*
X ************************************************************************
X * Structure required by ASyncRun() -- see docs for more info. *
X ************************************************************************
X */
Xstruct ProcessControlBlock {
X ULONG pcb_StackSize; /* Stacksize for new process */
X BYTE pcb_Pri; /* Priority of new task */
X UBYTE pcb_Control; /* Control bits, see defines below */
X APTR pcb_TrapCode; /* Optional Trap Code */
X BPTR pcb_Input;
X BPTR pcb_Output; /* Optional stdin, stdout */
X union {
X BPTR pcb_SplatFile; /* File to use for Open("*") */
X BYTE *pcb_ConName; /* CON: filename */
X } pcb_Console;
X CPTR pcb_LoadedCode; /* If not null, will not load/unload code */
X struct ZombieMsg *pcb_LastGasp; /* ReplyMsg() to be filled in by exit */
X struct MsgPort *pcb_WBProcess; /* Valid only when PRB_NOCLI */
X };
X
X/*
X ************************************************************************
X * Formerly needed to pass NULLCMD to a child. No longer needed. *
X * It is being kept here for compatibility only... *
X ************************************************************************
X */
X#define NOCMD "\n"
X
X/*
X ************************************************************************
X * The following control bits determine what ASyncRun() does on *
X * Abnormal Exits and on background process termination. *
X ************************************************************************
X */
X#define PRB_SAVEIO 0L /* Don't free/check file handles on exit */
X#define PRB_CLOSESPLAT 1L /* Close Splat file, must request explicitly */
X#define PRB_NOCLI 2L /* Don't create a CLI process */
X/* PRB_INTERACTIVE 3L This is now obsolete... */
X#define PRB_CODE 4L /* Dangerous yet enticing */
X#define PRB_STDIO 5L /* Do the stdio thing, splat = CON:Filename */
X
X#define PRF_SAVEIO (1L << PRB_SAVEIO)
X#define PRF_CLOSESPLAT (1L << PRB_CLOSESPLAT)
X#define PRF_NOCLI (1L << PRB_NOCLI)
X#define PRF_CODE (1L << PRB_CODE)
X#define PRF_STDIO (1L << PRB_STDIO)
X
X/*
X ************************************************************************
X * Error returns from SyncRun() and ASyncRun() *
X ************************************************************************
X */
X#define PR_NOFILE -1L /* Could not LoadSeg() the file */
X#define PR_NOMEM -2L /* No memory for something */
X/* PR_NOCLI -3L This is now obsolete */
X#define PR_NOSLOT -4L /* No room in TaskArray */
X#define PR_NOINPUT -5L /* Could not open input file */
X#define PR_NOOUTPUT -6L /* Could not get output file */
X/* PR_NOLOCK -7L This is now obsolete */
X/* PR_ARGERR -8L This is now obsolete */
X/* PR_NOBCPL -9L This is now obsolete */
X/* PR_BADLIB -10L This is now obsolete */
X#define PR_NOSTDIO -11L /* Couldn't get stdio handles */
X
X/*
X ************************************************************************
X * Added V35 of arp.library *
X ************************************************************************
X */
X#define PR_WANTSMESSAGE -12L /* Child wants you to report IoErr() to user */
X /* for SyncRun() only... */
X#define PR_NOSHELLPROC -13L /* Can't create a shell/cli process */
X#define PR_NOEXEC -14L /* 'E' bit is clear */
X#define PR_SCRIPT -15L /* S and E are set, IoErr() contains directory */
X
X/*
X ************************************************************************
X * Version 35 ASyncRun() allows you to create an independent *
X * interactive or background Shell/CLI. You need this variant of the *
X * pcb structure to do it, and you also have new values for nsh_Control,*
X * see below. *
X * *
X * Syntax for Interactive shell is: *
X * *
X * rc=ASyncRun("Optional Window Name","Optional From File",&NewShell); *
X * *
X * Syntax for a background shell is: *
X * *
X * rc=ASyncRun("Command line",0L,&NewShell); *
X * *
X * Same syntax for an Execute style call, but you have to be on drugs *
X * if you want to do that. *
X ************************************************************************
X */
Xstruct NewShell {
X ULONG nsh_StackSize; /* stacksize shell will use for children */
X BYTE nsh_Pri; /* ignored by interactive shells */
X UBYTE nsh_Control; /* bits/values: see above */
X CPTR nsh_LogMsg; /* Optional login message, if null, use default */
X BPTR nsh_Input; /* ignored by interactive shells, but */
X BPTR nsh_Output; /* used by background and execute options. */
X LONG nsh_RESERVED[5];
X };
X
X/*
X ************************************************************************
X * Bit Values for nsh_Control, you should use them as shown below, or *
X * just use the actual values indicated. *
X ************************************************************************
X */
X#define PRB_CLI 0L /* Do a CLI, not a shell */
X#define PRB_BACKGROUND 1L /* Background shell */
X#define PRB_EXECUTE 2L /* Do as EXECUTE... */
X#define PRB_INTERACTIVE 3L /* Run an interactive shell */
X#define PRB_FB 7L /* Alt function bit... */
X
X#define PRF_CLI (1L << PRB_CLI)
X#define PRF_BACKGOUND (1L << PRB_BACKGROUND)
X#define PRF_EXECUTE (1L << PRB_EXECUTE)
X#define PRF_INTERACTIVE (1L << PRB_INTERACTIVE)
X#define PRF_FB (1L << PRB_FB)
X
X/*
X ************************************************************************
X * Common values for sh_Control which allow you to do usefull *
X * and somewhat "standard" things... *
X ************************************************************************
X */
X#define INTERACTIVE_SHELL (PRF_FB|PRF_INTERACTIVE) /* Gimme a newshell! */
X#define INTERACTIVE_CLI (PRF_FB|PRF_INTERACTIVE|PRF_CLI) /* Gimme that ol newcli! */
X#define BACKGROUND_SHELL (PRF_FB|PRF_BACKGROUND) /* gimme a background shell */
X#define EXECUTE_ME (PRF_FB|PRF_BACKGROUND|PRF_EXECUTE) /* aptly named, doncha think? */
X
X/*
X ************************************************************************
X * Additional IoErr() returns added by ARP... *
X ************************************************************************
X */
X#define ERROR_NOT_CLI 400L /* Program/function neeeds to be cli */
X
X/*
X ************************************************************************
X * Resident Program Support *
X ************************************************************************
X * This is the kind of node allocated for you when you AddResidentPrg() *
X * a code segment. They are stored as a single linked list with the *
X * root in ArpBase. If you absolutely *must* wander through this list *
X * instead of using the supplied functions, then you must first obtain *
X * the semaphore which protects this list, and then release it *
X * afterwards. Do not use Forbid() and Permit() to gain exclusive *
X * access! Note that the supplied functions handle this locking *
X * protocol for you. *
X ************************************************************************
X */
Xstruct ResidentProgramNode {
X struct ResidentProgramNode *rpn_Next; /* next or NULL */
X LONG rpn_Usage; /* Number of current users */
X UWORD rpn_AccessCnt; /* Total times used... */
X ULONG rpn_CheckSum; /* Checksum of code */
X BPTR rpn_Segment; /* Actual segment */
X UWORD rpn_Flags; /* See definitions below... */
X BYTE rpn_Name[1]; /* Allocated as needed */
X };
X
X/*
X ************************************************************************
X * Bit definitions for rpn_Flags.... *
X ************************************************************************
X */
X#define RPNB_NOCHECK 0L /* Set in rpn_Flags for no checksumming... */
X#define RPNB_CACHE 1L /* Private usage in v1.3... */
X
X#define RPNF_NOCHECK (1L << RPNB_NOCHECK)
X#define RPNF_CACHE (1L << RPNB_CACHE)
X
X/*
X ************************************************************************
X * If your program starts with this structure, ASyncRun() and SyncRun() *
X * will override a users stack request with the value in rpt_StackSize. *
X * Furthermore, if you are actually attached to the resident list, a *
X * memory block of size rpt_DataSize will be allocated for you, and *
X * a pointer to this data passed to you in register A4. You may use *
X * this block to clone the data segment of programs, thus resulting in *
X * one copy of text, but multiple copies of data/bss for each process *
X * invocation. If you are resident, your program will start at *
X * rpt_Instruction, otherwise, it will be launched from the initial *
X * branch. *
X ************************************************************************
X */
Xstruct ResidentProgramTag {
X BPTR rpt_NextSeg; /* Provided by DOS at LoadSeg time */
X/*
X ************************************************************************
X * The initial branch destination and rpt_Instruction do not have to be *
X * the same. This allows different actions to be taken if you are *
X * diskloaded or resident. DataSize memory will be allocated only if *
X * you are resident, but StackSize will override all user stack *
X * requests. *
X ************************************************************************
X */
X UWORD rpt_BRA; /* Short branch to executable */
X UWORD rpt_Magic; /* Resident majik value */
X ULONG rpt_StackSize; /* min stack for this process */
X ULONG rpt_DataSize; /* Data size to allocate if resident */
X /* rpt_Instruction; Start here if resident */
X };
X
X/*
X ************************************************************************
X * The form of the ARP allocated node in your tasks memlist when *
X * launched as a resident program. Note that the data portion of the *
X * node will only exist if you have specified a nonzero value for *
X * rpt_DataSize. Note also that this structure is READ ONLY, modify *
X * values in this at your own risk. The stack stuff is for tracking, *
X * if you need actual addresses or stack size, check the normal places *
X * for it in your process/task struct. *
X ************************************************************************
X */
Xstruct ProcessMemory {
X struct Node pm_Node;
X UWORD pm_Num; /* This is 1 if no data, two if data */
X CPTR pm_Stack;
X ULONG pm_StackSize;
X CPTR pm_Data; /* Only here if pm_Num == 2 */
X ULONG pm_DataSize;
X };
X
X/*
X ************************************************************************
X * To find the above on your memlist, search for the following name. *
X * We guarantee this will be the only arp.library allocated node on *
X * your memlist with this name. *
X * i.e. FindName(task->tcb_MemEntry, PMEM_NAME); *
X ************************************************************************
X */
X#define PMEM_NAME "ARP_MEM"
X
X#define RESIDENT_MAGIC 0x4AFC /* same as RTC_MATCHWORD (trapf) */
X
X/*
X ************************************************************************
X * Date String/Data structures *
X ************************************************************************
X */
X#ifndef DOS_DATETIME_H /* added by mool */
X#define DOS_DATETIME_H
X
Xstruct DateTime {
X struct DateStamp dat_Stamp; /* DOS Datestamp */
X UBYTE dat_Format; /* controls appearance ot dat_StrDate */
X UBYTE dat_Flags; /* See BITDEF's below */
X BYTE *dat_StrDay; /* day of the week string */
X BYTE *dat_StrDate; /* date string */
X BYTE *dat_StrTime; /* time string */
X };
X
X/*
X ************************************************************************
X * Size of buffer you need for each DateTime strings: *
X ************************************************************************
X */
X#define LEN_DATSTRING 10L
X
X/*
X ************************************************************************
X * For dat_Flags *
X ************************************************************************
X */
X#define DTB_SUBST 0L /* Substitute "Today" "Tomorrow" where appropriate */
X#define DTB_FUTURE 1L /* Day of the week is in future */
X
X#define DTF_SUBST (1L << DTB_SUBST)
X#define DTF_FUTURE (1L << DTB_FUTURE)
X
X/*
X ************************************************************************
X * For dat_Format *
X ************************************************************************
X */
X#define FORMAT_DOS 0L /* dd-mmm-yy AmigaDOS's own, unique style */
X#define FORMAT_INT 1L /* yy-mm-dd International format */
X#define FORMAT_USA 2L /* mm-dd-yy The good'ol'USA. */
X#define FORMAT_CDN 3L /* dd-mm-yy Our brothers and sisters to the north */
X#define FORMAT_MAX FORMAT_CDN /* Larger than this? Defaults to AmigaDOS */
X
X /* dos/datetime.h uses the same structures and defines, so
X * keep the compiler from pulling it in. -olsen
X */
X
X/* #define DOS_DATETIME_H 1 */
X#endif
X
X/*
X ************************************************************************
X * Define NO_PROTOTYPES if your compiler does not handle them... *
X ************************************************************************
X */
X#if defined(NO_PROTOTYPES) || defined(__NO_PROTOS)
X#define ARGs(x) ()
X#else
X#define ARGs(x) x
X
X /* Added ArpVPrintf, ArpVFPrintf and ArpVSPrintf, so will have to
X * include the compiler specific stdarg header file. -olsen
X */
X
X#include <stdarg.h>
X
X#endif /* NO_PROTOTYPES */
X
X/*
X ************************************************************************
X * Note that C_Args is a #define that, in LATTICE does __stdargs *
X ************************************************************************
X */
X
X/*
X ************************************************************************
X * This prototype is here to prevent the possible error in defining *
X * IoErr() as LONG and thus causing LastTracker to give you trash... *
X * *
X * N O T E ! You MUST! have IoErr() defined as LONG to use LastTracker *
X * If your compiler has other defines for this, you may wish *
X * to move the prototype for IoErr() into the DO_ARP_COPIES *
X ************************************************************************
X */
X LONG IoErr ARGs( (VOID) );
X
X/*
X ************************************************************************
X * These duplicate the calls in dos.library *
X * Only include if you can use arp.library without dos.library *
X ************************************************************************
X */
X#ifdef DO_ARP_COPIES
X BPTR Open ARGs( (char *, LONG) );
X VOID Close ARGs( (BPTR) );
X LONG Read ARGs( (BPTR, char *, LONG) );
X LONG Write ARGs( (BPTR, char *, LONG) );
X BPTR Input ARGs( (VOID) );
X BPTR Output ARGs( (VOID) );
X LONG Seek ARGs( (BPTR, LONG, LONG) );
X LONG DeleteFile ARGs( (char *) );
X LONG Rename ARGs( (char *, char *) );
X BPTR Lock ARGs( (char *, LONG) );
X VOID UnLock ARGs( (BPTR) );
X BPTR DupLock ARGs( (BPTR) );
X LONG Examine ARGs( (BPTR, struct FileInfoBlock *) );
X LONG ExNext ARGs( (BPTR, struct FileInfoBlock *) );
X LONG Info ARGs( (BPTR, struct InfoData *) );
X BPTR CreateDir ARGs( (char *) );
X BPTR CurrentDir ARGs( (BPTR) );
Xstruct MsgPort *CreateProc ARGs( (char *, LONG, BPTR, LONG) );
X VOID Exit ARGs( (LONG) );
X BPTR LoadSeg ARGs( (char *) );
X VOID UnLoadSeg ARGs( (BPTR) );
Xstruct MsgPort *DeviceProc ARGs( (char *) );
X LONG SetComment ARGs( (char *, char *) );
X LONG SetProtection ARGs( (char *, LONG) );
X LONG *DateStamp ARGs( (LONG *) );
X VOID Delay ARGs( (LONG) );
X LONG WaitForChar ARGs( (BPTR, LONG) );
X BPTR ParentDir ARGs( (BPTR) );
X LONG IsInteractive ARGs( (BPTR) );
X LONG Execute ARGs( (char *, BPTR, BPTR) );
X#endif /* DO_ARP_COPIES */
X
X/*
X ************************************************************************
X * Now for the stuff that only exists in arp.library... *
X ************************************************************************
X */
X /* LONG C_Args Printf ARGs( (char *,...) ); */
X /* LONG C_Args FPrintf ARGs( (BPTR, char *,...) ); */
X#ifdef SASC
X LONG C_Args Printf ARGs( (UBYTE *,...) );
X LONG C_Args FPrintf ARGs( (BPTR, UBYTE *,...) );
X#else
X LONG C_Args Printf ARGs( (UBYTE *, long, ...) );
X LONG C_Args FPrintf ARGs( (BPTR, UBYTE *, long, ...) );
X#endif
X LONG Puts ARGs( (char *) );
X LONG ReadLine ARGs( (char *) );
X LONG GADS ARGs( (char *, LONG, char *, char **, char *) );
X LONG Atol ARGs( (char *) );
X ULONG EscapeString ARGs( (char *) );
X LONG CheckAbort ARGs( (VOID(*)) );
X LONG CheckBreak ARGs( (LONG, VOID(*)) );
X BYTE *Getenv ARGs( (char *, char *, LONG) );
X BOOL Setenv ARGs( (char *, char *) );
X BYTE *FileRequest ARGs( (struct FileRequester *) );
X VOID CloseWindowSafely ARGs( (struct Window *, LONG) );
X/* struct MsgPort *CreatePort ARGs( (const char *, LONG) ); */
Xstruct MsgPort *CreatePort ARGs( (UBYTE *, LONG) );
X VOID DeletePort ARGs( (struct MsgPort *) );
X LONG SendPacket ARGs( (LONG, LONG *, struct MsgPort *) );
X VOID InitStdPacket ARGs( (LONG, LONG *, struct DosPacket *, struct MsgPort *) );
X ULONG PathName ARGs( (BPTR, char *,LONG) );
X ULONG Assign ARGs( (char *, char *) );
X VOID *DosAllocMem ARGs( (LONG) );
X VOID DosFreeMem ARGs( (VOID *) );
X ULONG BtoCStr ARGs( (char *, BSTR, LONG) );
X ULONG CtoBStr ARGs( (char *, BSTR, LONG) );
Xstruct DeviceList *GetDevInfo ARGs( (struct DeviceList *) );
X BOOL FreeTaskResList ARGs( (VOID) );
X VOID ArpExit ARGs( (LONG,LONG) );
X VOID C_Args *ArpAlloc ARGs( (LONG) );
X VOID C_Args *ArpAllocMem ARGs( (LONG, LONG) );
X BPTR C_Args ArpOpen ARGs( (char *, LONG) );
X BPTR C_Args ArpDupLock ARGs( (BPTR) );
X BPTR C_Args ArpLock ARGs( (char *, LONG) );
X VOID C_Args *RListAlloc ARGs( (struct ResList *, LONG) );
Xstruct Process *FindCLI ARGs( (LONG) );
X BOOL QSort ARGs( (VOID *, LONG, LONG, int(*)) );
X BOOL PatternMatch ARGs( (char *,char *) );
X LONG FindFirst ARGs( (char *, struct AnchorPath *) );
X LONG FindNext ARGs( (struct AnchorPath *) );
X VOID FreeAnchorChain ARGs( (struct AnchorPath *) );
X ULONG CompareLock ARGs( (BPTR, BPTR) );
Xstruct ResList *FindTaskResList ARGs( (VOID) );
Xstruct ResList *CreateTaskResList ARGs( (VOID) );
X VOID FreeResList ARGs( (struct ResList *) );
X VOID FreeTrackedItem ARGs( (struct DefaultTracker *) );
Xstruct DefaultTracker C_Args *GetTracker ARGs( (LONG) );
X VOID *GetAccess ARGs( (struct DefaultTracker *) );
X VOID FreeAccess ARGs( (struct DefaultTracker *) );
X VOID FreeDAList ARGs( (struct DirectoryEntry *) );
Xstruct DirectoryEntry *AddDANode ARGs( (char *, struct DirectoryEntry **, LONG, LONG) );
X ULONG AddDADevs ARGs( (struct DirectoryEntry **, LONG) );
X LONG Strcmp ARGs( (char *, char *) );
X LONG Strncmp ARGs( (char *, char *, LONG) );
X BYTE Toupper ARGs( (BYTE) );
X LONG SyncRun ARGs( (char *, char *, BPTR, BPTR) );
X
X/*
X ************************************************************************
X * Added V32 of arp.library *
X ************************************************************************
X */
X LONG ASyncRun ARGs( (char *, char *, struct ProcessControlBlock *) );
X LONG SpawnShell ARGs( (char *, char *, struct NewShell *) );
X BPTR LoadPrg ARGs( (char *) );
X BOOL PreParse ARGs( (char *, char *) );
X
X/*
X ************************************************************************
X * Added V33 of arp.library *
X ************************************************************************
X */
X BOOL StamptoStr ARGs( (struct DateTime *) );
X BOOL StrtoStamp ARGs( (struct DateTime *) );
Xstruct ResidentProgramNode *ObtainResidentPrg ARGs( (char *) );
Xstruct ResidentProgramNode *AddResidentPrg ARGs( (BPTR, char *) );
X LONG RemResidentPrg ARGs( (char *) );
X VOID UnLoadPrg ARGs( (BPTR) );
X LONG LMult ARGs( (LONG, LONG) );
X LONG LDiv ARGs( (LONG, LONG) );
X LONG LMod ARGs( (LONG, LONG) );
X ULONG CheckSumPrg ARGs( (struct ResidentProgramNode *) );
X VOID TackOn ARGs( (char *, char *) );
X BYTE *BaseName ARGs( (char *) );
Xstruct ResidentProgramNode *ReleaseResidentPrg ARGs( (BPTR) );
X
X/*
X ************************************************************************
X * Added V36 of arp.library *
X ************************************************************************
X */
X LONG C_Args SPrintf ARGs( (char *, char *,...) );
X LONG GetKeywordIndex ARGs( (char *, char *) );
Xstruct Library C_Args *ArpOpenLibrary ARGs( (char *, LONG) );
Xstruct FileRequester C_Args *ArpAllocFreq ARGs( (VOID) );
X
X /* This one's a cutie which is supported via bypassing the
X * ??Printf glue routines. -olsen
X */
X
X LONG ArpVPrintf ARGs( (char *, va_list) );
X LONG ArpVFPrintf ARGs( (BPTR, char *, va_list) );
X LONG ArpVSPrintf ARGs( (char *, char *, va_list) );
X
X/*
X ************************************************************************
X * Check if we should do the pragmas... *
X ************************************************************************
X */
X
X#if !defined(NO_PRAGMAS) && !defined(__NO_PRAGMAS)
X#ifndef PROTO_ARP_H
X#include <proto/arp.h>
X#endif /* PROTO_ARP_H */
X#endif /* NO_PRAGMAS */
X
X#endif /* LIBRARIES_ARPBASE_H */
END_OF_FILE
if test 49919 -ne `wc -c <'vim/src/arpbase.h'`; then
echo shar: \"'vim/src/arpbase.h'\" unpacked with wrong size!
fi
# end of 'vim/src/arpbase.h'
fi
if test -f 'vim/src/term.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/term.h'\"
else
echo shar: Extracting \"'vim/src/term.h'\" \(16147 characters\)
sed "s/^X//" >'vim/src/term.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.

X */
X
X/*
X * This file contains the machine dependent escape sequences that the editor
X * needs to perform various operations. Some of the sequences here are
X * optional. Anything not available should be indicated by a null string. In
X * the case of insert/delete line sequences, the editor checks the capability
X * and works around the deficiency, if necessary.
X */
X
X#ifdef SASC
X/*
X * the SAS C compiler has a bug that makes typedefs being forget sometimes
X */
Xtypedef unsigned char char_u;
X#endif
X
X/*
X * the terminal capabilities are stored in this structure
X * keep in sync with array in term.c
X */
Xtypedef struct _tcarr
X{
X/* output codes */
X char_u *t_name; /* name of this terminal entry */
X char_u *t_el; /* el ce clear to end of line */
X char_u *t_il; /* il1 al add new blank line */
X char_u *t_cil; /* il AL add number of blank lines */
X char_u *t_dl; /* dl1 dl delete line */
X char_u *t_cdl; /* dl DL delete number of lines */
X char_u *t_cs; /* cs scroll region */
X char_u *t_ed; /* clear cl clear screen */
X char_u *t_ci; /* civis vi cursur invisible */
X char_u *t_cv; /* cnorm ve cursur visible */
X char_u *t_cvv; /* cvvis vs cursor very visible */
X char_u *t_tp; /* sgr0 me normal mode */
X char_u *t_ti; /* rev mr reverse mode */
X char_u *t_tb; /* bold md bold mode */
X char_u *t_se; /* rmso se normal mode */
X char_u *t_so; /* smso so standout mode */
X char_u *t_ms; /* msgr ms save to move cursor in reverse mode */
X char_u *t_cm; /* cup cm cursor motion */
X char_u *t_sr; /* ri sr scroll reverse (backward) */
X char_u *t_cri; /* cuf RI cursor number of chars right */
X char_u *t_vb; /* flash vb visual bell */
X char_u *t_ks; /* smkx ks put terminal in "keypad transmit" mode */
X char_u *t_ke; /* rmkx ke out of "keypad transmit" mode */
X char_u *t_ts; /* ti put terminal in termcap mode */
X char_u *t_te; /* te out of termcap mode */
X
X/* key codes */
X char_u *t_ku; /* kcuu1 ku arrow up */
X char_u *t_kd; /* kcud1 kd arrow down */
X char_u *t_kl; /* kcub1 kl arrow left */
X char_u *t_kr; /* kcuf1 kr arrow right */
X char_u *t_sku; /* shift arrow up */
X char_u *t_skd; /* shift arrow down */
X char_u *t_skl; /* kLFT #4 shift arrow left */
X char_u *t_skr; /* kRIT % shift arrow right */
X char_u *t_f1; /* kf1 k1 function key 1 */
X char_u *t_f2; /* kf2 k2 function key 2 */
X char_u *t_f3; /* kf3 k3 function key 3 */
X char_u *t_f4; /* kf4 k4 function key 4 */
X char_u *t_f5; /* kf5 k5 function key 5 */
X char_u *t_f6; /* kf6 k6 function key 6 */
X char_u *t_f7; /* kf7 k7 function key 7 */
X char_u *t_f8; /* kf8 k8 function key 8 */
X char_u *t_f9; /* kf9 k9 function key 9 */
X char_u *t_f10; /* kf10 k; function key 10 */
X char_u *t_sf1; /* kf11 F1 shifted function key 1 */
X char_u *t_sf2; /* kf12 F2 shifted function key 2 */
X char_u *t_sf3; /* kf13 F3 shifted function key 3 */
X char_u *t_sf4; /* kf14 F4 shifted function key 4 */
X char_u *t_sf5; /* kf15 F5 shifted function key 5 */
X char_u *t_sf6; /* kf16 F6 shifted function key 6 */
X char_u *t_sf7; /* kf17 F7 shifted function key 7 */
X char_u *t_sf8; /* kf18 F8 shifted function key 8 */
X char_u *t_sf9; /* kf19 F9 shifted function key 9 */
X char_u *t_sf10; /* kf20 FA shifted function key 10 */
X char_u *t_help; /* khlp %1 help key */
X char_u *t_undo; /* kund &8 undo key */
X /* adjust inchar() for last key entry! */
X
X char_u *t_csc; /* - - cursor relative to scrolling region */
X} Tcarr;
X
Xextern Tcarr term_strings; /* currently used terminal strings */
X
X/*
X * strings used for terminal
X */
X#define T_EL (term_strings.t_el)
X#define T_IL (term_strings.t_il)
X#define T_CIL (term_strings.t_cil)
X#define T_DL (term_strings.t_dl)
X#define T_CDL (term_strings.t_cdl)
X#define T_CS (term_strings.t_cs)
X#define T_ED (term_strings.t_ed)
X#define T_CI (term_strings.t_ci)
X#define T_CV (term_strings.t_cv)
X#define T_CVV (term_strings.t_cvv)
X#define T_TP (term_strings.t_tp)
X#define T_TI (term_strings.t_ti)
X#define T_TB (term_strings.t_tb)
X#define T_SE (term_strings.t_se)
X#define T_SO (term_strings.t_so)
X#define T_MS (term_strings.t_ms)
X#define T_CM (term_strings.t_cm)
X#define T_SR (term_strings.t_sr)
X#define T_CRI (term_strings.t_cri)
X#define T_VB (term_strings.t_vb)
X#define T_KS (term_strings.t_ks)
X#define T_KE (term_strings.t_ke)
X#define T_TS (term_strings.t_ts)
X#define T_TE (term_strings.t_te)
X#define T_CSC (term_strings.t_csc)
X
X
X#ifndef TERMINFO
X# ifndef NO_BUILTIN_TCAPS
X/*
X * here are the builtin termcap entries.
X * They not stored as complete Tcarr structures, as such a structure
X * is to big.
X * Each termcap is a concatenated string of entries, where '\0' characters
X * followed by a skip character sepereate the capabilities. The skip
X * character is the relative structure offset for the following entry.
X * See parse_builtin_tcap() in term.c for all details.
X */
X# define AMIGA_TCAP "amiga\0\
X\0\033[K\0\
X\0\033[L\0\
X\0\033[%dL\0\
X\0\033[M\0\
X\0\033[%dM\0\
X\1\014\0\
X\0\033[0 p\0\
X\0\033[1 p\0\
X\1\033[0m\0\
X\0\033[7m\0\
X\0\033[1m\0\
X\0\033[0m\0\
X\0\033[33m\0\
X\0\001\0\
X\0\033[%i%d;%dH\0\
X\1\033[%dC\0\
X\5\233A\0\
X\0\233B\0\
X\0\233D\0\
X\0\233C\0\
X\0\233T\0\
X\0\233S\0\
X\0\233 A\0\
X\0\233 @\0\
X\0\233\060~\0\
X\0\233\061~\0\
X\0\233\062~\0\
X\0\233\063~\0\
X\0\233\064~\0\
X\0\233\065~\0\
X\0\233\066~\0\
X\0\233\067~\0\
X\0\233\070~\0\
X\0\233\071~\0\
X\0\233\061\060~\0\
X\0\233\061\061~\0\
X\0\233\061\062~\0\
X\0\233\061\063~\0\
X\0\233\061\064~\0\
X\0\233\061\065~\0\
X\0\233\061\066~\0\
X\0\233\061\067~\0\
X\0\233\061\070~\0\
X\0\233\061\071~\0\
X\0\233?~\0\
X\0\0"
X
X# define ATARI_TCAP "atari\0\
X\0\033l\0\
X\0\033L\0\
X\1\033M\0\
X\2\033E\0\
X\0\033f\0\
X\0\033e\0\
X\0\0"
X
X# define ANSI_TCAP "ansi\0\
X\0\033[2K\0\
X\0\033[L\0\
X\0\033[%dL\0\
X\0\033[M\0\
X\0\033[%dM\0\
X\1\033[2J\0\
X\3\033[0m\0\
X\0\033[7m\0\
X\3\001\0\
X\0\033[%i%d;%dH\0\
X\1\033[%dC\0\
X\0\0"
X
X/*
X * These codes are valid when nansi.sys or equivalent has been installed.
X * Function keys on a PC are preceded with a NUL. These are converted into
X * K_NUL '\316' in GetChars(), because we cannot handle NULs in key codes.
X * CTRL-arrow is used instead of SHIFT-arrow.
X */
X# define PCANSI_TCAP "pcansi\0\
X\0\033[K\0\
X\0\033[L\0\
X\1\033[M\0\
X\2\033[2J\0\
X\3\033[0m\0\
X\0\033[7m\0\
X\3\001\0\
X\0\033[%i%d;%dH\0\
X\1\033[%dC\0\
X\5\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X/*
X * These codes are valid for the pc video.
X * The entries that start with ESC | are translated into conio calls in msdos.c.
X */
X# define PCTERM_TCAP "pcterm\0\
X\0\033|K\0\
X\0\033|L\0\
X\1\033|M\0\
X\1\033|%i%d;%dr\0\
X\0\033|J\0\
X\3\033|0m\0\
X\0\033|112m\0\
X\0\033|63m\0\
X\0\033|0m\0\
X\0\033|31m\0\
X\0\001\0\
X\0\033|%i%d;%dH\0\
X\7\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X/*
X * These codes are valid for the NT Console
X * The entries that start with ESC | are translated into console calls
X * in winnt.c.
X */
X# define NTCONSOLE_TCAP "ntconsole\0\
X\0\033|K\0\
X\0\033|L\0\
X\0\033|%dL\0\
X\0\033|M\0\
X\0\033|%dM\0\
X\1\033|J\0\
X\0\033|v\0\
X\0\033|V\0\
X\1\033|0m\0\
X\0\033|112m\0\
X\0\033|63m\0\
X\0\033|0m\0\
X\0\033|31m\0\
X\0\001\0\
X\0\033|%i%d;%dH\0\
X\7\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X
X# define VT52_TCAP "vt52\0\
X\0\033K\0\
X\0\033T\0\
X\1\033U\0\
X\2\014\0\
X\3\033SO\0\
X\0\033S2\0\
X\3\001\0\
X\0\033Y%+ %+ \0\
X\0\0"
X
X/*
X * The xterm termcap is missing F14 and F15, because they send the same
X * codes as the undo and help key, although they don't work on all keyboards.
X */
X# define XTERM_TCAP "xterm\0\
X\0\033[K\0\
X\0\033[L\0\
X\0\033[%dL\0\
X\0\033[M\0\
X\0\033[%dM\0\
X\0\033[%i%d;%dr\0\
X\0\033[H\033[2J\0\
X\3\033[m\0\
X\0\033[7m\0\
X\0\033[1m\0\
X\2\001\0\
X\0\033[%i%d;%dH\0\
X\0\033M\0\
X\0\033[%dC\0\
X\1\033[?1h\033=\0\
X\0\033[?1l\033>\0\
X\0\0337\033[?47h\0\
X\0\033[2J\033[?47l\0338\0\
X\0\033OA\0\
X\0\033OB\0\
X\0\033OD\0\
X\0\033OC\0\
X\0\033Ox\0\
X\0\033Or\0\
X\0\033Ot\0\
X\0\033Ov\0\
X\0\033[11~\0\
X\0\033[12~\0\
X\0\033[13~\0\
X\0\033[14~\0\
X\0\033[15~\0\
X\0\033[17~\0\
X\0\033[18~\0\
X\0\033[19~\0\
X\0\033[20~\0\
X\0\033[21~\0\
X\0\033[23~\0\
X\0\033[24~\0\
X\0\033[25~\0\
X\2\033[29~\0\
X\0\033[31~\0\
X\0\033[32~\0\
X\0\033[33~\0\
X\0\033[34~\0\
X\0\033[28~\0\
X\0\033[26~\0\
X\0\0"
X
X# define DEBUG_TCAP "debug\0\
X\0[EL]\0\
X\0[IL]\0\
X\0[CIL%d]\0\
X\0[DL]\0\
X\0[CDL%d]\0\
X\0[%dCS%d]\0\
X\0[ED]\0\
X\0[CI]\0\
X\0[CV]\0\
X\0[CVV]\0\
X\0[TP]\0\
X\0[TI]\0\
X\0[TB]\0\
X\0[SE]\0\
X\0[SO]\0\
X\0[MS]\0\
X\0[%dCM%d]\0\
X\0[SR]\0\
X\0[CRI%d]\0\
X\0[VB]\0\
X\0[KS]\0\
X\0[KE]\0\
X\0[TI]\0\
X\0[TE]\0\
X\0[KU]\0\
X\0[KD]\0\
X\0[KL]\0\
X\0[KR]\0\
X\0[SKU]\0\
X\0[SKD]\0\
X\0[SKL]\0\
X\0[SKR]\0\
X\0[F1]\0\
X\0[F2]\0\
X\0[F3]\0\
X\0[F4]\0\
X\0[F5]\0\
X\0[F6]\0\
X\0[F7]\0\
X\0[F8]\0\
X\0[F9]\0\
X\0[F10]\0\
X\0[SF1]\0\
X\0[SF2]\0\
X\0[SF3]\0\
X\0[SF4]\0\
X\0[SF5]\0\
X\0[SF6]\0\
X\0[SF7]\0\
X\0[SF8]\0\
X\0[SF9]\0\
X\0[SF10]\0\
X\0[HELP]\0\
X\0[UNDO]\0\
X\0\0"
X
X# ifdef ATARI
X# define DFLT_TCAP ATARI_TCAP
X# endif /* ATARI */
X
X# ifdef AMIGA
X# define DFLT_TCAP AMIGA_TCAP
X# endif /* AMIGA */
X
X# ifdef NT
X# define DFLT_TCAP NTCONSOLE_TCAP
X# else
X# ifdef MSDOS
X# define DFLT_TCAP PCTERM_TCAP
X# endif /* MSDOS */
X# endif /* NT */
X
X# ifdef UNIX
X# define DFLT_TCAP ANSI_TCAP
X# endif /* UNIX */
X
X# else /* NO_BUILTIN_TCAPS */
X# define DUMB_TCAP "dumb\0\
X\6\014\0\
X\9\033[%i%d;%dH\0\
X\0\0"
X# endif /* NO_BUILTIN_TCAPS */
X
X#else /* TERMINFO */
X# ifndef NO_BUILTIN_TCAPS
X/*
X * here are the builtin termcap entries.
X * They not stored as complete Tcarr structures, as such a structure
X * is to big.
X * Each termcap is a concatenated string of entries, where '\0' characters
X * followed by a skip character sepereate the capabilities. The skip
X * character is the relative structure offset for the following entry.
X * See parse_builtin_tcap() in term.c for all details.
X */
X# define AMIGA_TCAP "amiga\0\
X\0\033[K\0\
X\0\033[L\0\
X\0\033[%p1%dL\0\
X\0\033[M\0\
X\0\033[%p1%dM\0\
X\1\014\0\
X\0\033[0 p\0\
X\0\033[1 p\0\
X\1\033[0m\0\
X\0\033[7m\0\
X\0\033[1m\0\
X\0\033[0m\0\
X\0\033[33m\0\
X\0\001\0\
X\0\033[%i%p1%d;%p2%dH\0\
X\1\033[%p1%dC\0\
X\5\233A\0\
X\0\233B\0\
X\0\233D\0\
X\0\233C\0\
X\0\233T\0\
X\0\233S\0\
X\0\233 A\0\
X\0\233 @\0\
X\0\233\060~\0\
X\0\233\061~\0\
X\0\233\062~\0\
X\0\233\063~\0\
X\0\233\064~\0\
X\0\233\065~\0\
X\0\233\066~\0\
X\0\233\067~\0\
X\0\233\070~\0\
X\0\233\071~\0\
X\0\233\061\060~\0\
X\0\233\061\061~\0\
X\0\233\061\062~\0\
X\0\233\061\063~\0\
X\0\233\061\064~\0\
X\0\233\061\065~\0\
X\0\233\061\066~\0\
X\0\233\061\067~\0\
X\0\233\061\070~\0\
X\0\233\061\071~\0\
X\0\233?~\0\
X\0\0"
X
X# define ATARI_TCAP "atari\0\
X\0\033l\0\
X\0\033L\0\
X\1\033M\0\
X\2\033E\0\
X\0\033f\0\
X\0\033e\0\
X\0\0"
X
X# define ANSI_TCAP "ansi\0\
X\0\033[2K\0\
X\0\033[L\0\
X\0\033[%p1%dL\0\
X\0\033[M\0\
X\0\033[%p1%dM\0\
X\1\033[2J\0\
X\3\033[0m\0\
X\0\033[7m\0\
X\3\001\0\
X\0\033[%i%p1%d;%p2%dH\0\
X\1\033[%p1%dC\0\
X\0\0"
X
X/*
X * These codes are valid when nansi.sys or equivalent has been installed.
X * Function keys on a PC are preceded with a NUL. These are converted into
X * K_NUL '\316' in GetChars(), because we cannot handle NULs in key codes.
X * CTRL-arrow is used instead of SHIFT-arrow.
X */
X# define PCANSI_TCAP "pcansi\0\
X\0\033[K\0\
X\0\033[L\0\
X\1\033[M\0\
X\2\033[2J\0\
X\3\033[0m\0\
X\0\033[7m\0\
X\3\001\0\
X\0\033[%i%p1%d;%p2%dH\0\
X\1\033[%p1%dC\0\
X\5\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X/*
X * These codes are valid for the pc video.
X * The entries that start with ESC | are translated into conio calls in msdos.c.
X */
X# define PCTERM_TCAP "pcterm\0\
X\0\033|K\0\
X\0\033|L\0\
X\1\033|M\0\
X\1\033|%i%p1%d;%p2%dr\0\
X\0\033|J\0\
X\3\033|0m\0\
X\0\033|112m\0\
X\0\033|63m\0\
X\0\033|0m\0\
X\0\033|31m\0\
X\0\001\0\
X\0\033|%i%p1%d;%p2%dH\0\
X\7\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X/*
X * These codes are valid for the NT Console
X * The entries that start with ESC | are translated into console calls
X * in winnt.c.
X */
X# define NTCONSOLE_TCAP "ntconsole\0\
X\0\033|K\0\
X\0\033|L\0\
X\0\033|%dL\0\
X\0\033|M\0\
X\0\033|%dM\0\
X\1\033|J\0\
X\0\033|v\0\
X\0\033|V\0\
X\1\033|0m\0\
X\0\033|112m\0\
X\0\033|63m\0\
X\0\033|0m\0\
X\0\033|31m\0\
X\0\001\0\
X\0\033|%i%p1%d;%p2%dH\0\
X\7\316H\0\
X\0\316P\0\
X\0\316K\0\
X\0\316M\0\
X\2\316s\0\
X\0\316t\0\
X\0\316;\0\
X\0\316<\0\
X\0\316=\0\
X\0\316>\0\
X\0\316?\0\
X\0\316@\0\
X\0\316A\0\
X\0\316B\0\
X\0\316C\0\
X\0\316D\0\
X\0\316T\0\
X\0\316U\0\
X\0\316V\0\
X\0\316W\0\
X\0\316X\0\
X\0\316Y\0\
X\0\316Z\0\
X\0\316[\0\
X\0\316\\\0\
X\0\316]\0\
X\0\0"
X
X
X# define VT52_TCAP "vt52\0\
X\0\033K\0\
X\0\033T\0\
X\1\033U\0\
X\2\014\0\
X\3\033SO\0\
X\0\033S2\0\
X\3\001\0\
X\0\033Y%+ %+ \0\
X\0\0"
X
X/*
X * The xterm termcap is missing F14 and F15, because they send the same
X * codes as the undo and help key, although they don't work on all keyboards.
X */
X# define XTERM_TCAP "xterm\0\
X\0\033[K\0\
X\0\033[L\0\
X\0\033[%p1%dL\0\
X\0\033[M\0\
X\0\033[%p1%dM\0\
X\0\033[%i%p1%d;%p2%dr\0\
X\0\033[H\033[2J\0\
X\3\033[m\0\
X\0\033[7m\0\
X\3\001\0\
X\0\033[%i%p1%d;%p2%dH\0\
X\0\033M\0\
X\0\033[%p1%dC\0\
X\1\033[?1h\033=\0\
X\0\033[?1l\033>\0\
X\0\0337\033[?47h\0\
X\0\033[2J\033[?47l\0338\0\
X\0\033OA\0\
X\0\033OB\0\
X\0\033OD\0\
X\0\033OC\0\
X\0\033Ox\0\
X\0\033Or\0\
X\0\033Ot\0\
X\0\033Ov\0\
X\0\033[11~\0\
X\0\033[12~\0\
X\0\033[13~\0\
X\0\033[14~\0\
X\0\033[15~\0\
X\0\033[17~\0\
X\0\033[18~\0\
X\0\033[19~\0\
X\0\033[20~\0\
X\0\033[21~\0\
X\0\033[23~\0\
X\0\033[24~\0\
X\0\033[25~\0\
X\2\033[29~\0\
X\0\033[31~\0\
X\0\033[32~\0\
X\0\033[33~\0\
X\0\033[34~\0\
X\0\033[28~\0\
X\0\033[26~\0\
X\0\0"
X
X# define DEBUG_TCAP "debug\0\
X\0[EL]\0\
X\0[IL]\0\
X\0[CIL%p1%d]\0\
X\0[DL]\0\
X\0[CDL%p1%d]\0\
X\0[%p1%dCS%p2%d]\0\
X\0[ED]\0\
X\0[CI]\0\
X\0[CV]\0\
X\0[CVV]\0\
X\0[TP]\0\
X\0[TI]\0\
X\0[TB]\0\
X\0[SE]\0\
X\0[SO]\0\
X\0[MS]\0\
X\0[%p1%dCM%p2%d]\0\
X\0[SR]\0\
X\0[CRI%p1%d]\0\
X\0[VB]\0\
X\0[KS]\0\
X\0[KE]\0\
X\0[TI]\0\
X\0[TE]\0\
X\0[KU]\0\
X\0[KD]\0\
X\0[KL]\0\
X\0[KR]\0\
X\0[SKU]\0\
X\0[SKD]\0\
X\0[SKL]\0\
X\0[SKR]\0\
X\0[F1]\0\
X\0[F2]\0\
X\0[F3]\0\
X\0[F4]\0\
X\0[F5]\0\
X\0[F6]\0\
X\0[F7]\0\
X\0[F8]\0\
X\0[F9]\0\
X\0[F10]\0\
X\0[SF1]\0\
X\0[SF2]\0\
X\0[SF3]\0\
X\0[SF4]\0\
X\0[SF5]\0\
X\0[SF6]\0\
X\0[SF7]\0\
X\0[SF8]\0\
X\0[SF9]\0\
X\0[SF10]\0\
X\0[HELP]\0\
X\0[UNDO]\0\
X\0\0"
X
X# ifdef ATARI
X# define DFLT_TCAP ATARI_TCAP
X# endif /* ATARI */
X
X# ifdef AMIGA
X# define DFLT_TCAP AMIGA_TCAP
X# endif /* AMIGA */
X
X# ifdef NT
X# define DFLT_TCAP NTCONSOLE_TCAP
X# else
X# ifdef MSDOS
X# define DFLT_TCAP PCTERM_TCAP
X# endif /* MSDOS */
X# endif /* NT */
X
X# ifdef UNIX
X# define DFLT_TCAP ANSI_TCAP
X# endif /* UNIX */
X
X# else /* NO_BUILTIN_TCAPS */
X/*
X * The most minimal terminal: only clear screen and cursor positioning
X */
X# define DUMB_TCAP "dumb\0\
X\6\014\0\
X\9\033[%i%p1%d;%p2%dH\0\
X\0\0"
X# endif /* NO_BUILTIN_TCAPS */
X
X#endif
END_OF_FILE
if test 16147 -ne `wc -c <'vim/src/term.h'`; then
echo shar: \"'vim/src/term.h'\" unpacked with wrong size!
fi
# end of 'vim/src/term.h'
fi
if test -f 'vim/tools/ref' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tools/ref'\"
else
echo shar: Extracting \"'vim/tools/ref'\" \(137 characters\)
sed "s/^X//" >'vim/tools/ref' <<'END_OF_FILE'
X#!/bin/sh
X#
X# ref - Check spelling of the arguments
X#
X# Usage: ref word ..
X#
X# can be used for the K command of Vim
X#
Xspell <<EOF
X$*
XEOF
END_OF_FILE
if test 137 -ne `wc -c <'vim/tools/ref'`; then
echo shar: \"'vim/tools/ref'\" unpacked with wrong size!
fi
# end of 'vim/tools/ref'
fi
echo shar: End of archive 5 \(of 26\).
cp /dev/null ark5isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:45 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 25
Archive-name: vim/part06

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/reference.doc.C vim/macros/maze/maze_mac.UU
# vim/src/ascii.h


# Wrapped by kent@sparky on Mon Aug 15 21:44:00 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 6 (of 26)."'
if test -f 'vim/doc/reference.doc.C' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/reference.doc.C'\"
else
echo shar: Extracting \"'vim/doc/reference.doc.C'\" \(48444 characters\)
sed "s/^X//" >'vim/doc/reference.doc.C' <<'END_OF_FILE'


X comes from the 'scroll' option (default: half a
X screen). If [count] given, first set 'scroll' option
X to [count].
X

X<SC_UP> or
XCTRL-B Window [count] pages Backwards (upwards) in the
X buffer.
X
XWindow repositioning:
X
Xz<CR> Redraw, line [count] at top of window (default
X cursor line). Put cursor at first non-blank in the
X line.
X
Xzt Like "z<CR>", but leave the cursor in the same
X column. {not in Vi}
X
Xz{height}<CR> Redraw, make window {height} lines tall. This is
X useful to make the number of lines small when screen
X updating is very slow. Cannot make the height more
X than the physical screen height.
X
Xz. Redraw, line [count] at center of window (default
X cursor line). Put cursor at first non-blank in the
X line.
X
Xzz Like "z.", but leave the cursor in the same column.


X {not in Vi}
X

Xz- Redraw, line [count] at bottom of window (default
X cursor line). Put cursor at first non-blank in the
X line.
X
Xzb Like "z-", but leave the cursor in the same column.


X {not in Vi}
X

XThese commands move the contents of the window. If the cursor position is
Xmoved off of the window, the cursor is moved onto the window. A page is the
Xnumber of lines in the window minus two. The mnemonics for these commands
Xmay be a bit confusing. Remember that the commands refer to moving the
Xwindow upwards or downwards in the buffer. But when the window moves upwards
Xin the buffer, the text in the window moves downwards on your screen.
X
X
X 8. Tags
X
X:ta[g][!] {ident} Jump to the definition of {ident}, using the
X information in the tags file. Put {ident} in the tag
X stack. See below for [!].
X
XCTRL-] ":ta" to the identifier under or after cursor. Put
X the identifier in the tag stack. {Vi: identifier
X after the cursor}
X
XCTRL-T Jump to [count] older entry in the tag stack
X (default 1). {not in Vi}
X
X:[count]po[p][!] Jump to [count] older entry in tag stack (default 1).
X See below for [!]. {not in Vi}
X
X:[count]ta[g][!] Jump to [count] newer entry in tag stack (default 1).
X See below for [!]. {not in Vi}
X
X:tags Show the contents of the tag stack. The active
X entry is marked with a <>>. {not in Vi}
X
XA tag is an identifier that appears in the "tags" file. It is a sort of label
Xthat can be jumped to. For example: In C programs each function name can be
Xused as a tag.
X
XWith the ":tag" command the cursor will be positioned on the tag. With the
XCTRL-] command, the identifier on which the cursor is standing is used as the
Xtag. If the cursor is not on an identifier, the first identifier rightwards
Xof the cursor is used.
X
XThe 'ignorecase' option can be used to make the tag search case insensitive.
X
XIf the tag is in the current file this will always work. Otherwise the
Xperformed actions depend on whether the current file was changed, whether a !
Xis added to the command and on the 'autowrite' option:
X
X tag in file autowrite
Xcurrent file changed ! option action
X-----------------------------------------------------------------------------
X yes x x x goto tag
X no no x x read other file, goto tag
X no yes yes x abandon current file, read other file, goto
X tag
X no yes no on write current file, read other file, goto
X tag
X no yes no off fail
X-----------------------------------------------------------------------------
X
X- If the tag is in the current file, the command will always work.
X- If the tag is in another file and the current file was not changed, the
X other file will be made the current file and read into the buffer.
X- If the tag is in another file, the current file was changed and a ! is
X added to the command, the changes to the current file are lost, the other
X file will be made the current file and read into the buffer.
X- If the tag is in another file, the current file was changed and the
X 'autowrite' option is set, the current file will be written, the other
X file will be made the current file and read into the buffer.
X- If the tag is in another file, the current file was changed and the
X 'autowrite' option is not set, the command will fail. If you want to save
X the changes, use the ":w" command and then use ":tag" without an argument.
X This works because the tag is put on the stack anyway. If you want to lose
X the changes you can use the ":tag!" command.
X
XThe ":tag" command works very well for C programs. If you see a call to a
Xfunction and wonder what that function does, position the cursor inside of
Xthe function name and hit CTRL-]. This will bring you to the function
Xdefinition. An easy way back is with the CTRL-T command. Also read about the
Xtag stack below.
X
XA tags file can be created with the external command 'ctags'. It will
Xcontain a tag for each function. Some versions of 'ctags' will also make a
Xtag for each "#defined" macro.
X
XThe lines in the tags file should have this format:
X
X {tag}{separator}{filename}{separator}{command}
X
X{tag} the identifier
X{separator} one or more <TAB> or space characters
X{filename} the file that contains the definition of {tag}
X{command} the Ex command that positions the cursor on the tag.
X
XThe command can be any Ex command, but normally it is a search command like
X"/^main(argc, argv)". If it is a search command, and the search fails,
Xanother try is done to search for "^main(" (the tag with <^> prepended and
X<)> appended). When using function names, this will find the function name
Xwhen it is in column 0. This will help when the arguments to the function
Xhave changed since the tags file was made. If this search also fails another
Xtry is done with "^[#a-zA-Z_].*main(". This means: A line starting with <#>
Xor an identifier and containing the tag followed by <(>. This will find
Xmacro names and function names with a type prepended. {the two extra
Xsearches are not in vi}.


X
X{In vi the :tag command sets a new search pattern when the tag is searched
Xfor. In Vim this is not done, the previous search pattern is still

Xremembered. The search pattern for the tag is not remembered.}.
X
X
XThe 'tags' option is a list of file names separated by spaces. Each of these
Xfiles is searched for the tag. This can be used to use a different file than
Xthe default file "tags". It can also be used to access a common tags file.
XFor example:
X
X:set tags=tags\ /home/user/commontags
X
XThe tag will first be searched for in the file "tags" in the current
Xdirectory. If it is not found there the file "/home/user/commontags" will be
Xsearched for the tag. The backslash is required for the space to be included
Xin the string option.
X
XIf the 'tagrelative' option is set (which is the default) and using a tag file
Xin another directory, file names in that tag file are relative to the
Xdirectory where the tag file is.
X
X
XThe tags that you use are remembered in the tag stack. You can print this
Xstack with the ":tags" command. The result looks like this:
X
X # TO tag FROM line in file
X 1 main 1 harddisk2:text/vim/test
X> 2 FuncA 58 -current-
X 3 FuncC 357 harddisk2:text/vim/src/amiga.c
X
XThis list shows the tags that you jumped to and the cursor position before that
Xjump. The older tags are at the top, the newer at the bottom.
X
XThe <>> points to the active entry. This is the tag that will be used by the
Xnext ":tag" command. The CTRL-T and ":pop" command will use the position
Xabove the active entry.
X
XThe line number and file name are remembered to be able to get back to where
Xyou were before the tag command. The line number will be correct, also when
Xdeleting/inserting lines, unless this was done by another program (e.g.
Xanother instance of Vim).
X
XYou can jump to previously used tags with several commands. Some examples:
X
X ":pop" or CTRL-T to position before previous tag
X {count}CTRL_T to position before {count} older tag
X ":tag" to newer tag
X ":0tag" to last used tag
X
XThe most obvious way to use this is while browsing through the call graph of
Xa program. Consider the following call graph:
X
X main ---> FuncA ---> FuncC
X ---> FuncB
X
X(Explanation: main calls FuncA and FuncB; FuncA calls FuncC).
XYou can get from main to FuncA by using CTRL-] on the call to FuncA. Then
Xyou can CTRL-] to get to FuncC. If you now want to go back to main you can
Xuse CTRL-T twice. Then you can CTRL-] to FuncB.
X
XIf you issue a ":ta {ident}" or CTRL-] command, this tag is inserted at the
Xcurrent position in the stack. If the stack was full (it can hold up to 20
Xentries), the oldest entry is deleted and the older entries shift one
Xposition up (their index number is decremented by one). If the last used
Xentry was not at the bottom, the entries below the last used one are
Xdeleted. This means that an old branch in the call graph is lost. After the
Xcommands explained above the tag stack will look like this:
X
X # TO tag FROM line in file
X 1 main 1 harddisk2:text/vim/test
X 2 FuncB 59 harddisk2:text/vim/src/main.c
X>
X
X
X 9. Inserting text
X
XThe following commands can be used to insert new text into the buffer. They
Xcan all be undone. The non-Ex commands can be repeated with the "." command.
X
Xa Append text after the cursor [count] times.
X
XA Append text at the end of the line [count] times.
X
Xi Insert text before the cursor [count] times.
X
XI Insert text before the first CHAR on the line
X [count] times.
X
Xo Begin a new line below the cursor and insert text,
X repeat [count] times. {Vi: blank [count] screen
X lines}
X
XO Begin a new line above the cursor and insert text,
X repeat [count] times. {Vi: blank [count] screen
X lines}
X
XThese commands are used to start inserting text. They can be undone and
Xrepeated. You can end Insert mode with <ESC>. See the section "Insert and
XReplace mode" for the other special characters in Insert mode. The effect of
X[count] takes place after Insert mode is exited.
X
X:r[ead] [name] Insert the file [name] (default: current file) below
X the cursor.
X
X:{range}r[ead] [name] Insert the file [name] (default: current file) below
X the specified line.
X
X:r[ead] !{cmd} Execute {cmd} and insert its standard output below
X the cursor.
X
XThese commands insert the contents of a file, or the output of a command,
Xinto the buffer. They can be undone. They cannot be repeated with the "."
Xcommand. They work on a line basis, insertion starts below the line in which
Xthe cursor is, or below the specified line. To insert text above the first
Xline use the command ":0r {name}".
X
XThe <LF> character is recognized as end-of-line marker. If the 'textmode'
Xoption is set, a <CR> in front of an <LF> is ignored and a CTRL-Z at the end
Xof the file is ignored. The 'textmode' option is default on for MSDOS.
X
XIf the 'textauto' option is set Vim tries to recognize the type of
Xend-of-line marker (see 5.2 how this is done). However, the 'textmode'
Xoption will not be changed. Only while reading one file the text mode is
Xused or not.
X
XOn non-MSDOS systems the message "[textmode]" is shown if a file is read in
Xtext mode, to remind you that something unusual is done. On MSDOS the
Xmessage "[notextmode]" is shown if a file is read without text mode.
X
X
X 10. Deleting text
X
X["x]x Delete [count] characters under and after the cursor
X [into register x] (not linewise).
X
X["x]X Delete [count] characters before the cursor [into
X register x] (not linewise).
X
X["x]d{motion} Delete text that is moved over [into register x].
X See below for exception.
X
X["x]dd Delete [count] lines [into register x] (linewise).
X
X["x]D Delete the characters under the cursor until the end
X of the line and [count]-1 more lines [into register
X x]; synonym for d$ (not linewise).
X
X{visual}["x]x or
X{visual}["x]d Delete the highlighted text [into register x] (see
X the chapter on Visual mode). {not in Vi}
X
X{visual}["x]X or
X{visual}["x]D Delete the highlighted lines [into register x] (see
X the chapter on Visual mode). {not in Vi}
X
X:[range]d[elete] [x] Delete [range] lines (default: current line) [into
X register x].
X
X:[range]d[elete] [x] {count}
X Delete {count} lines, starting with [range]
X (default: current line, see 4.4.4) [into register
X x].
X
XThese commands delete text. They can be repeated with the "." command
X(except ":d") and undone. Use Visual mode to delete blocks of text. See
X"Copying and moving text" for an explanation of registers.
X
XAn exception for the d{motion} command: If the motion is not linewise, the
Xstart and end of the motion are not in the same line and before the start
Xand after the end are only blanks, the delete becomes linewise. This means
Xthat the blank line that would remain is also deleted.
X
X
XJ Join [count] lines, with a minimum of two lines.
X
X{visual}J Join the highlighted lines, with a minimum of two
X lines. {not in Vi}
X
X:[range]j[oin][!] Join [range] lines. Same as "J", except when [!] is
X given, then no spaces will be inserted or deleted.
X When [range] is given and the start and end of the
X range are equal, nothing happens. Default is to join
X two lines.
X
X:[range]j[oin][!] {count}
X Join {count} lines, starting with [range] (default:
X current line, see 4.4.4). Same as "J", except when
X [!] is given, then no spaces will be inserted or
X deleted.
X
XThese commands delete the newline between lines. This has the effect of
Xjoining them into one line. They can be repeated (except ":j") and undone.
X
XOne space is inserted in place of the <LF>, unless the line ended with a
Xspace, <TAB> or the next line started with a <)>. If the next line has
Xleading white space it is deleted first. If the 'joinspaces' option is set,
Xtwo spaces are inserted after a period.
X
X
X 11. Changing text
X
XThe following commands can be used to change text, that is delete some text
Xand insert something else, with one command. They can all be undone. The
Xnon-Ex commands can be repeated with the "." command.
X
X
X11.1 Delete and insert
X
XR Enter Replace mode: Each character you type replaces
X an existing character, starting with the character
X under the cursor. Repeat the entered text [count]-1
X times.
X
X["x]c{motion} Delete {motion} text [into register x] and start
X insert.
X
X["x]cc Delete [count] lines [into register x] and start
X insert (linewise). If 'autoindent' is set, preserve
X the indent of the first line.
X
X["x]C Delete from the cursor position to the end of the
X line and [count]-1 more lines [into register x], and
X start insert. Synonym for c$ (not linewise).
X
X["x]s Delete [count] characters [into register x] and start
X insert (s stands for Substitute). Synonym for "cl"
X (not linewise).
X
X["x]S Delete [count] lines [into register x] and start
X insert. Synonym for "cc" (not linewise).
X
X{visual}["x]c or
X{visual}["x]r or
X{visual}["x]s Delete the highlighted text [into register x] and
X start insert (see the chapter on Visual mode). {not
X in Vi}
X
X{visual}["x]C or
X{visual}["x]R or
X{visual}["x]S Delete the highlighted lines [into register x] and
X start insert (see the chapter on Visual mode). {not
X in Vi}
X
XYou can end Insert and Replace mode with <ESC>. See the section "Insert and
XReplace mode" for the other special characters in these modes. The effect of
X[count] takes place after Insert or Replace mode is exited. {Vi: does not
Xdirectly delete the text, but puts a <$> at the last deleted character}
XSee "Copying and moving text" for an explanation of registers.
X
XReplace mode is just like Insert mode, except that for every character you
Xenter, one character is deleted. If the end of a line is reached, further
Xcharacters are appended (just like Insert mode). In Replace mode the
Xbackspace key restores the original text (if there was any) (see section
X"Insert and Replace mode").


X
XSpecial case: "cw" and "cW" are treated like "ce" and "cE" if the cursor is
Xon a non-blank. This is because "cw" is interpreted as change-word, and a
Xword does not include the following white space. {Vi: "cw" when on a blank
Xfollowed by other blanks changes only the first blank; this is probably a
Xbug, because "dw" deletes all the blanks}
X
X

X11.2 Simple changes
X
Xr<char> Replace the character under the cursor by <char>. If
X <char> is a <CR> or <LF> the character will be
X replaced by a line break. If a [count] is given that
X many characters will be replaced by [count] <char>s
X or line breaks {Vi: "5r<CR>" replaces five
X characters with a single line break}
X
X~ 'notildeop' option: switch case of the character
X under the cursor and move the cursor to the right.
X If a [count] is given do that many characters {Vi:
X no count}
X
X~{motion} 'tildeop' option: switch case of {motion} text. {Vi:
X tilde cannot be used as an operator}
X
X{visual}~ switch case of highlighted text (see the chapter on
X Visual mode). {not in Vi}
X
X{visual}U Make highlighted text uppercase (see the chapter on
X Visual mode). {not in Vi}
X
X{visual}u Make highlighted text lowercase (see the chapter on
X Visual mode). {not in Vi}
X
XCTRL-A Add [count] to the number at or after the cursor.


X {not in Vi}
X

XCTRL-X Subtract [count] from the number at or after the
X cursor. {not in Vi}
X
XThe CTRL-A and CTRL-X commands work for (signed) decimal numbers and
Xunsigned octal and hexadecimal numbers. Numbers starting with '0x' or '0X'
Xare assumed to be hexadecimal. To decide whether the hexadecimal number
Xshould be printed uppercase or not, the case of the rightmost letter in the
Xnumber is considered. If there is no letter in the current number, the
Xpreviously detected case is used. Numbers starting with a <0> are considered
Xto be octal. Other numbers are decimal and may be preceded with a minus
Xsign. If the cursor is on a number, that one will be used. Otherwise the
Xnumber right of the cursor will be used.
X
XThe CTRL-A command is very useful in a macro. Example: How to make a
Xnumbered list.
X
X1. Create the first entry. The entry should start with a number.
X2. qa - start recording into buffer <a>
X3. Y - yank the entry
X4. p - put a copy of the entry below the first one
X5. CTRL-A - increment the number
X6. q - stop recording
X7. <count>@a - repeat the yank, put and increment <count> times
X
X
X<{motion} Shift the {motion} lines one shiftwidth leftwards.
X
X<< Shift [count] lines one shiftwidth leftwards.
X
X{visual}< Shift the highlighted lines [count] shiftwidth
X leftwards (see the chapter on Visual mode). {not in
X Vi}
X
X>{motion} Shift {motion} lines one shiftwidth rightwards.
X
X>> Shift [count] lines one shiftwidth rightwards.
X
X{visual}> Shift the highlighted lines [count] shiftwidth
X rightwards (see the chapter on Visual mode). {not in
X Vi}
X
X:[range]< Shift [range] lines left. Repeat '<' for multiple
X shifts.
X
X:[range]< {count} Shift {count} lines left, starting with [range]
X (default current line, see 4.4.4). Repeat '<' for
X multiple shifts.
X
X:[range]le[ft] [indent] left align lines in [range]. Sets the indent in the
X lines to [indent] (default 0). {not in Vi}
X
X:[range]> Shift {count} [range] lines right. Repeat '>' for
X multiple shifts.
X
X:[range]> {count} Shift {count} lines right, starting with [range]
X (default current line, see 4.4.4). Repeat '>' for
X multiple shifts.
X
XThe ">" and "<" commands are handy for changing the indent within programs.
XThe size of the white space which is inserted or deleted can be set with the
X'shiftwidth' option. Normally the 'shiftwidth' option is set to 8, but you
Xcan set it to e.g. 3 to make smaller indents. The shift leftwards stops when
Xthere is no indent. The shift right does not do anything with empty lines.
X
XIf the 'shiftround' option is set, the indent is rounded to a multiple of
X'shiftwidth'.
X
XIf the 'smartindent' option is set, lines starting with <#> will not be
Xshifted right.
X
XWhen the 'expandtab' option if off (this is the default) <TAB>s are used as
Xmuch as possible to make the indent. You can use ">><<" to replace an indent
Xmade out of spaces with the same indent made out of <TAB>s (and a few
Xspaces if necessary). If the 'expandtab' option is on, only spaces are
Xused. Then you can use ">><<" to replace <TAB>s in the indent by spaces.
X
XTo move a line several 'shiftwidth's use the visual mode or the ":"
Xcommands. For example:
X Vjj4> move three lines 4 indents to the right
X :<<< move current line 3 indents to the left
X :>> 5 move 5 lines 2 indents to the right
X
X
XQ{motion} Format the lines that were moved over. The length of
X each line will be restricted to the width set with
X the 'textwidth' option. If the 'textwidth' option is
X 0, all lines will be joined together. If the
X 'autoindent' option is set, the indent of the first
X line is used for the following lines. The
X 'formatprg' option can be set to the name of an
X external program, which will be used instead of the
X internal function. The 'textwidth' option will then
X not be used. {not in Vi}
X
X:[range]ce[nter] [width]
X Center lines in [range] between [width] columns
X (default 'textwidth' or 80 when 'textwidth' is 0).


X {not in Vi}
X

X:[range]ri[ght] [width]
X right align lines in [range] at [width] columns
X (default 'textwidth' or 80 when 'textwidth' is 0).


X {not in Vi}
X
X

X11.3 Complex changes
X
X!{motion}{filter} Filter {motion} text through the external program
X {filter}.
X
X!!{filter} Filter [count] lines through the external program
X {filter}.
X
X{visual}!{filter} Filter the highlighted lines through the external
X program {filter} (see the chapter on Visual mode).


X {not in Vi}
X

X:{range}![!]{filter} [!][arg]
X Filter {range} lines through the external program
X {filter}. The optional bangs are replaced with the
X latest given command. The optional [arg] is appended.
X
X={motion} Filter {motion} lines through the external program
X given with the 'equalprg' option (default:
X "indent"). {Vi: when 'lisp' option is set, autoindent
X {motion} lines}
X
X== Filter [count] lines through the external program
X given with the 'equalprg' option (default: indent).


X {not in Vi}
X

X{visual}= Filter the highlighted lines through the external
X program given with the 'equalprg' option (default:
X indent) (see the chapter on Visual mode). {not in
X Vi}
X
XA filter is a program that accepts text at standard input, changes it in some
Xway, and sends it to standard output. The commands above can be used to send
Xsome text through a filter. An example of a filter is "sort", which sorts
Xlines alphabetically. The "indent" program is used to pretty indent C
Xprograms (you need a version of indent that works like a filter, not all
Xversions do that). The shell, given with the 'shell' option, is used to
Xexecute the command (See also the 'shelltype' option).
XThe filter commands can be redone with ".". There cannot be a comment (with
X<">) after the ":!" command.
X
X
X:[range]s[ubstitute]/{pattern}/{string}/[g][c][r] [count]
X For each line in [range] replace {pattern} by
X {string}. See below for the flags.
X
X:[range]s[ubstitute] [g][c][r] [count]
X:[range]&[g][c][r] [count]
X Repeat last :substitute with same search pattern and
X substitute string. The flags may be different (see
X below).
X
X:[range]~[g][c][r] [count]
X Repeat last substitute with same substitute string
X but with last used search pattern. This is like
X "&r". See explanation for [r] below.
X
X& Synonym for ":s//~/" (repeat last substitute).
X
XThe arguments that can be given to the substitute commands:
X[g] All occurrences in the line are replaced. Otherwise only the first
X occurrence in the line is replaced. If the 'edcompatible' option is
X set this flag is remembered and toggled each time it is used. It is
X reset when a new search pattern is given. If the 'gdefault' option
X is set, this flag is default on. Give the [g] to switch it on.
X[c] Each substitute has to be confirmed. The cursor is positioned on the
X matching string. You can type <y> to substitute, <n> to skip, <q> to
X quit substituting. If the 'edcompatible' option is set this flag is
X remembered and toggled each time it is used. It is reset when a new
X search pattern is given.
X[r] When the search pattern is empty use the previously used search
X pattern instead of the search pattern from the last substitute.
X If the last command that did a search was a substitute there is no
X effect. If the last command was another search command, like
X "/" or ":global", the pattern from that command is used.
X[count] That many lines are are searched, starting with the last line number
X in [range] (default current line, see 4.4.4).
X
XIf the {pattern} for the substitute command is empty, the pattern from the
Xlast substitute command is used. With the [r] flag the pattern from the last
Xsubstitute or search command ("/", ":global" and the like) is used.
X
XInstead of the </> which surrounds the pattern and replacement string, you
Xcan use any other character, but not an alphanumeric character, <"> or <|>
Xor <#>. This is useful if you want to include a </> in the search pattern or
Xreplacement string. Example: ":s+/+//+"
X
XFor the definition of a pattern see 6.5, "Pattern searches".
X
XSome characters in {string} have a special meaning:
X
Xmagic nomagic action
X & \& replaced by the whole matched pattern
X \& & replaced by &
X \0 replaced by the whole matched pattern
X \1 replaced by the matched pattern in the first pair of ()
X \2 replaced by the matched pattern in the second pair of ()
X .. ..
X \9 replaced by the matched pattern in the ninth pair of ()
X ~ \~ replaced by the {string} of the previous substitute
X \~ ~ replaced by ~
X \u next character made uppercase
X \U following characters made uppercase
X \l next character made lowercase
X \L following characters made lowercase
X \e end of /u, /U, /l and /L
X \E end of /u, /U, /l and /L
X <CR> split line in two at this point
X CTRL-V <CR> insert a carriage-return (CTRL-M)
X
XExamples:
X:s/a\|b/xxx\0xxx/g modifies "a b" in "xxxaxxx xxxbxxx"
X:s/\([abc]\)\([efg]\)/\2\1/g modifies "af fa bg" in "fa fa gb"
X:s/abcde/abc^Mde/ modifies "abcde" in "abc", "de" (two lines)
X:s/$/^V^M/ modifies "abcde" in "abcde^M"
X
XNote: To insert a ^M you have to type CTRL-V <CR>. To insert a ^V you have
Xto type CTRL-V CTRL-V. So to insert the ^V^M in the last example you have to
Xtype CTRL-V CTRL-V CTRL-V <CR>.
X
XBecause CTRL-V <CR> inserts a <CR>, it is impossible to insert a CTRL-V just
Xin front of a line break. You will have to split it up in two parts:
X :s/foo/^Vxxxx/
X :s/xxxx/^M/
X
XWhen using parentheses in combination with <|>, like in \([ab]\)\|\([cd]\),
Xeither the first or second pattern in parentheses did not match, so either
X\1 or \2 is empty. Example:
X:s/\([ab]\)\|\([cd]\)/\1x/g modifies "a b c d" in "ax bx x x"
X
X
X 12. Copying and moving text
X
X"<a-zA-Z0-9.%:"> Use register <a-zA-Z0-9.%"> for next delete, yank or
X put (use uppercase character to append with delete
X and yank) (<.> only works with put).
X
X:di[splay] Display the contents of numbered and named registers.
X {Vi: no such command}
X
X["x]y{motion} Yank {motion} text [into register x].
X
X["x]yy Yank [count] lines [into register x] (linewise).
X
X["x]Y With 'noyankendofline' option: yank [count] lines
X [into register x] (synonym for yy, linewise); with
X 'yankendofline' option: yank until end of line
X (synonym for y$, not linewise).
X
X{visual}["x]y Yank the highlighed text [into register x] (see the
X chapter on Visual mode). {not in Vi}
X
X{visual}["x]Y Yank the highlighted lines [into register x] (see the
X chapter on Visual mode). {not in Vi}
X
X:[range]y[ank] [x] Yank [range] lines [into register x].
X
X:[range]y[ank] [x] {count}
X Yank {count} lines, starting with last line number
X in [range] (default: current line, see 4.4.4), [into
X register x].
X
X["x]p Put the text [from register x] after the cursor
X[count]
X times. {Vi: no count}
X
X["x]P Put the text [from register x] before the cursor
X [count] times. {Vi: no count}
X
X:[line]pu[t] [x] Put the text [from register x] after [line] (default
X current line).
X
X:[line]pu[t]! [x] Put the text [from register x] before [line] (default
X current line).
X
X["x]]p like "p", but adjust the indent to the current line.


X {not in Vi}
X

X["x][p like "P", but adjust the indent to the current line.


X {not in Vi}
X

XThese commands can be used to copy text from one place to another. This is
Xdone by first getting the text into a register with a yank, delete or change
Xcommand. The register can then be inserted with a put command. All registers
Xare kept when changing files. Thus you can also use this to move text from
Xone file to another (the CTRL-^ command is a quick way to toggle between two
Xfiles).
X
XThe put commands can be repeated with "." (except for :put) and undone. If the
Xcommand that was used to get the text into the register was linewise, the
Xtext will be inserted below ("p") or above ("P") the line where the cursor
Xis. Otherwise the text will be inserted after ("p") or before ("P") the
Xcursor. With the ":put" command the text will always be inserted in the next
Xline. You can exchange two characters with the command sequence "xp". You
Xcan exchange two lines with the command sequence "ddp". You can exchange
Xtwo words with the command sequence "deep" (start with the cursor in the
Xblank space before the first word). The "']" or "`]" command can be used
Xafter the put command to move the cursor to the end of the inserted text,
X"'[" or "`[" to move the cursor to the start.
X
XIf the command that was used to get the text into the register used
Xblockwise Visual mode, the block of text will be inserted before ("P") or
Xafter ("p") the cursor column, in the current and next lines. Vim will make
Xthe whole block of text start in the same column. Thus the inserted text
Xlooks the same as when it was yanked or deleted. Some <TAB> characters may
Xbe replaced by spaces to make this happen. However, if the width of the
Xblock is not a multiple of a <TAB> width and the text after the inserted
Xblock contains <TAB>s, that text may be misaligned.
X
XThere are four types of registers: The unnamed register, 10 numbered
Xregisters, 26 named registers and two read-only registers.
X The unnamed register is the register where all text deleted with
Xthe "d", "c", "s", "x" commands or copied with the yank "y" command is
Xplaced, regardless of whether or not a specific register was used (e.g.
X"xdd). The contents of this register are used by any put command (p or P)
Xwhich does not specify a register. Additionally it can be accessed by the
Xname <">. This means you have to type two double quotes. {Vi: register
Xcontents lost when changing files, no <">}
X The numbered registers are filled with yank and delete commands.
XNumbered register <0> is filled with the last yank command, unless another
Xregister was specified with ["x]. Numbered register <1> is filled with the
Xtext that was deleted by each delete or change command, unless another
Xregister was specified or the text is less than one line (text deleted with
X"x" or "dw" will not be put in a numbered register). The contents of
Xregister <1> are put in <2>, <2> in <3>, and so forth. The contents of
Xregister <9> are lost. {Vi: numbered register contents are lost when
Xchanging files; register 0 does not exist}
X The named registers are only filled when you say so. They are named
X<a> to <z> normally. If you use an uppercase letter, the same registers as
Xwith the lower case letter is used, but the text is appended to the previous
Xregister contents. With a lower case letter the previous contents are lost.
X The read-only registers are <%>, <:> and <.>. They can only be used
Xwith the commands "p", "P" and ":put". <.> contains the last inserted
Xtext (the same as what is inserted with the insert mode commands CTRL-A and
XCTRL-@). <%> contains the name of the current file. <:> contains the last
Xcommand line, it can also be used with "@", "@:" repeats the last command
Xline.
X
XIf you use a put command without specifying a register, the register that
Xwas last written to is used (this is also the contents of the unnamed
Xregister). If you are confused, use the ":dis" command to find out what will
Xbe put (all named and numbered registers are displayed; the unnamed register
Xis labelled <">).
X
XThe next three commands always work on whole lines.
X
X:[range]co[py] {address}
X Copy the lines given by [range] to below the line
X given by {address}.
X
X:t Synonym for copy.
X
X:[range]m[ove] {address}
X Move the lines given by [range] to below the line
X given by {address}.
X
X
X 13. Visual mode
X
XVisual mode is a flexible and easy way to select a piece of text for an
Xoperator. It is the only way to select a block of text.
X
Xv start/stop Visual mode per character. {not in Vi}
X
XV start/stop Visual mode linewise. {not in Vi}
X
XCTRL-V start/stop Visual mode blockwise. {not in Vi}
X
Xo go to Other end of highlighted text: The current
X cursor position becomes the start of the highlighted
X text and the cursor is moved to the Other end of the
X highlighted text. {not in Vi}
X
XTo apply an operator on a piece of text:
X 1. mark the start of the text with "v", "V" or CTRL-V
X The character under the cursor will be used as the start.
X 2. move to the end of the text
X The text from the start of the Visual mode up to and
X including the character under the cursor is highlighted.
X 3. hit an operator
X The highlighted characters will be operated upon.
X
XThe 'highlight' option can be used to set the display mode to use for
Xhighlighting in Visual mode.
X
XThe highlighted text includes the character under the cursor. On terminals
Xwhere it is possible to make the cursor invisible the cursor position is
Xalso highlighted. On terminals where this is not possible the cursor is
Xdisplayed normally. If your cursor cannot be made invisible and you want Vim
Xto highlight the character under the cursor anyway, you could set the 't_cv'
Xand 't_ci' options to something harmless, for example:
X :set t_cv=^[^[ t_ci=^[^[
X
XWith "v" the text before the start position and after the end position will
Xnot be highlighted. However, All uppercase and non-alpha operators, except
X"~", will work on whole lines anyway. See the list of operators below.
X
XWith CTRL-V (blockwise Visual mode) the highlighted text will be a rectangle
Xbetween start position and the cursor. However, some operators work on whole
Xlines anyway (see the list below). The change and substitute operators will
Xdelete the highlighted text and then start insertion at the top left
Xposition.
X
XWhen the "$" command is used with blockwise Visual mode, the right end of the
Xhighlighted text will be determined by the longest highlighted line. This
Xstops when a motion command is used that does not move straight up or down.
X
XIf you use "v", "V", CTRL-V, ESC or any command that does a jump to another
Xwindow while in Visual mode, the highlighting stops and no text is affected.
XIf you hit CTRL-Z the highlighting stops and the editor is suspended or a new
Xshell is started.
X
XFor moving the end of the block many commands can be used, but you cannot
Xuse Ex commands, commands that make changes or abandon the file. Commands
X(starting with) ".pPiIaAO&", CTRL_^, "ZZ", CTRL-], CTRL-T, CTRL-R, CTRL-I
Xand CTRL-O cause a beep and Visual mode continues.
X
XIf the "v", "V" or CTRL-V is preceded with a count, the previously
Xhighlighted area is used for a start. You can then move the end of the
Xhighlighted area and give an operator. The type of the old area is used
X(character, line or blockwise).
X- Linewise Visual mode: The number of lines is multiplied with the count.
X- Blockwise Visual mode: The number of lines and columns is multiplied with
X the count.
X- Normal Visual mode within one line: The number of characters is multiplied
X with the count.
X- Normal Visual mode with several lines: The number of lines is multiplied
X with the count, in the last line the same number of characters is used as
X in the last line in the previously highlighted area.
XThe start of the text is the Cursor position. If the "$" command was used as
Xone of the last commands to extend the highlighted text, the area will be
Xextended to the rightmost column of the longest line.
X
XThe operators that can be used are:
X ~ switch case
X d delete
X c change
X y yank
X > shift right (1)(*)
X < shift left (1)(*)
X ! filter through external command (1)
X = filter through 'equalprg' option command (1)
X Q format lines to 'textwidth' length (1)
X
XAdditionally the following commands can be used:
X : start ex command for highlighted lines (1)
X r change
X s change
X C change (2)
X R change (2)
X S change (2)
X x delete
X D delete (2)
X X delete (2)
X Y yank (2)
X J join (1)
X U make uppercase
X u make lowercase
X
X(1): always whole lines
X(2): whole lines when not using CTRL-V
X(*): in a future a blockwise shift will move the block only, not whole
X lines.
X
XIf you want to give a register name using the """ command, do this just before
Xtyping the operator character: "v{move around}"xd".
X
XIf you want to give a count to the command, do this just before typing the
Xoperator character: "v{move around}3>" (move lines 3 indents to the right).
X
XWhen repeating a Visual mode operator, the operator will be applied to the
Xsame amount of text as the last time:
X- Linewise Visual mode: The same number of lines.
X- Blockwise Visual mode: The same number of lines and columns.
X- Normal Visual mode within one line: The same number of characters.
X- Normal Visual mode with several lines: The same number of lines, in the
X last line the same number of characters as in the last line the last time.
XThe start of the text is the Cursor position. If the "$" command was used as
Xone of the last commands to extend the highlighted text, the repeating will
Xbe applied up to the rightmost column of the longest line.
X
X
X 14. Various commands
X
XCTRL-L Clear and redraw the screen.
X
XCTRL-Z On Unix systems: Suspend Vim. On other systems:
X start a new shell (like ":sh").
X
X<HELP> or
X:h[elp] Show the help file page by page. The help file name
X can be set with the 'helpfile' option. Type an index
X character to go directly to a page. Type <SPACE> or
X CTRL-F (with MSDOS: page-down) to go one page
X forward. Type <b> or CTRL-B (with MSDOS: page-up) to
X go one page back. Type <a> to go back to the index.
X Type <CR> to get out of the help screen. {Vi: no
X help}
X
X<DEL> When entering a number: remove the last digit.
X
X:[range]p[rint] Print [range] lines (default current line).
X
X:[range]p[rint] {count}
X Print {count} lines, starting with [range] (default
X current line, see 4.4.4).
X
X:[range]l[ist] [count]
X Same as :print, but display unprintable characters
X with <^>.
X
X:[range]nu[mber] [count]
X Same as :print, but precede each line with its line
X number.
X
X:[range]# [count] synonym for :number.
X
X:= Print the line number.
X
X:sh[ell] Escape to a shell (name from 'shell' option).
X
X:![!]{cmd} [!][arg] Execute {cmd} with the shell. The optional bangs are
X replaced with the previously given command. The
X optional [arg] is appended. See also the 'shell' and
X 'shelltype' option.
X
X:ve[rsion] Print the version number of the editor. If the
X compiler used understands "__DATE__" the compilation
X date is mentioned. Otherwise a fixed release-date is
X shown.
X
XK Run a program to lookup the identifier under the
X cursor. The name of the program is given with the
X 'keywordprg' (kp) option (default is "ref"). The
X identifier is formed of letters, numbers and the
X underscore. The identifier under or right of the
X cursor is used. The same can be done with the
X command
X ":!{program} {identifier}".
X There is an example of a program to use in the tools
X directory of Vim. It is called 'ref' and does a
X simple spelling check. {not in Vi}
X
X[N]gs
X:[N]sleep [N] Do nothing for [N] seconds. Can be interrupted with
X CTRL-C (CTRL-break on MSDOS). "gs" stands for "goto
X sleep". {not in Vi}
X
X
X 15. Repeating commands
X
X15.1 Single repeats
X
X. Repeat last change with count replaced by [count].
X
XSimple changes can be repeated with the "." command. Without a count, the
Xcount of the last change is used. If you enter a count, it will replace the
Xlast one. If the last change included a specification of a numbered
Xregister, the register number will be incremented. See the section on undo
Xand redo for an example how to use this.
X
X
X15.2 Multiple repeats
X
X:[range]g[lobal]/{pattern}/[cmd]
X Execute the Ex command [cmd] (default ":p") on the
X lines within [range] where {pattern} matches.
X
X:[range]g[lobal]!/{pattern}/[cmd]
X Execute the Ex command [cmd] (default ":p") on the
X lines within [range] where {pattern} does NOT match.
X
X:[range]v[global]/{pattern}/[cmd]
X Same as :g!.
X
XThe global commands work by first scanning through the [range] lines and
Xmarking each line where a match occurs. In a second scan the [cmd] is
Xexecuted for each marked line with its line number prepended. If a line is
Xchanged or deleted its mark disappears. The default for [range] is the whole
Xbuffer (1,$). Use "CTRL-C" to interrupt the command. If an error message is
Xgiven for a line global aborts.
X
XTo repeat a non-Ex command, you will have to put the command in a file and
Xuse "source!". For example:
X :g/pat/so! scriptfile
XMake sure that the scriptfile ends with a whole command, otherwise Vim will
Xwait for you to type the rest of the command for each match. The screen will
Xnot have been updated, so you don't know what you are doing.
X
XThe undo/redo command will undo/redo the whole global command at once.
X
X
X15.3 Complex repeats
X
Xq<0-9a-zA-Z"> Record typed characters into register <0-9a-zA-Z">
X (uppercase to append). The 'q' that stops recording
X is also stored in the register. The 'q' command is
X disabled while executing a register. (Implementation
X note: This was done because the 'q' command can be
X the result of mapping). {Vi: no recording}
X
Xq Stops recording. {Vi: no recording}
X
X@<0-9a-z"> Execute the contents of register <0-9a-z"> [count]
X times. {Vi: only named registers}
X
X@: Repeat last command line [count] times.
X
X@@ Repeat the previous @<0-9a-z":> [count] times.
X
X:[addr]@<0-9a-z"> Execute the contents of register <0-9a-z"> as
X an Ex command. First set cursor at line [addr]
X (default is current line). {Vi: only in some
X versions}
X
X:[addr]@: Repeat last command line [count] times. First set
X cursor at line [addr] (default is current line).
X {Vi: only in some versions}
X
X:[addr]@@ Repeat the previous :@<0-9a-z">. First set cursor at
X line [addr] (default is current line). {Vi: only in
X some versions}
X
X:so[urce] {file} Read Ex commands from {file}.
X
X:so[urce]! {file} Read Vim commands from {file}. {not in Vi}
X
XAll commands and command sequences can be repeated by putting them in a named
Xregister and then executing it. There are two ways to get the commands in the
Xregister:
X- Use the record command "q". You type the commands once, and while they are
X being executed they are stored in a register. Easy, because you can see
X what you are doing. If you make a mistake, 'put' the register into the
X file, edit the command sequence, and then delete it into the register
X again. You can continue recording by appending to the register (use an
X uppercase letter).
X- Delete or yank the command sequence into the register.
X
XOften used command sequences can be put under a function key with the ':map'
Xcommand.
X
XAn alternative is to put the commands in a file, and execute them with the
X':source!' command. Useful for long command sequences. Can be combined with
Xthe ':map' command to put complicated commands under a function key.
X
XThe ':source' command reads Ex commands from a file line by line. You will
Xhave to type any needed keyboard input. The ':source!' command reads from a
Xscript file character by character, interpreting each character as if you
Xtyped it.
X
XExample: When you give the ":!ls" command you are asked to "hit return to
Xcontinue". If you ':source' a file with the line "!ls" in it, you will have
Xto type the return yourself. But if you ':source!' a file with the line
X":!ls" in it, the next characters from that file are read until a <CR> is
Xfound. You will not have to type <CR> yourself, unless ":!ls" was the last
Xline in the file.
X
XIt is possible to put ':source[!]' commands in the script file, so you can
Xmake a top-down hierarchy of script files. The ':source' command can be
Xnested as deep as the number of files that can be opened at one time (about
X15). The ':source!' command can be nested up to 15 levels deep.
X
XIn script files terminal-dependent key codes are represented by
Xterminal-independent single character codes. In the MSDOS version the values
Xare 48 (0x30) higher. Any of these codes can be entered with CTRL-V followed
Xby the three digit decimal code.
X
X code hex meaning
X
X 128 0x80 up-arrow
X 129 0x81 down-arrow
X 130 0x82 left-arrow
X 131 0x83 right-arrow
X 132 0x84 shift up-arrow
X 133 0x85 shift down-arrow
X 134 0x86 shift left-arrow
X 135 0x87 shift right-arrow
X
X 136 0x88 function key 1
X 137 0x89 function key 2
X 138 0x8a function key 3
X 139 0x8b function key 4
X 140 0x8c function key 5
X 141 0x8d function key 6
X 142 0x8e function key 7
X 143 0x8f function key 8
X 144 0x90 function key 9
X 145 0x91 function key 10
X
X 146 0x92 shifted function key 1
X 147 0x93 shifted function key 2
X 148 0x94 shifted function key 3
X 149 0x95 shifted function key 4
X 150 0x96 shifted function key 5
X 151 0x97 shifted function key 6
X 152 0x98 shifted function key 7
X 153 0x99 shifted function key 8
X 154 0x9a shifted function key 9
X 155 0x9b shifted function key 10
X
X 156 0x9c help key
X 157 0x9d undo key
X 158 0x9e special-function key follows (MSDOS)
X 159 0x9f CTRL-@
X
X
X 16. Undo and redo
X
X<UNDO> or
Xu Undo [count] changes. {Vi: only one level}
X
X:u[ndo] Undo one change. {Vi: only one level}
X
XCTRL-R Redo [count] changes which were undone. {Vi: redraw
X screen}
X
X:red[o] Redo one change which was undone. {Vi: no redo}
X
XU Undo all latest changes on one line. {Vi: while not
X moved off of it}
X
XThe last changes are remembered. You can go back in time with the "u"
Xcommand. You can then go forward again with the 'CTRL-R' command. If you
Xmake a new change after the "u" command, the 'CTRL-R' will not be possible
Xanymore. The number of changes that are remembered is set with the
X'undolevels' option. If it is zero, the old fashioned Vi undo is present:
Xone level of undo and undo undoes itself. If it is negative no undo is
Xpossible. Use this if you are running out of memory.
X
XThe "U" command is treated by undo/redo just like any other command. Thus a
X"u" command undos a "U" command and a 'CTRL-R' command redoes it again. When
Xmixing "U", "u" and 'CTRL-R' you will notice that the "U" command will
Xrestore the situation of a line to before the previous "U" command. This may
Xbe confusing. Try it out to get used to it.
X
XWhen all changes have been undone the buffer is not considered to be changed.
XVim can then be exit with ":q" instead of ":q!". {this is not in Vi}
X
XThe numbered registers can also be used for undoing deletes. Each time you
Xdelete text, it is put into register "1. The contents of register "1 are
Xshifted to "2, etc. The contents of register "9 are lost. You can now get
Xback the most recent deleted text with the put command: '"1P'. (also, if the
Xdeleted text was the result of the last delete or copy operation, 'P' or 'p'
Xalso works as this puts the contents of the unnamed register). You can get
Xback the text of three deletes ago with '"3P'.
X
XIf you want to get back more than one part of deleted text, you can use a
Xspecial feature of the repeat command ".". It will increase the number of the
Xregister used. So if you first do ""1P", the following "." will result in a
X'"2P'. Repeating this will result in all numbered registers being inserted.
X
XExample: If you deleted text with 'dd....' it can be restored with
X '"1P....'.
X
XIf you don't know in which register the deleted text is, you can use the
X:display command. An alternative is to try the first register with '"1P', and
Xif it is not what you want do 'u.'. This will remove the contents of the
Xfirst put, and repeat the put command for the second register. Repeat the
X'u.' until you got what you want.
X
X
X 17. Key mapping
X
X:map {lhs} {rhs} Map the key sequence {lhs} to {rhs} in Command mode.
X
X:map! {lhs} {rhs} Map the key sequence {lhs} to {rhs} in Insert and
END_OF_FILE
if test 48444 -ne `wc -c <'vim/doc/reference.doc.C'`; then
echo shar: \"'vim/doc/reference.doc.C'\" unpacked with wrong size!
elif test -f 'vim/doc/reference.doc.A' && test -f 'vim/doc/reference.doc.B' && test -f 'vim/doc/reference.doc.D'; then


echo shar: Combining \"'vim/doc/reference.doc'\" \(210836 characters\)
cat 'vim/doc/reference.doc.A' 'vim/doc/reference.doc.B' 'vim/doc/reference.doc.C' 'vim/doc/reference.doc.D' > 'vim/doc/reference.doc'
if test 210836 -ne `wc -c <'vim/doc/reference.doc'`; then
echo shar: \"'vim/doc/reference.doc'\" combined with wrong size!
else
rm vim/doc/reference.doc.A vim/doc/reference.doc.B vim/doc/reference.doc.C vim/doc/reference.doc.D
fi
fi

# end of 'vim/doc/reference.doc.C'
fi
if test -f 'vim/macros/maze/maze_mac.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/maze_mac.UU'\"
else
echo shar: Extracting \"'vim/macros/maze/maze_mac.UU'\" \(16803 characters\)
sed "s/^X//" >'vim/macros/maze/maze_mac.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/maze/maze_mac
XM(B!4:&5S92!M86-R;W,@)W-O;'9E)R!A;GD@;6%Z92!P<F]D=6-E9"!B>2!T
XM:&4@82UM87IE+6EN9R!M87IE+F,@<')O9W)A;2X*(B *(B!&:7)S="P@82!B
XM:70@;V8@;6%Z92!T:&5O<GDN"B(@268@>6]U('=E<F4@<'5T(&EN=&\@82!M
XM87IE+"!A(&=U87)A;G1E960@;65T:&]D(&]F(&9I;F1I;F<@>6]U<B!W87D*
XM(B!O=70@;V8@=&AE(&UA>F4@:7,@=&\@<'5T('EO=7(@;&5F="!H86YD(&]N
XM=&\@82!W86QL(&%N9"!J=7-T(&ME97 @=V%L:VEN9RP*(B!N979E<B!T86MI
XM;F<@>6]U<B!H86YD(&]F9B!T:&4@=V%L;"X@5&AI<R!T96-H;FEQ=64@:7,@
XM;VYL>2!G=6%R86YT965D('1O"B(@=V]R:R!I9B!T:&4@;6%Z92!D;V5S(&YO
XM="!H879E(&%N>2 G:7-L86YD<R<L(&]R(&EF('1H92 G97AI="<@:7,@;VX@
XM=&AE"B(@<V%M92!I<VQA;F0@87,@>6]U<B!S=&%R=&EN9R!P;VEN="X@5&AE
XM<V4@8V]N9&ET:6]N<R!H;VQD(&9O<B!T:&4@;6%Z97,*(B!U;F1E<B!C;VYS
XM:61E<F%T:6]N+@HB( HB($%S<W5M:6YG('1H870@=&AE(&UA>F4@:7,@;6%D
XM92!U<"!O9B!H;W)I>F]N=&%L(&%N9"!V97)T:6-A;"!W86QL<R!S<&%C960*
XM(B!O;F4@<W1E<"!A<&%R="!A;F0@=&AA="!Y;W4@8V%N(&UO=F4@96ET:&5R
XM(&YO<G1H+"!S;W5T:"P@96%S="!O<B!W97-T+ HB('1H96X@>6]U(&-A;B!A
XM=71O;6%T92!T:&ES('!R;V-E9'5R92!B>2!C87)R>6EN9R!O=70@=&AE(&9O
XM;&QO=VEN9R!S=&5P<RX*(B *(B Q+B!0=70@>6]U<G-E;&8@<V]M97=H97)E
XM(&EN('1H92!M87IE(&YE87(@82!W86QL+@HB(#(N($-H96-K(&EF('EO=2!H
XM879E(&$@=V%L;"!O;B!Y;W5R(&QE9G0N($EF('-O+"!G;R!T;R!S=&5P(#0N
XM"B(@,RX@5&AE<F4@:7,@;F\@=V%L;"!O;B!Y;W5R(&QE9G0L('-O('1U<FX@
XM;VX@=&AE('-P;W0@=&\@>6]U<B!L969T(&%N9"!S=&5P"B(@(" @9F]R=V%R
XM9"!B>2!O;F4@<W1E<"!A;F0@<F5P96%T('-T97 @,BX*(B T+B!#:&5C:R!W
XM:&%T(&ES(&1I<F5C=&QY(&EN(&9R;VYT(&]F('EO=2X@268@:70@:7,@82!W
XM86QL+"!T=7)N(&]N('1H90HB(" @('-P;W0@=&\@>6]U<B!R:6=H="!B>2 Y
XM,"!D96=R965S(&%N9"!R97!E870@<W1E<" T+@HB(#4N(%1H97)E(&ES(&YO
XM('=A;&P@:6X@9G)O;G0@;V8@>6]U+"!S;R!S=&5P(&9O<G=A<F0@;VYE('-T
XM97 @86YD"B(@(" @9V\@=&\@<W1E<" R+@HB( HB($EN('1H:7,@=V%Y('EO
XM=2!W:6QL(&-O=F5R(&%L;"!T:&4@8V]R<FED;W)S(&]F('1H92!M87IE("AU
XM;G1I;"!Y;W4@9V5T(&)A8VL*(B!T;R!W:&5R92!Y;W4@<W1A<G1E9"!F<F]M
XM+"!I9B!Y;W4@9&\@;F]T('-T;W I+@HB( HB($)Y(&5X86UI;FEN9R!A(&UA
XM>F4@<')O9'5C960@8GD@=&AE(&UA>F4N8R!P<F]G<F%M('EO=2!W:6QL('-E
XM92!T:&%T( HB(&5A8V@@<W%U87)E(&]F('1H92!M87IE(&ES(&]N92!C:&%R
XM86-T97(@:&EG:"!A;F0@='=O(&-H87)A8W1E<G,@=VED92X*(B!4;R!G;R!N
XM;W)T:"!O<B!S;W5T:"P@>6]U(&UO=F4@8GD@82!O;F4@8VAA<F%C=&5R('-T
XM97 L(&)U="!T;R!M;W9E(&5A<W0@;W(*(B!W97-T('EO=2!M;W9E(&)Y(&$@
XM='=O(&-H87)A8W1E<B!S=&5P+B!!;'-O(&YO=&4@=&AA="!I;B!A;GD@<&]S
XM:71I;VX*(B!T:&5R92!A<F4@9F]U<B!P;&%C97,@=VAE<F4@=V%L;',@8V]U
XM;&0@8F4@<'5T("T@=&\@=&AE(&YO<G1H+"!T;R!T:&4@<V]U=&@L"B(@=&\@
XM=&AE(&5A<W0@86YD('1O('1H92!W97-T+@HB($$@=V%L;"!E>&ES=',@=&\@
XM=&AE(&YO<G1H(&]F('EO=2!I9B!T:&4@8VAA<F%C=&5R('1O('1H92!N;W)T
XM:"!O9@HB('EO=2!I<R!A(%\@*&]T:&5R=VES92!I="!I<R!A('-P86-E*2X*
XM(B!!('=A;&P@97AI<W1S('1O('1H92!E87-T(&]F('EO=2!I9B!T:&4@8VAA
XM<F%C=&5R('1O('1H92!E87-T(&]F('EO=0HB(&ES(&$@?" H;W1H97)W:7-E
XM(&ET(&ES(&$@+BDN"B(@02!W86QL(&5X:7-T<R!T;R!T:&4@=V5S="!O9B!Y
XM;W4@:68@=&AE(&-H87)A8W1E<B!T;R!T:&4@=V5S="!O9B!Y;W4*(B!I<R!A
XM('P@*&]T:&5R=VES92!I="!I<R!A("XI+@HB($$@=V%L;"!E>&ES=',@=&\@
XM=&AE('-O=71H(&]F('EO=2!I9B!T:&4@8VAA<F%C=&5R('=H97)E('EO=2!A
XM<F4*(B!I<R!A(%\@*&]T:&5R=VES92!I="!I<R!A('-P86-E*2X*(B *(B!.
XM;W1E('1H92!D:69F97)E;F-E(&9O<B!D:7)E8W1I;VX@<V]U=&@L('=H97)E
XM('=E(&UU<W0@97AA;6EN92!T:&4@8VAA<F%C=&5R"B(@=VAE<F4@=&AE(&-U
XM<G-O<B!I<R!R871H97(@=&AA;B!A;B!A9&IA8V5N="!C96QL+@HB( HB($EF
XM('EO=2!W97)E(&EM<&QE;65N=&EN9R!T:&4@86)O=F4@<')O8V5D=7)E(&ES
XM(&$@;F]R;6%L(&-O;7!U=&5R(&QA;F=U86=E"B(@>6]U(&-O=6QD('5S92!A
XM(&QO;W @=VET:"!I9B!S=&%T96UE;G1S(&%N9"!C;VYT:6YU92!S=&%T96UE
XM;G1S+" *(B!(;W=E=F5R+"!T:&5S92!C;VYS=')U8W1S(&%R92!N;W0@879A
XM:6QA8FQE(&EN('9I(&UA8W)O<R!S;R!)(&AA=F4@=7-E9 HB(&$@<W1A=&4@
XM;6%C:&EN92!W:71H(#@@<W1A=&5S+B!%86-H('-T871E('-I9VYI9FEE<R!T
XM:&4@9&ER96-T:6]N('EO=0HB(&%R92!G;VEN9R!I;B!A;F0@=VAE=&AE<B!O
XM<B!N;W0@>6]U(&AA=F4@8VAE8VME9"!I9B!T:&5R92!I<R!A('=A;&P@;VX*
XM(B!Y;W5R(&QE9G0N"B(@"B(@5&AE('1R86YS:71I;VX@9G)O;2!S=&%T92!T
XM;R!S=&%T92!A;F0@=&AE(&%C=&EO;G,@=&%K96X@;VX@96%C:"!T<F%N<VET
XM:6]N"B(@87)E(&=I=F5N(&EN('1H92!S=&%T92!T86)L92!B96QO=RX*(B!4
XM:&4@;F%M97,@;V8@=&AE('-T871E<R!A<F4@3C$L($XR+"!3,2P@4S(L($4Q
XM+"!%,BP@5S$L(%<R+"!W:&5R92!E86-H(&QE='1E<@HB('-T86YD<R!F;W(@
XM82!D:7)E8W1I;VX@;V8@=&AE(&-O;7!A<W,L('1H92!N=6UB97(@,2!I;F1I
XM8V%T97,@=&AA="!T:&4@=V4*(B!H879E(&YO="!Y970@8VAE8VME9"!T;R!S
XM964@:68@=&AE<F4@:7,@82!W86QL(&]N(&]U<B!L969T(&%N9"!T:&4@;G5M
XM8F5R(#(*(B!I;F1I8V%T97,@=&AA="!W92!H879E(&-H96-K960@86YD('1H
XM97)E(&ES(&$@=V%L;"!O;B!O=7(@;&5F="X*(B *(B!&;W(@96%C:"!S=&%T
XM92!W92!M=7-T(&-O;G-I9&5R('1H92!E>&ES=&5N8V4@;W(@;F]T(&]F(&$@
XM=V%L;"!I;B!A"B(@<&%R=&EC=6QA<B!D:7)E8W1I;VXN(%1H:7,@9&ER96-T
XM:6]N(&ES(&=I=F5N(&EN('1H92!F;VQL;W=I;F<@=&%B;&4N"B(@"B(@3F5X
XM=$-H87(@=&%B;&4Z"B(@<W1A=&4@(" @(" @(&1I<F5C=&EO;B @(" @("!V
XM:2!C;VUM86YD<PHB("!.,2 @(" @(" @(" @(" @5R @(" @(" @(" @(" @
XM(&A&"B(@($XR(" @(" @(" @(" @("!.(" @(" @(" @(" @(" @:T8*(B @
XM4S$@(" @(" @(" @(" @($4@(" @(" @(" @(" @("!L1@HB("!3,B @(" @
XM(" @(" @(" @4R @(" @(" @(" @(" @($8*(B @13$@(" @(" @(" @(" @
XM($X@(" @(" @(" @(" @("!K1@HB("!%,B @(" @(" @(" @(" @12 @(" @
XM(" @(" @(" @(&Q&"B(@(%<Q(" @(" @(" @(" @("!3(" @(" @(" @(" @
XM(" @1@HB("!7,B @(" @(" @(" @(" @5R @(" @(" @(" @(" @(&A&"B(@
XM"B(@=VAE<F4@1B!I<R!A(&UA8W)O('=H:6-H('EA;FMS('1H92!C:&%R86-T
XM97(@=6YD97(@=&AE(&-U<G-O<B!I;G1O"B(@=&AE($YE>'1#:&%R(')E9VES
XM=&5R("AN*2X*(B *(B!3=&%T92!T86)L93H*(B!);B!T:&4@)W9I(&-O;6UA
XM;F1S)R!C;VQU;6X@:7,@9VEV96X@=&AE(&%C=&EO;G,@=&\@8V%R<GD@;W5T
XM('=H96X@:6X*(B!T:&ES('-T871E(&%N9"!T:&4@3F5X=$-H87(@:7,@87,@
XM9VEV96XN(%1H92!C;VUM86YD<R!K+"!J+"!L;"P@:&@@;6]V90HB('1H92!C
XM=7)R96YT('!O<VET:6]N(&YO<G1H+"!S;W5T:"P@96%S="!A;F0@=V5S="!R
XM97-P96-T:79E;'DN(%1H90HB(&-O;6UA;F0@;6T@:7,@=7-E9"!A<R!A(&YO
XM+6]P(&-O;6UA;F0N"B(@26X@=&AE("=N97AT('-T871E)R!C;VQU;6X@:7,@
XM9VEV96X@=&AE(&YE=R!S=&%T92!O9B!T:&4@;6%C:&EN92!A9G1E<@HB('1H
XM92!A8W1I;VX@:7,@8V%R<FEE9"!O=70N"B(@"B(@8W5R<F5N="!S=&%T92 @
XM(" @(" @3F5X=$-H87(@(" @=FD@8V]M;6%N9',@(&YE>'0@<W1A=&4*(B @
XM(" @($XQ(" @(" @(" @(" @(" @(" N(" @(" @(" @(" @:&@@(" @(" @
XM(" @5S$*(B @(" @($XQ(" @(" @(" @(" @(" @("!\(" @(" @(" @(" @
XM;6T@(" @(" @(" @3C(*(B @(" @($XR(" @(" @(" @(" @(" @("!?(" @
XM(" @(" @(" @;6T@(" @(" @(" @13$*(B @(" @($XR(" @(" @(" @(" @
XM(" @<W!A8V4@(" @(" @(" @:R @(" @(" @(" @3C$*(B @(" @(%,Q(" @
XM(" @(" @(" @(" @(" N(" @(" @(" @(" @;&P@(" @(" @(" @13$*(B @
XM(" @(%,Q(" @(" @(" @(" @(" @("!\(" @(" @(" @(" @;6T@(" @(" @
XM(" @4S(*(B @(" @(%,R(" @(" @(" @(" @(" @("!?(" @(" @(" @(" @
XM;6T@(" @(" @(" @5S$*(B @(" @(%,R(" @(" @(" @(" @(" @<W!A8V4@
XM(" @(" @(" @:B @(" @(" @(" @4S$*(B @(" @($4Q(" @(" @(" @(" @
XM(" @<W!A8V4@(" @(" @(" @:R @(" @(" @(" @3C$*(B @(" @($4Q(" @
XM(" @(" @(" @(" @("!?(" @(" @(" @(" @;6T@(" @(" @(" @13(*(B @
XM(" @($4R(" @(" @(" @(" @(" @("!\(" @(" @(" @(" @;6T@(" @(" @
XM(" @4S$*(B @(" @($4R(" @(" @(" @(" @(" @(" N(" @(" @(" @(" @
XM;&P@(" @(" @(" @13$*(B @(" @(%<Q(" @(" @(" @(" @(" @<W!A8V4@
XM(" @(" @(" @:B @(" @(" @(" @4S$*(B @(" @(%<Q(" @(" @(" @(" @
XM(" @("!?(" @(" @(" @(" @;6T@(" @(" @(" @5S(*(B @(" @(%<R(" @
XM(" @(" @(" @(" @("!\(" @(" @(" @(" @;6T@(" @(" @(" @3C$*(B @
XM(" @(%<R(" @(" @(" @(" @(" @(" N(" @(" @(" @(" @:&@@(" @(" @
XM(" @5S$*(@HB( HB($-O;7!L86EN="!A8F]U="!V:2!M86-R;W,Z"B(@270@
XM<V5E;7,@=&AA="!Y;W4@8V%N;F]T(&AA=F4@;6]R92!T:&%N(&]N92 G=6YD
XM;RUA8FQE)R!V:2!C;VUM86YD"B(@:6X@=&AE(&]N92!M86-R;RP@<V\@>6]U
XM(&AA=F4@=&\@;6%K92!L;W1S(&]F(&QI='1L92!M86-R;W,@86YD"B(@<'5T
XM('1H96T@=&]G971H97(N"B(*(B!))VQL(&5X<&QA:6X@=VAA="!)(&UE86X@
XM8GD@86X@97AA;7!L92X@161I="!A(&9I;&4@86YD"B(@='EP92 G.FUA<"!1
XM(')862<N(%1H:7,@<VAO=6QD(&UA<"!T:&4@42!K97D@=&\@)W)E<&QA8V4@
XM=&AE"B(@8VAA<F%C=&5R('5N9&5R('1H92!C=7)S;W(@=VET:"!8(&%N9"!Y
XM86YK('1H92!L:6YE)RX*(B!"=70@=VAE;B!)('1Y<&4@42P@=FD@=&5L;',@
XM;64@)T-A;B=T('EA;FL@:6YS:61E(&=L;V)A;"]M86-R;R<@86YD"B(@9V]E
XM<R!I;G1O(&5X(&UO9&4N($AO=V5V97(@:68@22!T>7!E("<Z;6%P(%$@<EA4
XM)R!A;F0@)SIM87 @5"!9)RP*(B!E=F5R>71H:6YG(&ES($]++B!)8&T@9&]I
XM;F<@86QL('1H:7,@;VX@82!3<&%R8W-T871I;VXN"B(@268@86YY;VYE(')E
XM861I;F<@=&AI<R!H87,@86X@86YS=V5R('1O('1H:7,@<')O8FQE;2P@=&AE
XM(&%U=&AO<B!W;W5L9 HB(&QO=F4@=&\@9FEN9"!O=70N($UA:6P@=&\@9W)E
XM9VU ;W1C+F]T8V$N;WHN874N"B(*(B!4:&4@;6%C<F]S.@HB(%1H92!M86-R
XM;R!T;R!R=6X@=&AE(&UA>F4@<V]L=F5R(&ES("=G)RX@5&AI<R!S:6UP;'D@
XM8V%L;',@='=O(&]T:&5R"B(@;6%C<F]S.B!)+"!T;R!I;FET:6%L:7-E(&5V
XM97)Y=&AI;F<L(&%N9"!,+"!T;R!L;V]P(&9O<F5V97(@<G5N;FEN9PHB('1H
XM<F]U9V@@=&AE('-T871E('1A8FQE+@HB($)O=&@@;V8@=&AE<V4@;6%C<F]S
XM(&%R92!L;VYG('-E<75E;F-E<R!O9B!C86QL<R!T;R!O=&AE<B!M86-R;W,N
XM($%L; HB(&]F('1H97-E(&]T:&5R(&UA8W)O<R!A<F4@<75I=&4@<VEM<&QE
XM(&%N9"!S;R!T;R!U;F1E<G-T86YD(&AO=R!T:&ES"B(@=V]R:W,L(&%L;"!Y
XM;W4@;F5E9"!T;R!D;R!I<R!E>&%M:6YE(&UA8W)O<R!)(&%N9"!,(&%N9"!L
XM96%R;B!W:&%T('1H97D*(B!D;R H82!S:6UP;&4@<V5Q=65N8V4@;V8@=FD@
XM86-T:6]N<RD@86YD(&AO=R!,(&QO;W!S("AB>2!C86QL:6YG(%4L('=H:6-H
XM"B(@<VEM<&QY(&-A;&QS($P@86=A:6XI+@HB"B(@36%C<F\@22!S971S('5P
XM('1H92!S=&%T92!T86)L92!A;F0@3F5X=$-H87(@=&%B;&4@870@=&AE(&5N
XM9"!O9B!T:&4@9FEL92X*(B!-86-R;R!,('1H96X@<V5A<F-H97,@=&AE<V4@
XM=&%B;&5S('1O(&9I;F0@;W5T('=H870@86-T:6]N<R!T;R!P97)F;W)M(&%N
XM9 HB('=H870@<W1A=&4@8VAA;F=E<R!T;R!M86ME+@HB"B(@5&AE(&5N=')I
XM97,@:6X@=&AE('-T871E('1A8FQE(&%L;"!B96=I;B!W:71H(&$@:V5Y(&-O
XM;G-I<W1I;F<@;V8@=&AE"B(@;&5T=&5R("=S)RP@=&AE(&-U<G)E;G0@<W1A
XM=&4@86YD('1H92!.97AT0VAA<BX@($%F=&5R('1H:7,@:7,@=&AE"B(@86-T
XM:6]N('1O('1A:V4@:6X@=&AI<R!S=&%T92!A;F0@869T97(@=&AI<R!I<R!T
XM:&4@;F5X="!S=&%T92!T;R!C:&%N9V4@=&\N"B(*(B!4:&4@96YT<FEE<R!I
XM;B!T:&4@3F5X=$-H87(@=&%B;&4@8F5G:6X@=VET:"!A(&ME>2!C;VYS:7-T
XM:6YG(&]F('1H90HB(&QE='1E<B G;B<@86YD('1H92!C=7)R96YT('-T871E
XM+B!!9G1E<B!T:&ES(&ES('1H92!A8W1I;VX@=&\@=&%K92!T;PHB(&]B=&%I
XM;B!.97AT0VAA<B M('1H92!C:&%R86-T97(@=&AA="!M=7-T(&)E(&5X86UI
XM;F5D('1O(&-H86YG92!S=&%T92X*(@HB($]N92!W87D@=&\@<V5E('=H870@
XM96%C:"!P87)T(&]F('1H92!M86-R;W,@:7,@9&]I;F<@:7,@=&\@='EP92!I
XM;B!T:&4*(B!B;V1Y(&]F('1H92!M86-R;W,@22!A;F0@3"!M86YU86QL>2 H
XM:6YS=&5A9"!O9B!T>7!I;F<@)V<G*2!A;F0@<V5E"B(@=VAA="!H87!P96YS
XM(&%T(&5A8V@@<W1E<"X*(@HB($=O;V0@;'5C:RX*(@HB(%)E9VES=&5R<R!U
XM<V5D(&)Y('1H92!M86-R;W,Z"B(@<R H4W1A=&4I(" @(" @(" M(&AO;&1S
XM('1H92!S=&%T92!T:&4@;6%C:&EN92!I<R!I;@HB(&,@*$-H87(I(" @(" @
XM(" @+2!H;VQD<R!T:&4@8VAA<F%C=&5R('5N9&5R('1H92!C=7)R96YT('!O
XM<VET:6]N"B(@;2 H36%C<F\I(" @(" @(" M(&AO;&1S(&$@=FD@8V]M;6%N
XM9"!S=')I;F<@=&\@8F4@97AE8W5T960@;&%T97(*(B!N("A.97AT0VAA<BD@
XM(" @("T@:&]L9',@=&AE(&-H87)A8W1E<B!W92!M=7-T(&5X86UI;F4@=&\@
XM8VAA;F=E('-T871E"B(@<B H4V5C;VYD($UA8W)O*2 M(&AO;&1S(&$@<V5C
XM;VYD('9I(&-O;6UA;F0@<W1R:6YG('1O(&)E(&5X96-U=&5D(&QA=&5R"B(*
XM<V5T(')E;6%P"G-E="!N;VUA9VEC"G-E="!N;W1E<G-E"G-E="!W<F%P<V-A
XM;@HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@9R M(&=O(')U;G,@=&AE('=H
XM;VQE('-H;W<*(B @(" @(" @22 M(&EN:71I86QI<V4*(B @(" @(" @3" M
XM('1H96X@;&]O<"!F;W)E=F5R"FUA<"!G(" @24P*(@HB/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/0HB($D@+2!I;FET:6%L:7-E(&5V97)Y=&AI;F<@8F5F;W)E(')U
XM;FYI;F<@=&AE(&QO;W *(B @($<D/RY>32 M(&9I;F0@=&AE(&QA<W0@+B!I
XM;B!T:&4@;6%Z90HB(" @(" @("!>("T@<F5P;&%C92!I="!W:71H(&%N(%@@
XM*'1H92!G;V%L*0HB(" @1UE+9410("T@<')I;G0@=&AE('-T871E('1A8FQE
XM(&%N9"!N97AT(&-H87(@=&%B;&4@870@=&AE(&5N9"!O9B!T:&4@9FEL90HB
XM(" @(" @(#!3("T@:6YI=&EA;&ES92!T:&4@<W1A=&4@;V8@=&AE(&UA8VAI
XM;F4@=&\@13$*(B @(" @(#)';" M(&UO=F4@=&\@=&AE('1O<"!L969T(&-E
XM;&P@;V8@=&AE(&UA>F4*;6%P($D@("!')#\N#5Y'64ME1% P4S)'; HB"B(]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]"B(@3" M('1H92!L;V]P('=H:6-H(&ES(&5X
XM96-U=&5D(&9O<F5V97(*(B @(" @(" @42 M('-A=F4@=&AE(&-U<G)E;G0@
XM8VAA<F%C=&5R(&EN('1H92!#:&%R(')E9VES=&5R"B(@(" @(" @($$@+2!R
XM97!L86-E('1H92!C=7)R96YT(&-H87)A8W1E<B!W:71H(&%N("=/)PHB(" @
XM(" @(&UA("T@;6%R:R!T:&4@8W5R<F5N="!P;W-I=&EO;B!W:71H(&UA<FL@
XM)V$G"B(@(" @("!'3D(@+2!O;B!B;W1T;VT@;&EN92P@8W)E871E(&$@8V]M
XM;6%N9"!T;R!S96%R8V@@=&AE($YE>'1#:&%R('1A8FQE"B(@(" @(" @(" @
XM("!F;W(@=&AE(&-U<G)E;G0@<W1A=&4*(B P33!%0&U>32 M('EA;FL@=&AE
XM(&-O;6UA;F0@:6YT;R!T:&4@36%C<F\@<F5G:7-T97(@86YD(&5X96-U=&4@
XM:70*(B @(" @("!W6" M('=E(&AA=F4@;F]W(&9O=6YD('1H92!E;G1R>2!I
XM;B!T:&4@=&%B;&4L(&YO=R!Y86YK('1H90HB(" @(" @(" @(" @9F]L;&]W
XM:6YG('=O<F0@:6YT;R!T:&4@36%C<F\@<F5G:7-T97(*(B @(" @8&% ;2 M
XM(&=O(&)A8VL@=&\@=&AE(&-U<G)E;G0@<&]S:71I;VX@86YD(&5X96-U=&4@
XM=&AE(&UA8W)O+"!T:&ES('=I;&P*(B @(" @(" @(" @('EA;FL@=&AE($YE
XM>'1#:&%R(&EN(')E9VES=&5R(&X*(B @($=4)$(D4B M(&]N(&)O='1O;2!L
XM:6YE+"!C<F5A=&4@82!C;VUM86YD('1O('-E87)C:"!T:&4@<W1A=&4@=&%B
XM;&4*(B @(" @(" @(" @(&9O<B!T:&4@8W5R<F5N="!S=&%T92!A;F0@3F5X
XM=$-H87(*(B P33!%0&U>32 M('EA;FL@=&AE(&-O;6UA;F0@:6YT;R!T:&4@
XM36%C<F\@<F5G:7-T97(@86YD(&5X96-U=&4@:70*(B @(" @(#)74R M('=E
XM(&AA=F4@;F]W(&9O=6YD('1H92!E;G1R>2!I;B!T:&4@=&%B;&4L(&YO=R!Y
XM86YK('1H90HB(" @(" @(" @(" @;F5X="!S=&%T92!I;G1O('1H92!3=&%T
XM92!M86-R;PHB(" @(" @(&)8("T@86YD('EA;FL@=&AE(&%C=&EO;B!C;W)R
XM97-P;VYD:6YG('1O('1H:7,@<W1A=&4@=&%B;&4@96YT<GD*(B @(" @(" @
XM(" @(&EN=&\@=&AE($UA8W)O(')E9VES=&5R"B(@(" @("!'5DH@+2!O;B!B
XM;W1T;VT@;&EN92P@8W)E871E(&$@8V]M;6%N9"!T;R!R97-T;W)E('1H92!C
XM=7)R96YT(&-H87)A8W1E<@HB(" @(" @(#!(("T@86YD('-A=F4@=&AE(&-O
XM;6UA;F0@:6YT;R!T:&4@<V5C;VYD($UA8W)O(')E9VES=&5R"B(@(" @(&!A
XM0'(@+2!G;R!B86-K('1O('1H92!C=7)R96YT('!O<VET:6]N(&%N9"!E>&5C
XM='5T92!T:&4@;6%C<F\@=&\@<F5S=&]R90HB(" @(" @(" @(" @=&AE(&-U
XM<G)E;G0@8VAA<F%C=&5R"B(@(" @(" @0&T@+2!E>&5C=71E('1H92!A8W1I
XM;VX@87-S;V-I871E9"!W:71H('1H:7,@<W1A=&4*(B @(" @(" @52 M(&%N
XM9"!R97!E870*;6%P($P@("!106UA1TY",$TP14!M#7=88&% ;4=4)$(D4C!-
XM,$5 ;0TR5U-B6$=62C!(8&% <D!M50HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM"B(@52 M(&YO('1A:6P@<F5C=7)S:6]N(&%L;&]W960@:6X@=FD@;6%C<F]S
XM('-O(&-H96%T(&%N9"!S970@52 ]($P*;6%P(%4@("!,"B(*(CT]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T*(B!3("T@>6%N:R!T:&4@;F5X="!T=V\@8VAA<F%C=&5R
XM<R!I;G1O('1H92!3=&%T92!R96=I<W1E<@IM87 @4R @(")S>3)L"B(*(CT]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T*(B!1("T@<V%V92!T:&4@8W5R<F5N="!C:&%R
XM86-T97(@:6X@=&AE($-H87(@<F5G:7-T97(*;6%P(%$@(" B8WEL"B(*(CT]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T*(B!!("T@<F5P;&%C92!T:&4@8W5R<F5N="!C
XM:&%R86-T97(@=VET:"!A;B G3R<*;6%P($$@("!R3PHB"B(]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]"B(@3B M(')E<&QA8V4@=&AI<R!L:6YE('=I=&@@=&AE('-T
XM<FEN9R G;B<*;6%P($X@("!#+VX;"B(*(CT]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T*
XM(B!"("T@<'5T('1H92!C=7)R96YT('-T871E"FUA<"!"(" @(G-P"B(*(CT]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T*(B!-("T@>6%N:R!T:&ES(&QI;F4@:6YT;R!T
XM:&4@36%C<F\@<F5G:7-T97(*;6%P($T@(" B;7DD"B(*(CT]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T*(B!%("T@9&5L971E('1O('1H92!E;F0@;V8@=&AE(&QI;F4*
XM;6%P($4@("!D) HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@6" M('EA;FL@
XM=&AI<R!W;W)D(&EN=&\@=&AE($UA8W)O(')E9VES=&5R"FUA<"!8(" @(FUY
XM=" *(@HB/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0HB(%0@+2!R97!L86-E('1H:7,@
XM;&EN92!W:71H('1H92!S=')I;F<@)W,G"FUA<"!4(" @0R]S&PHB"B(]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]"B(@4B M('!U="!.97AT0VAA<@IM87 @4B @(")N
XM< HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]"B(@5B M(&%D9"!T:&4@;&5T=&5R
XM("=R)R H=&AE(')E<&QA8V4@=FD@8V]M;6%N9"D*;6%P(%8@("!A<AL*(@HB
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/0HB($H@+2!R97-T;W)E('1H92!C=7)R96YT
XM(&-H87)A8W1E<@IM87 @2B @(")C< HB"B(]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM"B(@2" M('EA;FL@=&AI<R!L:6YE(&EN=&\@=&AE('-E8V]N9"!-86-R;R!R
XM96=I<W1E<@IM87 @2" @(")R>20*(@HB/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0HB
XM($8@+2!Y86YK($YE>'1#:&%R("AT:&ES(&UA8W)O(&ES(&-A;&QE9"!F<F]M
XM('1H92!-86-R;R!R96=I<W1E<BD*;6%P($8@(" B;GEL"B(*(CT]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T*(B!>("T@<F5P;&%C92!T:&4@8W5R<F5N="!C:&%R86-T
XM97(@=VET:"!A;B G6"<*;6%P(%X@("!R6 HB"B(]/3T]/3T]/3T]/3T]/3T]
XM/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
XM/3T]"B(@64ME1% @+2!C<F5A=&4@=&AE('-T871E('1A8FQE+"!.97AT0VAA
XM<B!T86)L92!A;F0@:6YI=&EA;"!S=&%T90HB($YO=&4@=&AA="!Y;W4@:&%V
XM92!T;R!E<V-A<&4@=&AE(&)A<B!C:&%R86-T97(L('-I;F-E(&ET(&ES('-P
XM96-I86P@=&\*(B!T:&4@;6%P(&-O;6UA;F0@*&ET(&EN9&EC871E<R!A(&YE
XM=R!L:6YE*2X*;6%P(%D@("!O<T4Q("!K("!.,2 @(" @("!S13%?(&UM($4R
XM(" @(" @('-%,A9\(&UM(%,Q(" @(" @('-%,BX@;&P@13$;"FUA<"!+(" @
XM;W-7,2 @:B @4S$@(" @(" @<U<Q7R!M;2!7,B @(" @("!S5S(6?"!M;2!.
XM,2 @(" @("!S5S(N(&AH(%<Q&PIM87 @92 @(&]S3C$N(&AH(%<Q(" @(" @
XM('-.,19\(&UM($XR(" @(" @('-.,B @:R @3C$@(" @(" @<TXR7R!M;2!%
XM,1L*;6%P($0@("!O<U,Q+B!L;"!%,2 @(" @("!S4S$6?"!M;2!3,B @(" @
XM("!S4S(@(&H@(%,Q(" @(" @('-3,E\@;6T@5S$;"FUA<"!0(" @;VY%,2!K
XM1B!N13(@;$8@;E<Q($<D2D8@;E<R(&A&(&Y.,2!H1B!N3C(@:T8@;E,Q(&Q&
X/(&Y3,B!')$I&( U%,1L*
X
Xend
END_OF_FILE
if test 16803 -ne `wc -c <'vim/macros/maze/maze_mac.UU'`; then
echo shar: \"'vim/macros/maze/maze_mac.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/maze/maze_mac'\" \(12165 characters\)
cat vim/macros/maze/maze_mac.UU | uudecode
if test 12165 -ne `wc -c <'vim/macros/maze/maze_mac'`; then
echo shar: \"'vim/macros/maze/maze_mac'\" uudecoded with wrong size!
else
rm vim/macros/maze/maze_mac.UU
fi
fi
# end of 'vim/macros/maze/maze_mac.UU'
fi
if test -f 'vim/src/ascii.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/ascii.h'\"
else
echo shar: Extracting \"'vim/src/ascii.h'\" \(787 characters\)
sed "s/^X//" >'vim/src/ascii.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Definitions of various common control characters
X */
X
X#define NUL '\000'
X#define BS '\010'
X#define BS_STR (char_u *)"\010"
X#define TAB '\011'
X#define NL '\012'
X#define NL_STR (char_u *)"\012"
X#define CR '\015'
X#define ESC '\033'
X#define ESC_STR (char_u *)"\033"
X#define DEL 0x7f
X#define CSI 0x9b
X
X#define Ctrl(x) ((x) & 0x1f)
X#define Meta(x) ((x) | 0x80)
X
X/*
X * character that separates dir names in a path
X */
X#ifdef MSDOS
X# define PATHSEP '\\'
X# define PATHSEPSTR "\\"
X#else
X# define PATHSEP '/'
X# define PATHSEPSTR "/"
X#endif
END_OF_FILE
if test 787 -ne `wc -c <'vim/src/ascii.h'`; then
echo shar: \"'vim/src/ascii.h'\" unpacked with wrong size!
fi
# end of 'vim/src/ascii.h'
fi
echo shar: End of archive 6 \(of 26\).
cp /dev/null ark6isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:17:56 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 26
Archive-name: vim/part07

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/screen.c vim/src/tcconfig.tc.UU vim/src/version.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:01 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 7 (of 26)."'
if test -f 'vim/src/screen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/screen.c'\"
else
echo shar: Extracting \"'vim/src/screen.c'\" \(46442 characters\)
sed "s/^X//" >'vim/src/screen.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * screen.c: code for displaying on the screen
X */
X
X#include "vim.h"


X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xchar *tgoto __PARMS((char *cm, int col, int line));
X
Xstatic char_u *Nextscreen = NULL; /* What is currently on the screen. */
Xstatic char_u **LinePointers = NULL; /* array of pointers into Nextscreen */
X
X/*
X * Cline_height is set (in cursupdate) to the number of physical
X * lines taken by the line the cursor is on. We use this to avoid extra calls
X * to plines(). The optimized routine updateline()
X * makes sure that the size of the cursor line hasn't changed. If so, lines
X * below the cursor will move up or down and we need to call the routine
X * updateScreen() to examine the entire screen.
X */
Xstatic int Cline_height; /* current size of cursor line */
X
Xstatic int Cline_row; /* starting row of the cursor line on screen */
X
Xstatic FPOS old_cursor = {0, 0}; /* last known end of visual part */
Xstatic int oldCurswant = 0; /* last known value of Curswant */
Xstatic int canopt; /* TRUE when cursor goto can be optimized */
Xstatic int invert = 0; /* set to INVERTCODE when inverting */
X
X#define INVERTCODE 0x80
X
Xstatic int win_line __ARGS((WIN *, linenr_t, int, int));
Xstatic void screen_char __ARGS((char_u *, int, int));
Xstatic void screenalloc __ARGS((int));
Xstatic void screenclear2 __ARGS((void));
Xstatic int screen_ins_lines __ARGS((int, int, int, int));
X
X/*
X * updateline() - like updateScreen() but only for cursor line
X *
X * This determines whether or not we need to call updateScreen() to examine
X * the entire screen for changes. This occurs if the size of the cursor line
X * (in rows) hasn't changed.
X */
X void
Xupdateline()
X{
X int row;
X int n;
X
X if (must_redraw) /* must redraw whole screen */
X {
X updateScreen(must_redraw);
X return;
X }
X
X screenalloc(TRUE); /* allocate screen buffers if size changed */
X
X if (Nextscreen == NULL || RedrawingDisabled)
X return;
X
X screen_start(); /* init cursor position of screen_char() */
X cursor_off();
X
X (void)set_highlight('v');
X row = win_line(curwin, curwin->w_cursor.lnum, Cline_row, curwin->w_height);
X
X if (row == curwin->w_height + 1) /* line too long for window */
X updateScreen(VALID_TO_CURSCHAR);
X else
X {
X n = row - Cline_row;
X if (n != Cline_height) /* line changed size */
X {
X if (n < Cline_height) /* got smaller: delete lines */
X win_del_lines(curwin, row, Cline_height - n, FALSE, TRUE);
X else /* got bigger: insert lines */
X win_ins_lines(curwin, Cline_row + Cline_height, n - Cline_height, FALSE, TRUE);
X updateScreen(VALID_TO_CURSCHAR);
X }
X }
X}
X
X/*
X * updateScreen()
X *
X * Based on the current value of curwin->w_topline, transfer a screenfull
X * of stuff from Filemem to Nextscreen, and update curwin->w_botline.


X */
X
X void

XupdateScreen(type)
X int type;
X{
X WIN *wp;
X
X screenalloc(TRUE); /* allocate screen buffers if size changed */
X if (Nextscreen == NULL)
X return;
X
X if (must_redraw)
X {
X if (type < must_redraw) /* use maximal type */
X type = must_redraw;
X must_redraw = 0;
X }
X
X if (type == CURSUPD) /* update cursor and then redraw NOT_VALID*/
X {
X curwin->w_lsize_valid = 0;
X cursupdate(); /* will call updateScreen() */
X return;
X }
X if (curwin->w_lsize_valid == 0 && type != CLEAR)
X type = NOT_VALID;
X
X if (RedrawingDisabled)
X {
X must_redraw = type; /* remember type for next time */
X return;
X }
X
X /*
X * if the screen was scrolled up when displaying a message, scroll it down
X */
X if (msg_scrolled)
X {
X clear_cmdline = TRUE;
X if (msg_scrolled > Rows - 5) /* clearing is faster */
X type = CLEAR;
X else if (type != CLEAR)
X {
X if (screen_ins_lines(0, 0, msg_scrolled, (int)Rows) == FAIL)
X type = CLEAR;
X win_rest_invalid(firstwin); /* should do only first/last few */
X }
X msg_scrolled = 0;
X }
X
X /*
X * reset cmdline_row now (may have been changed temporarily)
X */
X compute_cmdrow();
X
X if (type == CLEAR) /* first clear screen */
X {
X screenclear(); /* will reset clear_cmdline */
X type = NOT_VALID;
X }
X
X if (clear_cmdline)
X gotocmdline(TRUE, NUL); /* first clear cmdline */
X
X/* return if there is nothing to do */
X if ((type == VALID && curwin->w_topline == curwin->w_lsize_lnum[0]) ||
X (type == INVERTED && old_cursor.lnum == curwin->w_cursor.lnum &&
X old_cursor.col == curwin->w_cursor.col && curwin->w_curswant == oldCurswant))
X return;
X
X curwin->w_redr_type = type;
X
X/*
X * go from top to bottom through the windows, redrawing the ones that need it
X */
X cursor_off();
X for (wp = firstwin; wp; wp = wp->w_next)
X {
X if (wp->w_redr_type)
X win_update(wp);
X if (wp->w_redr_status)
X win_redr_status(wp);
X }
X if (redraw_cmdline)
X showmode();
X}
X
X/*
X * update a single window
X *
X * This may cause the windows below it also to be redrawn
X */
X void
Xwin_update(wp)
X WIN *wp;
X{
X int type = wp->w_redr_type;
X register int row;
X register int endrow;
X linenr_t lnum;
X linenr_t lastline = 0; /* only valid if endrow != Rows -1 */
X int done; /* if TRUE, we hit the end of the file */
X int didline; /* if TRUE, we finished the last line */
X int srow = 0; /* starting row of the current line */
X int idx;
X int i;
X long j;
X
X if (type == NOT_VALID)
X {
X wp->w_redr_status = TRUE;
X wp->w_lsize_valid = 0;
X }
X
X idx = 0;
X row = 0;
X lnum = wp->w_topline;
X
X /* The number of rows shown is w_height. */
X /* The default last row is the status/command line. */
X endrow = wp->w_height;
X
X if (type == VALID || type == VALID_TO_CURSCHAR)
X {
X /*
X * We handle two special cases:
X * 1: we are off the top of the screen by a few lines: scroll down
X * 2: wp->w_topline is below wp->w_lsize_lnum[0]: may scroll up
X */
X if (wp->w_topline < wp->w_lsize_lnum[0]) /* may scroll down */
X {
X j = wp->w_lsize_lnum[0] - wp->w_topline;
X if (j < wp->w_height - 2) /* not too far off */
X {
X lastline = wp->w_lsize_lnum[0] - 1;
X i = plines_m_win(wp, wp->w_topline, lastline);
X if (i < wp->w_height - 2) /* less than a screen off */
X {
X /*
X * Try to insert the correct number of lines.
X * If not the last window, delete the lines at the bottom.
X * win_ins_lines may fail.
X */
X if (win_ins_lines(wp, 0, i, FALSE, wp == firstwin) == OK &&
X wp->w_lsize_valid)
X {
X endrow = i;
X
X if ((wp->w_lsize_valid += j) > wp->w_height)
X wp->w_lsize_valid = wp->w_height;
X for (idx = wp->w_lsize_valid; idx - j >= 0; idx--)
X {
X wp->w_lsize_lnum[idx] = wp->w_lsize_lnum[idx - j];
X wp->w_lsize[idx] = wp->w_lsize[idx - j];
X }
X idx = 0;
X }
X }
X else if (lastwin == firstwin) /* far off: clearing the screen is faster */
X screenclear();
X }
X else if (lastwin == firstwin) /* far off: clearing the screen is faster */
X screenclear();
X }
X else /* may scroll up */
X {
X j = -1;
X for (i = 0; i < wp->w_lsize_valid; i++) /* try to find wp->w_topline in wp->w_lsize_lnum[] */
X {
X if (wp->w_lsize_lnum[i] == wp->w_topline)
X {
X j = i;
X break;
X }
X row += wp->w_lsize[i];
X }
X if (j == -1) /* wp->w_topline is not in wp->w_lsize_lnum */
X {
X row = 0;
X if (lastwin == firstwin)
X screenclear(); /* far off: clearing the screen is faster */
X }
X else
X {
X /*
X * Try to delete the correct number of lines.
X * wp->w_topline is at wp->w_lsize_lnum[i].
X */
X if ((row == 0 || win_del_lines(wp, 0, row, FALSE, wp == firstwin) == OK) && wp->w_lsize_valid)
X {
X srow = row;
X row = 0;


X for (;;)
X {

X if (type == VALID_TO_CURSCHAR && lnum == wp->w_cursor.lnum)
X break;
X if (row + srow + (int)wp->w_lsize[j] >= wp->w_height)
X break;
X wp->w_lsize[idx] = wp->w_lsize[j];
X wp->w_lsize_lnum[idx] = lnum++;
X
X row += wp->w_lsize[idx++];
X if ((int)++j >= wp->w_lsize_valid)
X break;
X }
X wp->w_lsize_valid = idx;
X }
X else
X row = 0; /* update all lines */
X }
X }
X if (endrow == wp->w_height && idx == 0) /* no scrolling */
X wp->w_lsize_valid = 0;
X }
X
X done = didline = FALSE;
X screen_start(); /* init cursor position of screen_char() */
X
X if (VIsual.lnum) /* check if we are updating the inverted part */
X {
X linenr_t from, to;
X
X /* find the line numbers that need to be updated */
X if (wp->w_cursor.lnum < old_cursor.lnum)
X {
X from = wp->w_cursor.lnum;
X to = old_cursor.lnum;
X }
X else
X {
X from = old_cursor.lnum;
X to = wp->w_cursor.lnum;
X }
X /* if in block mode and changed column or wp->w_curswant: update all lines */
X if (Visual_block && (wp->w_cursor.col != old_cursor.col || wp->w_curswant != oldCurswant))
X {
X if (from > VIsual.lnum)
X from = VIsual.lnum;
X if (to < VIsual.lnum)
X to = VIsual.lnum;
X }
X
X if (from < wp->w_topline)
X from = wp->w_topline;
X if (to >= wp->w_botline)
X to = wp->w_botline - 1;
X
X /* find the minimal part to be updated */
X if (type == INVERTED)
X {
X while (lnum < from) /* find start */
X {
X row += wp->w_lsize[idx++];
X ++lnum;
X }
X srow = row;
X for (j = idx; j < wp->w_lsize_valid; ++j) /* find end */
X {
X if (wp->w_lsize_lnum[j] == to + 1)
X {
X endrow = srow;
X break;
X }
X srow += wp->w_lsize[j];
X }
X old_cursor = wp->w_cursor;
X oldCurswant = wp->w_curswant;
X }
X /* if we update the lines between from and to set old_cursor */
X else if (lnum <= from && (endrow == wp->w_height || lastline >= to))
X {
X old_cursor = wp->w_cursor;
X oldCurswant = wp->w_curswant;
X }
X }
X
X (void)set_highlight('v');
X
X /*
X * Update the screen rows from "row" to "endrow".
X * Start at line "lnum" which is at wp->w_lsize_lnum[idx].


X */
X for (;;)
X {

X if (lnum > wp->w_buffer->b_ml.ml_line_count) /* hit the end of the file */
X {
X done = TRUE;
X break;
X }
X srow = row;
X row = win_line(wp, lnum, srow, endrow);
X if (row > endrow) /* past end of screen */
X {
X wp->w_lsize[idx] = plines_win(wp, lnum); /* we may need the size of that */
X wp->w_lsize_lnum[idx++] = lnum; /* too long line later on */
X break;
X }
X
X wp->w_lsize[idx] = row - srow;
X wp->w_lsize_lnum[idx++] = lnum;
X if (++lnum > wp->w_buffer->b_ml.ml_line_count)
X {
X done = TRUE;
X break;
X }
X
X if (row == endrow)
X {
X didline = TRUE;
X break;
X }
X }
X if (idx > wp->w_lsize_valid)
X wp->w_lsize_valid = idx;
X
X /* Do we have to do off the top of the screen processing ? */
X if (endrow != wp->w_height)
X {
X row = 0;
X for (idx = 0; idx < wp->w_lsize_valid && row < wp->w_height; idx++)
X row += wp->w_lsize[idx];
X
X if (row < wp->w_height)
X {
X done = TRUE;
X }
X else if (row > wp->w_height) /* Need to blank out the last line */
X {
X lnum = wp->w_lsize_lnum[idx - 1];
X srow = row - wp->w_lsize[idx - 1];
X didline = FALSE;
X }
X else
X {
X lnum = wp->w_lsize_lnum[idx - 1] + 1;
X didline = TRUE;
X }
X }
X
X wp->w_empty_rows = 0;
X /*
X * If we didn't hit the end of the file, and we didn't finish the last
X * line we were working on, then the line didn't fit.
X */
X if (!done && !didline)
X {
X if (lnum == wp->w_topline)
X {
X /*
X * Single line that does not fit!
X * Fill last line with '@' characters.
X */
X screen_fill(wp->w_winpos + wp->w_height - 1, wp->w_winpos + wp->w_height, 0, (int)Columns, '@', '@');
X wp->w_botline = lnum + 1;
X }
X else
X {
X /*
X * Clear the rest of the screen and mark the unused lines.
X */
X screen_fill(wp->w_winpos + srow, wp->w_winpos + wp->w_height, 0, (int)Columns, '@', ' ');
X wp->w_botline = lnum;
X wp->w_empty_rows = wp->w_height - srow;
X }
X }
X else
X {
X /* make sure the rest of the screen is blank */
X /* put '~'s on rows that aren't part of the file. */
X screen_fill(wp->w_winpos + row, wp->w_winpos + wp->w_height, 0, (int)Columns, '~', ' ');
X wp->w_empty_rows = wp->w_height - row;
X
X if (done) /* we hit the end of the file */
X wp->w_botline = wp->w_buffer->b_ml.ml_line_count + 1;
X else
X wp->w_botline = lnum;
X }
X
X wp->w_redr_type = 0;
X}
X
X/*
X * mark all status lines for redraw; used after first :cd
X */
X void
Xstatus_redraw_all()
X{
X WIN *wp;
X
X for (wp = firstwin; wp; wp = wp->w_next)
X wp->w_redr_status = TRUE;
X updateScreen(NOT_VALID);
X}
X
X/*
X * Redraw the status line of window wp.
X *
X * If inversion is possible we use it. Else '=' characters are used.
X */
X void
Xwin_redr_status(wp)
X WIN *wp;
X{
X int row;
X int col;
X char_u *p;
X int len;
X int fillchar;
X
X if (wp->w_status_height) /* if there is a status line */
X {
X if (set_highlight('s') == OK) /* can highlight */
X {
X fillchar = ' ';
X start_highlight();
X }
X else /* can't highlight, use '=' */
X fillchar = '=';
X
X screen_start(); /* init cursor position */
X row = wp->w_winpos + wp->w_height;
X col = 0;
X p = wp->w_buffer->b_xfilename;
X if (p == NULL)
X p = (char_u *)"[No File]";
X else
X {
X home_replace(p, NameBuff, MAXPATHL);
X p = NameBuff;
X }
X len = STRLEN(p);
X if (wp->w_buffer->b_changed)
X len += 4;
X if (len > ru_col - 1)
X {
X screen_outchar('<', row, 0);
X p += len - (ru_col - 1) + 1;
X len = (ru_col - 1);
X col = 1;
X }
X screen_msg(p, row, col);
X if (wp->w_buffer->b_changed)
X screen_msg((char_u *)" [+]", row, len - 4);
X screen_fill(row, row + 1, len, ru_col, fillchar, fillchar);
X
X stop_highlight();
X win_redr_ruler(wp, TRUE);
X }
X else /* no status line, can only be last window */
X redraw_cmdline = TRUE;
X wp->w_redr_status = FALSE;
X}
X
X/*
X * display line "lnum" of window 'wp' on the screen
X * Start at row "startrow", stop when "endrow" is reached.
X * Return the number of last row the line occupies.


X */
X
X static int

Xwin_line(wp, lnum, startrow, endrow)
X WIN *wp;
X linenr_t lnum;
X int startrow;
X int endrow;
X{
X char_u *screenp;
X int c;
X int col; /* visual column on screen */
X long vcol; /* visual column for tabs */
X int row; /* row in the window, excluding w_winpos */
X int screen_row; /* row on the screen, including w_winpos */
X char_u *ptr;
X char_u extra[16]; /* "%ld" must fit in here */
X char_u *p_extra;
X int n_extra;
X int n_spaces = 0;
X
X int fromcol, tocol; /* start/end of inverting */
X int noinvcur = FALSE; /* don't invert the cursor */
X int temp;
X FPOS *top, *bot;
X
X row = startrow;
X screen_row = row + wp->w_winpos;
X col = 0;
X vcol = 0;
X fromcol = -10;
X tocol = MAXCOL;
X canopt = TRUE;
X if (VIsual.lnum && wp == curwin) /* visual active in this window */
X {
X if (ltoreq(wp->w_cursor, VIsual)) /* Visual is after wp->w_cursor */
X {
X top = &wp->w_cursor;
X bot = &VIsual;
X }
X else /* Visual is before wp->w_cursor */
X {
X top = &VIsual;
X bot = &wp->w_cursor;
X }
X if (Visual_block) /* block mode */
X {
X if (lnum >= top->lnum && lnum <= bot->lnum)
X {
X fromcol = getvcol(wp, top, 2);
X temp = getvcol(wp, bot, 2);
X if (temp < fromcol)
X fromcol = temp;
X
X if (wp->w_curswant != MAXCOL)
X {
X tocol = getvcol(wp, top, 3);
X temp = getvcol(wp, bot, 3);
X if (temp > tocol)
X tocol = temp;
X ++tocol;
X }
X }
X }
X else /* non-block mode */
X {
X if (lnum > top->lnum && lnum <= bot->lnum)
X fromcol = 0;
X else if (lnum == top->lnum)
X fromcol = getvcol(wp, top, 2);
X if (lnum == bot->lnum)
X tocol = getvcol(wp, bot, 3) + 1;
X
X if (VIsual.col == VISUALLINE) /* linewise */
X {
X if (fromcol > 0)
X fromcol = 0;
X tocol = VISUALLINE;
X }
X }
X /* if the cursor can't be switched off, don't invert the character
X where the cursor is */
X if ((T_CI == NULL || *T_CI == NUL) && lnum == wp->w_cursor.lnum)
X noinvcur = TRUE;
X
X if (tocol <= wp->w_leftcol) /* inverting is left of screen */
X fromcol = 0;
X else if (fromcol >= 0 && fromcol < wp->w_leftcol) /* start of invert is left of screen */
X fromcol = wp->w_leftcol;
X
X /* if inverting in this line, can't optimize cursor positioning */
X if (fromcol >= 0)
X canopt = FALSE;
X }
X
X ptr = ml_get_buf(wp->w_buffer, lnum, FALSE);
X if (!wp->w_p_wrap) /* advance to first character to be displayed */
X {
X while (vcol < wp->w_leftcol && *ptr)
X vcol += chartabsize(*ptr++, vcol);
X if (vcol > wp->w_leftcol)
X {
X n_spaces = vcol - wp->w_leftcol; /* begin with some spaces */
X vcol = wp->w_leftcol;
X }
X }
X screenp = LinePointers[screen_row];
X if (wp->w_p_nu)
X {
X sprintf((char *)extra, "%7ld ", (long)lnum);
X p_extra = extra;
X n_extra = 8;
X vcol -= 8; /* so vcol is 0 when line number has been printed */
X }
X else
X {
X p_extra = NULL;
X n_extra = 0;


X }
X for (;;)
X {

X if (!canopt) /* Visual in this line */
X {
X if (((vcol == fromcol && !(noinvcur && vcol == wp->w_virtcol)) ||
X (noinvcur && vcol == wp->w_virtcol + 1 && vcol >= fromcol)) &&
X vcol < tocol)
X start_highlight(); /* start highlighting */
X else if (invert && (vcol == tocol || (noinvcur && vcol == wp->w_virtcol)))
X stop_highlight(); /* stop highlighting */
X }
X
X /* Get the next character to put on the screen. */
X /*
X * The 'extra' array contains the extra stuff that is inserted to
X * represent special characters (non-printable stuff).
X */
X
X if (n_extra)
X {
X c = *p_extra++;
X n_extra--;
X }
X else if (n_spaces)
X {
X c = ' ';
X n_spaces--;
X }
X else
X {
X if ((c = *ptr++) < ' ' || (c > '~' && c <= 0xa0))
X {
X /*
X * when getting a character from the file, we may have to turn it
X * into something else on the way to putting it into 'Nextscreen'.
X */
X if (c == TAB && !wp->w_p_list)
X {
X /* tab amount depends on current column */
X n_spaces = (int)wp->w_buffer->b_p_ts - vcol % (int)wp->w_buffer->b_p_ts - 1;
X c = ' ';
X }
X else if (c == NUL && wp->w_p_list)
X {
X p_extra = (char_u *)"";
X n_extra = 1;
X c = '$';
X }
X else if (c != NUL)
X {
X p_extra = transchar(c);
X n_extra = charsize(c) - 1;
X c = *p_extra++;
X }
X }
X }
X
X if (c == NUL)
X {
X if (invert)
X {
X if (vcol == 0) /* invert first char of empty line */
X {
X if (*screenp != (' ' ^ INVERTCODE))
X {
X *screenp = (' ' ^ INVERTCODE);
X screen_char(screenp, screen_row, col);
X }
X ++screenp;
X ++col;
X }
X stop_highlight();
X }
X /*
X * blank out the rest of this row, if necessary
X */
X while (col < Columns && *screenp == ' ')
X {
X ++screenp;
X ++col;
X }
X if (col < Columns)
X {
X screen_fill(screen_row, screen_row + 1, col, (int)Columns, ' ', ' ');
X col = Columns;
X }
X row++;
X screen_row++;
X break;
X }
X if (col >= Columns)
X {
X col = 0;
X ++row;
X ++screen_row;
X if (!wp->w_p_wrap)
X break;
X if (row == endrow) /* line got too long for screen */
X {
X ++row;
X break;
X }
X screenp = LinePointers[screen_row];
X }
X
X /*
X * Store the character in Nextscreen.
X * Be careful with characters where (c ^ INVERTCODE == ' '), they may be
X * confused with spaces inserted by scrolling.
X */
X if (*screenp != (c ^ invert) || c == (' ' ^ INVERTCODE))
X {
X *screenp = (c ^ invert);
X screen_char(screenp, screen_row, col);
X }
X ++screenp;
X col++;
X vcol++;
X }
X
X if (invert)
X stop_highlight();
X return (row);
X}
X
X/*
X * output a single character directly to the screen
X * update NextScreen
X * Note: must do screen_start() before this!
X */
X void
Xscreen_outchar(c, row, col)
X int c;
X int row, col;
X{
X char_u buf[2];
X
X buf[0] = c;
X buf[1] = NUL;
X screen_msg(buf, row, col);
X}
X
X/*
X * put string '*msg' on the screen at position 'row' and 'col'
X * update NextScreen
X * Note: only outputs within one row, message is truncated at screen boundary!
X * Note: must do screen_start() before this!
X * Note: caller must make sure that row is valid!
X */
X void
Xscreen_msg(msg, row, col)
X char_u *msg;
X int row;
X int col;
X{
X char_u *screenp;
X
X screenp = LinePointers[row] + col;
X while (*msg && col < Columns)
X {
X if (*screenp != (*msg ^ invert) || *msg == (' ' ^ INVERTCODE))
X {
X *screenp = (*msg ^ invert);
X screen_char(screenp, row, col);
X }
X ++screenp;
X ++col;
X ++msg;
X }
X}
X
X/*
X * last cursor position known by screen_char
X */
Xstatic int oldrow, oldcol; /* old cursor position */
X
X/*
X * reset cursor position. Use whenever cursor moved before calling screen_char.
X */
X void
Xscreen_start()
X{
X oldcol = 9999;
X}
X
X/*
X * set_highlight - set highlight depending on 'highlight' option and context.
X *
X * return FAIL if highlighting is not possible, OK otherwise
X */
X int
Xset_highlight(context)
X int context;
X{
X int len;
X int i;
X int mode;
X
X len = STRLEN(p_hl);
X for (i = 0; i < len; i += 3)
X if (p_hl[i] == context)
X break;
X if (i < len)
X mode = p_hl[i + 1];
X else
X mode = 'i';
X switch (mode)
X {
X case 'b': highlight = T_TB; /* bold */
X unhighlight = T_TP;
X break;
X case 's': highlight = T_SO; /* standout */
X unhighlight = T_SE;
X break;
X case 'n': highlight = NULL; /* no highlighting */
X unhighlight = NULL;
X break;
X default: highlight = T_TI; /* invert/reverse */
X unhighlight = T_TP;
X break;
X }
X if (highlight == NULL || *highlight == NUL ||
X unhighlight == NULL || *unhighlight == NUL)
X {
X highlight = NULL;
X return FAIL;
X }


X return OK;
X}
X

X void
Xstart_highlight()
X{
X if (highlight != NULL)
X {
X outstr(highlight);
X invert = INVERTCODE;


X }
X}
X
X void

Xstop_highlight()
X{
X if (invert)
X {
X outstr(unhighlight);
X invert = 0;
X }
X}
X
X/*
X * put character '*p' on the screen at position 'row' and 'col'


X */
X static void

Xscreen_char(p, row, col)
X char_u *p;
X int row;
X int col;
X{
X int c;
X int noinvcurs;
X
X /*
X * Outputting the last character on the screen may scrollup the screen.
X * Don't to it!
X */
X if (row == Rows - 1 && col == Columns - 1)
X return;
X if (oldcol != col || oldrow != row)
X {
X /* check if no cursor movement is allowed in standout mode */
X if (invert && !p_wi && (T_MS == NULL || *T_MS == NUL))
X noinvcurs = 7;
X else
X noinvcurs = 0;
X
X /*
X * If we're on the same row (which happens a lot!), try to
X * avoid a windgoto().
X * If we are only a few characters off, output the
X * characters. That is faster than cursor positioning.
X * This can't be used when inverting (a part of) the line.
X */
X if (oldrow == row && oldcol < col)


X {
X register int i;
X

X i = col - oldcol;
X if (i <= 4 + noinvcurs && canopt)
X {
X while (i)
X {
X c = *(p - i--);
X outchar(c ^ invert);
X }
X }
X else
X {
X if (noinvcurs)
X stop_highlight();
X
X if (T_CRI && *T_CRI) /* use tgoto interface! jw */
X OUTSTR(tgoto((char *)T_CRI, 0, i));
X else
X windgoto(row, col);
X
X if (noinvcurs)
X start_highlight();
X }
X oldcol = col;
X }
X else
X {
X if (noinvcurs)
X stop_highlight();
X windgoto(oldrow = row, oldcol = col);
X if (noinvcurs)
X start_highlight();
X }
X }
X /*
X * For weird invert mechanism: output (un)highlight before every char
X * Lots of extra output, but works.
X */
X if (p_wi)
X {
X if (invert)
X outstr(highlight);
X else
X outstr(unhighlight);
X }
X outchar(*p ^ invert);
X oldcol++;
X}
X
X/*
X * Fill the screen from 'start_row' to 'end_row', from 'start_col' to 'end_col'
X * with character 'c1' in first column followed by 'c2' in the other columns.
X */
X void
Xscreen_fill(start_row, end_row, start_col, end_col, c1, c2)
X int start_row, end_row;
X int start_col, end_col;
X int c1, c2;
X{
X int row;
X int col;
X char_u *screenp;
X int did_delete = FALSE;
X int c;
X
X if (start_row >= end_row || start_col >= end_col) /* nothing to do */
X return;
X
X c1 ^= invert;
X c2 ^= invert;
X for (row = start_row; row < end_row; ++row)
X {
X /* try to use delete-line termcap code */
X if (c2 == ' ' && end_col == Columns && T_EL != NULL && *T_EL != NUL)
X {
X /*
X * check if we really need to clear something
X */
X col = start_col;
X screenp = LinePointers[row] + start_col;
X if (c1 != ' ') /* don't clear first char */
X {
X ++col;
X ++screenp;
X }
X while (col < end_col && *screenp == ' ') /* skip blanks */
X {
X ++col;
X ++screenp;
X }
X if (col < end_col) /* something to be cleared */
X {
X windgoto(row, col);
X outstr(T_EL);
X }
X did_delete = TRUE;
X }
X
X screen_start(); /* init cursor position of screen_char() */
X screenp = LinePointers[row] + start_col;
X c = c1;
X for (col = start_col; col < end_col; ++col)
X {
X if (*screenp != c)
X {
X *screenp = c;
X if (!did_delete || c != ' ')
X screen_char(screenp, row, col);
X }
X ++screenp;
X c = c2;
X }
X if (row == Rows - 1)
X {
X redraw_cmdline = TRUE;
X if (c1 == ' ' && c2 == ' ')
X clear_cmdline = FALSE;
X }
X }
X}
X
X/*
X * recompute all w_botline's. Called after Rows changed.
X */
X void
Xcomp_Botline_all()
X{
X WIN *wp;
X
X for (wp = firstwin; wp; wp = wp->w_next)
X comp_Botline(wp);
X}
X
X/*
X * compute wp->w_botline. Can be called after wp->w_topline changed.
X */
X void
Xcomp_Botline(wp)
X WIN *wp;
X{
X linenr_t lnum;
X int done = 0;
X
X for (lnum = wp->w_topline; lnum <= wp->w_buffer->b_ml.ml_line_count; ++lnum)
X {
X if ((done += plines_win(wp, lnum)) > wp->w_height)
X break;
X }
X wp->w_botline = lnum; /* wp->w_botline is the line that is just below the window */


X}
X
X static void

Xscreenalloc(clear)
X int clear;
X{
X static int old_Rows = 0;
X static int old_Columns = 0;
X register int i;
X WIN *wp;
X int outofmem = FALSE;
X
X /*
X * Allocation of the screen buffers is done only when the size changes
X * and when Rows and Columns have been set.
X */
X if ((Nextscreen != NULL && Rows == old_Rows && Columns == old_Columns) || Rows == 0 || Columns == 0)
X return;
X
X comp_col(); /* recompute columns for shown command and ruler */
X old_Rows = Rows;
X old_Columns = Columns;
X
X /*
X * If we're changing the size of the screen, free the old arrays
X */
X free(Nextscreen);
X free(LinePointers);
X for (wp = firstwin; wp; wp = wp->w_next)
X win_free_lsize(wp);
X
X Nextscreen = (char_u *)malloc((size_t) (Rows * Columns));
X LinePointers = (char_u **)malloc(sizeof(char_u *) * Rows);
X for (wp = firstwin; wp; wp = wp->w_next)
X {
X if (win_alloc_lsize(wp) == FAIL)
X {
X outofmem = TRUE;


X break;
X }
X }
X

X if (Nextscreen == NULL || LinePointers == NULL || outofmem)
X {
X emsg(e_outofmem);
X free(Nextscreen);
X Nextscreen = NULL;
X }
X else
X {
X for (i = 0; i < Rows; ++i)
X LinePointers[i] = Nextscreen + i * Columns;
X }
X
X if (clear)
X screenclear2();
X}
X
X void
Xscreenclear()
X{
X screenalloc(FALSE); /* allocate screen buffers if size changed */
X screenclear2();


X}
X
X static void

Xscreenclear2()
X{
X if (starting || Nextscreen == NULL)
X return;
X
X outstr(T_ED); /* clear the display */
X
X /* blank out Nextscreen */
X memset((char *)Nextscreen, ' ', (size_t)(Rows * Columns));
X
X win_rest_invalid(firstwin);
X clear_cmdline = FALSE;
X if (must_redraw == CLEAR) /* no need to clear again */
X must_redraw = NOT_VALID;
X}
X
X/*
X * check cursor for a valid lnum
X */
X void
Xcheck_cursor()
X{
X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X if (curwin->w_cursor.lnum <= 0)
X curwin->w_cursor.lnum = 1;
X}
X
X void
Xcursupdate()
X{
X linenr_t p;
X long nlines;
X int i;
X int temp;
X
X screenalloc(TRUE); /* allocate screen buffers if size changed */
X
X if (Nextscreen == NULL)
X return;
X
X check_cursor();
X if (bufempty()) /* special case - file is empty */
X {
X curwin->w_topline = 1;
X curwin->w_cursor.lnum = 1;
X curwin->w_cursor.col = 0;
X curwin->w_lsize[0] = 0;
X if (curwin->w_lsize_valid == 0) /* don't know about screen contents */
X updateScreen(NOT_VALID);
X curwin->w_lsize_valid = 1;
X }
X else if (curwin->w_cursor.lnum < curwin->w_topline)
X {
X/*
X * If the cursor is above the top of the screen, scroll the screen to
X * put it at the top of the screen.
X * If we weren't very close to begin with, we scroll more, so that
X * the line is close to the middle.
X */
X temp = curwin->w_height / 2 - 1;
X if (temp < 2)
X temp = 2;
X if (curwin->w_topline - curwin->w_cursor.lnum >= temp) /* not very close */
X {
X p = curwin->w_cursor.lnum;
X i = plines(p);
X temp += i;
X /* count lines for 1/2 screenheight */
X while (i < curwin->w_height + 1 && i < temp && p > 1)
X i += plines(--p);
X curwin->w_topline = p;
X if (i > curwin->w_height) /* cursor line won't fit, backup one line */
X ++curwin->w_topline;
X }
X else if (p_sj > 1) /* scroll at least p_sj lines */
X {
X for (i = 0; i < p_sj && curwin->w_topline > 1; i += plines(--curwin->w_topline))
X ;
X }
X if (curwin->w_topline > curwin->w_cursor.lnum)
X curwin->w_topline = curwin->w_cursor.lnum;
X updateScreen(VALID);
X }
X else if (curwin->w_cursor.lnum >= curwin->w_botline)
X {
X/*
X * If the cursor is below the bottom of the screen, scroll the screen to
X * put the cursor on the screen.
X * If the cursor is less than a screenheight down
X * compute the number of lines at the top which have the same or more
X * rows than the rows of the lines below the bottom
X */
X nlines = curwin->w_cursor.lnum - curwin->w_botline + 1;
X if (nlines <= curwin->w_height + 1)
X {
X /* get the number or rows to scroll minus the number of
X free '~' rows */
X temp = plines_m(curwin->w_botline, curwin->w_cursor.lnum) - curwin->w_empty_rows;
X if (temp <= 0) /* curwin->w_empty_rows is larger, no need to scroll */
X nlines = 0;
X else if (temp > curwin->w_height) /* more than a screenfull, don't scroll */
X nlines = temp;
X else
X {
X /* scroll minimal number of lines */
X if (temp < p_sj)
X temp = p_sj;
X for (i = 0, p = curwin->w_topline; i < temp && p < curwin->w_botline; ++p)
X i += plines(p);
X if (i >= temp) /* it's possible to scroll */
X nlines = p - curwin->w_topline;
X else /* below curwin->w_botline, don't scroll */
X nlines = 9999;
X }
X }
X
X /*
X * Scroll up if the cursor is off the bottom of the screen a bit.
X * Otherwise put it at 1/2 of the screen.
X */
X if (nlines >= curwin->w_height / 2 && nlines > p_sj)
X {
X p = curwin->w_cursor.lnum;
X temp = curwin->w_height / 2 + 1;
X nlines = 0;
X i = 0;
X do /* this loop could win a contest ... */
X i += plines(p);
X while (i < temp && (nlines = 1) != 0 && --p != 0);
X curwin->w_topline = p + nlines;
X }
X else
X scrollup(nlines);
X updateScreen(VALID);
X }
X else if (curwin->w_lsize_valid == 0) /* don't know about screen contents */
X updateScreen(NOT_VALID);
X curwin->w_row = curwin->w_col = curwin->w_virtcol = i = 0;
X for (p = curwin->w_topline; p != curwin->w_cursor.lnum; ++p)
X if (RedrawingDisabled) /* curwin->w_lsize[] invalid */
X curwin->w_row += plines(p);
X else
X curwin->w_row += curwin->w_lsize[i++];
X
X Cline_row = curwin->w_row;
X if (!RedrawingDisabled && i > curwin->w_lsize_valid)
X /* Should only happen with a line that is too */
X /* long to fit on the last screen line. */
X Cline_height = 0;
X else
X {
X if (RedrawingDisabled) /* curwin->w_lsize[] invalid */
X Cline_height = plines(curwin->w_cursor.lnum);
X else
X Cline_height = curwin->w_lsize[i];
X
X curs_columns(!RedrawingDisabled); /* compute curwin->w_virtcol and curwin->w_col */
X if (must_redraw)
X updateScreen(must_redraw);
X }
X
X if (curwin->w_set_curswant)
X {
X curwin->w_curswant = curwin->w_virtcol;
X curwin->w_set_curswant = FALSE;
X }
X}
X
X/*
X * compute curwin->w_col and curwin->w_virtcol
X */
X void
Xcurs_columns(scroll)
X int scroll; /* when TRUE, may scroll horizontally */
X{
X int diff;
X
X curwin->w_virtcol = getvcol(curwin, &curwin->w_cursor, 1);
X curwin->w_col = curwin->w_virtcol;
X if (curwin->w_p_nu)
X curwin->w_col += 8;
X
X curwin->w_row = Cline_row;
X if (curwin->w_p_wrap) /* long line wrapping, adjust curwin->w_row */
X while (curwin->w_col >= Columns)
X {
X curwin->w_col -= Columns;
X curwin->w_row++;
X }
X else if (scroll) /* no line wrapping, compute curwin->w_leftcol if scrolling is on */
X /* if scrolling is off, curwin->w_leftcol is assumed to be 0 */
X {
X /* If Cursor is in columns 0, start in column 0 */
X /* If Cursor is left of the screen, scroll rightwards */
X /* If Cursor is right of the screen, scroll leftwards */
X if (curwin->w_cursor.col == 0)
X {
X /* screen has to be redrawn with new curwin->w_leftcol */
X if (curwin->w_leftcol != 0 && must_redraw < NOT_VALID)
X must_redraw = NOT_VALID;
X curwin->w_leftcol = 0;
X }
X else if (((diff = curwin->w_leftcol + (curwin->w_p_nu ? 8 : 0)
X - curwin->w_col) > 0 ||
X (diff = curwin->w_col - (curwin->w_leftcol + Columns) + 1) > 0))
X {
X if (p_ss == 0 || diff >= Columns / 2)
X curwin->w_leftcol = curwin->w_col - Columns / 2;
X else
X {
X if (diff < p_ss)
X diff = p_ss;
X if (curwin->w_col < curwin->w_leftcol + 8)
X curwin->w_leftcol -= diff;
X else
X curwin->w_leftcol += diff;
X }
X if (curwin->w_leftcol < 0)
X curwin->w_leftcol = 0;
X if (must_redraw < NOT_VALID)
X must_redraw = NOT_VALID; /* screen has to be redrawn with new curwin->w_leftcol */
X }
X curwin->w_col -= curwin->w_leftcol;
X }
X if (curwin->w_row > curwin->w_height - 1) /* Cursor past end of screen */
X curwin->w_row = curwin->w_height - 1; /* happens with line that does not fit on screen */
X}
X
X/*
X * get virtual column number of pos
X * type = 1: where the cursor is on this character
X * type = 2: on the first position of this character (TAB)
X * type = 3: on the last position of this character (TAB)
X */
X int
Xgetvcol(wp, pos, type)
X WIN *wp;
X FPOS *pos;
X int type;
X{
X int col;
X int vcol;
X char_u *ptr;
X int incr;
X int c;
X
X vcol = 0;
X ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
X for (col = pos->col; col >= 0; --col)
X {
X c = *ptr++;
X if (c == NUL) /* make sure we don't go past the end of the line */
X break;
X
X /* A tab gets expanded, depending on the current column */
X incr = chartabsize(c, (long)vcol);
X
X if (col == 0) /* character at pos.col */
X {
X if (type == 3 || (type == 1 && c == TAB && State == NORMAL && !wp->w_p_list))
X --incr;
X else
X break;
X }
X vcol += incr;
X }
X return vcol;
X}
X
X void
Xscrolldown(nlines)
X long nlines;
X{
X register long done = 0; /* total # of physical lines done */
X
X /* Scroll up 'nlines' lines. */
X while (nlines--)
X {
X if (curwin->w_topline == 1)
X break;
X done += plines(--curwin->w_topline);
X }
X /*
X * Compute the row number of the last row of the cursor line
X * and move it onto the screen.
X */
X curwin->w_row += done;
X if (curwin->w_p_wrap)
X curwin->w_row += plines(curwin->w_cursor.lnum) - 1 - curwin->w_virtcol / Columns;
X while (curwin->w_row >= curwin->w_height && curwin->w_cursor.lnum > 1)
X curwin->w_row -= plines(curwin->w_cursor.lnum--);
X}
X
X void
Xscrollup(nlines)
X long nlines;
X{
X#ifdef NEVER
X register long done = 0; /* total # of physical lines done */
X
X /* Scroll down 'nlines' lines. */
X while (nlines--)
X {
X if (curwin->w_topline == curbuf->b_ml.ml_line_count)
X break;
X done += plines(curwin->w_topline);
X if (curwin->w_cursor.lnum == curwin->w_topline)
X ++curwin->w_cursor.lnum;
X ++curwin->w_topline;
X }
X win_del_lines(curwin, 0, done, TRUE, TRUE);
X#endif
X curwin->w_topline += nlines;
X if (curwin->w_topline > curbuf->b_ml.ml_line_count)
X curwin->w_topline = curbuf->b_ml.ml_line_count;
X if (curwin->w_cursor.lnum < curwin->w_topline)
X curwin->w_cursor.lnum = curwin->w_topline;
X}
X
X/*
X * insert 'nlines' lines at 'row' in window 'wp'
X * if 'invalid' is TRUE the wp->w_lsize_lnum[] is invalidated.
X * if 'mayclear' is TRUE the screen will be cleared if it is faster than scrolling
X * Returns FAIL if the lines are not inserted, OK for success.
X */
X int
Xwin_ins_lines(wp, row, nlines, invalid, mayclear)
X WIN *wp;
X int row;
X int nlines;
X int invalid;
X int mayclear;
X{
X int did_delete;
X int nextrow;
X int lastrow;
X int retval;
X
X if (invalid)
X wp->w_lsize_valid = 0;
X
X if (RedrawingDisabled || nlines <= 0 || wp->w_height < 5)
X return FAIL;
X
X if (nlines > wp->w_height - row)
X nlines = wp->w_height - row;
X
X if (mayclear && Rows - nlines < 5) /* only a few lines left: redraw is faster */
X {
X screenclear(); /* will set wp->w_lsize_valid to 0 */


X return FAIL;
X }
X

X if (nlines == wp->w_height) /* will delete all lines */
X return FAIL;
X
X /*
X * when scrolling, the message on the command line should be cleared,
X * otherwise it will stay there forever.
X */
X clear_cmdline = TRUE;
X
X /*
X * if the terminal can set a scroll region, use that
X */
X if (scroll_region)
X {
X scroll_region_set(wp);
X retval = screen_ins_lines(wp->w_winpos, row, nlines, wp->w_height);
X scroll_region_reset();


X return retval;
X }
X

X if (wp->w_next && p_tf) /* don't delete/insert on fast terminal */
X return FAIL;
X
X /*
X * If there is a next window or a status line, we first try to delete the
X * lines at the bottom to avoid messing what is after the window.
X * If this fails and there are following windows, don't do anything to avoid
X * messing up those windows, better just redraw.
X */
X did_delete = FALSE;
X if (wp->w_next || wp->w_status_height)
X {
X if (screen_del_lines(0, wp->w_winpos + wp->w_height - nlines, nlines, (int)Rows) == OK)
X did_delete = TRUE;
X else if (wp->w_next)
X return FAIL;
X }
X /*
X * if no lines deleted, blank the lines that will end up below the window
X */
X if (!did_delete)
X {
X wp->w_redr_status = TRUE;
X redraw_cmdline = TRUE;
X nextrow = wp->w_winpos + wp->w_height + wp->w_status_height;
X lastrow = nextrow + nlines;
X if (lastrow > Rows)
X lastrow = Rows;
X screen_fill(nextrow - nlines, lastrow - nlines, 0, (int)Columns, ' ', ' ');
X }
X
X if (screen_ins_lines(0, wp->w_winpos + row, nlines, (int)Rows) == FAIL)
X {
X /* deletion will have messed up other windows */
X if (did_delete)
X {
X wp->w_redr_status = TRUE;
X win_rest_invalid(wp->w_next);
X }


X return FAIL;
X }
X

X return OK;
X}
X
X/*
X * delete 'nlines' lines at 'row' in window 'wp'
X * If 'invalid' is TRUE curwin->w_lsize_lnum[] is invalidated.
X * If 'mayclear' is TRUE the screen will be cleared if it is faster than scrolling
X * Return OK for success, FAIL if the lines are not deleted.
X */
X int
Xwin_del_lines(wp, row, nlines, invalid, mayclear)
X WIN *wp;
X int row;
X int nlines;
X int invalid;
X int mayclear;
X{
X int retval;
X
X if (invalid)
X wp->w_lsize_valid = 0;
X
X if (RedrawingDisabled || nlines <= 0)
X return FAIL;
X
X if (nlines > wp->w_height - row)
X nlines = wp->w_height - row;
X
X if (mayclear && Rows - nlines < 5) /* only a few lines left: redraw is faster */
X {
X screenclear(); /* will set wp->w_lsize_valid to 0 */


X return FAIL;
X }
X

X if (nlines == wp->w_height) /* will delete all lines */
X return FAIL;
X
X /*
X * when scrolling, the message on the command line should be cleared,
X * otherwise it will stay there forever.
X */
X clear_cmdline = TRUE;
X
X /*
X * if the terminal can set a scroll region, use that
X */
X if (scroll_region)
X {
X scroll_region_set(wp);
X retval = screen_del_lines(wp->w_winpos, row, nlines, wp->w_height);
X scroll_region_reset();


X return retval;
X }
X

X if (wp->w_next && p_tf) /* don't delete/insert on fast terminal */
X return FAIL;
X
X if (screen_del_lines(0, wp->w_winpos + row, nlines, (int)Rows) == FAIL)
X return FAIL;
X
X /*
X * If there are windows or status lines below, try to put them at the
X * correct place. If we can't do that, they have to be redrawn.
X */
X if (wp->w_next || wp->w_status_height || cmdline_row < Rows - 1)
X {
X if (screen_ins_lines(0, wp->w_winpos + wp->w_height - nlines, nlines, (int)Rows) == FAIL)
X {
X wp->w_redr_status = TRUE;
X win_rest_invalid(wp->w_next);
X }
X }
X /*
X * If this is the last window and there is no status line, redraw the
X * command line later.
X */
X else
X redraw_cmdline = TRUE;
X return OK;
X}
X
X/*
X * window 'wp' and everything after it is messed up, mark it for redraw
X */
X void
Xwin_rest_invalid(wp)
X WIN *wp;
X{
X while (wp)
X {
X wp->w_lsize_valid = 0;
X wp->w_redr_type = NOT_VALID;
X wp->w_redr_status = TRUE;
X wp = wp->w_next;
X }
X redraw_cmdline = TRUE;
X}
X
X/*
X * The rest of the routines in this file perform screen manipulations. The
X * given operation is performed physically on the screen. The corresponding
X * change is also made to the internal screen image. In this way, the editor
X * anticipates the effect of editing changes on the appearance of the screen.
X * That way, when we call screenupdate a complete redraw isn't usually
X * necessary. Another advantage is that we can keep adding code to anticipate
X * screen changes, and in the meantime, everything still works.
X */
X
X/*
X * insert lines on the screen and update Nextscreen
X * 'end' is the line after the scrolled part. Normally it is Rows.
X * When scrolling region used 'off' is the offset from the top for the region.
X * 'row' and 'end' are relative to the start of the region.
X *
X * return FAIL for failure, OK for success.
X */
X static int
Xscreen_ins_lines(off, row, nlines, end)
X int off;
X int row;
X int nlines;
X int end;
X{
X int i;
X int j;
X char_u *temp;
X int cursor_row;
X
X if (T_CSC != NULL && *T_CSC != NUL) /* cursor relative to region */
X cursor_row = row;
X else
X cursor_row = row + off;
X
X screenalloc(TRUE); /* allocate screen buffers if size changed */
X if (Nextscreen == NULL)
X return FAIL;
X
X if (nlines <= 0 || ((T_CIL == NULL || *T_CIL == NUL) &&
X (T_IL == NULL || *T_IL == NUL) &&
X (T_SR == NULL || *T_SR == NUL || row != 0)))
X return FAIL;
X
X /*
X * It "looks" better if we do all the inserts at once
X */
X if (T_CIL && *T_CIL)
X {
X windgoto(cursor_row, 0);
X if (nlines == 1 && T_IL && *T_IL)
X outstr(T_IL);
X else
X OUTSTR(tgoto((char *)T_CIL, 0, nlines));
X }
X else
X {
X for (i = 0; i < nlines; i++)
X {
X if (i == 0 || cursor_row != 0)
X windgoto(cursor_row, 0);
X if (T_IL && *T_IL)
X outstr(T_IL);
X else
X outstr(T_SR);
X }
X }
X /*
X * Now shift LinePointers nlines down to reflect the inserted lines.
X * Clear the inserted lines.
X */
X row += off;
X end += off;
X for (i = 0; i < nlines; ++i)
X {
X j = end - 1 - i;
X temp = LinePointers[j];
X while ((j -= nlines) >= row)
X LinePointers[j + nlines] = LinePointers[j];
X LinePointers[j + nlines] = temp;
X memset((char *)temp, ' ', (size_t)Columns);
X }
X return OK;
X}
X
X/*
X * delete lines on the screen and update Nextscreen
X * 'end' is the line after the scrolled part. Normally it is Rows.
X * When scrolling region used 'off' is the offset from the top for the region.
X * 'row' and 'end' are relative to the start of the region.
X *
X * Return OK for success, FAIL if the lines are not deleted.
X */
X int
Xscreen_del_lines(off, row, nlines, end)
X int off;
X int row;
X int nlines;
X int end;
X{
X int j;
X int i;
X char_u *temp;
X int cursor_row;
X int cursor_end;
X
X if (T_CSC != NULL && *T_CSC != NUL) /* cursor relative to region */
X {
X cursor_row = row;
X cursor_end = end;
X }
X else
X {
X cursor_row = row + off;
X cursor_end = end + off;
X }
X
X screenalloc(TRUE); /* allocate screen buffers if size changed */
X if (Nextscreen == NULL)
X return FAIL;
X
X if (nlines <= 0 || ((T_DL == NULL || *T_DL == NUL) &&
X (T_CDL == NULL || *T_CDL == NUL) &&
X row != 0))
X return FAIL;
X
X /* delete the lines */
X if (T_CDL && *T_CDL)
X {
X windgoto(cursor_row, 0);
X if (nlines == 1 && T_DL && *T_DL)
X outstr(T_DL);
X else
X OUTSTR(tgoto((char *)T_CDL, 0, nlines));
X }
X else
X {
X if (row == 0)
X {
X windgoto(cursor_end - 1, 0);
X for (i = 0; i < nlines; i++)
X outchar('\n');
X }
X else
X {
X for (i = 0; i < nlines; i++)
X {
X windgoto(cursor_row, 0);
X outstr(T_DL); /* delete a line */
X }
X }
X }
X
X /*
X * Now shift LinePointers nlines up to reflect the deleted lines.
X * Clear the deleted lines.
X */
X row += off;
X end += off;
X for (i = 0; i < nlines; ++i)
X {
X j = row + i;
X temp = LinePointers[j];
X while ((j += nlines) <= end - 1)
X LinePointers[j - nlines] = LinePointers[j];
X LinePointers[j - nlines] = temp;
X memset((char *)temp, ' ', (size_t)Columns);
X }
X return OK;
X}
X
X/*
X * show the current mode and ruler
X *
X * If clear_cmdline is TRUE, clear it first.
X * If clear_cmdline is FALSE there may be a message there that needs to be
X * cleared only if a mode is shown.
X */
X void
Xshowmode()
X{
X int did_clear = clear_cmdline;
X int need_clear = FALSE;
X
X if ((p_smd && (State & INSERT)) || Recording)
X {
X gotocmdline(clear_cmdline, NUL);
X if (p_smd)
X {
X if (State & INSERT)
X {
X msg_outstr((char_u *)"-- ");
X if (p_ri)
X msg_outstr((char_u *)"REVERSE ");
X if (State == INSERT)
X msg_outstr((char_u *)"INSERT --");
X else
X msg_outstr((char_u *)"REPLACE --");
X need_clear = TRUE;
X }
X }
X if (Recording)
X {
X msg_outstr((char_u *)"recording");
X need_clear = TRUE;
X }
X if (need_clear && !did_clear)
X msg_ceol();
X }
X win_redr_ruler(lastwin, TRUE);
X redraw_cmdline = FALSE;
X}
X
X/*
X * delete mode message
X */
X void
Xdelmode()
X{
X if (Recording)
X MSG("recording");
X else
X MSG("");
X}
X
X/*
X * if ruler option is set: show current cursor position
X * if always is FALSE, only print if position has changed
X */
X void
Xshowruler(always)
X int always;
X{
X win_redr_ruler(curwin, always);
X}
X
X void
Xwin_redr_ruler(wp, always)
X WIN *wp;
X int always;
X{
X static linenr_t oldlnum = 0;
X static colnr_t oldcol = 0;
X char_u buffer[30];
X int row;
X int fillchar;
X
X if (p_ru && (redraw_cmdline || always || wp->w_cursor.lnum != oldlnum || wp->w_virtcol != oldcol))
X {
X cursor_off();
X if (wp->w_status_height)
X {
X row = wp->w_winpos + wp->w_height;
X if (set_highlight('s') == OK) /* can use highlighting */
X {
X fillchar = ' ';
X start_highlight();
X }
X else
X fillchar = '=';
X }
X else
X {
X row = Rows - 1;
X fillchar = ' ';
X }
X /*
X * Some sprintfs return the lenght, some return a pointer.
X * To avoid portability problems we use strlen here.
X */
X sprintf((char *)buffer, "%ld,%d", wp->w_cursor.lnum, (int)wp->w_cursor.col + 1);
X if (wp->w_cursor.col != wp->w_virtcol)
X sprintf((char *)buffer + STRLEN(buffer), "-%d", wp->w_virtcol + 1);
X
X screen_start(); /* init cursor position */
X screen_msg(buffer, row, ru_col);
X screen_fill(row, row + 1, ru_col + (int)STRLEN(buffer), (int)Columns, fillchar, fillchar);
X oldlnum = wp->w_cursor.lnum;
X oldcol = wp->w_virtcol;
X stop_highlight();
X }
X}
X
X/*
X * screen_valid: Returns TRUE if there is a valid screen to write to.
X * Returns FALSE when starting up and screen not initialized yet.
X * Used by msg() to decide to use either screen_msg() or printf().
X */
X int
Xscreen_valid()
X{
X screenalloc(FALSE); /* allocate screen buffers if size changed */
X return (Nextscreen != NULL);
X}
END_OF_FILE
if test 46442 -ne `wc -c <'vim/src/screen.c'`; then
echo shar: \"'vim/src/screen.c'\" unpacked with wrong size!
fi
# end of 'vim/src/screen.c'
fi
if test -f 'vim/src/tcconfig.tc.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/tcconfig.tc.UU'\"
else
echo shar: Extracting \"'vim/src/tcconfig.tc.UU'\" \(2368 characters\)
sed "s/^X//" >'vim/src/tcconfig.tc.UU' <<'END_OF_FILE'
Xbegin 644 vim/src/tcconfig.tc
XM5'5R8F\@0R!#;VYF:6=U<F%T:6]N($9I;&4@&@ !#1(7 1H @$! ( "
XM ( 0 # ( @ $ $ 4 0 !@ ! ( $ ! D @ T @ ! X
XM @ !$ 0 ($@ " $P " !D % " %0 " $ %@ " %P " $
XM& " $ 9 ! %E $ 68 0 !9P ! %H $ 6D 0 !:@ ! %K $
XM 6P 0 !;0 ! %N $ 6\ 0 !< ! %Q $ 7( 0 !<P ! %T $
XM 74 0 !=@ ! %W $ 7@ 0 !>0 ! %Z $ 7L 0 ? ! %] $
XM 7X 0 ?P ! & $ 8( 0 A ! &% $ <@ 0 R0 ! #* $
XM <L 0 S ! #- $ ,X 0 !SP ! #0 $ &=$ 0!DT@ ! "#5 $
XM -< 0 V ! #9 $ =H 0 !VP ! #< $ =T 0 !W@ ! #? $
XM . 0 X0 ! #B $ 2P!1
XM "T!
XM@ !$.EQ40UQ)3D-,541%
XM
XM "X!@ !$
XM.EQ40UQ,24(
XM
XM "\!4 !624TN
XM4%)*
XM # !! S,@ ,0$% #(U
XM ,@$% #$P, ,P%_ $U31$]3.U=)3$1?0T%21%,
XM
XM
XM T 1X *@ -0$>
XM "H #8!'@ J
XM W 1X *@
XM . $> "H #D!
XM'@ J Z 1X *@
XM .P$> "H
XM #P!'@ J ]
XM 8
XM
XM ^ 00
XM. #\!4
XM $ !
XM1 !$.EQ40P
XM $$!4
XM
X9 /__ @ :
X
Xend
END_OF_FILE
if test 2368 -ne `wc -c <'vim/src/tcconfig.tc.UU'`; then
echo shar: \"'vim/src/tcconfig.tc.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/src/tcconfig.tc'\" \(1690 characters\)
cat vim/src/tcconfig.tc.UU | uudecode
if test 1690 -ne `wc -c <'vim/src/tcconfig.tc'`; then
echo shar: \"'vim/src/tcconfig.tc'\" uudecoded with wrong size!
else
rm vim/src/tcconfig.tc.UU
fi
fi
# end of 'vim/src/tcconfig.tc.UU'
fi
if test -f 'vim/src/version.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/version.c'\"
else
echo shar: Extracting \"'vim/src/version.c'\" \(15714 characters\)
sed "s/^X//" >'vim/src/version.c' <<'END_OF_FILE'
X/* vi:ts=4:sw=4:tw=78


X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X Started with Stevie version 3.6 (Fish disk 217) - GRWalter (Fred)
X
X VIM 1.0 - Changed so many things that I felt that a new name was required
X (I didn't like the name Stevie that much: I don't have an ST).
X - VIM stands for "Vi IMitation".
X - New storage structure, MULTI-LEVEL undo and redo,
X improved screen output, removed an awful number of bugs,
X removed fixed size buffers, added counts to a lot of commands,
X added new commands, added new options, added 'smart indent',
X added recording mode, added script files, moved help to a file,
X etc. etc. etc.
X - Compiles under Manx/Aztec C 5.0. You can use "rez" to make VIM
X resident.
X - Bram Moolenaar (Mool)
X
X VIM 1.09 - spaces can be used in tags file instead of tabs (compatible with
X Manx ctags).
X
X VIM 1.10 - Csh not required anymore for CTRL-D. Search options /e and /s added.
X Shell option implemented. BS in replace mode does not delete
X character. Backspace, wrapmargin and tags options added.
X Added support for Manx's QuickFix mode (just like "Z").
X The ENV: environment variables instead of the Old Manx environment
X variables are now used, because Vim was compiled with version 5.0d
X of the compiler. "mool" library not used anymore. Added index to
X help screens.
X
X VIM 1.11 - removed bug that caused :e of same file, but with name in upper case,
X to re-edit that file.
X
X VIM 1.12 - The second character of several commands (e.g. 'r', 't', 'm') not
X :mapped anymore (UNIX vi does it like this, don't know why); Some
X operators did not work when doing a 'l' on the last character in
X a line (e.g. 'yl'); Added :mapping when executing registers;
X Removed vi incompatibility from 't' and 'T' commands; :mapping! also
X works for command line editing; Changed a few details to have Vim
X run the macros for solving a maze and Towers of Hanoi! It now also
X runs the Turing machine macros!
X
X VIM 1.13 - Removed a bug for !! on empty line. "$" no longer puts cursor at
X the end of the line when combined with an operator. Added
X automatic creation of a script file for recovery after a crash.
X Added "-r" option. Solved bug for not detecting end of script file.
X ".bak" is now appended, thus "main.c" and "main.h" will have
X separate backup files.
X
X VIM 1.14 - Removed a few minor bugs. Added "-n" option to skip autoscript.
X Made options more Vi compatible. Improved ^C handling. On serious
X errors typahead and scripts are discarded. 'U' is now correctly
X undone with 'u'. Fixed showmatch() handling of 'x' and '\x'.
X Solved window size dependency for scripts by adding ":winsize"
X commands to scripts. This version released on Fish disk 591.
X
X VIM 1.15 - No extra return in recording mode (MCHAR instead of MLINE buffer).
X plural() argument is now a long. Search patterns shared between
X :g, :s and /. After recovery a message is given. Overflow of mapbuf
X is detected. Line number possible with :read. Error message when
X characters follow a '$' in a search pattern. Cause for crash
X removed: ":s/pat/repl/g" allocated not enough memory. Option
X "directory" added. Option "expandtab" added. Solved showmode non-
X functioning. Solved bug with window resizing. Removed some *NULL
X references. CTRL-], * and # commands now skips non-identifier
X characters. Added tag list, CTRL-T, :pop and :tags commands.
X Added jump list, CTRL-O and CTRL-I commands. Added "shiftround"
X option. Applied AUX and Lattice mods from Juergen Weigert.
X Finally made linenr_t a long, files can be > 65000 lines!
X :win command could be written to script file halfway a command.
X Option shelltype added. With ^V no mapping anymore.
X Added :move, :copy, :t, :mark and :k. Improved Ex address parsing.
X Many delimiters possible with :s.
X
X VIM 1.16 - Solved bug with zero line number in Ex range. Added file-number to
X jump list. Solved bug when scrolling downwards. Made tagstack vi
X compatible. Cmdline editing: CTRL-U instead of '@'. Made Vim DICE
X compatible. Included regexp improvements from Olaf Seibert,
X mapstring() removed. Removed bug with CTRL-U in insert mode.
X Count allowed before ". Added uppercase (file) marks. Added
X :marks command. Added joinspaces option. Added :jumps command. Made
X jumplist compatible with tag list. Added count to :next and :Next.
X
X VIM 1.17 - Removed '"' for Ex register name. Repaired stupid bug in tag code.
X Now compiled with Aztec 5.2a. Changed Arpbase.h for use with 2.04
X includes. Added repdel option. Improved :set listing. Added count
X to 'u' and CTRL-R commands. "vi:" and "ex:" in modelines must now
X be preceded with a blank. Option "+command" for command line and
X :edit command added.
X
X VIM 1.18 - Screen was not updated when all lines deleted. Readfile() now
X puts cursor on first new line. Catch strange disk label.
X Endless "undo line missing" loop removed. With empty file 'O' would
X cause this. Added window size reset in windexit(). Flush .vim file
X only when buffer has been changed. Added the nice things from
X Elvis 1.5: Added "equalprg" and "ruler" option. Added quoting.
X Added third meaning to 'backspace' option: backspacing over start
X of insert. Added "-c {command}" command line option. Made generating
X of prototypes automatically. Added insert mode command CTRL-O and
X arrow keys. CTRL-T/CTRL-D now always insert/delete indent. When
X starting an edit on specified lnum there was redraw of first lines.
X Added 'inputmode' option. Added CTRL-A and CTRL-S commands. '`' is
X now exclusive (as it should be). Added digraphs as an option.
X Changed implementation of parameters. Added :wnext command.
X Added ':@r' command. Changed handling of CTRL-V in command line.
X Block macros now work. Added keyword lookup command 'K'. Added
X CTRL-N and CTRL-P to command line editing. For DOS 2.0x the Flush
X function is used for the autoscript file; this should solve the
X lockup bug. Added wait_return to msg() for long messages.
X
X VIM 1.19 - Changes from Juergen Weigert:
X Terminal type no longer restricted to machine console. New
X option -T terminal. New set option "term". Builtin termcap
X entries for "amiga", "ansi", "atari", "nansi", "pcterm".
X Ported to MSDOS. New set option "textmode" ("tx") to control
X CR-LF translation. CTRL-U and CTRL-D scroll half a screen full,
X rather than 12 lines. New set option "writebackup" ("wb") to
X disable even the 'backup when writing' feature.
X Ported to SunOS. Full termcap support. Does resize on SIGWINCH.
X
X Made storage.c portable. Added reading of ".vimrc". Added
X 'helpfile' option. With quoting the first char of an empty line
X is inverted. Optimized screen updating a bit. Startup code
X looks for VIMINIT variable and .vimrc file first. Added option
X helpfile. Solved bug of inserting deletes: redefined ISSPECIAL.
X Changed inchar() to use key codes from termcap. Added parameters
X for terminal codes. Replaced aux device handling by amiga window
X handling. Added optional termcap code. Added 'V', format
X operator.
X
X VIM 1.20 - wait_return only ignores CR, LF and space. 'V' also works for
X single line. No redrawing while formatting text. Added CTRL-Z.
X Added usage of termcap "ks" and "ke". Fixed showmatch().
X Added timeout option. Added newfile argument to readfile().
X
X VIM 1.21 - Added block mode. Added 'o' command for quoting. Added :set inv.
X Added pos2ptr(). Added repeating and '$' to Quoting.
X
X VIM 1.22 - Fixed a bug in doput() with count > 1.
X Port to linux by Juergen Weigert included.
X More unix semantics in writeit(), forceit flag ignores errors while
X preparing backup file. For UNIX, backup is now copied, not moved.
X When the current directory is not writable, vim now tries a backup
X in the directory given with the backupdir option. For UNIX, raw mode
X has now ICRNL turned off, that allowes ^V^M. Makefiles for BSD,
X SYSV, and linux unified in makefile.unix. For MSDOS
X mch_get_winsize() implemented. Reimplemented builtin termcaps in
X term.c and term.h. set_term() now handles all cases. Even builtins
X when TERMCAP is defined. Show "..." while doing filename completion.
X
X VIM 1.23 - Improved MSDOS version: Added function and cursor keys to builtin
X pcterm. Replaced setmode by settmode, delay by vim_delay and
X delline by dellines to avoid name conflicts. Made F1 help key.
X Renamed makecmdtab to mkcmdtab and cmdsearch to csearch for
X 8 char name limit. Wildcard expansion adds *.* to names without a
X dot. Added shell execution.
X For unix: writeit() overwrites readonly files when forced write,
X more safety checks. Termcap buffer for linux now 2048 bytes.
X Expandone() no longer appends "*" to file name. Added "graphic"
X option. Added ':' command to quoting.
X
X VIM 1.24 Adjusted number of spaces inserted by dojoin(). MSDOS version uses
X searchpath() to find helpfile. Fixed a few small problems. Fixed
X nasty bug in getperm() for SAS 6.0. Removed second argument from
X wait_return(). Script files accessed in binary mode with MSDOS.
X Added 'u' and 'U' commands to quoting (make upper or lower case).
X Added "CTRL-V [0-9]*" to enter any byte value. Fixed doput().
X Dodis() displays register 0. Added CTRL-B to insert mode. Attempt
X to fix the lockup bug by adding Delay() to startscript(). -v
X option now implies -n option. doformat() added to improve 'V'
X command. Replace bool_t with int. Fixed handling of \& and ~ in
X regsub(). Added interrupt handling in msdos.c for ctrl-break and
X critical errors. Added scrolljump option. Added :stop. Added -d
X argument. Fixed bug in quickfix startup from cli. Fixed enforcer
X hit with aux:. Added CTRL-C handling to unix.c. Fixed "O<BS><CR>"
X bug with autoindent. Worked around :cq not working by adding a
X printf()!? Added default mapping for MSDOS PageUp etc. Fixed
X cursor position after 'Y'. Added shift-cursor commands. Changed
X ExpandFile() to keep names with errors. Added CLEAR and CURSUPD
X arguments to updateScreen(). Fixed CTRL-@ after a change command.
X modname() changes '.' into '_'. Added emptyrows to screen.c.
X Fixed redo of search with offset. Added count to 'z' command.
X Made :so! work with :global. Added writing of cursor postition to
X startscript(). Minimized terminal requirements. Fixed problem
X with line in tags file with mixed spaces and tabs. Fixed problem
X with pattern "\\" in :s and :g. This version posted on Usenet.
X
X VIM 1.25 Improved error messages for :set. Open helpfile in binary mode
X for MSDOS. Fixed ignorecase for Unix in cstrncmp(). Fixed read
X from NULL with :tags after vim -t. Repaired 'z' command. Changed
X outnum() for >32767. In msdos.c flushbuf did write(1, .. instead
X of write(0, .. Added secure to fix security. Fixed pointer
X use after free() bug in regsub() (made :s fail under MSDOS).
X Added nofreeNULL(), needed for some UNIXes. Improved window
X resizing for Unix. Fixed messages for report == 0. Added
X bsdmemset(). Changed a few small things for portability. Added
X :list. Made '0' and '^' exclusive. Fixed regexp for /pattern*
X (did /(pattern)* instead of /pattern(n)*). Added "']" and "'[".
X Changed Delay(2L) into Delay(10L). Made 'timeout' option
X vi-compatible, added 'ttimeout' option. Changed TIOCSETP to
X TIOCSETN in unix.c. Added "ti" and "te" termcap entries, makes
X sun cmdtool work. Added stop- and starttermcap(). Use cooked
X output for listings on Amiga only. Added "starting" flag, no ~s
X anymore with every startup. Modname made portable; Added
X 'shortname' option, Fixed problems with .vim file on messydos.
X Global .exrc/.vimrc for Unix added. Added patches for SCO Xenix.
X Add :w argument to list of alternate file names. Applied a few
X changes for HPUX. Added Flock in writeit() for safety. Command
X ":'a,'bm." moved to 'b instead of current line. Argument in
X 'shell' option allowed. Re-implemented :copy and :move. Fixed
X BS-CR-BS on empty line bug in edit.c. -t option was ignored if
X there is a file ".vim". Changed amiga.c to work without
X arp.library for dos 2.0. Fixed "\$" and "\^" in regexp. Fixed
X pipe in filter command. Fixed CTRL-U and CTRL-D. With '}' indent
X in front of the cursor is included in the operated text. Fixed
X tag with '[' in search pattern. Added CTRL-V to 'r'. Fixed "tc"
X entry in termlib.c. term_console now default off. Added :noremap
X and ^V in :map argument. Replaced CTRL by Ctrl because some
X unixes have this already. Fixed "Empty file" message disappearing
X when there is no .exrc file. Added CTRL-K for entering digraphs.
X Removed escape codes from vim.hlp, added handling of inversion to
X help().
X
X VIM 1.26 For Unix: Removed global .exrc; renamed global .vimrc to vimrc.
X Moved names of *rc and help files to makefile. Added various
X little changes for different kinds of Unix. Changed CR-LF
X handling in dosource() for MSDOS. Added :mkvimrc. Fixed
X WildExpand in unix.c for empty file. Fixed incompatibility with
X msdos share program (removed setperm(fname, 0) from fileio.c).
X Added ":set compatible". Fixed 'history=0'.
X
X VIM 1.27 Added USE_LOCALE. Changed swapchar() to use toupper() and
X tolower(). Changed init order: .vimrc before EXINIT. Half-fixed
X lines that do not fit on screen. A few minor bug fixes. Fixed
X typehead bug in Read() in unix.c. Added :number. Reset IXON flag
X in unix.c for CTRL-Q. In tags file any Ex command can be used. Ex
X search command accepts same flags as normal search command. Fixed
X '?' in tag search pattern. 'New file' message was wrong when 'bk'
X and 'wb' options were both off.
X
X Vim 1.29 to 1.31 and Vim 2.0 See ../readme2.0.
X
X Vim 2.0 When reading and writing files and in some other cases use short
X filename if ":cd" not used. Fixes problem with networks. Deleted
X "#include <ctype.h>" from regexp.c. ":v" without argument was not
X handled correctly in doglob(). Check for tail recursion removed
X again, because it forbids ":map! foo ^]foo", which is OK. Removed
X redraw on exit for msdos. Fixed return value for FullName in
X unix.c. Call_shell does not always use cooked mode, fixes problem
X with typing CR while doing filename completion in unix. "r<TAB>"
X now done by edit() to make expandtab works. Implemented FullName
X for msdos. Implemented the drive specifier for the :cd command for
X MSDOS. Added CTRL-B and CTRL-E to command line editing. Del key
X for msdos not mapped to "x" in command mode, could not delete last
X char of count. Fixed screen being messed up with long commands
X when 'sc' is set. Fixed use of CR-LF in tags file. Added check
X for abbreviation when typing ESC or CTRL-O in insert mode. Doing
X a ":w file" does overwrite when "file" is the current file. Unmap
X will check for 'to' string if there is no match with 'from'
X string; Fixes ":unab foo" after ":ab foo bar". Fixed problem in
X addstar() for msdos: Check for negative index. Added possibility
X to switch off undo ":set ul=-1". Allow parameters to be set to
X numbers >32000 for machines with 16 bit ints.
X
X Vim 2.1 to 3.0: see readme3.0
X
X*/
X
Xchar *Version = "VIM 3.0";
X#if !defined(__DATE__) || !defined(__TIME__)
Xchar *longVersion = "Vi IMproved 3.0 by Bram Moolenaar (1994 Aug 12)";
X#else
Xchar *longVersion = "Vi IMproved 3.0 by Bram Moolenaar (1994 Aug 12, compiled " __DATE__ " " __TIME__ ")";
X#endif
END_OF_FILE
if test 15714 -ne `wc -c <'vim/src/version.c'`; then
echo shar: \"'vim/src/version.c'\" unpacked with wrong size!
fi
# end of 'vim/src/version.c'
fi
echo shar: End of archive 7 \(of 26\).
cp /dev/null ark7isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:01 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 27
Archive-name: vim/part08

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/difference.doc vim/src/cmdline.c.B
# vim/src/proto/buffer.pro
# Wrapped by kent@sparky on Mon Aug 15 21:44:02 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 8 (of 26)."'
if test -f 'vim/doc/difference.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/difference.doc'\"
else
echo shar: Extracting \"'vim/doc/difference.doc'\" \(20566 characters\)
sed "s/^X//" >'vim/doc/difference.doc' <<'END_OF_FILE'
X
X
XThis is a summary of the differences between VIM and vi. It is not complete.
Xsee also reference.doc and look for comments in {}.
X
X
XThe most interesting additions:
X
XVi compatibility.
XWhen the 'compatible' option is set, all options are given a vi-compatible
Xvalue. Vim will behave like the "real" vi as much as possible.
X
X
XMulti level undo.
X'u' goes backward in time, 'ctrl-R' goes forward again. Set option
X'undolines' to the number of changes to be remembered (default 100). Set
X'undolines' to 0 for vi-compatible one level undo.
X
XWhen all changes in a buffer have been undone, the buffer is not considered
Xchanged anymore. You can exit it with :q, without <!>.
X
X
XMultiple windows and buffers.
XVim can split the screen into several windows, each editing a different
Xbuffer or the same buffer at a different location. Buffers can still be
Xloaded (and changed) but not displayed in a window. This is called a hidden
Xbuffer. Many commands and options have been added for this facility, see
Xwindows.doc.
X
X
XRepeat a series of commands.
X'q'<c> starts recording typed characters into named register <c> (append to
Xthe register if register name is upper case). A subsequent 'q' stops
Xrecording. The register can then be executed with the '@'<c> command. This is
Xvery useful to repeat a complex action.
X
X
XFlexible insert mode.
XThe arrow keys can be used in insert mode to move around in the file. This
Xbreaks the insert in two parts as far as undo and redo is concerned.
X
XCTRL-O can be used to execute a single command-mode command. This is almost
Xthe same as hitting ESC, typing the command and hitting 'a'. For undo/redo
Xonly those inserts are remembered where something was actually inserted.
X
X
XVisual mode.
XVisual can be used to first choose a piece of text and then give a command
Xto do something with it. This is an (easy to use) alternative to first giving
Xthe operator and then moving to the end of the text to be operated upon. 'v'
Xand 'V' are used to start Visual mode. 'v' works on characters and 'V' on
Xlines. Move the cursor to extend the Visual part. It is shown highlighted on
Xthe screen. By typing 'o' the other end of the Visual text can be moved. The
XVisual text can be affected by an operator:


X d delete
X c change
X y yank

X > or < insert or delete indent
X ! filter through external program
X = filter through indent
X : start ":" command for the Visual lines.
X Q format text to 'textwidth' columns
X J join lines
X ~ swap case
X u make lowercase
X U make uppercase
X
X
XBlock operators.
XWith Visual a rectangular block of text can be selected. Start Visual with
XCTRL-V. The block can be deleted ('d'), yanked ('y') or its case can be
Xchanged ('~', 'u' and 'U'). A deleted or yanked block can be put into the
Xtext with the 'p' and 'P' commands.
X
X
XOnline help.
X':help' command and help key (F1 for MSDOS) display several pages of concise
Xhelp. The name of the help file can be set with the "helpfile" option.
X
X
XCommand line editing.
XYou can insert or delete at any place in the command line using the cursor
Xkeys. The right/left cursor keys can be used to move forward/backward one
Xcharacter. The shifted right/left cursor keys can be used to move
Xforward/backward one word. CTRL-B/CTRL-E can be used to go to the begin/end
Xof the command line.
X
XThe command lines are remembered. The up/down cursor keys can be used to
Xrecall previous command lines. The 'history' option can be set to the number
Xof lines that will be remembered.
X
X
XCommand line completion.
XWhile entering a command line (on the bottom line of the screen) <TAB> can be
Xtyped to complete
X what example where
X- a command :e<TAB> at start of command line
X- a tag :ta no<TAB> after :ta
X- an option :set sc<TAB> after :set
X- a filename :e v<TAB> after any command that accepts a filename
X
XIf there are multiple matches, CTRL-N (next) and CTRL-P (previous) will walk
Xthrough the matches. <TAB> works line CTRL-N, but wraps around to the first
Xmatch.
X
XThe 'wildchar' option can be set to the character for command line
Xcompletion, <TAB> is the default. CTRL-D can be typed after an (incomplete)
Xwildcard; all matches will be listed. CTRL-A will insert all matches.
XCTRL-L will insert the longest common part of the matches.
X
X
XHorizontal scrolling.
XIf the 'wrap' option is off, long lines will not wrap and only part of them
Xwill be shown. When the cursor is moved to a part that is not shown, the
Xscreen will scroll horizontally. The minimal number of columns to scroll can
Xbe set with the 'sidescroll' option.
X
X
XText formatting.
XThe 'textwidth' (tw) option can be used to automatically limit the line
Xlength. This supplements the 'wrapmargin' option of Vi, which was not very
Xuseful. The 'Q' operator can be used to format a piece of text ("Q}" formats
Xa paragraph). Commands for text alignment: ":center", ":left" and ":right".
X
X
XEdit-compile-edit speedup.
XThe ":make" command can be used to run the compilation and jump to the first
Xerror. Alternatively Vim can be started with the "-e" option from the
Xcompiler. A file with compiler error messages is interpreted. Each line in
Xthe error file is scanned for the name of a file, line number and error
Xmessage. Vim starts editing at the first error. Optionally the name of the
Xerror file can be given with "-e errorfile". The ":cn" command can be used to
Xjump to the next error. ":cl" lists all the error messages. Other commands
Xare available (almost the same as with Manx's Z editor). The 'errorfile'
Xoption has the name of the file with error messages. The 'errorformat' option
Xcan be set to a scanf-like string to handle output from many compilers. The
X'makeprg' option contains the name of the program to be executed with the
X":make" command. The 'shellpipe' option contains the string to be used to put
Xthe output of the compiler into the errorfile.
X
X
XCommand line options:
X
XWhen Vim is started with "-v" (View) then readonly mode is used (includes
X"-n").
X
XWhen Vim is started with "-b" (Binary) then some options are set to be able
Xto edit binary or executable files.
X
XWhen Vim is started with "-s scriptfile", the characters read from
X"scriptfile" are treated as if you typed them. If end of file is reached
Xbefore the editor exits, further characters are read from the console.
X
XThe "-w" option can be used to record all typed characters in a script file.
XThis file can then be used to redo the editing, possibly on another file or
Xafter changing some commands in the script file.
X
XThe "-n" option disables the writing of a ".swp" file (see below).
X
XThe "-c command" option does the same as the the "+command" option.
X
XThe "-T terminal" option sets the terminal type.
X
XThe "-e" option starts Vim in quickfix mode.
X
XThe "-o" option opens a window for each argument. "-o4" opens four windows.
X
X
XIn command mode:
X
XMissing command: 'Q' (go to Ex mode).
XMissing Ex commands: append, change, insert, open, recover and z.
X
XThe command characters are shown in the last line of the screen. They are
Xremoved when the command is finished. If you do not want this (on a slow
Xterminal) reset the 'showcmd' option.
X
XIf the 'ruler' option is set, the current cursor position is shown in the
Xlast line of the screen.
X
X'u' and CTRL-R accept a count for the number of undos/redos.
X
X'U' still works after having moved off of the last changed line and after
X'u'.
X
XNulls in the file are replaced by <LF> internally. This allows editing of
Xbinary files (more or less).
X
XCharacters with the 8th bit set are displayed. The characters between '~' and
X0xa0 are displayed as "~?", "~@", "~A", etc., unless the "graphic' option is
Xset.
X
X'=' is an operator to filter lines through an external command (vi: lisp
Xstuff). The name of the command can be set with the 'equalprg' option. The
Xdefault is "indent".
X
X'][' goes to the next ending of a C function ('}' in column 1).
X'[]' goes to the previous ending of a C function ('}' in column 1).
X
X']f', '[f' and 'gf' start editing the file whose name is under the cursor.
XCTRL-W f splits the window and starts editint the file whose name is under
Xthe cursor.
X
X'*' searches forward for the identifier under the cursor, '#' backward.
X'K' runs the program defined by the "keywordprg" option, with the identifier
Xunder the cursor as argument.
X
X'%' can be preceded with a count. The cursor jumps to the line that
Xpercentage down in the file. The normal '%' function to jump to the matching
Xbrace skips braces inside quotes.
X
XWith the CTRL-] command, the cursor may be in the middle of the identifier.
X
XThe used tags are remembered. Commands that can be used with the tag stack
Xare CTRL-T, ':pop' and ':tag'. ':tags' lists the tag stack.
X
XThe 'tags' option can be set to a list of tag file names. Thus multiple
Xtag files can be used.
X
XPreviously used file names are remembered in the alternate file name list.
XCTRL-^ accepts a count, which is an index in this list.
X
XSearch patterns have more features. The <NL> character is seen as part of the
Xsearch pattern and the substitute string of ":s". Vi sees it as the end of
Xthe command.
X
XSearches can put the cursor on the end of a match and may include a character
Xoffset.
X
XCount added to '~', ':next', ':Next', 'n' and 'N'.
X
XThe command ":next!" with 'autowrite' set does not write the file. In vi the
Xfile was written, but this is considered to be a bug, because one does not
Xexpect it and the file is not written with ':rewind!'.
X
X"5r<CR>" replaces five characters by five line breaks. Vi replaces five
Xcharacters with a single line break.
X
XAdded :wnext command. Same as ":write" followed by ":next".
X
XThe ":w!" command always writes, also when the file is write protected.
X
XIf option "tildeop" has been set, '~' is an operator (must be followed by a
Xmovement command).
X
XWith the 'J' (join) command you can reset the 'joinspaces' (js) option to
Xhave only one space after a period (Vi inserts two spaces).
X
X'cw' can be used to change white space formed by several characters (Vi is
Xconfusing: 'cw' only changes one space, while 'dw' deletes all white space).
X
X'o' and 'O' accept a count for repeating the insert (Vi clears a part of
Xdisplay).
X
X':dis' command shows the contents of the yank register.
X
XPreviously used file names are remembered in the alternate file name list.
X":files" command shows the list of alternate filenames.
X'#'<N> is replaced by the <N>th alternate filename in the list.
X"#<" is replaced by the current filename without extension.
X
XFlags after command not supported (no plans to include it).
X
XOn non-UNIX systems ":cd" command shows current directory instead of going to
Xthe home directory. ":pwd" prints the current directory on all systems.
X
X':source!' command reads Vi commands from a file.
X
X':mkexrc' command writes current modified options and mappings to a ".exrc"
Xfile. ':mkvimrc' writes to a ".vimrc" file.
X
XNo check for "tail recursion" with mappings. This allows things like
X":map! foo ^]foo".
X
XThe :put! command inserts the contents of a register above the current line.
X
XThe 'p' and 'P' commands of vi cannot be repeated with '.' when the putted
Xtext is less than a line. In Vim they can always be repeated.
X
XThe named register '.' can be used with commands p, P and :put. The contents
Xof the register is the last inserted text.
X
X":noremap" command can be used to enter a mapping that will not be remapped.
XThis is useful to exchange the meaning of two keys. ":cmap", ":cunmap" and
X":cnoremap" can be used for mapping in command line editing only. ":imap",
X":iunmap" and ":inoremap" can be used for mapping in insert mode only.
XSimilar commands exist for abbreviations: ":noreabbrev", ":iabbrev"
X":cabbrev", ":iunabbrev", ":cunabbrev", ":inoreabbrev", ":cnoreabbrev".
X
XIn vi the command ":map foo bar" would remove a previous mapping
X":map bug foo". This is considered a bug, so it is not included in Vim.
X":unmap! foo" does remove ":map! bug foo", because unmapping would be very
Xdifficult otherwise (this is vi compatible).
X
X":@r" command executes register r (is in some versions of vi).
X
XThe ':' register contains the last command line.
XThe '%' register contians the current file name.
X
XCTRL-O/CTRL-I can be used to jump to older/newer positions. These are the
Xsame positions as used with the '' command, but may be in another file. The
X':jumps' command lists the older positions.
X
XIf the 'shiftround' option is set, an indent is rounded to a multiple of
X'shiftwidth' with '>' and '<' commands.
X
XThe 'scrolljump' option can be set to the minimal number of lines to scroll
Xwhen the cursor gets off the screen. Use this when scrolling is slow.
X
XUppercase marks can be used to jump between files. The ':marks' command lists
Xall currently set marks. The commands "']" and "`]" jump to the end of the
Xprevious operator or end of the text inserted with the put command. "'[" and
X"`[" do jump to the start.
X
XThe 'shelltype' option can be set to reflect the type of shell used.
X
XThe 'highlight' option can be set for the higlight mode to be used for
Xseveral commands.
X
XThe CTRL-A (add) and CTRL-X (subtract) commands are new. The count to the
Xcommand (default 1) is added to/subtracted from the number at or after the
Xcursor. That number may be decimal, octal (starts with a '0') or hexadecimal
X(starts with '0x'). Very useful in macros.
X
XWith the :set command the prefix "inv" can be used to invert toggle options.
X
XIn both Vi and Vim you can create a line break with the ":substitute" command
Xby using a CTRL-M. For Vi this means you cannot insert a real CTRL-M in the
Xtext. With Vim you can put a real CTRL-M in the text by preceding it with a
XCTRL-V.
X
X
XIn insert mode:
X
XIf the 'revins' option is set, insert happens backwards. This is for typing
XHebrew. When inserting normal characters the cursor will not be shifted and
Xthe text moves rightwards. In replace mode the cursor will move leftwards.
XBackspace, CTRL-W and CTRL-U will also work in the opposite direction. CTRL-B
Xtoggles the 'revins' option.
X
XThe backspace key can be used just like CTRL-D to remove auto-indents.
X
XYou can backspace, ctrl-U and CTRL-W over line breaks if the 'backspace' (bs)
Xoption is set to non-zero. You can backspace over the start of insert if the
X'backspace' option is set to 2.
X
XWhen the 'paste' option is set, a few option are reset and mapping in insert
Xmode and abbreviation are disabled. This allows for pasting text in windowing
Xsystems without unexpected results. When the 'paste' option is reset, the old
Xoption values are restored.
X
XCTRL-T/CTRL-D always insert/delete an indent in the current line, no matter
Xwhat column the cursor is in.
X
XCTRL-@ (insert previously inserted text) works always (Vi: only when typed as
Xfirst character).
X
XCTRL-A works like CTRL-@ but does not leave insert mode.
X
XCTRL-R <0-9a-z> can be used to insert the contents of a register.
X
XWhen the 'smartindent' (si) option is set, C programs will be better
Xauto-indented.
X
XCTRL-Y and CTRL-E can be used to copy a character from above/below the
Xcurrent cursor position.
X
XAfter CTRL-V you can enter a three digit decimal number. This byte value is
Xinserted in the text as a single character. Useful for international
Xcharacters that are not on your keyboard.
X
XWhen the 'expandtab' (et) option is set, a <TAB> is expanded to the
Xappropriate number of spaces.
X
XThe window always reflects the contents of the buffer (Vi does not do this
Xwhen changing text and in some other cases).
X
XIf Vim is compiled with DIGRAPHS defined, digraphs are supported. A set of
Xnormal Amiga digraphs is included. They are shown with the :digraph" command.
XMore can be added with ":digraph {char1}{char2} {number}". A digraph is
Xentered with "CTRL-K {char1} {char2}" or "{char1} BS {char2}" (only when
X'digraph' option is set).
X
XWhen repeating an insert, e.g. "10atest <ESC>" vi would only handle wrapmargin
Xfor the first insert. Vim does it for all.
X
X
XIn command line mode:
X
XESC terminates the command line without executing it. In vi the command line
Xwould be executed, which is not what most people expect (hitting ESC should
Xalways get you back to command mode). To avoid problems with some
Xobscure macros, an ESC in a macro will execute the command. If you want a
Xtyped ESC to execute the command like vi does you can fix this with
X ":cmap ^V<ESC> ^V<CR>"
X
Xgeneral:
X
XMissing options: autoprint (ap), beautify (bf), edcompatible, hardtabs (ht),
Xlisp, mesg, open, optimize (op), prompt, redraw, slowopen (slow), terse,
Xwindow, w300, w1200 and w9600. These options can be set but are otherwise
Xignored.
X
XWhen the 'compatible' option is set, all options are set for maximum
Xvi-compatibility
X
XThe 'ttimeout' option is like 'timeout', but only works for cursor and
Xfunction keys, not for ordinary mapped characters. The 'timoutlen' option
Xgives the number of milliseconds that is waited for. If the 'esckeys' option
Xis not set, cursor and function keys that start with <ESC> are not recognized
Xin insert mode.
X
XThere is an option for each terminal string. Can be used when termcap is not
Xsupported or to change individual strings.
X
XWhen the 'textmode' option is set (default for MSDOS) <CR><LF> is used as
Xline separator. When reset (default for Unix and Amiga) <LF> is used. When
Xthe 'textauto' option is set, Vim tries to detect the type of line separator
Xused by reading up to the first <LF>. The 'textmode' option is set
Xaccordingly.
X
XOn systems that have no job control (most systems but BSD-UNIX) the CTRL-Z,
X":stop" or ":suspend" command starts a new shell.
X
XIf Vim is started on the Amiga without an interactive window for output, a
Xwindow is opened (and :sh still works). You can give a device to use for
Xediting with the '-d' argument, e.g. "-d con:20/20/600/150".
X
XOn startup the VIMINIT or EXINIT environment variables, the file s:.vimrc or
Xs:.exrc and .vimrc or .exrc are read for initialization commands. When
Xreading .vimrc and .exrc some commands are not allowed because of security
Xreasons (shell commands and writing to a file, :map commands are echoed).
XThis can be overrided with the 'secure' option.
X
XLine lenght can be at least upto the maximum value of an int (for the Amiga
X32767 characters, for most 32-bit systems much larger). Editing such lines is
Xnot always possible. File length upto 2147483646 lines. If a line is larger
Xthan the screen, the last line is filled with <@>s and only the part of the
Xline before that is shown (unless 'wrap' option is reset).
X
XThe 'columns' option is used to set or get the width of the display.
X
XThe name of the current file name is shown in the title bar of the window.
X
XWildcards in file names are expanded.
X
XOption settings are read from the first and last few lines of the file.
XOption 'modelines' determines how many lines are tried (default is 5). Note
Xthat this is different from the Vi versions that can execute any Ex command
Xin a modeline (a major security problem).
X
XIf the 'insertmode' option is set (e.g. in .exrc), Vim starts in insert mode.
X
XAll text is kept in memory. Available memory limits the file size (and other
Xthings such as undo). This may be a problem with MSDOS, is hardly a problem
Xont the Amiga and almost never with Unix.
X
XIf the 'backup' or 'writebackup' option is set: Before a file is overwritten,
Xa backup file (.bak) is made. If the "backup" option is set it is left
Xbehind.
X
XIf the 'binary' option is set and the file does not have an end-of-line for
Xthe last line, the end-of-line is not appended when writing.
X
XVim creates a file ending in ".swp" to store parts of the file that have been
Xchanged or that do not fit in memory. This file can be used to recover from
Xan aborted editing session with "vim -r file". Using the swap file can be
Xswitched off by setting the 'updatecount' option to 0 or starting Vim with
Xthe "-n" option. Use the 'directory' option for placing the .swp file
Xsomewhere else.
X
XThe 'shortname' (sn) option, when set, tells Vim that ".bak" and ".swp"
Xfilenames are to be MSDOS-like: 8 characters plus 3 for extention. This
Xshould be used on messydos or crossdos filesystems on the Amiga. If this
Xoption is off, Vim tries to guess if MSDOS filename restrictions are
Xeffective.
X
XRecovery after a crash has a smaller chance for success, because there is no
Xtemporary file.
X
XError messages are shown at least one second (Vi overwrites error messages).
X
XIf Vim asks to "Hit RETURN to continue", you can hit any key. Characters
Xother than <CR>, <LF> and <SPACE> are interpreted as the (start of) a
Xcommand. (Vi only accepts a command starting with ':').
X
XThe contents of the numbered and unnamed registers is remembered when
Xchanging files.
X
XThe AUX: device of the Amiga is supported.
X
Xvi:tw=77:
END_OF_FILE
if test 20566 -ne `wc -c <'vim/doc/difference.doc'`; then
echo shar: \"'vim/doc/difference.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/difference.doc'
fi
if test -f 'vim/src/cmdline.c.B' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/cmdline.c.B'\"
else
echo shar: Extracting \"'vim/src/cmdline.c.B'\" \(44081 characters\)
sed "s/^X//" >'vim/src/cmdline.c.B' <<'END_OF_FILE'
X break;
X
X case CMD_set:
X (void)doset(arg);
X break;
X
X case CMD_abbreviate:
X case CMD_cabbrev:
X case CMD_iabbrev:
X case CMD_cnoreabbrev:
X case CMD_inoreabbrev:
X case CMD_noreabbrev:
X case CMD_unabbreviate:
X case CMD_cunabbrev:
X case CMD_iunabbrev:
X i = ABBREV;
X goto doabbr; /* almost the same as mapping */
X
X case CMD_cmap:
X case CMD_imap:
X case CMD_map:
X case CMD_cnoremap:
X case CMD_inoremap:
X case CMD_noremap:
X /*
X * If we are sourcing .exrc or .vimrc in current directory we
X * print the mappings for security reasons.
X */
X if (secure)
X {
X secure = 2;
X msg_outtrans(cmd, -1);


X msg_outchar('\n');
X }

X case CMD_cunmap:
X case CMD_iunmap:
X case CMD_unmap:
X i = 0;
Xdoabbr:
X if (*cmd == 'c') /* cmap, cunmap, cnoremap, etc. */
X {
X i += CMDLINE;
X ++cmd;
X }
X else if (*cmd == 'i') /* imap, iunmap, inoremap, etc. */
X {
X i += INSERT;
X ++cmd;
X }
X else if (forceit || i) /* map!, unmap!, noremap!, abbrev */
X i += INSERT + CMDLINE;
X else
X i += NORMAL; /* map, unmap, noremap */
X switch (domap((*cmd == 'n') ? 2 : (*cmd == 'u'), arg, i))
X {
X case 1: emsg(e_invarg);
X break;
X case 2: emsg(e_nomap);
X break;
X case 3: emsg(e_ambmap);
X break;
X }
X break;
X
X case CMD_display:
X dodis(); /* display buffer contents */
X break;
X
X case CMD_help:
X help();
X break;
X
X case CMD_version:
X msg(longVersion);
X break;
X
X case CMD_winsize: /* obsolete command */
X line1 = getdigits(&arg);
X skipspace(&arg);
X line2 = getdigits(&arg);
X set_winsize((int)line1, (int)line2, TRUE);
X break;
X
X case CMD_delete:
X case CMD_yank:
X case CMD_rshift:
X case CMD_lshift:
X yankbuffer = regname;
X curbuf->b_startop.lnum = line1;
X curbuf->b_endop.lnum = line2;
X nlines = line2 - line1 + 1;
X mtype = MLINE;
X curwin->w_cursor.lnum = line1;
X switch (cmdidx)
X {
X case CMD_delete:
X dodelete();
X break;
X case CMD_yank:
X (void)doyank(FALSE);
X curwin->w_cursor.lnum = line2; /* put cursor on last line */
X break;
X case CMD_rshift:
X doshift(RSHIFT, FALSE, amount);
X break;
X case CMD_lshift:
X doshift(LSHIFT, FALSE, amount);
X break;
X }
X break;
X
X case CMD_put:
X yankbuffer = regname;
X curwin->w_cursor.lnum = line2;
X doput(forceit ? BACKWARD : FORWARD, -1L, FALSE);
X break;
X
X case CMD_t:
X case CMD_copy:
X case CMD_move:
X n = get_address(&arg);
X /*
X * move or copy lines from 'line1'-'line2' to below line 'n'
X */
X if (n == MAXLNUM || n < 0 || n > curbuf->b_ml.ml_line_count)
X {
X emsg(e_invaddr);
X break;
X }
X
X if (cmdidx == CMD_move)
X {
X if (do_move(line1, line2, n) == FAIL)
X break;
X }
X else
X do_copy(line1, line2, n);
X u_clearline();


X curwin->w_cursor.col = 0;

X updateScreen(NOT_VALID);
X break;
X
X case CMD_and: /* :& */
X case CMD_tilde: /* :~ */
X case CMD_substitute: /* :s */
X dosub(line1, line2, arg, &nextcomm,
X cmdidx == CMD_substitute ? 0 :
X cmdidx == CMD_and ? 1 : 2);
X break;
X
X case CMD_join:
X curwin->w_cursor.lnum = line1;
X if (line1 == line2)
X {
X if (addr_count >= 2) /* :2,2join does nothing */
X break;
X if (line2 == curbuf->b_ml.ml_line_count)
X {
X beep();
X break;
X }
X ++line2;
X }
X dodojoin(line2 - line1 + 1, !forceit, TRUE);
X break;
X
X case CMD_global:
X if (forceit)
X *cmd = 'v';
X case CMD_vglobal:
X doglob(*cmd, line1, line2, arg);
X break;
X
X case CMD_at: /* :[addr]@r */
X curwin->w_cursor.lnum = line2;
X if (doexecbuf(*arg) == FAIL) /* put the register in mapbuf */
X beep();
X else
X (void)docmdline((char_u *)NULL); /* execute from the mapbuf */
X break;
X
X case CMD_bang:
X dobang(addr_count, line1, line2, forceit, arg);
X break;
X
X case CMD_undo:
X u_undo(1);
X break;
X
X case CMD_redo:
X u_redo(1);
X break;
X
X case CMD_source:
X if (forceit) /* :so! read vi commands */
X (void)openscript(arg);
X else
X {
X ++no_wait_return;
X if (dosource(arg) == FAIL) /* :so read ex commands */
X emsg2(e_notopen, arg);
X --no_wait_return;
X if (need_wait_return)
X wait_return(FALSE);
X }
X break;
X
X case CMD_mkvimrc:
X if (*arg == NUL)
X arg = (char_u *)VIMRC_FILE;
X /*FALLTHROUGH*/
X
X case CMD_mkexrc:
X {
X FILE *fd;
X
X if (*arg == NUL)
X arg = (char_u *)EXRC_FILE;
X#ifdef UNIX
X /* with Unix it is possible to open a directory */
X if (isdir(arg) == TRUE)
X {
X EMSG2("\"%s\" is a directory", arg);
X break;
X }
X#endif
X if (!forceit && (fd = fopen((char *)arg, "r")) != NULL)
X {
X fclose(fd);
X EMSG2("\"%s\" exists (use ! to override)", arg);
X break;
X }
X
X if ((fd = fopen((char *)arg, "w")) == NULL)
X {
X EMSG2("Cannot open \"%s\" for writing", arg);
X break;
X }
X if (makemap(fd) == FAIL || makeset(fd) == FAIL || fclose(fd))
X emsg(e_write);
X break;
X }
X
X case CMD_cc:
X qf_jump(0, atoi((char *)arg));
X break;
X
X case CMD_cf:
X if (*arg != NUL)
X {
X /*
X * Great trick: Insert 'ef=' before arg.
X * Always ok, because "cf " must be there.
X */
X arg -= 3;
X arg[0] = 'e';
X arg[1] = 'f';
X arg[2] = '=';
X (void)doset(arg);
X }
X (void)qf_init();
X break;
X
X case CMD_cl:
X qf_list();
X break;
X
X case CMD_cn:
X qf_jump(FORWARD, *arg == NUL ? 1 : atoi((char *)arg));
X break;
X
X case CMD_cp:
X qf_jump(BACKWARD, *arg == NUL ? 1 : atoi((char *)arg));
X break;
X
X case CMD_cq:
X getout(1); /* this does not always work. why? */
X
X case CMD_mark:
X case CMD_k:
X pos = curwin->w_cursor; /* save curwin->w_cursor */
X curwin->w_cursor.lnum = line2;


X curwin->w_cursor.col = 0;

X (void)setmark(*arg); /* set mark */
X curwin->w_cursor = pos; /* restore curwin->w_cursor */
X break;
X
X#ifdef SETKEYMAP
X case CMD_setkeymap:
X set_keymap(arg);
X break;
X#endif
X
X case CMD_center:
X case CMD_right:
X case CMD_left:
X do_align(line1, line2, atoi((char *)arg),
X cmdidx == CMD_center ? 0 : cmdidx == CMD_right ? 1 : -1);
X break;
X
X case CMD_make:
X domake(arg);
X break;
X
X default:
X emsg(e_invcmd);
X }
X
X
Xdoend:
X forceit = FALSE; /* reset now so it can be used in getfile() */
X if (nextcomm && *nextcomm == NUL) /* not really a next command */
X nextcomm = NULL;
X return nextcomm;
X}
X
X/*
X * if 'autowrite' option set, try to write the file
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xautowrite(buf)
X BUF *buf;
X{
X if (!p_aw || (!forceit && buf->b_p_ro) || buf->b_filename == NULL)
X return FAIL;
X return buf_write_all(buf);
X}
X
X/*
X * flush all buffers, except the ones that are readonly
X */
X void
Xautowrite_all()


X{
X BUF *buf;
X

X if (!p_aw)
X return;
X for (buf = firstbuf; buf; buf = buf->b_next)
X if (buf->b_changed && !buf->b_p_ro)
X (void)buf_write_all(buf);
X}
X
X/*
X * flush the contents of a buffer, unless it has no file name
X *
X * return FAIL for failure, OK otherwise


X */
X static int

Xbuf_write_all(buf)
X BUF *buf;
X{
X return (buf_write(buf, buf->b_filename, buf->b_sfilename, (linenr_t)1, buf->b_ml.ml_line_count, 0, 0, TRUE));
X}
X
X/*
X * write current buffer to file 'fname'
X * if 'append' is TRUE, append to the file
X *
X * if *fname == NUL write to current file
X * if b_notedited is TRUE, check for overwriting current file
X *
X * return FAIL for failure, OK otherwise


X */
X static int

Xdowrite(fname, append)
X char_u *fname;
X int append;
X{
X FILE *fd;
X int other;
X char_u *sfname = NULL; /* init to shut up gcc */
X
X if (*fname == NUL)
X other = FALSE;
X else
X {
X sfname = fname;
X fname = fix_fname(fname);
X other = otherfile(fname);
X }
X
X /*
X * if we have a new file name put it in the list of alternate file names
X */
X if (other)
X setaltfname(fname, sfname, (linenr_t)1);
X
X /*
X * writing to the current file is not allowed in readonly mode
X * and need a file name
X */
X if (!other && (check_readonly() || check_fname() == FAIL))
X return FAIL;
X
X if (!other)
X {
X fname = curbuf->b_filename;
X sfname = curbuf->b_sfilename;
X }
X
X /*
X * write to other file or b_notedited set: overwriting only allowed with '!'
X */
X if ((other || curbuf->b_notedited) && !forceit && !append && !p_wa && (fd = fopen((char *)fname, "r")) != NULL)
X { /* don't overwrite existing file */
X fclose(fd);
X#ifdef UNIX
X /* with UNIX it is possible to open a directory */
X if (isdir(fname) == TRUE)
X EMSG2("\"%s\" is a directory", fname);
X else
X#endif
X emsg(e_exists);
X return FAIL;
X }
X return (buf_write(curbuf, fname, sfname, line1, line2, append, forceit, TRUE));
X}
X
X/*
X * start editing a new file
X *
X * fname: the file name
X * - full path if sfname used,
X * - any file name if sfname is NULL
X * - empty string to re-edit with the same file name (but may be
X * in a different directory)
X * - NULL to start an empty buffer
X * sfname: the short file name (or NULL)
X * command: the command to be executed after loading the file
X * hide: if TRUE don't free the current buffer
X * newlnum: put cursor on this line number (if possible)
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xdoecmd(fname, sfname, command, hide, newlnum)
X char_u *fname;
X char_u *sfname;
X char_u *command;
X int hide;
X linenr_t newlnum;
X{
X int other_file; /* TRUE if editing another file */
X int oldbuf = FALSE; /* TRUE if using existing buffer */
X BUF *buf;
X
X /* if no short name given, use fname for short name */
X if (sfname == NULL)
X sfname = fname;


X
X if (fname == NULL)

X other_file = TRUE;
X else if (*fname == NUL && curbuf->b_filename == NULL) /* there is no file name */
X other_file = FALSE;
X else
X {
X if (*fname == NUL) /* re-edit with same file name */
X {
X fname = curbuf->b_filename;
X sfname = curbuf->b_sfilename;
X }
X fname = fix_fname(fname); /* may expand to full path name */
X other_file = otherfile(fname);
X }
X/*
X * if the file was changed we may not be allowed to abandon it
X * - if we are going to re-edit the same file
X * - or if we are the only window on this file and if hide is FALSE
X */
X if ((!other_file || (curbuf->b_nwindows == 1 && !hide)) &&
X check_changed(curbuf, FALSE, !other_file))
X {
X if (other_file && fname != NULL)
X setaltfname(fname, sfname, (linenr_t)1);
X return FAIL;
X }
X/*
X * If we are starting to edit another file, open a (new) buffer.
X * Otherwise we re-use the current buffer.
X */
X if (other_file)
X {
X curwin->w_alt_fnum = curbuf->b_fnum;
X buflist_altlnum();
X
X buf = buflist_new(fname, sfname, 1L, TRUE);
X if (buf == NULL)
X return FAIL;
X if (buf->b_ml.ml_mfp == NULL) /* no memfile yet */
X {
X oldbuf = FALSE;
X buf->b_nwindows = 1;
X }
X else /* existing memfile */
X {
X oldbuf = TRUE;
X ++buf->b_nwindows;
X }
X /*
X * make the (new) buffer the one used by the current window
X * if the old buffer becomes unused, free it if hide is FALSE
X * If the current buffer was empty and has no file name, curbuf
X * is returned by buflist_new().
X */
X if (buf != curbuf)
X {
X close_buffer(curbuf, !hide, FALSE);
X curwin->w_buffer = buf;
X curbuf = buf;
X }
X
X curwin->w_pcmark.lnum = 1;
X curwin->w_pcmark.col = 0;
X }
X else if (check_fname() == FAIL)
X return FAIL;
X
X/*
X * If we get here we are sure to start editing
X */
X /* don't redraw until the cursor is in the right line */
X ++RedrawingDisabled;
X
X/*
X * other_file oldbuf
X * FALSE FALSE re-edit same file, buffer is re-used
X * FALSE TRUE not posible
X * TRUE FALSE start editing new file, new buffer
X * TRUE TRUE start editing in existing buffer (nothing to do)
X */
X if (!other_file) /* re-use the buffer */
X {
X if (newlnum == 0)
X newlnum = curwin->w_cursor.lnum;
X buf_freeall(curbuf); /* free all things for buffer */
X buf_clear(curbuf);
X curbuf->b_startop.lnum = 0; /* clear '[ and '] marks */
X curbuf->b_endop.lnum = 0;
X }
X
X if (!oldbuf) /* need to read the file */
X (void)open_buffer();
X win_init(curwin);
X maketitle();
X
X if (newlnum && command == NULL)
X {
X curwin->w_cursor.lnum = newlnum;


X curwin->w_cursor.col = 0;
X }

X check_cursor();
X
X /*
X * Did not read the file, need to show some info about the file.
X * Do this after setting the cursor.
X */
X if (oldbuf)
X fileinfo(did_cd);
X
X if (command != NULL)
X docmdline(command);
X --RedrawingDisabled;
X if (!skip_redraw)
X updateScreen(CURSUPD); /* redraw now */
X
X if (p_im)
X stuffReadbuff((char_u *)"i"); /* start editing in insert mode */


X return OK;
X}
X
X/*

X * get + command from ex argument


X */
X static char_u *

Xgetargcmd(argp)
X char_u **argp;
X{
X char_u *arg = *argp;
X char_u *command = NULL;
X
X if (*arg == '+') /* +[command] */
X {
X ++arg;
X if (isspace(*arg))
X command = (char_u *)"$";
X else
X {
X command = arg;
X /*
X * should check for "\ " (but vi has a bug that prevents it to work)
X */
X skiptospace(&arg);
X }
X if (*arg)
X *arg++ = NUL; /* terminate command with NUL */
X
X skipspace(&arg); /* skip over spaces */
X *argp = arg;
X }
X return command;
X}
X
X/*
X * look for command separator '|' or '\n'


X */
X static char_u *

Xchecknextcomm(arg)
X char_u *arg;
X{
X char_u *p;
X char_u *nextcomm = NULL;
X
X for (p = arg; *p; ++p)
X {
X if (*p == '\\' && p[1])
X ++p;
X else if (*p == '|' || *p == '\n')
X {
X nextcomm = p + 1; /* remember start of next command */
X *p = NUL; /* delete '|' or '\n' */
X del_spaces(arg); /* delete spaces in front of '|' or '\n' */
X break;
X }
X }
X return nextcomm;


X}
X
X static void

Xdomake(arg)
X char_u *arg;
X{
X if (*p_ef == NUL)
X {
X EMSG("errorfile option not set");
X return;
X }
X if (curbuf->b_changed)
X (void)autowrite(curbuf);
X remove((char *)p_ef);
X outchar(':');
X outstr(arg); /* show what we are doing */
X sprintf((char *)IObuff, "%s %s %s", arg, p_sp, p_ef);
X doshell(IObuff);
X#ifdef AMIGA
X flushbuf();
X vpeekc(); /* read window status report and redraw before message */
X#endif
X (void)qf_init();
X remove((char *)p_ef);
X}
X
X/*
X * Redefine the argument list to 'str'.
X *
X * Return FAIL for failure, OK otherwise.


X */
X static int

Xdoarglist(str)
X char_u *str;
X{
X int new_count = 0;
X char_u **new_files = NULL;
X int exp_count;
X char_u **exp_files;
X char_u **t;
X char_u *p;
X int inquote;
X int i;
X
X while (*str)
X {
X /*
X * create a new entry in new_files[]
X */
X t = (char_u **)lalloc((long_u)(sizeof(char_u *) * (new_count + 1)), TRUE);
X if (t != NULL)
X for (i = new_count; --i >= 0; )
X t[i] = new_files[i];
X free(new_files);
X if (t == NULL)
X return FAIL;
X new_files = t;
X new_files[new_count++] = str;
X
X /*
X * isolate one argument, taking quotes
X */
X inquote = FALSE;
X for (p = str; *str; ++str)
X {
X /*
X * for MSDOS a backslash is part of a file name.
X * Only skip ", space and tab.
X */
X#ifdef MSDOS
X if (*str == '\\' && (str[1] == '"' || str[1] == ' ' || str[1] == '\t'))
X#else
X if (*str == '\\' && str[1] != NUL)
X#endif
X *p++ = *++str;
X else
X {
X if (!inquote && isspace(*str))
X break;
X if (*str == '"')
X inquote ^= TRUE;
X else
X *p++ = *str;
X }
X }
X skipspace(&str);


X *p = NUL;
X }

X
X i = ExpandWildCards(new_count, new_files, &exp_count, &exp_files, FALSE, TRUE);
X free(new_files);
X if (i == FAIL)
X return FAIL;
X if (exp_count == 0)
X {
X emsg(e_nomatch);
X return FAIL;
X }
X if (arg_exp) /* arg_files[] has been allocated, free it */
X FreeWild(arg_count, arg_files);
X else
X arg_exp = TRUE;
X arg_files = exp_files;
X arg_count = exp_count;
X
X /*
X * put all file names in the buffer list
X */
X for (i = 0; i < arg_count; ++i)
X (void)buflist_add(arg_files[i]);


X
X return OK;
X}
X
X void

Xgotocmdline(clr, firstc)
X int clr;
X int firstc;
X{
X msg_start();
X if (clr) /* clear the bottom line(s) */
X msg_ceol(); /* will reset clear_cmdline */
X windgoto(cmdline_row, 0);
X if (firstc)
X msg_outchar(firstc);
X}
X
X void
Xgotocmdend()
X{
X windgoto((int)Rows - 1, 0);


X outchar('\n');
X}
X

X static int
Xcheck_readonly()
X{
X if (!forceit && curbuf->b_p_ro)
X {
X emsg(e_readonly);
X return TRUE;
X }
X return FALSE;
X}
X
X/*
X * return TRUE if buffer was changed and cannot be abandoned.


X */
X static int

Xcheck_changed(buf, checkaw, mult_win)
X BUF *buf;
X int checkaw; /* do autowrite if buffer was changed */
X int mult_win; /* check also when several windows for this buffer */
X{
X if ( !forceit &&
X buf->b_changed && (mult_win || buf->b_nwindows <= 1) &&
X (!checkaw || autowrite(buf) == FAIL))
X {
X emsg(e_nowrtmsg);
X return TRUE;
X }
X return FALSE;
X}
X
X/*
X * return TRUE if any buffer was changed and cannot be abandoned.


X */
X static int

Xcheck_changed_any(checkaw)
X int checkaw; /* do autowrite if buffer was changed */


X{
X BUF *buf;
X

X if (!forceit)


X {
X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X {

X if (buf->b_changed && (!checkaw || autowrite(buf) == FAIL))
X {
X EMSG2("No write since last change for buffer \"%s\"",
X buf->b_xfilename == NULL ? (char_u *)"No File" : buf->b_xfilename);
X return TRUE;
X }
X }
X }
X return FALSE;
X}
X
X/*
X * return FAIL if there is no filename, OK if there is one
X * give error message for FAIL
X */
X int
Xcheck_fname()


X{
X if (curbuf->b_filename == NULL)

X {
X emsg(e_noname);


X return FAIL;
X }
X return OK;
X}
X

X/*
X * - if there are more files to edit
X * - and this is the last window
X * - and forceit not used
X * - and not repeated twice on a row
X * return FAIL and give error message if 'message' TRUE
X * return OK otherwise
X */
X static int
Xcheck_more(message)
X int message; /* when FALSE check only, no messages */
X{
X if (!forceit && firstwin == lastwin && curwin->w_arg_idx + 1 < arg_count &&
X quitmore == 0)
X {
X if (message)
X {
X emsg2((char_u *)"%ld more files to edit", (char_u *)(long)(arg_count - curwin->w_arg_idx - 1));
X quitmore = 2; /* next try to quit is allowed */


X }
X return FAIL;
X }
X return OK;
X}
X
X/*

X * try to abandon current file and edit "fname"
X * return 1 for "normal" error, 2 for "not written" error, 0 for success
X * -1 for succesfully opening another file
X * 'lnum' is the line number for the cursor in the new file (if non-zero).
X */
X int
Xgetfile(fname, sfname, setpm, lnum)
X char_u *fname;
X char_u *sfname;
X int setpm;
X linenr_t lnum;
X{
X int other;
X
X fname_expand(&fname, &sfname); /* make fname full path and set sfname */
X other = otherfile(fname);
X
X if (other && !forceit && curbuf->b_nwindows == 1 &&
X !p_hid && curbuf->b_changed && autowrite(curbuf) == FAIL)
X {
X emsg(e_nowrtmsg);
X return 2; /* file has been changed */
X }
X if (setpm)
X setpcmark();
X if (!other)
X {
X if (lnum != 0)
X curwin->w_cursor.lnum = lnum;
X check_cursor();


X curwin->w_cursor.col = 0;
X

X return 0; /* it's in the same file */
X }
X if (doecmd(fname, sfname, NULL, p_hid, lnum) == OK)
X return -1; /* opened another file */
X return 1; /* error encountered */
X}
X
X#ifdef WEBB_COMPLETE
X/*
X * vim_strncpy()
X *
X * This is here because strncpy() does not guarantee successful results when
X * the to and from strings overlap. It is only currently called from nextwild()
X * which copies part of the command line to another part of the command line.
X * This produced garbage when expanding files etc in the middle of the command
X * line (on my terminal, anyway) -- webb.


X */
X static void

Xvim_strncpy(to, from, len)
X char_u *to;
X char_u *from;
X int len;


X{
X int i;
X

X if (to <= from)
X {
X while (len-- && *from)
X *to++ = *from++;
X if (len >= 0)
X *to = *from; /* Copy NUL */
X }
X else
X {
X for (i = 0; i < len; i++)
X {
X to++;
X if (*from++ == NUL)
X {
X i++;
X break;
X }
X }
X for (; i > 0; i--)
X *--to = *--from;
X }
X}
X
X/* Return FALSE if this is not an appropriate context in which to do
X * completion of anything, & TRUE if it is (even if there are no matches). For
X * the caller, this means that the character is just passed through like a
X * normal character (instead of being expanded). This allows :s/^I^D etc.


X */
X static int

X#else
X static void
X#endif /* WEBB_COMPLETE */
Xnextwild(buff, type)
X char_u *buff;
X int type;
X{
X int i;
X char_u *p1;
X char_u *p2 = NULL;
X int oldlen;
X int difflen;
X
X#ifdef WEBB_COMPLETE
X if (cmd_numfiles == -1)
X set_expand_context(cmdfirstc, cmdbuff);
X if (expand_context == EXPAND_UNSUCCESSFUL)
X {
X beep();
X return OK; /* Something illegal on command line */
X }
X if (expand_context == EXPAND_NOTHING)
X {
X /* Caller can use the character as a normal char instead */
X return FAIL;
X }
X expand_interactively = TRUE;
X
X#endif /* WEBB_COMPLETE */
X msg_outstr((char_u *)"..."); /* show that we are busy */
X flushbuf();
X
X#ifdef WEBB_COMPLETE
X i = expand_pattern - buff;
X#else
X for (i = cmdpos; i > 0 && buff[i - 1] != ' '; --i)
X ;
X#endif /* WEBB_COMPLETE */
X oldlen = cmdpos - i;
X
X /* add a "*" to the file name and expand it */
X if ((p1 = addstar(&buff[i], oldlen)) != NULL)
X {
X if ((p2 = ExpandOne(p1, FALSE, type)) != NULL)
X {
X if (cmdlen + (difflen = STRLEN(p2) - oldlen) > CMDBUFFSIZE - 4)
X emsg(e_toolong);
X else
X {
X#ifdef WEBB_COMPLETE
X vim_strncpy(&buff[cmdpos + difflen], &buff[cmdpos], cmdlen - cmdpos);
X#else
X STRNCPY(&buff[cmdpos + difflen], &buff[cmdpos], (size_t)(cmdlen - cmdpos));
X#endif /* WEBB_COMPLETE */
X STRNCPY(&buff[i], p2, STRLEN(p2));
X cmdlen += difflen;
X cmdpos += difflen;
X }
X free(p2);
X }
X free(p1);
X }
X redrawcmd();
X#ifdef WEBB_COMPLETE
X if (cmd_numfiles <= 0 && p2 == NULL)
X beep();
X else if (cmd_numfiles == 1)
X {
X (void)ExpandOne(NULL, FALSE, -2); /* free expanded "file" names */
X cmd_numfiles = -1;
X }
X expand_interactively = FALSE;
X return OK;
X#endif /* WEBB_COMPLETE */
X}
X
X/*
X * Do wildcard expansion on the string 'str'.
X * Return a pointer to alloced memory containing the new string.
X * Return NULL for failure.
X *
X * mode = -2: only release file names
X * mode = -1: normal expansion, do not keep file names
X * mode = 0: normal expansion, keep file names
X * mode = 1: use next match in multiple match
X * mode = 2: use previous match in multiple match
X * mode = 3: use next match in multiple match and wrap to first
X * mode = 4: return all matches concatenated
X * mode = 5: return longest matched part


X */
X char_u *

XExpandOne(str, list_notfound, mode)
X char_u *str;
X int list_notfound;
X int mode;
X{
X char_u *ss = NULL;
X static char_u **cmd_files = NULL; /* list of input files */
X static int findex;
X int i, found = 0;
X int multmatch = FALSE;
X long_u len;
X char_u *filesuf, *setsuf, *nextsetsuf;
X int filesuflen, setsuflen;
X
X/*
X * first handle the case of using an old match
X */
X if (mode >= 1 && mode < 4)
X {
X if (cmd_numfiles > 0)
X {


X if (mode == 2)

X --findex;
X else /* mode == 1 || mode == 3 */
X ++findex;
X if (findex < 0)
X findex = 0;
X if (findex > cmd_numfiles - 1)
X {
X if (mode == 3)
X findex = 0;
X else
X findex = cmd_numfiles - 1;
X }
X return strsave(cmd_files[findex]);
X }
X else


X return NULL;
X }
X

X/* free old names */
X if (cmd_numfiles != -1 && mode < 4)
X {
X FreeWild(cmd_numfiles, cmd_files);
X cmd_numfiles = -1;
X }
X findex = 0;
X
X if (mode == -2) /* only release file name */
X return NULL;
X
X if (cmd_numfiles == -1)
X {
X#ifdef WEBB_COMPLETE
X if (ExpandFromContext((char_u *)str, &cmd_numfiles, &cmd_files, FALSE,
X list_notfound) == FAIL)
X /* error: do nothing */;
X else if (cmd_numfiles == 0)
X {
X if (!expand_interactively)
X emsg(e_nomatch);
X }
X#else
X if (ExpandWildCards(1, (char_u **)&str, &cmd_numfiles, &cmd_files, FALSE, list_notfound) == FAIL)
X /* error: do nothing */;
X else if (cmd_numfiles == 0)
X emsg(e_nomatch);
X#endif /* WEBB_COMPLETE */
X else if (mode < 4)
X {
X if (cmd_numfiles > 1) /* more than one match; check suffixes */
X {
X found = -2;
X for (i = 0; i < cmd_numfiles; ++i)
X {
X if ((filesuf = STRRCHR(cmd_files[i], '.')) != NULL)
X {
X filesuflen = STRLEN(filesuf);
X for (setsuf = p_su; *setsuf; setsuf = nextsetsuf)
X {
X if ((nextsetsuf = STRCHR(setsuf + 1, '.')) == NULL)
X nextsetsuf = setsuf + STRLEN(setsuf);
X setsuflen = (int)(nextsetsuf - setsuf);
X if (filesuflen == setsuflen &&
X STRNCMP(setsuf, filesuf, (size_t)setsuflen) == 0)
X break;
X }
X if (*setsuf) /* suffix matched: ignore file */
X continue;
X }
X if (found >= 0)
X {
X multmatch = TRUE;
X break;
X }
X found = i;
X }
X }
X if (multmatch || found < 0)
X {
X#ifdef WEBB_COMPLETE
X /* Can we ever get here unless it's while expanding
X * interactively? If not, we can get rid of this all together.
X * Don't really want to wait for this message (and possibly
X * have to hit return to continue!).
X */
X if (!expand_interactively)
X#endif /* WEBB_COMPLETE */
X emsg(e_toomany);
X#ifdef WEBB_COMPLETE
X else
X beep();
X#endif /* WEBB_COMPLETE */
X found = 0; /* return first one */
X multmatch = TRUE; /* for found < 0 */
X }
X if (found >= 0 && !(multmatch && mode == -1))
X ss = strsave(cmd_files[found]);
X }
X }
X
X if (mode == 5 && cmd_numfiles > 0) /* find longest common part */
X {
X for (len = 0; cmd_files[0][len]; ++len)
X {
X for (i = 0; i < cmd_numfiles; ++i)
X {
X#ifdef AMIGA
X if (toupper(cmd_files[i][len]) != toupper(cmd_files[0][len]))
X#else
X if (cmd_files[i][len] != cmd_files[0][len])
X#endif
X break;
X }
X if (i < cmd_numfiles)
X break;
X }
X ss = alloc((unsigned)len + 1);
X if (ss)
X {
X STRNCPY(ss, cmd_files[0], (size_t)len);
X ss[len] = NUL;
X }
X multmatch = TRUE; /* don't free the names */
X findex = -1; /* next p_wc gets first one */
X }
X
X if (mode == 4 && cmd_numfiles > 0) /* concatenate all file names */


X {
X len = 0;

X for (i = 0; i < cmd_numfiles; ++i)
X len += STRLEN(cmd_files[i]) + 1;
X ss = lalloc(len, TRUE);
X if (ss)
X {
X *ss = NUL;
X for (i = 0; i < cmd_numfiles; ++i)
X {
X STRCAT(ss, cmd_files[i]);
X if (i != cmd_numfiles - 1)
X STRCAT(ss, " ");
X }
X }
X }
X
X#ifdef WEBB_COMPLETE
X if (mode == -1 || mode == 4)
X#else
X if (!multmatch || mode == -1 || mode == 4)
X#endif /* WEBB_COMPLETE */
X {
X FreeWild(cmd_numfiles, cmd_files);
X cmd_numfiles = -1;
X }
X return ss;
X}
X
X/*
X * show all filenames that match the string "file" with length "len"
X */
X#ifdef WEBB_COMPLETE
X static int
Xshowmatches(buff)
X char_u *buff;
X#else
X static void
Xshowmatches(file, len)
X char_u *file;
X int len;
X#endif /* WEBB_COMPLETE */
X{
X char_u *file_str;
X int num_files;
X char_u **files_found;
X int i, j, k;
X int maxlen;
X int lines;
X int columns;
X
X#ifdef WEBB_COMPLETE
X set_expand_context(cmdfirstc, cmdbuff);
X if (expand_context == EXPAND_UNSUCCESSFUL)
X {
X beep();
X return OK; /* Something illegal on command line */
X }
X if (expand_context == EXPAND_NOTHING)
X {
X /* Caller can use the character as a normal char instead */
X return FAIL;
X }
X expand_interactively = TRUE;
X
X /* add star to file name, or convert to regexp if not expanding files! */
X file_str = addstar(expand_pattern, (int)(buff + cmdpos - expand_pattern));
X if (file_str == NULL)
X {
X expand_interactively = FALSE;
X return OK;
X }
X#else
X file_str = addstar(file, len); /* add star to file name */
X if (file_str == NULL)
X return;
X#endif /* WEBB_COMPLETE */


X
X msg_outchar('\n');

X flushbuf();
X
X /* find all files that match the description */
X#ifdef WEBB_COMPLETE
X if (ExpandFromContext(file_str, &num_files, &files_found, FALSE, FALSE) == FAIL)
X {
X num_files = 0;
X files_found = (char_u **)"";
X }
X#else
X if (ExpandWildCards(1, &file_str, &num_files, &files_found, FALSE, FALSE) == FAIL)
X return;
X#endif /* WEBB_COMPLETE */
X
X /* find the maximum length of the file names */
X maxlen = 0;
X for (i = 0; i < num_files; ++i)
X {
X j = STRLEN(files_found[i]);
X if (j > maxlen)
X maxlen = j;
X }
X
X /* compute the number of columns and lines for the listing */
X maxlen += 2; /* two spaces between file names */
X columns = ((int)Columns + 2) / maxlen;
X if (columns < 1)
X columns = 1;
X lines = (num_files + columns - 1) / columns;
X
X (void)set_highlight('d'); /* find out highlight mode for directories */
X
X /* list the files line by line */
X for (i = 0; i < lines; ++i)
X {
X for (k = i; k < num_files; k += lines)
X {
X if (k > i)
X for (j = maxlen - STRLEN(files_found[k - lines]); --j >= 0; )
X msg_outchar(' ');
X#ifdef WEBB_COMPLETE
X if (expand_context == EXPAND_FILES)
X j = isdir(files_found[k]); /* highlight directories */
X else
X j = FALSE;
X#else
X j = isdir(files_found[k]); /* highlight directories */
X#endif /* WEBB_COMPLETE */
X if (j)
X {
X start_highlight();
X screen_start(); /* don't output spaces to position cursor */
X }
X msg_outstr(files_found[k]);
X if (j)
X stop_highlight();


X }
X msg_outchar('\n');

X flushbuf(); /* show one line at a time */
X }
X free(file_str);
X FreeWild(num_files, files_found);
X
X/*
X * we redraw the command below the lines that we have just listed
X * This is a bit tricky, but it saves a lot of screen updating.
X */
X cmdline_row = msg_row; /* will put it back later */
X#ifdef WEBB_COMPLETE
X
X expand_interactively = FALSE;
X return OK;
X#endif /* WEBB_COMPLETE */
X}
X
X/*
X * copy the file name into allocated memory and add a '*' at the end


X */
X static char_u *

Xaddstar(fname, len)
X char_u *fname;
X int len;
X{
X char_u *retval;
X#ifdef WEBB_COMPLETE
X int i, j;
X int new_len;
X char_u save_char;
X
X if (expand_interactively && expand_context != EXPAND_FILES &&
X expand_context != EXPAND_DIRECTORIES)
X {
X /* Matching will be done internally (on something other than files).
X * So we convert the file-matching-type wildcards into our kind for
X * use with regcomp(). First work out how long it will be:
X */
X new_len = len + 2; /* +2 for '^' at start, NUL at end */
X for (i = 0; i < len; i++)
X if (fname[i] == '*')
X new_len++; /* '*' needs to be replaced by '.*' */
X retval = alloc(new_len);
X if (retval != NULL)
X {
X retval[0] = '^';
X for (i = 0, j = 1; i < len; i++, j++)
X if (fname[i] == '*')
X {
X retval[j++] = '.';
X retval[j] = '*';
X }
X else if (fname[i] == '?')
X retval[j] = '.';
X else
X retval[j] = fname[i];
X retval[j] = NUL;


X }
X }
X else
X {

X retval = alloc(len + 4);
X if (retval != NULL)
X {
X STRNCPY(retval, fname, (size_t)len);
X /*
X * Don't add a star to ~ or ~user
X */
X save_char = fname[j = len];
X fname[j] = NUL;
X if (gettail(fname)[0] != '~')
X {
X#ifdef MSDOS
X /*
X * if there is no dot in the file name, add "*.*" instead of "*".
X */
X for (i = len - 1; i >= 0; --i)
X if (strchr(".\\/:", retval[i]))
X break;
X if (i < 0 || retval[i] != '.')
X {
X retval[len++] = '*';
X retval[len++] = '.';
X }
X#endif
X retval[len++] = '*';
X }
X retval[len] = NUL;
X fname[j] = save_char;
X }
X }
X#else /* WEBB_COMPLETE */
X#ifdef MSDOS
X int i;
X#endif
X
X retval = alloc(len + 4);
X if (retval != NULL)
X {
X STRNCPY(retval, fname, (size_t)len);
X#ifdef MSDOS
X /*
X * if there is no dot in the file name, add "*.*" instead of "*".
X */
X for (i = len - 1; i >= 0; --i)
X if (strchr(".\\/:", retval[i]))
X break;
X if (i < 0 || retval[i] != '.')
X {
X retval[len++] = '*';
X retval[len++] = '.';
X }
X#endif
X retval[len] = '*';
X retval[len + 1] = 0;
X }
X#endif /* WEBB_COMPLETE */


X return retval;
X}
X

X/*
X * dosource: read the file "fname" and execute its lines as EX commands
X *
X * This function may be called recursively!
X *
X * return FAIL if file could not be opened, OK otherwise
X */
X int
Xdosource(fname)
X register char_u *fname;
X{
X register FILE *fp;
X register int len;
X#ifdef MSDOS
X int error = FALSE;
X#endif
X
X expand_env(fname, NameBuff, MAXPATHL); /* use NameBuff for expanded name */
X if ((fp = fopen((char *)NameBuff, READBIN)) == NULL)
X return FAIL;
X
X ++dont_sleep; /* don't call sleep() in emsg() */
X len = 0;
X while (fgets((char *)IObuff + len, IOSIZE - len, fp) != NULL && !got_int)
X {
X len = STRLEN(IObuff) - 1;
X if (len >= 0 && IObuff[len] == '\n') /* remove trailing newline */
X {
X#ifdef MSDOS
X if (len > 0 && IObuff[len - 1] == '\r') /* trailing CR-LF */
X --len;
X else
X {
X if (!error)
X EMSG("Warning: Wrong line separator, ^M may be missing");
X error = TRUE; /* lines like ":map xx yy^M" will fail */
X }
X#endif
X /* escaped newline, read more */
X if (len > 0 && len < IOSIZE && IObuff[len - 1] == Ctrl('V'))
X {
X IObuff[len - 1] = '\n'; /* remove CTRL-V */
X continue;
X }
X IObuff[len] = NUL;
X }
X breakcheck(); /* check for ^C here, so recursive :so will be broken */
X docmdline(IObuff);


X len = 0;
X }

X fclose(fp);
X if (got_int)
X emsg(e_interr);
X --dont_sleep;


X return OK;
X}
X
X/*

X * get single EX address
X */
X static linenr_t
Xget_address(ptr)
X char_u **ptr;
X{
X linenr_t cursor_lnum = curwin->w_cursor.lnum;
X int c;
X int i;
X long n;
X char_u *cmd;
X FPOS pos;
X FPOS *fp;
X linenr_t lnum;
X
X cmd = *ptr;
X skipspace(&cmd);
X lnum = MAXLNUM;
X do
X {
X switch (*cmd)
X {
X case '.': /* '.' - Cursor position */
X ++cmd;
X lnum = cursor_lnum;
X break;
X
X case '$': /* '$' - last line */
X ++cmd;
X lnum = curbuf->b_ml.ml_line_count;
X break;
X
X case '\'': /* ''' - mark */
X if (*++cmd == NUL || (fp = getmark(*cmd++, FALSE)) == NULL)
X {
X emsg(e_umark);
X goto error;
X }
X lnum = fp->lnum;
X break;
X
X case '/':
X case '?': /* '/' or '?' - search */
X c = *cmd++;
X pos = curwin->w_cursor; /* save curwin->w_cursor */
X curwin->w_cursor.col = -1; /* searchit() will increment the col */
X if (c == '/')
X {
X if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) /* :/pat on last line */


X curwin->w_cursor.lnum = 1;

X else
X ++curwin->w_cursor.lnum;
X }
X searchcmdlen = 0;
X if (dosearch(c, cmd, FALSE, (long)1, FALSE, TRUE))
X lnum = curwin->w_cursor.lnum;
X curwin->w_cursor = pos;
X
X cmd += searchcmdlen; /* adjust command string pointer */
X break;
X
X default:
X if (isdigit(*cmd)) /* absolute line number */
X lnum = getdigits(&cmd);
X }
X
X while (*cmd == '-' || *cmd == '+')
X {
X if (lnum == MAXLNUM)
X lnum = cursor_lnum;
X i = *cmd++;
X if (!isdigit(*cmd)) /* '+' is '+1', but '+0' is not '+1' */
X n = 1;
X else
X n = getdigits(&cmd);
X if (i == '-')
X lnum -= n;
X else
X lnum += n;
X }
X
X cursor_lnum = lnum;
X } while (*cmd == '/' || *cmd == '?');
X
Xerror:
X *ptr = cmd;
X return lnum;
X}
X
X
X#ifdef WEBB_COMPLETE
X/*
X * Must parse the command line so far to work out what context we are in.
X * Completion can then be done based on that context.
X * This routine sets two global variables:
X * char_u *expand_pattern --- The start of the pattern to be expanded within
X * the command line (ends at the cursor).
X * int expand_context --- The type of thing to expand. Will be one of:
X * EXPAND_UNSUCCESSFUL --- Used somtimes when there is something illegal on
X * the command line, like an unknown command. Caller should beep.
X * EXPAND_NOTHING --- Unrecognised context for completion, use char like a
X * normal char, rather than for completion. eg :s/^I/
X * EXPAND_COMMANDS --- Cursor is still touching the command, so complete it.
X * EXPAND_FILES --- After command with XFILE set, or after setting with
X * P_EXPAND set. eg :e ^I, :w>>^I
X * EXPAND_DIRECTORIES --- In some cases this is used instead of the latter
X * when we know only directories are of interest. eg :set dir=^I
X * EXPAND_SETTINGS --- Complete variable names. eg :set d^I
X * EXPAND_BOOL_SETTINGS --- Complete bollean variables only, eg :set no^I
X * EXPAND_TAGS --- Complete tags from the files in p_tags. eg :ta a^I
X *
X * -- webb.


X */
X static void

Xset_expand_context(firstc, buff)
X int firstc; /* either ':', '/', or '?' */
X char_u *buff; /* buffer for command string */
X{
X char_u *nextcomm;
X char_u old_char;
X
X old_char = cmdbuff[cmdpos];
X cmdbuff[cmdpos] = NUL;
X nextcomm = buff;
X while (nextcomm != NULL)
X nextcomm = set_one_cmd_context(firstc, nextcomm);
X cmdbuff[cmdpos] = old_char;
X}
X
X/*
X * This is all pretty much copied from DoOneCmd(), with all the extra stuff we
X * don't need/want deleted. Maybe this could be done better if we didn't
X * repeat all this stuff. The only problem is that they may not stay perfectly
X * compatible with each other, but then the command line syntax probably won't
X * change that much -- webb.


X */
X static char_u *

Xset_one_cmd_context(firstc, buff)
X int firstc; /* either ':', '/', or '?' */
X char_u *buff; /* buffer for command string */
X{
X register char_u *p;
X char_u *cmd, *arg;
X int i;
X int cmdidx;
X int argt;
X char_u delim;
X int forced = FALSE;
X int usefilter = FALSE; /* filter instead of file name */
X
X expand_pattern = buff;
X if (firstc != ':')
X {
X expand_context = EXPAND_NOTHING;
X return NULL;
X }
X expand_context = EXPAND_COMMANDS; /* Default until we get past command */
X
X/*
X * 2. skip comment lines and leading space, colons or bars
X */
X for (cmd = buff; *cmd && strchr(" \t:|", *cmd) != NULL; cmd++)
X ;
X expand_pattern = cmd;
X
X if (*cmd == NUL)
X return NULL;
X if (*cmd == '"') /* ignore comment lines */
X {
X expand_context = EXPAND_NOTHING;
X return NULL;
X }
X
X/*
X * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
X */
X
X --cmd;
X do
X {
X ++cmd; /* skip ',' or ';' */
X skipspace(&cmd);
X do
X {
X switch (*cmd)
X {
X case '.': /* '.' - Cursor position */
X case '$': /* '$' - last line */
X case '%': /* '%' - all lines */
X ++cmd;
X break;
X
X case '\'': /* ''' - mark */
X if (*++cmd != NUL)
X ++cmd;
X break;
X
X case '/':
X case '?': /* '/' or '?' - search */
X delim = *cmd++;
X while (*cmd != NUL && *cmd != delim)
X cmd++;
X if (*cmd == delim)
X cmd++;
X break;
X
X default:
X while (isdigit((char)*cmd))
X ++cmd;
X break;
X }
X
X while (*cmd == '-' || *cmd == '+')
X {
X cmd++;
X while (isdigit(*cmd))
X cmd++;
X }
X } while (*cmd == '/' || *cmd == '?');
X } while (*cmd == ',' || *cmd == ';');
X
X/*
X * 4. parse command
X */
X
X skipspace(&cmd);
X expand_pattern = cmd;
X if (*cmd == NUL)
X return NULL;
X if (*cmd == '"')
X {
X expand_context = EXPAND_NOTHING;


X return NULL;
X }
X

X if (*cmd == '|' || *cmd == '\n')
X return cmd + 1; /* There's another command */
X
X /*
X * Isolate the command and search for it in the command table.
X * Exeptions:
X * - the 'k' command can directly be followed by any character.
X * - the 's' command can be followed directly by 'c', 'g' or 'r'
X */
X if (*cmd == 'k')
X {
X cmdidx = CMD_k;
X p = cmd + 1;
X }
X else
X {
X p = cmd;
X while (isalpha(*p) || *p == '*') /* Allow * wild card */
X ++p;
X if (p == cmd && strchr("@!=><&~#", *p) != NULL) /* non-alpha command */
X ++p;
X i = (int)(p - cmd);
X
X if (i == 0)
X {
X expand_context = EXPAND_UNSUCCESSFUL;
X return NULL;
X }
X for (cmdidx = 0; cmdidx < CMD_SIZE; ++cmdidx)
X if (STRNCMP(cmdnames[cmdidx].cmd_name, cmd, (size_t)i) == 0)
X break;
X }
X if (p == cmdbuff + cmdpos) /* We are still touching the command */
X return NULL; /* So complete it */
X
X if (cmdidx == CMD_SIZE)
X {
X if (*cmd == 's' && strchr("cgr", cmd[1]) != NULL)
X {
X cmdidx = CMD_substitute;
X p = cmd + 1;
X }
X else
X {
X /* Not still touching the command and it was an illegal command */
X expand_context = EXPAND_UNSUCCESSFUL;


X return NULL;
X }
X }

X
X expand_context = EXPAND_NOTHING; /* Default now that we're past command */
X
X if (*p == '!') /* forced commands */
X {
X forced = TRUE;
X ++p;
X }
X
X/*
X * 5. parse arguments
X */
X argt = cmdnames[cmdidx].cmd_argt;
X
X arg = p; /* remember start of argument */
X skipspace(&arg);
X
X if (cmdidx == CMD_write)
X {
X if (*arg == '>') /* append */
X {
X if (*++arg == '>') /* It should be */
X ++arg;
X skipspace(&arg);
X }
X else if (*arg == '!') /* :w !filter */
X {
X ++arg;
X usefilter = TRUE;
X }
X }
X
X if (cmdidx == CMD_read)
X {
X usefilter = forced; /* :r! filter if forced */
X if (*arg == '!') /* :r !filter */
X {
X ++arg;
X usefilter = TRUE;
X }
X }
X
X if (cmdidx == CMD_lshift || cmdidx == CMD_rshift)
X {
X while (*arg == *cmd) /* allow any number of '>' or '<' */
X ++arg;
X skipspace(&arg);
X }
X
X /*
X * Check for '|' to separate commands and '"' to start comments.
X * Don't do this for ":read !cmd" and ":write !cmd".
X */
X if ((argt & TRLBAR) && !usefilter)
X {
X p = arg;
X while (*p)
X {
X if (*p == Ctrl('V'))
X {
X if (p[1] != NUL)
X ++p;
X }
X else if ((*p == '"' && !(argt & NOTRLCOM)) || *p == '|' || *p == '\n')
X {
X if (*(p - 1) != '\\')
X {
X if (*p == '|' || *p == '\n')
X return p + 1;
X return NULL; /* It's a comment */
X }
X }
X ++p;
X }
X }
X
X if (!(argt & EXTRA) && strchr("|\"", *arg) == NULL) /* no arguments allowed */
X return NULL;
X
X /* Find start of last argument (argument just before cursor): */
X p = cmdbuff + cmdpos;
X while (p != arg && *p != ' ' && *p != TAB)
X p--;
X if (*p == ' ' || *p == TAB)
X p++;
X expand_pattern = p;
X
X if (argt & XFILE)
X expand_context = EXPAND_FILES;
X
X/*
X * 6. switch on command name
X */
X switch (cmdidx)
X {
X case CMD_cd:
X case CMD_chdir:
X expand_context = EXPAND_DIRECTORIES;
X break;
X case CMD_buffer:
X case CMD_wnext:
X case CMD_args: /* args now takes arguments like :next */
X case CMD_next:
X case CMD_snext:
X case CMD_split:
X case CMD_new:
X case CMD_edit:
X case CMD_ex:
X case CMD_visual:
X for (p = arg; *p; ++p)
X {
X if (*p == '\\' && p[1])
X ++p;
X else if (*p == '|' || *p == '\n')
X return p + 1;
X }
X break;
X case CMD_global:
X case CMD_vglobal:
X delim = *arg; /* get the delimiter */
X if (delim)
X ++arg; /* skip delimiter if there is one */
X
X while (arg[0] != NUL && arg[0] != delim)
X {
X if (arg[0] == '\\' && arg[1] != NUL)
X ++arg;
X ++arg;
X }
X if (arg[0] != NUL)
X return arg + 1;
X break;
X case CMD_and:
X case CMD_substitute:
X delim = *arg;
X if (delim)
X ++arg;
X for (i = 0; i < 2; i++, arg++)
X while (arg[0] != NUL && arg[0] != delim)
X {
X if (arg[0] == '\\' && arg[1] != NUL)
X ++arg;
X ++arg;
X }
X while (arg[0] != NUL && strchr("|\"#", arg[0]) == NULL)
X ++arg;
X if (arg[0] != NUL)
X return arg;
X break;
X case CMD_set:
X set_context_in_set_cmd(arg);
X break;
X case CMD_tag:
X expand_context = EXPAND_TAGS;
X expand_pattern = arg;
X break;
X default:
X break;
X }
X return NULL;
X}
X
X/*
X * Do the expansion based on the global variables expand_context and
X * expand_pattern -- webb.


X */
X static int

XExpandFromContext(pat, num_file, file, files_only, list_notfound)
X char_u *pat;
X int *num_file;
X char_u ***file;


X int files_only;
X int list_notfound;
X{

X regexp *prog;
X int cmdidx;
X int count;
X int ret;
X int i;
X
X if (!expand_interactively || expand_context == EXPAND_FILES)
X return ExpandWildCards(1, &pat, num_file, file, files_only, list_notfound);
X else if (expand_context == EXPAND_DIRECTORIES)
X {
X if (ExpandWildCards(1, &pat, num_file, file, files_only, list_notfound)
X == FAIL)
X return FAIL;
X count = 0;
X for (i = 0; i < *num_file; i++)
X if (isdir((*file)[i]))
X (*file)[count++] = (*file)[i];
X else
X free((*file)[i]);


X if (count == 0)

X {
X free(*file);
X *file = (char_u **)"";
X *num_file = -1;
X return FAIL;
X }
X *num_file = count;
X return OK;
X }
X *file = (char_u **)"";
X *num_file = 0;
X ret = OK;
X reg_ic = FALSE;
X reg_magic = p_magic;
X prog = regcomp(pat);
X if (prog == NULL)
X return FAIL;
X if (expand_context == EXPAND_COMMANDS)
X {
X /* Count the matches: */
X count = 0;
X for (cmdidx = 0; cmdidx < CMD_SIZE; cmdidx++)
X if (regexec(prog, cmdnames[cmdidx].cmd_name, TRUE))
X count++;
X if (count == 0
X || (*file = (char_u **) alloc((int)(count * sizeof(char_u *)))) == NULL)
X ret = FAIL;
X else
X {
X *num_file = count;
X count = 0;
X for (cmdidx = 0; cmdidx < CMD_SIZE; cmdidx++)
X if (regexec(prog, cmdnames[cmdidx].cmd_name, TRUE))
X (*file)[count++] = strsave(cmdnames[cmdidx].cmd_name);
X }
X }
X else if (expand_context == EXPAND_SETTINGS
X || expand_context == EXPAND_BOOL_SETTINGS)
X ret = ExpandSettings(prog, num_file, file);
X else if (expand_context == EXPAND_TAGS)
X ret = ExpandTags(prog, num_file, file);
X else
X ret = FAIL;
X
X free(prog);
X return ret;
X}
X#endif /* WEBB_COMPLETE */
END_OF_FILE
if test 44081 -ne `wc -c <'vim/src/cmdline.c.B'`; then
echo shar: \"'vim/src/cmdline.c.B'\" unpacked with wrong size!
elif test -f 'vin/src/cmdline.c.A'; then
echo shar: Combining \"'vim/src/cmdline.c'\" \(82989 characters\)
cat 'vim/src/cmdline.c.A' 'vim/src/cmdline.c.B' > 'vim/src/cmdline.c'
if test 82989 -ne `wc -c <'vim/src/cmdline.c'`; then
echo shar: \"'vim/src/cmdline.c'\" combined with wrong size!
else
rm vim/src/cmdline.c.A vim/src/cmdline.c.B
fi
fi
# end of 'vim/src/cmdline.c.B'
fi
if test -f 'vim/src/proto/buffer.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/buffer.pro'\"
else
echo shar: Extracting \"'vim/src/proto/buffer.pro'\" \(1276 characters\)
sed "s/^X//" >'vim/src/proto/buffer.pro' <<'END_OF_FILE'
X/* buffer.c */
Xint open_buffer __PARMS((void));
Xvoid close_buffer __PARMS((struct buffer *buf, int free_buf, int remove));
Xvoid buf_clear __PARMS((struct buffer *buf));
Xvoid buf_freeall __PARMS((struct buffer *buf));
Xint do_buffer __PARMS((int action, int start, int dir, int count, int forceit));
Xstruct buffer *buflist_new __PARMS((unsigned char *fname, unsigned char *sfname, long lnum, int use_curbuf));
Xint buflist_getfile __PARMS((int n, long lnum, int setpm));
Xvoid buflist_getlnum __PARMS((void));
Xunsigned char *buflist_nr2name __PARMS((int n));
Xvoid buflist_list __PARMS((void));
Xint buflist_name_nr __PARMS((int fnum, unsigned char **fname, long *lnum));
Xint setfname __PARMS((unsigned char *fname, unsigned char *sfname, int message));
Xvoid setaltfname __PARMS((unsigned char *fname, unsigned char *sfname, long lnum));
Xint buflist_add __PARMS((unsigned char *fname));
Xvoid buflist_altlnum __PARMS((void));
Xint otherfile __PARMS((unsigned char *fname));
Xvoid fileinfo __PARMS((int fullname));
Xvoid maketitle __PARMS((void));
Xvoid resettitle __PARMS((void));
Xunsigned char *fix_fname __PARMS((unsigned char *fname));
Xvoid fname_expand __PARMS((unsigned char **fname, unsigned char **sfname));
Xvoid do_arg_all __PARMS((void));
Xvoid do_buffer_all __PARMS((int all));
END_OF_FILE
if test 1276 -ne `wc -c <'vim/src/proto/buffer.pro'`; then
echo shar: \"'vim/src/proto/buffer.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/buffer.pro'
fi
echo shar: End of archive 8 \(of 26\).
cp /dev/null ark8isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:09 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 28
Archive-name: vim/part09

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/vim.hlp.UU vim/src/buffer.c vim/src/proto/mark.pro
# Wrapped by kent@sparky on Mon Aug 15 21:44:03 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 9 (of 26)."'
if test -f 'vim/doc/vim.hlp.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/vim.hlp.UU'\"
else
echo shar: Extracting \"'vim/doc/vim.hlp.UU'\" \(43036 characters\)
sed "s/^X//" >'vim/doc/vim.hlp.UU' <<'END_OF_FILE'
Xbegin 644 vim/doc/vim.hlp
XM(" @(" @(" @(" @(" @(" @(" @5DE-(&AE;' @9FEL92!I;F1E> H*4D54
XM55).('%U:70@:&5L<" @(" @(" @(" @(" @("!624T@<W1A;F1S(&9O<B!6
XM:2!)37!R;W9E9"X*(%-004-%("!O;F4@<&%G92!F;W)W87)D(" @(" @("!-
XM;W-T(&]F(%9)32!W87,@;6%D92!B>2!"<F%M($UO;VQE;F%A<BX*(" @("!A
XM("!G;R!T;R!T:&ES(&EN9&5X"B @(" @8B @;VYE('!A9V4@8F%C:W=A<F0*
XM"F,@("!L969T+7)I9VAT(&%N9"!U<"UD;W=N(&UO=&EO;G,@("!Q(" @;W!T
XM:6]N<R!I+6X*9" @('=O<F0@86YD('1E>'0@;V)J96-T(&UO=&EO;G,@(" @
XM('(@("!O<'1I;VYS(' M<PIE(" @<&%T=&5R;B!S96%R8VAE<R @(" @(" @
XM(" @(" @(" @<R @(&]P=&EO;G,@<RUT"F8@("!V87)I;W5S(&UO=&EO;G,[
XM('5S:6YG('1A9W,@(" @("!T(" @;W!T:6]N<R!T+7D*9R @('-C<F]L;&EN
XM9R @(" @(" @(" @(" @(" @(" @(" @('4@("!U;F1O.R!S:&5L;#L@<75I
XM8VMF:7@[('9A<FEO=7,*:" @(&EN<V5R=&EN9R!T97AT.R!D:6=R87!H<R @
XM(" @(" @('8@("!C;VUM86YD(&QI;F4@961I=&EN9PII(" @:6YS97)T(&UO
XM9&4@(" @(" @(" @(" @(" @(" @(" @=R @($5X(')A;F=E<SL@17@@<W!E
XM8VEA;"!C:&%R86-T97)S"FH@("!C:&%N9VEN9R!T97AT(" @(" @(" @(" @
XM(" @(" @("!X(" @961I=&EN9R!F:6QE<PIK(" @8V]M<&QE>"!C:&%N9V5S
XM(" @(" @(" @(" @(" @(" @>2 @('5S:6YG('1H92!F:6QE(&QI<W0*;" @
XM(&1E;&5T:6YG+"!C;W!Y:6YG+"!M;W9I;F<@=&5X=" @('H@("!W<FET:6YG
XM(&%N9"!Q=6ET=&EN9PIM(" @<F5P96%T:6YG(&-O;6UA;F1S(" @(" @(" @
XM(" @(" @02 @('-T87)T:6YG(%9)30IN(" @:V5Y(&UA<'!I;F<[(&%B8G)E
XM=FEA=&EO;G,@(" @(" @0B @(&UU;'1I('=I;F1O=R!F=6YC=&EO;G,*;R @
XM(&]P=&EO;B!C;VUM86YD<RP@;W!T:6]N<R!A+6,@(" @($,@("!B=69F97(@
XM;&ES="!F=6YC=&EO;G,*<" @(&]P=&EO;G,@9"UH"@I296%D(")R969E<F5N
XM8V4N9&]C(B!F;W(@82!M;W)E(&-O;7!L971E(&5X<&QA;F%T:6]N+@H, DQE
XM9G0M<FEG:'0@;6]T:6]N<P4*3B @:" @(" @(" @(" @(&QE9G0@*'-A;64@
XM87,@0U123"U(+"!"4R!A;F0@8W5R<V]R+6QE9G0@:V5Y*0I.("!L(" @(" @
XM(" @(" @<FEG:'0@*'-A;64@87,@4U!!0T4@86YD(&-U<G-O<BUR:6=H="!K
XM97DI"B @(# @(" @(" @(" @("!T;R!F:7)S="!C:&%R86-T97(@:6X@=&AE
XM(&QI;F4*(" @7B @(" @(" @(" @('1O(&9I<G-T(&YO;BUB;&%N:R!C:&%R
XM86-T97(@:6X@=&AE(&QI;F4*3B @)" @(" @(" @(" @('1O('1H92!L87-T
XM(&-H87)A8W1E<B!I;B!T:&4@;&EN92 H3BTQ(&QI;F5S(&QO=V5R*0I.("!\
XM(" @(" @(" @(" @=&\@8V]L=6UN($X*3B @9CQC:&%R/B @(" @('1O('1H
XM92!.=&@@;V-C=7)R96YC92!O9B \8VAA<CX@=&\@=&AE(')I9VAT"DX@($8\
XM8VAA<CX@(" @("!T;R!T:&4@3G1H(&]C8W5R<F5N8V4@;V8@/&-H87(^('1O
XM('1H92!L969T"DX@('0\8VAA<CX@(" @("!T:6QL(&)E9F]R92!T:&4@3G1H
XM(&]C8W5R<F5N8V4@;V8@/&-H87(^('1O('1H92!R:6=H= I.("!4/&-H87(^
XM(" @(" @=&EL;"!B969O<F4@=&AE($YT:"!O8V-U<G)E;F-E(&]F(#QC:&%R
XM/B!T;R!T:&4@;&5F= I.(" [(" @(" @(" @(" @<F5P96%T('1H92!L87-T
XM(&8L($8L('0@;W(@5"!.('1I;65S"DX@("P@(" @(" @(" @("!R97!E870@
XM=&AE(&QA<W0@9BP@1BP@="!O<B!4($X@=&EM97,@:6X@;W!P;W-I=&4@9&ER
XM96-T:6]N"@H"57 M9&]W;B!M;W1I;VYS!0I.("!K(" @(" @(" @(" @=7 @
XM*'-A;64@87,@0U123"U0(&%N9"!C=7)S;W(M=7 @:V5Y*0I.("!J(" @(" @
XM(" @(" @9&]W;B H<V%M92!A<R!#5%),+4HL($-44DPM3BP@3$8@86YD(&-U
XM<G-O<BUD;W=N(&ME>2D*3B @+2 @(" @(" @(" @('5P+"!O;B!T:&4@9FER
XM<W0@;F]N+6)L86YK(&-H87)A8W1E<@I.(" K(" @(" @(" @(" @9&]W;BP@
XM;VX@=&AE(&9I<G-T(&YO;BUB;&%N:R!C:&%R+B H<V%M92!A<R!#5%),+4T@
XM86YD($-2*0I.("!?(" @(" @(" @(" @3B M(#$@;&EN97,@9&]W;BP@;VX@
XM=&AE(&9I<G-T(&YO;BUB;&%N:R!C:&%R86-T97(*3B @1R @(" @(" @(" @
XM(&=O=&\@;&EN92!.("AD969A=6QT(&QA<W0@;&EN92DL(&]N('1H92!F:7)S
XM="!N;VXM8FQA;FL@8VAA<BX*3B @)2 @(" @(" @(" @(&=O=&\@;&EN92!.
XM('!E<F-E;G1A9V4@9&]W;B!I;B!T:&4@9FEL92X*# )7;W)D(&UO=&EO;G,%
XM"DX@('<@(" @(" @(" @("!.('=O<F1S(&9O<G=A<F0*3B @5R @(" @(" @
XM(" @($X@8FQA;FLM<V5P87)A=&5D('=O<F1S(&9O<G=A<F0*3B @92 @(" @
XM(" @(" @(&9O<G=A<F0@=&\@=&AE(&5N9"!O9B!T:&4@3G1H('=O<F0*3B @
XM12 @(" @(" @(" @(&9O<G=A<F0@=&\@=&AE(&5N9"!O9B!T:&4@3G1H(&)L
XM86YK+7-E<&%R871E9"!W;W)D"DX@(&(@(" @(" @(" @("!.('=O<F1S(&)A
XM8VMW87)D"DX@($(@(" @(" @(" @("!.(&)L86YK+7-E<&%R871E9"!W;W)D
XM<R!B86-K=V%R9 H* E1E>'0@;V)J96-T(&UO=&EO;G,%"DX@("D@(" @(" @
XM(" @("!.('-E;G1E;F-E<R!F;W)W87)D"DX@("@@(" @(" @(" @("!.('-E
XM;G1E;F-E<R!B86-K=V%R9 I.("!](" @(" @(" @(" @3B!P87)A9W)A<&AS
XM(&9O<G=A<F0*3B @>R @(" @(" @(" @($X@<&%R86=R87!H<R!B86-K=V%R
XM9 I.("!=72 @(" @(" @(" @3B!S96-T:6]N<R!F;W)W87)D"DX@(%M;(" @
XM(" @(" @("!.('-E8W1I;VYS(&)A8VMW87)D"DX@(%U;(" @(" @(" @("!.
XM('-E8W1I;VYS("AS=&%R=&EN9R!W:71H(&$@/'T^*2!F;W)W87)D"DX@(%M=
XM(" @(" @(" @("!.('-E8W1I;VYS("AS=&%R=&EN9R!W:71H(&$@/'T^*2!B
XM86-K=V%R9 I.("!;*" @6WL@(" @(" @3B!T:6UE<R!B86-K('1O('5N8VQO
XM<V5D(#PH/B!O<B \>SX*3B @72D@(%U](" @(" @($X@=&EM97,@9F]R=V%R
XM9"!T;R!U;F-L;W-E9" \*#X@;W(@/'L^"@P"4&%T=&5R;B!S96%R8VAE<P4*
XM3B @+WMP871T97)N?5LO72 @(" @(" @<V5A<F-H(&9O<G=A<F0@9F]R('1H
XM92!.=&@@;V-C=7)R96YC92!O9B![<&%T=&5R;GT*3B @/WMP871T97)N?5L_
XM72 @(" @(" @<V5A<F-H(&)A8VMW87)D(&9O<B!T:&4@3G1H(&]C8W5R<F5N
XM8V4@;V8@>W!A='1E<FY]"DX@("\@(" @(" @(" @(" @(" @(" @(')E<&5A
XM="!L87-T('-E87)C:"P@:6X@=&AE(&9O<G=A<F0@9&ER96-T:6]N"DX@(#\@
XM(" @(" @(" @(" @(" @(" @(')E<&5A="!L87-T('-E87)C:"P@:6X@=&AE
XM(&)A8VMW87)D(&1I<F5C=&EO;@I.("!N(" @(" @(" @(" @(" @(" @("!R
XM97!E870@;&%S="!S96%R8V@*3B @3B @(" @(" @(" @(" @(" @(" @<F5P
XM96%T(&QA<W0@<V5A<F-H+"!I;B!O<'!O<VET92!D:7)E8W1I;VX*3B @*B @
XM(" @(" @(" @(" @(" @(" @<V5A<F-H(&9O<G=A<F0@9F]R('1H92!I9&5N
XM="!U;F1E<B!T:&4@8W5R<V]R"DX@(",@(" @(" @(" @(" @(" @(" @('-E
XM87)C:"!B86-K=V%R9"!F;W(@=&AE(&ED96YT('5N9&5R('1H92!C=7)S;W(*
XM"@)S<&5C:6%L(&-H87)A8W1E<G,@:6X@<V5A<F-H('!A='1E<FYS!2 @(" @
XM(&UA9VEC(" @(" @;F]M86=I8PH@(" @(" @(" @(&UA=&-H97,@86YY('-I
XM;F=L92!C:&%R86-T97(@(" @(" N(" @(" @(" @(" @7"X*(" @(" @(" @
XM(" @(" @(" @;6%T8VAE<R!S=&%R="!O9B!L:6YE(" @(" @7B @(" @(" @
XM(" @(%X*(" @(" @(" @(" @(" @(" @("!M871C:&5S(&5N9"!O9B!L:6YE
XM(" @(" @)" @(" @(" @(" @("0*(" @(" @(" @(" @(" @(" @;6%T8VAE
XM<R!S=&%R="!O9B!W;W)D(" @(" @7#P@(" @(" @(" @(%P\"B @(" @(" @
XM(" @(" @(" @(" @;6%T8VAE<R!E;F0@;V8@=V]R9" @(" @(%P^(" @(" @
XM(" @("!</@H@("!M871C:&5S(&$@<VEN9VQE(&-H87(@9G)O;2!T:&4@<F%N
XM9V4@(" @("!;82UZ72 @(" @(" @7%MA+7I="B!M871C:&5S(&$@<VEN9VQE
XM(&-H87(@;F]T(&EN('1H92!R86YG92 @(" @(%M>82UZ72 @(" @("!<6UYA
XM+7I="FUA=&-H97,@,"!O<B!M;W)E(&]F('1H92!P<F5C961I;F<@871O;2 @
XM(" @("H@(" @(" @(" @("!<*@IM871C:&5S(#$@;W(@;6]R92!O9B!T:&4@
XM<')E8V5D:6YG(&%T;VT@(" @("!<*R @(" @(" @(" @7"L*(" @;6%T8VAE
XM<R P(&]R(#$@;V8@=&AE('!R96-E9&EN9R!A=&]M(" @(" @7#T@(" @(" @
XM(" @(%P]"B @(" @(" @(" @(" @(" @<V5P87)A=&5S('1W;R!B<F%N8VAE
XM<R @(" @(%Q\(" @(" @(" @("!<? H@(" @(" @(" @(&=R;W5P(&$@<&%T
XM=&5R;B!I;G1O(&%N(&%T;VT@(" @("!<*%PI(" @(" @(" @7"A<*0H, E9A
XM<FEO=7,@;6]T:6]N<P4*(" @;3QA+7I!+5H^(" @(&UA<FL@8W5R<F5N="!P
XM;W-I=&EO;B!W:71H(&UA<FL@/&$M>D$M6CX*(" @8#QA+7I!+5H^(" @(&=O
XM('1O(&UA<FL@/&$M>D$M6CX*(" @8& @(" @(" @(" @(&=O('1O('1H92!P
XM;W-I=&EO;B!B969O<F4@=&AE(&QA<W0@:G5M< H@("!@6R!O<B!@72 @(" @
XM9V\@=&\@=&AE('-T87)T(&]R(&5N9"!O9B!T:&4@<')E=FEO=7-L>2!O<&5R
XM871E9"!O<B!P=70@=&5X= H@(" G/&$M>D$M6EM=)SX@<V%M92!A<R!@+"!B
XM=70@;VX@=&AE(&9I<G-T(&YO;BUB;&%N:R!I;B!T:&4@;&EN90HZ;6%R:W,@
XM(" @(" @(" @<')I;G0@=&AE(&%C=&EV92!M87)K<PI.("!#5%),+4\@(" @
XM(" @9V\@=&\@3B!O;&1E<B!P;W-I=&EO;B!I;B!J=6UP(&QI<W0*3B @0U12
XM3"U)(" @(" @(&=O('1O($X@;F5W97(@<&]S:71I;VX@:6X@:G5M<"!L:7-T
XM"CIJ=6UP<R @(" @(" @("!P<FEN="!T:&4@:G5M<"!L:7-T"B @("4@(" @
XM(" @(" @("!F:6YD('1H92!N97AT(&)R86-E+"!B<F%C:V5T+"!C;VUM96YT
XM(&]R("-I9B\C96QS92\C96YD:68@:6X*(" @(" @(" @(" @(" @('1H:7,@
XM;&EN92!A;F0@9V\@=&\@:71S(&UA=&-H"DX@($@@(" @(" @(" @("!G;R!T
XM;R!T:&4@3G1H(&QI;F4@:6X@=&AE('=I;F1O=RP@;VX@=&AE(&9I<G-T(&YO
XM;BUB;&%N:PH@("!-(" @(" @(" @(" @9V\@=&\@=&AE(&UI9&1L92!L:6YE
XM(&EN('1H92!W:6YD;W<L(&]N('1H92!F:7)S="!N;VXM8FQA;FL*3B @3" @
XM(" @(" @(" @(&=O('1O('1H92!.=&@@;&EN92!F<F]M('1H92!B;W1T;VTL
XM(&]N('1H92!F:7)S="!N;VXM8FQA;FL*"@)5<VEN9R!T86=S!0HZ=&%;9UU;
XM(5T@>W1A9WT@(" @(" @("!*=6UP('1O('1A9R![=&%G?2P@=6YL97-S(&-H
XM86YG97,@:&%V92!B965N(&UA9&4*(" @0U123"U=(" @(" @(" @(" @(" @
XM2G5M<"!T;R!T:&4@=&%G('5N9&5R(&-U<G-O<BP@=6YL97-S(&-H86YG97,@
XM;6%D90I.("!#5%),+50@(" @(" @(" @(" @("!*=6UP('1O($X@;VQD97(@
XM=&%G(&EN('1A9R!L:7-T"CI;8V]U;G1=<&];<%U;(5T@(" @(" @($IU;7 @
XM=&\@6V-O=6YT72!O;&1E<B!T86<@:6X@=&%G(&QI<W0*.EMC;W5N=%UT85MG
XM75LA72 @(" @(" @2G5M<"!T;R!;8V]U;G1=(&YE=V5R('1A9R!I;B!T86<@
XM;&ES= HZ=&%G<R @(" @(" @(" @(" @(" @("!0<FEN="!T86<@;&ES= H,
XM E-C<F]L;&EN9P4*3B @0U123"U%(" @(" @('=I;F1O=R!.(&QI;F5S(&1O
XM=VYW87)D<R H3B!L:6YE<R!%>'1R82D*3B @0U123"U$(" @(" @('=I;F1O
XM=R!.(&QI;F5S($1O=VYW87)D<R H9&5F875L="!H86QF(&$@=VEN9&]W*0I.
XM("!#5%),+48@(" @(" @=VEN9&]W($X@<&%G97,@1F]R=V%R9',@*&1O=VYW
XM87)D<RD*3B @0U123"U9(" @(" @('=I;F1O=R!.(&QI;F5S('5P=V%R9',*
XM3B @0U123"U5(" @(" @('=I;F1O=R!.(&QI;F5S(%5P=V%R9',@*&1E9F%U
XM;'0@:&%L9B!A('=I;F1O=RD*3B @0U123"U"(" @(" @('=I;F1O=R!.('!A
XM9V5S($)A8VMW87)D<R H=7!W87)D<RD*(" @>CQ#4CX@;W(@>G0@(')E9')A
XM=RP@8W5R<F5N="!L:6YE(&%T('1O<"!O9B!W:6YD;W<*(" @>BX@(" @;W(@
XM>GH@(')E9')A=RP@8W5R<F5N="!L:6YE(&%T(&-E;G1E<B!O9B!W:6YD;W<*
XM(" @>BT@(" @;W(@>F(@(')E9')A=RP@8W5R<F5N="!L:6YE(&%T(&)O='1O
XM;2!O9B!W:6YD;W<*# ));G-E<G1I;F<@=&5X= 4*3B @82 @(" @(" @(" @
XM(&%P<&5N9"!T97AT(&%F=&5R('1H92!C=7)S;W(@*$X@=&EM97,I"DX@($$@
XM(" @(" @(" @("!A<'!E;F0@=&5X="!A="!T:&4@96YD(&]F('1H92!L:6YE
XM("A.('1I;65S*0I.("!I(" @(" @(" @(" @:6YS97)T('1E>'0@8F5F;W)E
XM('1H92!C=7)S;W(@*$X@=&EM97,I"DX@($D@(" @(" @(" @("!I;G-E<G0@
XM=&5X="!B969O<F4@=&AE(&9I<G-T(&YO;BUB;&%N:R!I;B!T:&4@;&EN92 H
XM3B!T:6UE<RD*3B @;R @(" @(" @(" @(&]P96X@82!N97<@;&EN92!B96QO
XM=R!T:&4@8W5R<F5N="!L:6YE+"!A<'!E;F0@=&5X=" H3B!T:6UE<RD*3B @
XM3R @(" @(" @(" @(&]P96X@82!N97<@;&EN92!A8F]V92!T:&4@8W5R<F5N
XM="!L:6YE+"!A<'!E;F0@=&5X=" H3B!T:6UE<RD*"@)3<&5C:6%L(&EN<V5R
XM=',%"CIR(%MF:6QE72 @(" @("!I;G-E<G0@=&AE(&-O;G1E;G1S(&]F(%MF
XM:6QE72!B96QO=R!T:&4@8W5R<V]R"CIR(7MC;VUM86YD?2 @("!I;G-E<G0@
XM=&AE('-T86YD87)D(&]U='!U="!O9B![8V]M;6%N9'T@8F5L;W<@=&AE(&-U
XM<G-O<@H* D1I9W)A<&AS!0HZ9&EG6W)A<&AS72 @(" @<VAO=R!C=7)R96YT
XM(&QI<W0@;V8@9&EG<F%P:',*.F1I9UMR87!H<UT@>V-H87(Q?7MC:&%R,GT@
XM>VYU;6)E<GT@+BXN"B @(" @(" @(" @(" @("!A9&0@9&EG<F%P:"AS*2!T
XM;R!T:&4@;&ES= H, F-H87(%(" @(" @(" @(" @(" "86-T:6]N(&EN(&EN
XM<V5R="!M;V1E!0I#5%),+5L@;W(@/$530SX@("!E;F0@:6YS97)T(&]R(')E
XM<&QA8V4@;6]D92P@8F%C:R!T;R!C;VUM86YD(&UO9&4*0U123"U!(" @(" @
XM(" @(" @:6YS97)T('!R979I;W5S;'D@:6YS97)T960@=&5X= I#5%),+4 @
XM(" @(" @(" @("!I;G-E<G0@<')E=FEO=7-L>2!I;G-E<G1E9"!T97AT(&%N
XM9"!S=&]P(&EN<V5R= I#5%),+5(@/# M.6$M>B4Z/B!I;G-E<G0@8V]N=&5N
XM=',@;V8@<F5G:7-T97(@/# M.6$M>B4Z/@I#5%),+4H@;W(@/$Q&/B!O<B!#
XM5%),+4T@;W(@/$-2/B @(&)E9VEN(&YE=R!L:6YE"D-44DPM2R![8VAA<C%]
XM('MC:&%R,GT@(&5N=&5R(&1I9W)A<&@*0U123"U%("\@0U123"U9(" @:6YS
XM97)T('1H92!C:&%R86-T97(@=VAI8V@@:7,@8F5L;W<O86)O=F4@=&AE(&-U
XM<G-O<@I#5%),+58@(" @(" @(" @("!I;G-E<G0@8VAA<F%C=&5R(&QI=&5R
XM86QL>2P@;W(@96YT97(@9&5C:6UA;"!B>71E('9A;'5E"D-44DPM3B O($-4
XM4DPM4" @(&EN<V5R="!N97AT+W!R979I;W5S(&UA=&-H(&]F(&ED96YT:69I
XM97(@8F5F;W)E('1H92!C=7)S;W(*0U123"U((&]R(#Q"4SX@;W(@/$1%3#X@
XM9&5L971E('1H92!C:&%R86-T97(@8F5F;W)E('1H92!C=7)S;W(*0U123"U7
XM(" @(" @(" @(" @9&5L971E('=O<F0@8F5F;W)E('1H92!C=7)S;W(*0U12
XM3"U5(" @(" @(" @(" @9&5L971E(&%L;"!E;G1E<F5D(&-H87)A8W1E<G,@
XM:6X@=&AE(&-U<G)E;G0@;&EN90I#5%),+50@(" @(" @(" @("!I;G-E<G0@
XM;VYE('-H:69T=VED=&@@;V8@:6YD96YT(&EN('1H92!C=7)R96YT(&QI;F4*
XM0U123"U$(" @(" @(" @(" @9&5L971E(&]N92!S:&EF='=I9'1H(&]F(&EN
XM9&5N="!I;B!T:&4@8W5R<F5N="!L:6YE"C @0U123"U$(&]R(%X@0U123"U$
XM(" @(&1E;&5T92!A;&P@:6YD96YT(&EN('1H92!C=7)R96YT(&QI;F4*>V-H
XM87(Q?2 \0E,^('MC:&%R,GT@(" @96YT97(@9&EG<F%P:"!I9B G9&<G(&]P
XM=&EO;B!S970*0U123"U"(" @(" @(" @(" @=&]G9VQE("=R979I;G,G("AR
XM979E<G-E(&EN<V5R="D@;W!T:6]N"B @(" @(" @ FME>7,@=&AA="!S=&]P
XM(&EN<V5R="P@9&\@<V]M971H:6YG(&%N9"!G970@8F%C:R!T;R!I;G-E<G0Z
XM!0IC=7)S;W(@:V5Y<R @(" @("!M;W9E(&-U<G-O<B!L969T+W)I9VAT+W5P
XM+V1O=VX*<VAI9G0M=7 O9&]W;B @(" @;VYE('-C<F5E;F9U;&P@8F%C:W=A
XM<F0O9F]R=V%R9 IS:&EF="UL969T+W)I9VAT("!O;F4@=V]R9"!L969T+W)I
XM9VAT"D-44DPM3R![8V]M;6%N9'T@(&5X96-U=&4@>V-O;6UA;F1]"@P"0VAA
XM;F=I;F<@=&5X= 4*3B @4B @(" @(" @(" @(&5N=&5R(')E<&QA8V4@;6]D
XM92 H<F5P96%T('1H92!E;G1E<F5D('1E>'0@3B!T:6UE<RD*3B @8WMM;W1I
XM;VY](" @(&-H86YG92!T:&4@=&5X="!T:&%T(&ES(&UO=F5D(&]V97(@=VET
XM:"![;6]T:6]N?0I[=FES=6%L?6,@(" @(" @8VAA;F=E('1H92!H:6=H;&EG
XM:'1E9"!T97AT"DX@(&-C(" @(" @(" @("!C:&%N9V4@3B!L:6YE<PI.("!#
XM(" @(" @(" @(" @8VAA;F=E('1O(&5N9"!O9B!L:6YE("AA;F0@3BTQ(&UO
XM<F4@;&EN97,I"DX@(',@(" @(" @(" @("!C:&%N9V4@3B!C:&%R86-T97)S
XM"DX@(%,@(" @(" @(" @("!C:&%N9V4@3B!L:6YE<PI.("!R/&-H87(^(" @
XM(" @<F5P;&%C92!.(&-H87)A8W1E<G,@8GD@/&-H87(^"DX@('X@(" @(" @
XM(" @("!S=VET8V@@8V%S92!F;W(@3B!C:&%R86-T97)S(&%N9"!A9'9A;F-E
XM(&-U<G-O<@I[=FES=6%L?7X@(" @(" @<W=I=&-H(&-A<V4@9F]R(&AI9VAL
XM:6=H=&5D('1E>'0*>W9I<W5A;'UU(" @(" @(&UA:V4@:&EG:&QI9VAT960@
XM=&5X="!L;W=E<F-A<V4*>W9I<W5A;'U5(" @(" @(&UA:V4@:&EG:&QI9VAT
XM960@=&5X="!U<'!E<F-A<V4*3B @0U123"U!(" @(" @(&%D9"!.('1O('1H
XM92!N=6UB97(@870@;W(@869T97(@=&AE(&-U<G-O<@I.("!#5%),+5@@(" @
XM(" @<W5B=')A8W0@3B!F<F]M('1H92!N=6UB97(@870@;W(@869T97(@=&AE
XM(&-U<G-O<@I.(" \>VUO=&EO;GT@(" @;6]V92!T:&4@;&EN97,@=&AA="!A
XM<F4@;6]V960@;W9E<B!O;F4@<VAI9G1W:61T:"!L969T"DX@(#P\(" @(" @
XM(" @("!M;W9E($X@;&EN97,@;VYE('-H:69T=VED=&@@;&5F= I.(" ^>VUO
XM=&EO;GT@(" @;6]V92!T:&4@;&EN97,@=&AA="!A<F4@;6]V960@;W9E<B!O
XM;F4@<VAI9G1W:61T:"!R:6=H= I.(" ^/B @(" @(" @(" @;6]V92!.(&QI
XM;F5S(&]N92!S:&EF='=I9'1H(')I9VAT"DX@(%%[;6]T:6]N?2 @("!F;W)M
XM870@=&AE(&QI;F5S('1H870@87)E(&UO=F5D(&]V97(@=&\@)W1E>'1W:61T
XM:"<@;&5N9W1H"CI;<F%N9V5=8V5;;G1E<ET@6W=I9'1H72 @(&-E;G1E<B!T
XM:&4@;&EN97,@:6X@6W)A;F=E70HZ6W)A;F=E76QE6V9T72!;:6YD96YT72 @
XM("!L969T(&%L:6=N('1H92!L:6YE<R!I;B!;<F%N9V5=(%MW:71H(&EN9&5N
XM=%T*.EMR86YG95UR:5MG:'1=(%MW:61T:%T@(" @<FEG:'0@86QI9VX@=&AE
XM(&QI;F5S(&EN(%MR86YG95T*# )#;VUP;&5X(&-H86YG97,%"B @('8@(" @
XM(" @(" @("!S=&%R="!H:6=H;&EG:'1I;F<@8VAA<F%C=&5R<R @?2!M;W9E
XM(&-U<G-O<B!A;F0@=7-E"B @(%8@(" @(" @(" @("!S=&%R="!H:6=H;&EG
XM:'1I;F<@;&EN97=I<V4@(" @?2!O<&5R871O<B!T;R!A9F9E8W0*(" @0U12
XM3"U6(" @(" @('-T87)T(&AI9VAL:6=H=&EN9R!B;&]C:W=I<V4@("!](&AI
XM9VAL:6=H=&5D('1E>'0*(" @;R @(" @(" @(" @(&5X8VAA;F=E(&-U<G-O
XM<B!P;W-I=&EO;B!W:71H('-T87)T(&]F(&AI9VAL:6=H=&EN9PH*3B @(7MM
XM;W1I;VY]>V-O;6UA;F1]"B @(" @(" @(" @(" @("!F:6QT97(@=&AE(&QI
XM;F5S('1H870@87)E(&UO=F5D(&]V97(@=&AR;W5G:"![8V]M;6%N9'T*3B @
XM(2%[8V]M;6%N9'T*(" @(" @(" @(" @(" @(&9I;'1E<B!.(&QI;F5S('1H
XM<F]U9V@@>V-O;6UA;F1]"CI;<F%N9V5=(7MC;VUM86YD?0H@(" @(" @(" @
XM(" @(" @9FEL=&5R(%MR86YG95T@;&EN97,@=&AR;W5G:"![8V]M;6%N9'T*
XM3B @/7MM;W1I;VY]>V-O;6UA;F1]"B @(" @(" @(" @(" @("!F:6QT97(@
XM=&AE(&QI;F5S('1H870@87)E(&UO=F5D(&]V97(@=&AR;W5G:" B:6YD96YT
XM(@I.(" ]/7MC;VUM86YD?0H@(" @(" @(" @(" @(" @9FEL=&5R($X@;&EN
XM97,@=&AR;W5G:" B:6YD96YT(@HZ6W)A;F=E77-;=6)S=&ET=71E72][<&%T
XM=&5R;GTO>W-T<FEN9WTO6V==6V-="B @(" @(" @(" @(" @("!S=6)S=&ET
XM=71E('MP871T97)N?2!B>2![<W1R:6YG?2!I;B!;<F%N9V5=(&QI;F5S.R!W
XM:71H(%MG70H@(" @(" @(" @(" @(" @<F5P;&%C92!A;&P@;V-C=7)R96YC
XM97,@;V8@>W!A='1E<FY].R!W:71H(%MC72!A<VL@9FER<W0*.EMR86YG95US
XM6W5B<W1I='5T95T@6V==6V-="B @(" @(" @(" @(" @("!R97!E870@<')E
XM=FEO=7,@.G,@=VET:"!N97<@<F%N9V4@86YD(&]P=&EO;G,*(" @)B @(" @
XM(" @(" @(%)E<&5A="!P<F5V:6]U<R Z<R!O;B!C=7)R96YT(&QI;F4@=VET
XM:&]U="!O<'1I;VYS"@H, D1E;&5T:6YG('1E>'0%"DX@('@@(" @(" @(" @
XM("!D96QE=&4@3B!C:&%R86-T97)S('5N9&5R(&%N9"!A9G1E<B!T:&4@8W5R
XM<V]R"DX@(%@@(" @(" @(" @("!D96QE=&4@3B!C:&%R86-T97)S(&)E9F]R
XM92!T:&4@8W5R<V]R"DX@(&1[;6]T:6]N?2 @("!D96QE=&4@=&AE('1E>'0@
XM=&AA="!I<R!M;W9E9"!O=F5R('=I=&@@>VUO=&EO;GT*>W9I<W5A;'UD(" @
XM(" @(&1E;&5T92!T:&4@:&EG:&QI9VAT960@=&5X= I.("!D9" @(" @(" @
XM(" @9&5L971E($X@;&EN97,*3B @1" @(" @(" @(" @(&1E;&5T92!T;R!E
XM;F0@;V8@;&EN92 H86YD($XM,2!M;W)E(&QI;F5S*0I.("!*(" @(" @(" @
XM(" @:F]I;B!.+3$@;&EN97,@*&1E;&5T92!N97=L:6YE<RD*>W9I<W5A;'U*
XM(" @(" @(&IO:6X@=&AE(&AI9VAL:6=H=&5D(&QI;F5S"CI;<F%N9V5=9"!;
XM>%T@("!D96QE=&4@6W)A;F=E72!L:6YE<R!;:6YT;R!R96=I<W1E<B!X70H*
XM D-O<'EI;F<@86YD(&UO=FEN9R!T97AT!0H@(" B/&-H87(^(" @(" @=7-E
XM(')E9VES=&5R(#QC:&%R/B!F;W(@=&AE(&YE>'0@9&5L971E+"!Y86YK(&]R
XM('!U= HZ9&ES(" @(" @(" @(" @<VAO=R!T:&4@8W5R<F5N="!R96=I<W1E
XM<B!C;VYT96YT<PI.("!Y>VUO=&EO;GT@(" @>6%N:R!T:&4@=&5X="P@;6]V
XM960@;W9E<B!W:71H('MM;W1I;VY]+"!I;G1O(&$@<F5G:7-T97(*>W9I<W5A
XM;'UY(" @(" @('EA;FL@=&AE(&AI9VAL:6=H=&5D('1E>'0@:6YT;R!A(')E
XM9VES=&5R"DX@('EY(" @(" @(" @("!Y86YK($X@;&EN97,@:6YT;R!A(')E
XM9VES=&5R"DX@(%D@(" @(" @(" @("!Y86YK($X@;&EN97,@:6YT;R!A(')E
XM9VES=&5R"DX@(' @(" @(" @(" @("!P=70@82!R96=I<W1E<B!A9G1E<B!T
XM:&4@8W5R<V]R('!O<VET:6]N("A.('1I;65S*0I.("!0(" @(" @(" @(" @
XM<'5T(&$@<F5G:7-T97(@8F5F;W)E('1H92!C=7)S;W(@<&]S:71I;VX@*$X@
XM=&EM97,I"DX@(%UP(" @(" @(" @("!L:6ME(' L(&)U="!A9&IU<W0@:6YD
XM96YT('1O(&-U<G)E;G0@;&EN90I.("!;<" @(" @(" @(" @;&EK92!0+"!B
XM=70@861J=7-T(&EN9&5N="!T;R!C=7)R96YT(&QI;F4*# )297!E871I;F<@
XM8V]M;6%N9',%"DX@("X@(" @(" @(" @("!R97!E870@;&%S="!C:&%N9V4@
XM*'=I=&@@8V]U;G0@<F5P;&%C960@8GD@3BD*(" @<3QA+7H^(" @(" @(')E
XM8V]R9"!T>7!E9"!C:&%R86-T97)S(&EN=&\@<F5G:7-T97(@/&$M>CX*(" @
XM<2 @(" @(" @(" @('-T;W @<F5C;W)D:6YG"DX@($ \82UZ/B @(" @("!E
XM>&5C=71E('1H92!C;VYT96YT<R!O9B!R96=I<W1E<B \82UZ/B H3B!T:6UE
XM<RD*3B @0$ @(" @(" @(" @(')E<&5A="!P<F5V:6]U<R! /&$M>CX@*$X@
XM=&EM97,I"CI /&$M>CX@(" @(" @("!E>&5C=71E('1H92!C;VYT96YT<R!O
XM9B!R96=I<W1E<B \82UZ/B!A<R!A;B!%>"!C;VUM86YD"CI 0" @(" @(" @
XM(" @("!R97!E870@<')E=FEO=7,@.D \82UZ/@HZ6W)A;F=E76=;;&]B86Q=
XM+WMP871T97)N?2];8VUD70H@(" @(" @(" @(" @(" @17AE8W5T92!%>"!C
XM;VUM86YD(%MC;61=("AD969A=6QT(#IP*2!O;B!T:&4@;&EN97,@=VET:&EN
XM"B @(" @(" @(" @(" @("!;<F%N9V5=('=H97)E('MP871T97)N?2!M871C
XM:&5S+@HZ6W)A;F=E76=;;&]B86Q=(2][<&%T=&5R;GTO6V-M9%T*(" @(" @
XM(" @(" @(" @($5X96-U=&4@17@@8V]M;6%N9"!;8VUD72 H9&5F875L=" Z
XM<"D@;VX@=&AE(&QI;F5S('=I=&AI;@H@(" @(" @(" @(" @(" @6W)A;F=E
XM72!W:&5R92![<&%T=&5R;GT@9&]E<R!.3U0@;6%T8V@N"CIS;UMU<F-E72![
XM9FEL97T*(" @(" @(" @(" @(" @(%)E860@17@@8V]M;6%N9',@9G)O;2![
XM9FEL97TN"CIS;UMU<F-E72$@>V9I;&5]"B @(" @(" @(" @(" @("!296%D
XM(%9)32!C;VUM86YD<R!F<F]M('MF:6QE?2X*.G-L6V5E<%T@6TY;(" @(&1O
XM;B=T(&1O(&%N>71H:6YG(&9O<B!.('-E8V]N9',*3B @9W,@(" @(" @(" @
XM(&=O=&\@<VQE97 @9F]R($X@<V5C;VYD<PH, DME>2!M87!P:6YG!0HZ;6%;
XM<%T@>VQH<WT@>W)H<WT@(" @("!-87 @>VQH<WT@=&\@>W)H<WT@:6X@;F]R
XM;6%L(&UO9&4N"CIM85MP72$@>VQH<WT@>W)H<WT@(" @($UA<"![;&AS?2!T
XM;R![<FAS?2!I;B!I;G-E<G0@86YD(&-O;6UA;F0@;&EN92!M;V1E+@HZ;F];
XM<F5M87!=6R%=('ML:'-]('MR:'-]"B @(" @(" @(" @(" @(" @(" @(" @
XM(%-A;64@87,@.FUA<"P@;F\@<F5M87!P:6YG(&9O<B!T:&ES('MR:'-]"CIU
XM;FU;87!=('ML:'-](" @(" @(" @(%)E;6]V92!T:&4@;6%P<&EN9R!O9B![
XM;&AS?2!F;W(@;F]R;6%L(&UO9&4N"CIU;FU;87!=(2![;&AS?2 @(" @(" @
XM(%)E;6]V92!T:&4@;6%P<&EN9R!O9B![;&AS?2!F;W(@:6YS97)T(&%N9"!C
XM;VUM86YD"B @(" @(" @(" @(" @(" @(" @(" @(&QI;F4@;6]D92X*.FUA
XM6W!=(%ML:'-=(" @(" @(" @(" @3&ES="!M87!P:6YG<R H<W1A<G1I;F<@
XM=VET:"!;;&AS72D@9F]R(&YO<FUA;"!M;V1E+@HZ;6%;<%TA(%ML:'-=(" @
XM(" @(" @("!,:7-T(&UA<'!I;F=S("AS=&%R=&EN9R!W:71H(%ML:'-=*2!F
XM;W(@:6YS97)T(&%N9 H@(" @(" @(" @(" @(" @(" @(" @("!C;VUM86YD
XM(&QI;F4@;6]D92X*.F-M87 O.F-U;FUA<"\Z8VYO<F5M87 @;&EK92!M87 O
XM=6YM87 O;F]R96UA<"!B=70@9F]R(&-O;6UA;F0@;&EN92!M;V1E(&]N;'D*
XM.FEM87 O.FEU;FUA<"\Z:6YO<F5M87 @;&EK92!M87 O=6YM87 O;F]R96UA
XM<"!B=70@9F]R(&EN<V5R="!M;V1E(&]N;'D*.FUK6V5X<F-=6R%=(%MF:6QE
XM72 @(" @=W)I=&4@8W5R<F5N="!M87!P:6YG<RP@86)B<F5V:6%T:6]N<R!A
XM;F0@<V5T=&EN9W,*(" @(" @(" @(" @(" @(" @(" @(" @=&\@6V9I;&5=
XM("AD969A=6QT("(N97AR8R([('5S92 A('1O(&]V97)W<FET92D*.FUK=EMI
XM;7)C75LA72!;9FEL95T@(" @<V%M92!A<R Z;6ME>')C+"!B=70@=VET:"!D
XM969A=6QT("(N=FEM<F,B"@H"06)B<F5V:6%T:6]N<P4*.F%B6V)R979I871E
XM72![;&AS?2![<FAS?2 @("!A9&0@86)B<F5V:6%T:6]N(&9O<B![;&AS?2!T
XM;R![<FAS?0HZ86);8G)E=FEA=&5=('ML:'-](" @(" @(" @('-H;W<@86)B
XM<F5V:6%T:6]N<R!T:&%T('-T87)T('=I=&@@>VQH<WT*.F%B6V)R979I871E
XM72 @(" @(" @(" @(" @("!S:&]W(&%L;"!A8F)R979I871I;VYS"CIU;F%;
XM8F)R979I871E72![;&AS?2 @(" @(" @<F5M;W9E(&%B8G)E=FEA=&EO;B!F
XM;W(@>VQH<WT*.FEA8B\Z8V%B+SII=6YA8B\Z8W5N86(O.FYO<F5A8B\Z8VYO
XM<F5A8B\Z:6YO<F5A8B @("!A;'-O(&%V86EL86)L92$*# )/<'1I;VYS!0HZ
XM<V5;=%T@(" @(" @(" @(" @(" @("!3:&]W(&%L;"!M;V1I9FEE9"!O<'1I
XM;VYS+@HZ<V5;=%T@86QL(" @(" @(" @(" @("!3:&]W(&%L;"!O<'1I;VYS
XM+@HZ<V5;=%T@>V]P=&EO;GT@(" @(" @("!3970@=&]G9VQE(&]P=&EO;B!O
XM;BP@<VAO=R!S=')I;F<@;W(@;G5M8F5R(&]P=&EO;BX*.G-E6W1=(&YO>V]P
XM=&EO;GT@(" @(" @4V5T('1O9V=L92!O<'1I;VX@;V9F+@HZ<V5;=%T@:6YV
XM>V]P=&EO;GT@(" @("!I;G9E<G0@=&]G9VQE(&]P=&EO;BX*.G-E6W1=('MO
XM<'1I;VY]/7MV86QU97T@4V5T('-T<FEN9R!O<B!N=6UB97(@;W!T:6]N('1O
XM('MV86QU97TN"CIS95MT72![;W!T:6]N?3\@(" @(" @(%-H;W<@=F%L=64@
XM;V8@>V]P=&EO;GTN"@H";W!T:6]N("AS:&]R=&AA;F0I!2 @( )T>7!E!2 @
XM F1E9F%U;'0%(" @(" @(" "969F96-T!0IA=71O:6YD96YT("AA:2D@(" @
XM('1O9V=L92 @("!O9F8@("!I;G-E<G0@;6]D93H@8V]P>2!I;F1E;G0@9G)O
XM;2!P<F5V(&QI;F4*875T;W=R:71E("AA=RD@(" @("!T;V=G;&4@(" @;V9F
XM(" @=W)I=&4@=&AE(&9I;&4@=VAE;B!S=&%R=&EN9R!A(&YE=R!E9&ET"F)A
XM8VMS<&%C92 H8G,I(" @(" @;G5M8F5R(" @(# @(" @(# @<W1A;F1A<F0@
XM5FDL(#$@9&5L971E($Y,+" R(&1E;&5T92!A;&P*8F%C:W5P("AB:RD@(" @
XM(" @("!T;V=G;&4@(" @;VX@(" @8F%C:W5P(&$@9FEL92!B969O<F4@;W9E
XM<G=R:71I;F<@:70*8F%C:W5P9&ER("AB9&ER*2 @("!S=')I;F<@(" @(GXO
XM(B @56YI>"!O;FQY.B!$:7)E8W1O<GD@9F]R(&)A8VMU<"!F:6QE<PIB:6YA
XM<GD@*&)I;BD@(" @(" @('1O9V=L92 @("!O9F8@("!B:6YA<GD@9FEL92!M
XM;V1E"F)I;W-K97D@*&)K*2 @(" @(" @=&]G9VQE(" @(&]N(" @($U31$]3
XM.B!U<V4@8FEO<R!T;R!G970@8VAA<F%C=&5R<PIC;61H96EG:'0@*&-H*2 @
XM(" @(&YU;6)E<B @(" @,2 @("!N=6UB97(@;V8@;&EN97,@9F]R('1H92!C
XM;VUM86YD(&QI;F4*8V]L=6UN<R H8V\I(" @(" @("!N=6UB97(@(" @.# @
XM(" @;G5M8F5R(&]F(&-O;'5M;G,@:6X@=&AE(&1I<W!L87D*8V]M<&%T:6)L
XM92 H8W I(" @("!T;V=G;&4@(" @;V9F(" @<V5T(&]P=&EO;G,@9F]R(&UA
XM>&EM=6T@=FDM8V]M<&%T:6)I;&ET>0H, F]P=&EO;B H<VAO<G1H86YD*04@
XM(" "='EP904@( )D969A=6QT!2 @(" @(" @ F5F9F5C= 4*9&EG<F%P:" H
XM9&<I(" @(" @("!T;V=G;&4@(" @;V9F(" @96YA8FQE(#Q"4SX@9&EG<F%P
XM:',@:6X@:6YS97)T(&UO9&4*9&ER96-T;W)Y("AD:7(I(" @("!S=')I;F<@
XM(" @(B(@(" @9&ER96-T;W)Y('1O('!U="!S=V%P(&9I;&4*961C;VUP871I
XM8FQE(" @(" @("!T;V=G;&4@(" @;V9F(" @9FQA9W,@9F]R(#IS=6)S=&ET
XM=71E('1O9V=L90IE;F1O9FQI;F4@*&5O;"D@(" @('1O9V=L92 @("!O;B @
XM("!L87-T(&QI;F4@:&%S(&$@;F5W;&EN92!C:&%R86-T97(*97%U86QA;'=A
XM>7,@*&5A*2 @("!T;V=G;&4@(" @;VX@(" @=VEN9&]W<R!M861E(&5Q=6%L
XM(&AE:6=H="!A9G1E<B!O<&5N+V-L;W-E"F5Q=6%L<')G("AE<"D@(" @(" @
XM<W1R:6YG(" @(")I;F1E;G0B("!P<F]G<F%M('5S960@9F]R("<])R!C;VUM
XM86YD"F5R<F]R8F5L;',@*&5B*2 @(" @=&]G9VQE(" @(&]F9B @(')I;F<@
XM=&AE(&)E;&P@9F]R(&5R<F]R(&UE<W-A9V5S"F5R<F]R9FEL92 H968I(" @
XM(" @<W1R:6YG(" @(")!>G1E8T,N17)R(B!F:6QE(&9O<B!1=6EC:T9I>"!O
XM<'1I;VX*97)R;W)F;W)M870@*&5F;2D@("!S=')I;F<@(" @(" @(" @9F]R
XM;6%T(&]F(&5R<F]R(&UE<W-A9V5S(&9R;VT@8V]M<&EL97(*97-C:V5Y<R H
XM96LI(" @(" @("!T;V=G;&4@(" @;VX@(" @9G5N8RX@:V5Y<R!W:71H(#Q%
XM4T,^('=O<FL@:6X@:6YS97)T(&UO9&4*97AP86YD=&%B("AE="D@(" @("!T
XM;V=G;&4@(" @;V9F(" @:6YS97)T(&UO9&4Z('5S92!S<&%C97,@=&\@96YT
XM97(@82!T86(*97AR8R @(" @(" @(" @(" @("!T;V=G;&4@(" @;V9F(" @
XM<F5A9" N97AR8R\N=FEM<F,@9G)O;2!C=7)R96YT(&1I<F5C=&]R>0IF;W)M
XM871P<F<@*&9P*2 @(" @('-T<FEN9R @(" B(B @("!E>'1E<FYA;"!P<F]G
XM<F%M(&9O<B G42<@8V]M;6%N9 IG9&5F875L=" H9V0I(" @(" @('1O9V=L
XM92 @("!O9F8@("!T:&4@)V<G(&9L86<@:7,@9&5F875L="!O;B!F;W(@.G-U
XM8G-T:71U=&4*9W)A<&AI8R H9W(I(" @(" @("!T;V=G;&4@(" @;V9F(" @
XM9&ES<&QA>2!C:&%R<R P>#@P+3!X.68@9&ER96-T;'D*:&5L<&9I;&4@*&AF
XM*2 @(" @("!S=')I;F<@(" @(G9I;3IV:6TN:&QP(B @(" @;F%M92!O9B!H
XM96QP(&9I;&4*:&ED9&5N("AH:60I(" @(" @("!T;V=G;&4@(" @;V9F(" @
XM8G5F9F5R<R!B96-O;64@:&ED9&5N('=H96X@86)A;F1O;F5D"FAI9VAL:6=H
XM=" H:&PI(" @(" @<W1R:6YG(" @(")D8BQE<RQH<RQR<RQV:2QS:2(@("!W
XM:&5N('1O('5S92!H:6=L:6=H=&EN9PIH:7-T;W)Y("AH:2D@(" @(" @(&YU
XM;6)E<B @(" R," @("!N=6UB97(@;V8@<F5M96UB97)E9"!C;VUM86YD(&QI
XM;F5S"@P";W!T:6]N("AS:&]R=&AA;F0I!2 @( )T>7!E!2 @ F1E9F%U;'0%
XM(" @(" @(" "969F96-T!0II8V]N(" @(" @(" @(" @(" @('1O9V=L92 @
XM("!O9F8@("!S970@:6-O;B!T:71L92!T;R!F:6QE(&YA;64*:6=N;W)E8V%S
XM92 H:6,I(" @("!T;V=G;&4@(" @;V9F(" @:6=N;W)E(&-A<V4@:6X@<V5A
XM<F-H('!A='1E<FYS"FEN<V5R=&UO9&4@*&EM*2 @(" @=&]G9VQE(" @(&]F
XM9B @('-T87)T(&5D:71I;F<@:6X@:6YS97)T(&UO9&4*:F]I;G-P86-E<R H
XM:G,I(" @("!T;V=G;&4@(" @;VX@(" @:6YS97)T('1W;R!S<&%C97,@869T
XM97(@82 G+B<@=VET:"!J;VEN"FME>7=O<F1P<F<@*&MP*2 @(" @<W1R:6YG
XM(" @(")R968B(&YA;64@;V8@<')O9W)A;2!F;W(@)TLG(&-O;6UA;F0*;&%S
XM='-T871U<R H;',I(" @("!N=6UB97(@(" @,2 @(" @=VAE;B P(&QA<W0@
XM=VEN9&]W(&AA<R!N;R!S=&%T=7,@;&EN92P@=VAE;@H@(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @(" @(" @(" Q(&]N;'D@=VET:"!M=6QT:7!L92!W
XM:6YD;W=S+"!W:&5N(#(@86QW87ES"FQI;F5S(" @(" @(" @(" @(" @;G5M
XM8F5R(" @(#(U(" @(&YU;6)E<B!O9B!L:6YE<R!I;B!T:&4@9&ES<&QA>0IL
XM:7-T(" @(" @(" @(" @(" @('1O9V=L92 @("!O9F8@("!D:7-P;&%Y(&QI
XM;F5S(&EN(&QI<W0@;6]D90IM86=I8R @(" @(" @(" @(" @('1O9V=L92 @
XM("!O;B @("!D:69F97)E;G0@<&%T=&5R;B!M871C:&EN9R!C:&%R86-T97)S
XM"FUA:V5P<F<@*&UP*2 @(" @(" @<W1R:6YG(" @(")M86ME(B!N86UE(&]F
XM('!R;V=R86T@9F]R("<Z;6%K92<@8V]M;6%N9 IM87AM96T@*&UM*2 @(" @
XM(" @(&YU;6)E<B @(" U,3(@("!(;W<@;6%Y($MB>71E('1O('5S92!F;W(@
XM;VYE(&)U9F9E<@IM87AM96UT;W0@*&UM="D@(" @(&YU;6)E<B @(" U,3(@
XM("!(;W<@;6%Y($MB>71E('1O('5S92!F;W(@86QL(&)U9F9E<G,*;6]D96QI
XM;F4@*&UL*2 @(" @("!T;V=G;&4@(" @;VX@(" @;&EN97,@87)E(&-H96-K
XM960@9F]R('-E="!C;VUM86YD<PIM;V1E;&EN97,@*&UL<RD@(" @(&YU;6)E
XM<B @(" U(" @("!N=6UB97(@;V8@;&EN97,@8VAE8VME9"!F;W(@<V5T(&-O
XM;6UA;F1S"FUO<F4@(" @(" @(" @(" @(" @=&]G9VQE(" @(&]N(" @('!A
XM=7-E('=I=&@@;&]N9R!L:7-T:6YG<PIN=6UB97(@*&YU*2 @(" @(" @('1O
XM9V=L92 @("!O9F8@("!D:7-P;&%Y(&QI;F4@;G5M8F5R<PH, F]P=&EO;B H
XM<VAO<G1H86YD*04@(" "='EP904@( )D969A=6QT!2 @(" @(" @ F5F9F5C
XM= 4*<&%R86=R87!H<R H<&%R82D@("!S=')I;F<@(" @(DE03%!04%%04"!,
XM27!P;'!I<&)P(@H@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
XM("!N<F]F9B!M86-R;W,@=&AA="!S97!A<F%T92!P87)A9W)A<&AS"G!A<W1E
XM(" @(" @(" @(" @(" @=&]G9VQE(" @(&]F9B @('!A<W1E(&UO9&4Z(&EN
XM<V5R="!L:71E<F%L;'D*<&%T8VAM;V1E("AP;2D@(" @("!S=')I;F<@(" @
XM(B(@(" @97AT96YS:6]N('1O('5S92!W:&5N('!A=&-H:6YG(&9I;&5S"G)E
XM861O;FQY("AR;RD@(" @(" @=&]G9VQE(" @(&]F9B @(&]V97)W<FET:6YG
XM('1H92!F:6QE(&YO="!A;&QO=V5D"G)E;6%P(" @(" @(" @(" @(" @=&]G
XM9VQE(" @(&]N(" @(#IM87 @8V]M;6%N9"!W;W)K<R!R96-U<G-I=F5L>0IR
XM97!O<G0@(" @(" @(" @(" @(&YU;6)E<B @(" R(" @("!M:6YI;6%L(&YU
XM;6)E<B!O9B!L:6YE<R!F;W(@<F5P;W)T:6YG"G)E=FEN<R H<FDI(" @(" @
XM(" @=&]G9VQE(" @(&]F9B @(&EN<V5R="!C:&%R86-T97)S(')I9VAT('1O
XM(&QE9G0*<G5L97(@*')U*2 @(" @(" @("!T;V=G;&4@(" @;V9F(" @<VAO
XM=R!C=7)S;W(@<&]S:71I;VX@:6X@<W1A='5S(&QI;F4*<V-R;VQL(" @(" @
XM(" @(" @("!N=6UB97(@(" @,3(@(" @<V-R;VQL('-I>F4@9F]R($-44DPM
XM52!A;F0@0U123"U$"G-C<F]L;&IU;7 @*'-J*2 @(" @;G5M8F5R(" @(#$@
XM(" @(&UI;FEM86P@;G5M8F5R(&]F(&QI;F5S(&9O<B!S8W)O;&QI;F<*<V5C
XM=&EO;G,@*'-E8W0I(" @("!S=')I;F<@(" @(E-(3DA(($A5;FAS:"(@(" @
XM("!M86-R;W,@<V5P87)A=&EN9R!S96-T:6]N<PIS96-U<F4@(" @(" @(" @
XM(" @('1O9V=L92 @("!O9F8@("!S96-U<FET>2!C:&5C:W,@9F]R("YV:6UR
XM8R!A;F0@+F5X<F,*<VAE;&P@*'-H*2 @(" @(" @("!S=')I;F<@(" @(G-H
XM(B @<VAE;&P@=&\@=7-E(&9O<B A(&%N9" Z(2!C;VUM86YD<PIS:&5L;'!I
XM<&4@*'-H*2 @(" @('-T<FEN9R @(" @(" @("!P:7!E(&-O;6UA;F0@=&\@
XM8F4@=7-E9"!F;W(@.FUA:V4*<VAE;&QT>7!E("AS="D@(" @("!N=6UB97(@
XM(" @," @(" @:&]W('1O('5S92!T:&4@<VAE;&P@*$%M:6=A(&]N;'DI"G-H
XM:69T<F]U;F0@*'-R*2 @(" @=&]G9VQE(" @(&]F9B @(')O=6YD(&EN9&5N
XM="!T;R!S:&EF='=I9'1H('=I=&@@/B!A;F0@/ IS:&EF='=I9'1H("AS=RD@
XM(" @(&YU;6)E<B @(" X(" @("!N=6UB97(@;V8@<W!A8V5S('1O('5S92!F
XM;W(@*&%U=&\I:6YD96YT"G-H;W)T;F%M92 H<VXI(" @(" @=&]G9VQE(" @
XM(&]F9B @($U31$]3+6QI:V4@9FEL97-Y<W1E;2!B96EN9R!U<V5D"G-H;W=C
XM;60@*'-C*2 @(" @(" @=&]G9VQE(" @(&]N(" @('-H;W<@8V]M;6%N9"!I
XM;B!S=&%T=7,@;&EN90IS:&]W;6%T8V@@*'-M*2 @(" @('1O9V=L92 @("!O
XM9F8@("!S:&]W(&UA=&-H:6YG(&)R86-K970@:68@;VYE(&ES(&EN<V5R=&5D
XM"@P";W!T:6]N("AS:&]R=&AA;F0I!2 @( )T>7!E!2 @ F1E9F%U;'0%(" @
XM(" @(" "969F96-T!0IS:&]W;6]D92 H<VUD*2 @(" @('1O9V=L92 @("!O
XM;B @("!S:&]W(&EN<V5R="]R97!L86-E(&UO9&4@;65S<V%G90IS:61E<V-R
XM;VQL("AS<RD@(" @(&YU;6)E<B @(" P(" @("!M:6YI;6%L(&YR(&]F(&-O
XM;'5M;G,@9F]R(&AO<FEZ+B!S8W)O;&P*<VUA<G1I;F1E;G0@*'-I*2 @("!T
XM;V=G;&4@(" @;V9F(" @9&\@<VUA<G0@875T;VEN9&5N=&EN9PIS;6%R='1A
XM8B H<W1A*2 @(" @('1O9V=L92 @("!O9F8@("!T86(@<VEZ92!D97!E;F1S
XM(&]N('!O<VET:6]N"G-P;&ET8F5L;W<@*'-B*2 @(" @=&]G9VQE(" @(&]F
XM9B @(&-R96%T92!N97<@=VEN9&]W<R!B96QO=R!C=7)R96YT(&]N90IS=69F
XM:7AE<R H<W4I(" @(" @('-T<FEN9R @(" B+F)A:RYO+F@N:6YF;RYS=W B
XM('-U9F9I>&5S('1H870@87)E(&EG;F]R960*(" @(" @(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @(" @=VAE;B!M=6QT:7!L92!F:6QE<R!M871C:"!A
XM('=I;&1C87)D"G1A8G-T;W @*'1S*2 @(" @(" @;G5M8F5R(" @(#@@(" @
XM(&YU;6)E<B!O9B!S<&%C97,@=&AA="!A(%1!0B!C;W5N=',@9F]R"G1A9VQE
XM;F=T:" H=&PI(" @(" @;G5M8F5R(" @(# @(" @(&EF(&YO;BUZ97)O+"!T
XM86=S(&%R92!S:6=N:69I8V%N="!U<'1O"B @(" @(" @(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @(" @("!T:&ES(&YU;6)E<B!O9B!C:&%R86-T97)S
XM"G1A9W)E;&%T:79E("AT<BD@(" @=&]G9VQE(" @(&]N(" @(&9I;&4@;F%M
XM97,@:6X@=&%G<R!F:6QE(&%R92!R96QA=&EV90IT86=S(" @(" @(" @(" @
XM(" @('-T<FEN9R @(" B=&%G<R(@("!N86UE<R!O9B!T86<@9FEL97,*=&5R
XM;2 @(" @(" @(" @(" @("!S=')I;F<@(" @(F%M:6=A(B @(&YA;64@;V8@
XM=&5R;6EN86P*=&5R<V4@(" @(" @(" @(" @("!T;V=G;&4@(" @;V9F(" @
XM;6%K92!S;VUE(&UE<W-A9V5S('-H;W)T97(*=&5X=&%U=&\@*'1A*2 @(" @
XM("!T;V=G;&4@(" @;VX@(" @9&5T96-T(&QI;F4@<V5P87)A=&]R+" H<F4I
XM<V5T("=T97AT;6]D92<*=&5X=&UO9&4@*'1X*2 @(" @("!T;V=G;&4@(" @
XM;V9F(" @=7-E(#Q#4CX\3$8^(&9O<B!L:6YE('-E<&%R871O<@IT97AT=VED
XM=&@@*'1W*2 @(" @(&YU;6)E<B @(" P(" @("!M87AI;75M('=I9'1H(&]F
XM(&$@;&EN92!I;B!I;G-E<G0@;6]D90IT:6QD96]P("AT;RD@(" @(" @('1O
XM9V=L92 @("!O9F8@("!T:6QD92!B96AA=F5S(&QI:V4@86X@;W!E<F%T;W(*
XM=&EM96]U=" @(" @(" @(" @("!T;V=G;&4@(" @;VX@(" @=V%I="!O;FQY
XM("=T;2<@;7-E8R!F;W(@;6%P<&EN9W,F:V5Y(&-O9&5S"@P";W!T:6]N("AS
XM:&]R=&AA;F0I!2 @( )T>7!E!2 @ F1E9F%U;'0%(" @(" @(" "969F96-T
XM!0IT=&EM96]U=" @(" @(" @(" @('1O9V=L92 @("!O9F8@("!W86ET(&]N
XM;'D@)W1M)R!M<V5C(&9O<B!K97D@8V]D97,*=&EM96]U=&QE;B H=&TI(" @
XM("!N=6UB97(@(" @,3 P," @;6EL;&ES96-O;F1S('1O('=A:70@9F]R(&UA
XM<'!I;F=S)FME>2!C;V1E<PIT:71L92 @(" @(" @(" @(" @('1O9V=L92 @
XM("!O;B @("!S970@=VEN9&]W('1I=&QE('1O(&9I;&4@;F%M90IT='EF87-T
XM("AT9BD@(" @(" @('1O9V=L92 @("!O9F8@("!D;VXG="!U<V4@<V-R;VQL
XM(&-O;6UA;F1S(&9O<B!T97)M:6YA; IU;F1O;&5V96QS("AU;"D@(" @(&YU
XM;6)E<B @(" Q,# @("!N=6UB97(@;V8@8VAA;F=E<R!T:&%T(&-A;B!B92!U
XM;F1O;F4*(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
XM("@P(&9O<B!6:2!C;VUP871I8FEL:71Y*0IU<&1A=&5C;W5N=" H=6,I(" @
XM(&YU;6)E<B @(" R,# @("!A9G1E<B!T:&ES(&UA;GD@:V5Y(&AI=',@<W=A
XM<"!F:6QE('5P9&%T960*=7!D871E=&EM92 H=70I(" @("!N=6UB97(@(" @
XM-# P," @869T97(@=&AI<R!M86YY(&UI;"YS96,N('-W87 @9FEL92!U<&1A
XM=&5D"G9I<W5A;&)E;&P@*'9B*2 @(" @=&]G9VQE(" @(&]F9B @('5S92!V
XM:7-U86P@:6YS=&5A9"!O9B!A=61I8FQE(&)E97 *=V%R;B @(" @(" @(" @
XM(" @("!T;V=G;&4@(" @;VX@(" @=V%R;B!W:&5N(&-H86YG97,@86YD('-H
XM96QL(&-O;6UA;F0@=7-E9 IW96ER9&EN=F5R=" H=VDI(" @('1O9V=L92 @
XM("!O9F8@("!T97)M:6YA;"!H87,@82!W96ER9"!I;G9E<G0@8F5H879I;W5R
XM"G=H:6-H=W)A<" H=W<I(" @(" @;G5M8F5R(" @(#,@(" @('=H:6-H(&QE
XM9G0O<FEG:'0@;6]V92!C;VUM86YD<R!W<F%P"G=I;&1C:&%R("AW8RD@(" @
XM(" @;G5M8F5R(" @(%1!0B @(&-H87(@=7-E9"!T;R!S=&%R="!F:6QE;F%M
XM92!C;VUP;&5T:6]N"G=I;FAE:6=H=" H=V@I(" @(" @;G5M8F5R(" @(# @
XM(" @(&UI;FEM86P@;G5M8F5R(&]F(&QI;F5S(&9O<B!C=7)R96YT('=I;F1O
XM=PIW<F%P(" @(" @(" @(" @(" @('1O9V=L92 @("!O;B @("!W:&5N(&]F
XM9CH@:&]R:7IO;G1A;"!S8W)O;&QI;F<*=W)A<&UA<F=I;B H=VTI(" @("!N
XM=6UB97(@(" @," @(" @=W)A<"!T97AT('=H96X@870@*&-O;'5M;G,@+2!W
XM<F%P;6%R9VEN*0IW<F%P<V-A;B H=W,I(" @(" @('1O9V=L92 @("!O;B @
XM("!S96%R8VAE<R!W<F%P(&%R;W5N9"!T:&4@96YD(&]F('1H92!F:6QE"G=R
XM:71E86YY("AW82D@(" @(" @=&]G9VQE(" @(&]F9B @(&%L=V%Y<R!W<FET
XM92!F:6QE('=I=&AO=70@87-K:6YG"G=R:71E8F%C:W5P("AW8BD@(" @=&]G
XM9VQE(" @(&]N(" @(&)A8VMU<"!A(&9I;&4@5TA)3$4@;W9E<G=R:71I;F<@
XM:70*>6%N:V5N9&]F;&EN92 H>64I("!T;V=G;&4@(" @;V9F(" @)UDG('EA
XM;FMS(&9R;VT@8W5R<V]R('1O(&5N9"!O9B!L:6YE"@P"56YD;R]2961O(&-O
XM;6UA;F1S!0I.("!U(" @(" @(" @(" @=6YD;R!.(&QA<W0@8VAA;F=E<PI.
XM("!#5%),+5(@(" @(" @<F5D;R!.(&QA<W0@=6YD;VYE(&-H86YG97,*(" @
XM52 @(" @(" @(" @(')E<W1O<F4@;&%S="!C:&%N9V5D(&QI;F4* D5X=&5R
XM;F%L(&-O;6UA;F1S!0HZ<V@@(" @(" @(" @(" @<W1A<G0@82!S:&5L; HZ
XM(7MC;VUM86YD?2 @(" @97AE8W5T92![8V]M;6%N9'T@=VET:"!A('-H96QL
XM"B @($L@(" @(" @(" @("!L;V]K=7 @:V5Y=V]R9"!U;F1E<B!T:&4@8W5R
XM<V]R('=I=&@@)VME>7=O<F1P<F<G('!R;V=R86T* E%U:6-K9FEX(&-O;6UA
XM;F1S!0HZ8V,@6VYR72 @(" @(" @9&ES<&QA>2!E<G)O<B!;;G)=("AD969A
XM=6QT(&ES('1H92!S86UE(&%G86EN*0HZ8VX@(" @(" @(" @(" @9&ES<&QA
XM>2!T:&4@;F5X="!E<G)O<@HZ8W @(" @(" @(" @(" @9&ES<&QA>2!T:&4@
XM<')E=FEO=7,@97)R;W(*.F-L(" @(" @(" @(" @(&QI<W0@86QL(&5R<F]R
XM<PHZ8V8@(" @(" @(" @(" @<F5A9"!E<G)O<G,@9G)O;2!T:&4@9FEL92 G
XM97)R;W)F:6QE)PHZ8W$@(" @(" @(" @(" @<75I="!W:71H;W5T('=R:71I
XM;F<@86YD(')E='5R;B!E<G)O<B!C;V1E("AT;R!T:&4@8V]M<&EL97(I"CIM
XM86ME(%MA<F=S72 @("!S=&%R="!M86ME+"!R96%D(&5R<F]R<R!A;F0@:G5M
XM<"!T;R!F:7)S="!E<G)O<@H"5F%R:6]U<R!C;VUM86YD<P4*(" @0U123"U,
XM(" @(" @($-L96%R(&%N9"!R961R87<@=&AE('-C<F5E;BX*(" @0U123"U'
XM(" @(" @('-H;W<@8W5R<F5N="!F:6QE(&YA;64@*'=I=&@@<&%T:"D@86YD
XM(&-U<G-O<B!P;W-I=&EO;@H@("!#5%),+4,@(" @(" @9'5R:6YG('-E87)C
XM:&5S.B!I;G1E<G)U<'0@=&AE('-E87)C: H@(" \1$5,/B @(" @(" @=VAI
XM;&4@96YT97)I;F<@82!C;W5N=#H@9&5L971E(&QA<W0@8VAA<F%C=&5R"CIV
XM97)S(" @(" @(" @("!S:&]W(&5X86-T('9E<G-I;VX@;G5M8F5R(&]F('1H
XM:7,@5DE-"CIM;V1E($X@(" @(" @("!-4T1/4SH@<V5T('-C<F5E;B!M;V1E
XM('1O($X@*&YU;6)E<BP@0S@P+"!#-#,U,"P@971C+BD*# )#;VUM86YD(&QI
XM;F4@961I=&EN9P4*/$530SX@(" @(" @(" @(" @(&%B86YD;VX@8V]M;6%N
XM9"!L:6YE("AI9B G=VEL9&-H87(G(&ES(#Q%4T,^('1Y<&4@:70@='=I8V4I
XM"D-44DPM5B![8VAA<GT@(" @("!I;G-E<G0@>V-H87)](&QI=&5R86QL>0I#
XM5%),+58@>VYU;6)E<GT@(" @96YT97(@9&5C:6UA;"!B>71E('9A;'5E("AU
XM<"!T;R!T:')E92!D:6=I=',I"CQ#7TQ%1E0^+SQ#7U))1TA4/B!C=7)S;W(@
XM;&5F="]R:6=H= H\4T-?3$5&5#XO/%-#7U))1TA4/B @8W5R<V]R(&]N92!W
XM;W)D(&QE9G0O<FEG:'0*0U123"U"+T-44DPM12 @(" @(&-U<G-O<B!T;R!B
XM96=I;B]E;F0@;V8@8V]M;6%N9"!L:6YE"CQ"4SX@(" @(" @(" @(" @("!D
XM96QE=&4@=&AE(&-H87)A8W1E<B!I;B!F<F]N="!O9B!T:&4@8W5R<V]R"CQ$
XM14P^(" @(" @(" @(" @("!D96QE=&4@=&AE(&-H87)A8W1E<B!U;F1E<B!T
XM:&4@8W5R<V]R"D-44DPM5R @(" @(" @(" @("!D96QE=&4@=&AE('=O<F0@
XM:6X@9G)O;G0@;V8@=&AE(&-U<G-O<@I#5%),+54@(" @(" @(" @(" @<F5M
XM;W9E(&%L;"!C:&%R86-T97)S"CQ#7U50/B\\0U]$3U=./B @("!R96-A;&P@
XM;VQD97(O;F5W97(@8V]M;6%N9"!L:6YE(&9R;VT@:&ES=&]R>0H\4T-?55 ^
XM+SQ30U]$3U=./B @<F5C86QL(&]L9&5R+VYE=V5R(&-O;6UA;F0@=&AA="!S
XM=&%R=',@=VET:"!C=7)R96YT(&-O;6UA;F0*"@)#;VYT97AT('-E;G-I=&EV
XM92!C;VUP;&5T:6]N!0HG=VEL9&-H87(G(" H9&5F+B \5$%"/BD@(&1O(&-O
XM;7!L971I;VX@;VX@=&AE('!A='1E<FX@:6X@9G)O;G0@;V8@=&AE(&-U<G-O
XM<@I#5%),+40@(" @(" @(" @(" @;&ES="!A;&P@;F%M97,@=&AA="!M871C
XM:"!T:&4@<&%T=&5R;B!I;B!F<F]N="!O9B!T:&4@8W5R<V]R"D-44DPM02 @
XM(" @(" @(" @("!I;G-E<G0@86QL(&YA;65S('1H870@;6%T8V@@<&%T=&5R
XM;B!I;B!F<F]N="!O9B!C=7)S;W(*0U123"U,(" @(" @(" @(" @(&EN<V5R
XM="!L;VYG97-T(&-O;6UO;B!P87)T(&]F(&YA;65S('1H870@;6%T8V@@<&%T
XM=&5R;@I#5%),+4X@(" @(" @(" @(" @869T97(@)W=I;&1C:&%R)R!W:71H
XM(&UU;'1I<&QE(&UA=&-H97,Z(&=O('1O(&YE>'0@;6%T8V@*0U123"U0(" @
XM(" @(" @(" @(&%F=&5R("=W:6QD8VAA<B<@=VET:"!M=6QT:7!L92!M871C
XM:&5S.B!G;R!T;R!P<F5V:6]U<R!M871C: H, D5X(')A;F=E<P4*+" @(" @
XM(" @(" @(" @('-E<&%R871E<R!T=V\@;&EN92!N=6UB97)S"CL@(" @(" @
XM(" @(" @("!I9&5M+"!S970@8W5R<V]R('1O('1H92!F:7)S="!L:6YE(&YU
XM;6)E<@H*>VYU;6)E<GT@(" @(" @(&%N(&%B<V]L=71E(&QI;F4@;G5M8F5R
XM"BX@(" @(" @(" @(" @("!T:&4@8W5R<F5N="!L:6YE"B0@(" @(" @(" @
XM(" @("!T:&4@;&%S="!L:6YE(&EN('1H92!F:6QE"B4@(" @(" @(" @(" @
XM("!E<75A;"!T;R Q+"0@*'1H92!E;G1I<F4@9FEL92D*)W0@(" @(" @(" @
XM(" @('!O<VET:6]N(&]F(&UA<FL@= HO>W!A='1E<FY](" @(" @=&AE(&YE
XM>'0@;&EN92!W:&5R92![<&%T=&5R;GT@;6%T8VAE<PH_>W!A='1E<FY](" @
XM(" @=&AE('!R979I;W5S(&QI;F4@=VAE<F4@>W!A='1E<FY](&UA=&-H97,*
XM"BM;;G5M72 @(" @(" @("!A9&0@6VYU;5T@=&\@=&AE('!R96-E9&EN9R!L
XM:6YE(&YU;6)E<B H9&5F875L=" Q*0HM6VYU;5T@(" @(" @(" @<W5B=')A
XM8W0@6VYU;5T@9G)O;2!T:&4@<')E8V5D:6YG(&QI;F4@;G5M8F5R("AD969A
XM=6QT(#$I"@H"4W!E8VEA;"!%>"!C:&%R86-T97)S!0H@(" @?" @(" @(" @
XM(" @<V5P87)A=&5S('1W;R!C;VUM86YD<R H;F]T(&9O<B B.F=L;V)A;"(@
XM86YD("(Z(2(I"B @(" B(" @(" @(" @("!B96=I;G,@8V]M;65N= H@(" @
XM(UMN=6UB97)=(" @86QT97)N871E(&9I;&5N86UE(%MN=6UB97)=("AO;FQY
XM('=H97)E(&9I;&5N86UE(&ES(&5X<&5C=&5D*0H@(" @)2 @(" @(" @(" @
XM8W5R<F5N="!F:6QE;F%M92 H;VYL>2!W:&5R92!F:6QE;F%M92!I<R!E>'!E
XM8W1E9"D*(" @("4\("!O<B C/" @(&ED96TL(&)U="!W:71H;W5T(&5X=&5N
XM<VEO;@H, D5D:71I;F<@82!F:6QE!0HZ92 @(" @(" @(" @(" @(" @(" @
XM("!%9&ET('1H92!C=7)R96YT(&9I;&4L('5N;&5S<R!C:&%N9V5S(&AA=F4@
XM8F5E;B!M861E+@HZ92$@(" @(" @(" @(" @(" @(" @("!%9&ET('1H92!C
XM=7)R96YT(&9I;&4@86QW87ES+B!$:7-C87)D(&%N>2!C:&%N9V5S+@HZ95MD
XM:71=('MF:6QE?2 @(" @(" @("!%9&ET('MF:6QE?2P@=6YL97-S(&-H86YG
XM97,@:&%V92!B965N(&UA9&4N"CIE6V1I=%TA('MF:6QE?2 @(" @(" @($5D
XM:70@>V9I;&5](&%L=V%Y<RX@1&ES8V%R9"!A;GD@8VAA;F=E<RX*3B @($-4
XM4DPM7B @(" @(" @(" @(" @161I="!A;'1E<FYA=&4@9FEL92!.("AE<75I
XM=F%L96YT('1O("(Z92 C3B(I+@IG9B @;W(@768@(" @(" @(" @(" @("!%
XM9&ET('1H92!F:6QE('=H;W-E(&YA;64@:7,@=6YD97(@=&AE(&-U<G-O<@HZ
XM<'=D(" @(" @(" @(" @(" @(" @("!0<FEN="!T:&4@8W5R<F5N="!D:7)E
XM8W1O<GD@;F%M92X*.F-D(%MP871H72 @(" @(" @(" @(" @0VAA;F=E('1H
XM92!C=7)R96YT(&1I<F5C=&]R>2!T;R!;<&%T:%TN"CIF6VEL95T@(" @(" @
XM(" @(" @(" @(%!R:6YT('1H92!C=7)R96YT(&9I;&5N86UE(&%N9"!T:&4@
XM8W5R<V]R('!O<VET:6]N+@HZ9EMI;&5=('MN86UE?2 @(" @(" @("!3970@
XM=&AE(&-U<G)E;G0@9FEL96YA;64@=&\@>VYA;65]+@HZ9FEL97,@(" @(" @
XM(" @(" @(" @("!3:&]W(&%L=&5R;F%T92!F:6QE(&YA;65S+@H*# )5<VEN
XM9R!T:&4@9FEL92!L:7-T!0HZ87);9W-=(" @(" @(" @(" @(" @("!0<FEN
XM="!T:&4@9FEL92!L:7-T+"!W:71H('1H92!C=7)R96YT(&9I;&4@:6X@(EM=
XM(BX*.F%L;" @;W(@.G-A;&P@(" @(" @(" @3W!E;B!A('=I;F1O=R!F;W(@
XM979E<GD@9FEL92X*.G=N6V5X=%U;(5T@(" @(" @(" @(" @5W)I=&4@9FEL
XM92!A;F0@961I="!N97AT(&9I;&4N"CIW;EME>'1=6R%=('MF:6QE?2 @(" @
XM(%=R:71E('1O('MF:6QE?2!A;F0@961I="!N97AT(&9I;&4L('5N;&5S<R![
XM9FEL97T*(" @(" @(" @(" @(" @(" @(" @(" @97AI<W1S+B!7:71H("$@
XM;W9E<G=R:71E(&5X:7-T:6YG(&9I;&5S+@HZ=TY;97AT75LA72!;9FEL95T@
XM(" @("!7<FET92!F:6QE(&%N9"!E9&ET('!R979I;W5S(&9I;&4N"@H":6X@
XM8W5R<F5N="!W:6YD;W<%(" @( )I;B!N97<@=VEN9&]W!0HZ87)G=5MM96YT
XM72!.(" @(" @(" Z<V%R6V=U;65N=%T@3B @(" @(" @161I="!F:6QE($X*
XM.FY;97AT72 @(" @(" @(" @(" @.G-N6V5X=%T@(" @(" @(" @(" @($5D
XM:70@;F5X="!F:6QE"CIN6V5X=%T@>V9I;&5L:7-T?2 @(#IS;EME>'1=('MF
XM:6QE;&ES='T@("!D969I;F4@;F5W(&QI<W0@;V8@9FEL97,@86YD(&5D:70*
XM(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
XM(" @=&AE(&9I<G-T(&]N90HZ3EME>'1=(" @(" @(" @(" @(" Z<TY;97AT
XM72 @(" @(" @(" @(" @161I="!P<F5V:6]U<R!F:6QE"CIR97=;:6YD75LA
XM72 @(" @(" @(#IS<F5W6VEN9%T@(" @(" @(" @("!%9&ET(&9I<G-T(&9I
XM;&4*.FQA<W0@(" @(" @(" @(" @(" @.G-L87-T(" @(" @(" @(" @(" @
XM($5D:70@;&%S="!F:6QE"@H, E=R:71I;F<@86YD('%U:71T:6YG!0HZ6W)A
XM;F=E77=;<FET95U;(5T@(" @("!7<FET92!T;R!T:&4@8W5R<F5N="!F:6QE
XM+@HZ6W)A;F=E77=;<FET95T@>V9I;&5]("!7<FET92!T;R![9FEL97TL('5N
XM;&5S<R!I="!A;')E861Y(&5X:7-T<RX*.EMR86YG95UW6W)I=&5=(2![9FEL
XM97T@5W)I=&4@=&\@>V9I;&5]+B!/=F5R=W)I=&4@86X@97AI<W1I;F<@9FEL
XM92X*.EMR86YG95UW6W)I=&5=6R%=(#X^(" @07!P96YD('1O('1H92!C=7)R
XM96YT(&9I;&4N"CI;<F%N9V5==UMR:71E75LA72 ^/B![9FEL97T*(" @(" @
XM(" @(" @(" @(" @(" @(" @07!P96YD('1O('MF:6QE?2X*.EMR86YG95UW
XM6W)I=&5=("%[8VUD?2 @17AE8W5T92![8VUD?2!W:71H(%MR86YG95T@;&EN
XM97,@87,@<W1A;F1A<F0@:6YP=70N"CIW86QL6R%=(" @(" @(" @(" @(" @
XM('=R:71E(&%L;"!C:&%N9V5D(&)U9F9E<G,*"CIQ6W5I=%T@(" @(" @(" @
XM(" @(" @(%%U:70L('5N;&5S<R!C:&%N9V5S(&AA=F4@8F5E;B!M861E+@HZ
XM<5MU:71=(2 @(" @(" @(" @(" @("!1=6ET(&%L=V%Y<RP@9&ES8V%R9"!A
XM;GD@8VAA;F=E<RX*.G%A;&Q;(5T@(" @(" @(" @(" @(" @97AI="P@86QS
XM;R!W:&5N(&)U9F9E<G,@86YD('=I;F1O=W,@;W!E;@HZ8W$@(" @(" @(" @
XM(" @(" @(" @("!1=6ET('=I=&AO=70@=W)I=&EN9R!A;F0@<F5T=7)N(&5R
XM<F]R(&-O9&4*.G=Q6R%=(" @(" @(" @(" @(" @(" @5W)I=&4@=&AE(&-U
XM<G)E;G0@9FEL92!A;F0@97AI="X*.G=Q6R%=('MF:6QE?2 @(" @(" @(" @
XM5W)I=&4@=&\@>V9I;&5](&%N9"!E>&ET+@HZ>%MI=%U;(5T@6V9I;&5=(" @
XM(" @("!,:6ME("(Z=W$B(&)U="!W<FET92!O;FQY('=H96X@8VAA;F=E<R!H
XM879E(&)E96X@;6%D90H@("!:6B @(" @(" @(" @(" @(" @("!386UE(&%S
XM("(Z>"(N"CIX86QL6R%=("!O<B Z=W%A;&Q;(5T@('=R:71E(&%L;"!C:&%N
XM9V5D(&)U9F9E<G,@86YD(&5X:70*"CIS=%MO<%U;(5T@(" @(" @(" @(" @
XM('-U<W!E;F0@5DE-(&]R('-T87)T(&YE=R!S:&5L;"X@268@)V%W)R!O<'1I
XM;VX@:7,@<V5T"B @(" @(" @(" @(" @(" @(" @(" @(&%N9"!;(5T@;F]T
XM(&=I=F5N('=R:71E('1H92!B=69F97(N"D-44DPM6B @(" @(" @(" @(" @
XM(" @('-A;64@87,@(CIS=&]P(2(*# )3=&%R=&EN9R!624T%"G9I;2!;;W!T
XM:6]N<UT@(" @(" @(" @('-T87)T(&5D:71I;F<@=VET:"!A;B!E;7!T>2!B
XM=69F97(*=FEM(%MO<'1I;VYS72![9FEL92 N+GT@<W1A<G0@961I=&EN9R!O
XM;F4@;W(@;6]R92!F:6QE<PIV:6T@6V]P=&EO;G-=("UT('MT86=]("!E9&ET
XM('1H92!F:6QE(&%S<V]C:6%T960@=VET:"![=&%G?0IV:6T@6V]P=&EO;G-=
XM("UE(%MF;F%M95T@<W1A<G0@961I=&EN9R!I;B!1=6EC:T9I>"!M;V1E+"!D
XM:7-P;&%Y('1H92!F:7)S="!E<G)O<@H"3W!T:6]N<P4**UMN=6U=(" @(" @
XM(" @(" @(" @(" @<'5T('1H92!C=7)S;W(@870@;&EN92!;;G5M72 H9&5F
XM875L="!L87-T(&QI;F4I"BLO>W!A='T@>V9I;&4@+BY](" @(" @('!U="!T
XM:&4@8W5R<V]R(&%T('1H92!F:7)S="!O8V-U<G)E;F-E(&]F('MP871]"BUV
XM(" @(" @(" @(" @(" @(" @(" @(')E860M;VYL>2!M;V1E("A6:65W*2P@
XM:6UP;&EE<R M;@HM8B @(" @(" @(" @(" @(" @(" @("!B:6YA<GD@;6]D
XM90HM<B @(" @(" @(" @(" @(" @(" @("!R96-O=F5R(&%B;W)T960@961I
XM="P@=7-I;F<@(BYS=W B(&9I;&4*+6X@(" @(" @(" @(" @(" @(" @(" @
XM9&\@;F]T(&-R96%T92 B+G-W<"(@9FEL90HM;R!;3ET@(" @(" @(" @(" @
XM(" @("!O<&5N($X@=VEN9&]W<R H9&5F875L=#H@;VYE(&9O<B!E86-H(&9I
XM;&4I"BUX(" @(" @(" @(" @(" @(" @(" @(&1O(&YO="!R97-T87)T(%9)
XM32!T;R!O<&5N(&$@=VEN9&]W("AF;W(@92YG+B!M86EL*0HM<R![<V-R:7!T
XM:6Y](" @(" @(" @("!F:7)S="!R96%D('1H92!C;VUM86YD<R!I;B!T:&4@
XM9FEL92![<V-R:7!T:6Y]"BUW('MS8W)I<'1O=71](" @(" @(" @('=R:71E
XM(&%L;"!T>7!E9"!C:&%R86-T97)S('1O('1H92!F:6QE('MS8W)I<'1O=71]
XM"BU4('MT97)M:6YA;'T@(" @(" @(" @('-E="!T97)M:6YA;"!T>7!E"BUD
XM('MD979I8V5](" @(" @(" @(" @(&]P96X@>V1E=FEC97T@=&\@8F4@=7-E
XM9"!A<R!A(&-O;G-O;&4*"@)!=71O;6%T:6,@;W!T:6]N('-E='1I;F<@=VAE
XM;B!E9&ET:6YG(&$@9FEL904*=FEM.GMS970M87)G?3H@+BX@(" @(" @26X@
XM=&AE(&9I<G-T(&%N9"!L87-T(&QI;F5S(&]F('1H92!F:6QE("AS964@)VUL
XM)PH@(" @(" @(" @(" @(" @(" @(" @("!O<'1I;VXI+"![<V5T+6%R9WT@
XM:7,@9VEV96X@87,@86X@87)G=6UE;G0@=&\@.G-E= H, DUU;'1I('=I;F1O
XM=R!F=6YC=&EO;G,%"D-44DPM5R!S("!O<B Z<W!L:70@(" @(%-P;&ET('=I
XM;F1O=R!I;B!T=V\@<&%R=',*.G-P;&ET(#QF:6QE/B @(" @(" @(" @4W!L
XM:70@=VEN9&]W(&%N9"!E9&ET(#QF:6QE/B!I;B!O;F4@;V8@=&AE;0I#5%),
XM+5<@72 @(" @(" @(" @(" @("!3<&QI="!W:6YD;W<@86YD(&IU;7 @=&\@
XM=&%G('5N9&5R(&-U<G-O<@I#5%),+5<@9B @(" @(" @(" @(" @("!3<&QI
XM="!W:6YD;W<@86YD(&5D:70@9FEL92!N86UE('5N9&5R('1H92!C=7)S;W(*
XM0U123"U7(&X@(&]R(#IN97<@(" @(" @0W)E871E(&YE=R!E;7!T>2!W:6YD
XM;W<*0U123"U7('$@(&]R(#IQ6W5I=%T@(" @475I="!E9&ET:6YG(&%N9"!C
XM;&]S92!W:6YD;W<*0U123"U7(&,@(&]R(#IC;%MO<V5=(" @36%K92!B=69F
XM97(@:&ED9&5N(&%N9"!C;&]S92!W:6YD;W<*0U123"U7(&\@(&]R(#IO6VYL
XM>5T@(" @36%K92!C=7)R96YT('=I;F1O=R!O;FQY(&]N92!O;B!T:&4@<V-R
XM965N"@I#5%),+5<@:B @(" @(" @(" @(" @("!-;W9E(&-U<G-O<B!T;R!W
XM:6YD;W<@8F5L;W<*0U123"U7(&L@(" @(" @(" @(" @(" @36]V92!C=7)S
XM;W(@=&\@=VEN9&]W(&%B;W9E"D-44DPM5R!#5%),+5<@(" @(" @(" @($UO
XM=F4@8W5R<V]R('1O(&YE>'0@=VEN9&]W("AW<F%P(&%R;W5N9"D*0U123"U7
XM(' @(" @(" @(" @(" @(" @36]V92!C=7)S;W(@=&\@<')E=FEO=7,@86-T
XM:79E('=I;F1O=PH*0U123"U7('(@(" @(" @(" @(" @(" @4F]T871E('=I
XM;F1O=W,@9&]W;G=A<F1S"D-44DPM5R!2(" @(" @(" @(" @(" @(%)O=&%T
XM92!W:6YD;W=S('5P=V%R9',*0U123"U7('@@(" @(" @(" @(" @(" @17AC
XM:&%N9V4@8W5R<F5N="!W:6YD;W<@=VET:"!N97AT(&]N90H*0U123"U7(#T@
XM(" @(" @(" @(" @(" @36%K92!A;&P@=VEN9&]W<R!E<75A;"!H96EG:'0*
XM0U123"U7("T@(" @(" @(" @(" @(" @9&5C<F5A<V4@8W5R<F5N="!W:6YD
XM;W<@:&5I9VAT"D-44DPM5R K(" @(" @(" @(" @(" @(&EN8W)E87-E(&-U
XM<G)E;G0@=VEN9&]W(&AE:6=H= I#5%),+5<@7R @(" @(" @(" @(" @("!3
XM970@8W5R<F5N="!W:6YD;W<@:&5I9VAT("AD969A=6QT.B!V97)Y(&AI9V@I
XM"@P"0G5F9F5R(&QI<W0@9G5N8W1I;VYS!0HZ8G5F9F5R<R @;W(@.F9I;&5S
XM(" @("!L:7-T(&%L;"!K;F]W;B!B=69F97(@86YD(&9I;&4@;F%M97,*"CIB
XM86QL(" @("!O<B Z<V)A;&P@(" @(&5D:70@86QL(&%R9W,O8G5F9F5R<PHZ
XM=6YH:61E(" @;W(@.G-U;FAI9&4@("!E9&ET(&%L;"!L;V%D960@8G5F9F5R
XM<PH* FEN(&-U<G)E;G0@=VEN9&]W!2 @(" @ FEN(&YE=R!W:6YD;W<%"CI;
XM3EUB=69F97(@6TY=(" @(" @(#I;3EUS8G5F9F5R(%M.72 @(" @("!T;R!A
XM<F<O8G5F($X*.EM.76)N97AT(%M.72 @(" @(" @.EM.77-B;F5X="!;3ET@
XM(" @(" @('1O($YT:"!N97AT(&%R9R]B=68*.EM.76).97AT(%M.72 @(" @
XM(" @.EM.77-B3F5X="!;3ET@(" @(" @('1O($YT:"!P<F5V:6]U<R!A<F<O
XM8G5F"CI;3EUB<')E=FEO=7,@6TY=(" @(#I;3EUS8G!R979I;W5S(%M.72 @
XM("!T;R!.=&@@<')E=FEO=7,@87)G+V)U9@HZ8G)E=VEN9" @(" @(" @(" @
XM(" Z<V)R97=I;F0@(" @(" @(" @(" @=&\@9FER<W0@87)G+V)U9@HZ8FQA
XM<W0@(" @(" @(" @(" @(" Z<V)L87-T(" @(" @(" @(" @(" @=&\@;&%S
XM="!A<F<O8G5F"CI;3EUB;6]D(%M.72 @(" @(" @(#I;3EUS8FUO9"!;3ET@
XM(" @(" @("!T;R!.=&@@;6]D:69I960@8G5F"@HZ8G5N;&]A9%LA72!;3ET@
XM(" @(" @(" @=6YL;V%D(&)U9F9E<B!;3ET@9G)O;2!M96UO<GD*.F)D96QE
XM=&5;(5T@6TY=(" @(" @(" @('5N;&]A9"!B=69F97(@6TY=(&%N9"!D96QE
X;=&4@:70@9G)O;2!T:&4@8G5F9F5R(&QI<W0*
X
Xend
END_OF_FILE
if test 43036 -ne `wc -c <'vim/doc/vim.hlp.UU'`; then
echo shar: \"'vim/doc/vim.hlp.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/doc/vim.hlp'\" \(31212 characters\)
cat vim/doc/vim.hlp.UU | uudecode
if test 31212 -ne `wc -c <'vim/doc/vim.hlp'`; then
echo shar: \"'vim/doc/vim.hlp'\" uudecoded with wrong size!
else
rm vim/doc/vim.hlp.UU
fi
fi
# end of 'vim/doc/vim.hlp.UU'
fi
if test -f 'vim/src/buffer.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/buffer.c'\"
else
echo shar: Extracting \"'vim/src/buffer.c'\" \(22119 characters\)
sed "s/^X//" >'vim/src/buffer.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.

X */
X
X/*
X * buffer.c: functions for dealing with the buffer structure
X */
X
X/*
X * The buffer list is a double linked list of all buffers.
X * Each buffer can be in one of these states:
X * never loaded: b_neverloaded == TRUE, only the file name is valid
X * not loaded: b_ml.ml_mfp == NULL, no memfile allocated
X * hidden: b_nwindows == 0, loaded but not displayed in a window
X * normal: loaded and displayed in a window
X *
X * Instead of storing file names all over the place, each file name is
X * stored in the buffer list. It can be referenced by a number.
X *
X * The current implementation remembers all file names ever used.


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic void enter_buffer __ARGS((BUF *));
Xstatic BUF *buflist_findname __ARGS((char_u *));
Xstatic BUF *buflist_findnr __ARGS((int));
Xstatic void buflist_setlnum __ARGS((BUF *, linenr_t));
Xstatic linenr_t buflist_findlnum __ARGS((BUF *));
X
X/*
X * Open current buffer, that is: open the memfile and read the file into memory


X * return FAIL for failure, OK otherwise
X */
X int

Xopen_buffer()
X{
X if (readonlymode && curbuf->b_filename != NULL)
X curbuf->b_p_ro = TRUE;
X if (ml_open() == FAIL)
X {
X /*
X * There MUST be a memfile, otherwise we can't do anything
X * If we can't create one for the current buffer, take another buffer
X */
X close_buffer(curbuf, FALSE, FALSE);
X for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
X if (curbuf->b_ml.ml_mfp != NULL)
X break;
X /*
X * if there is no memfile at all, exit
X * This is OK, since there are no changes to loose.
X */
X if (curbuf == NULL)
X {
X EMSG("Cannot allocate buffer, exiting...");
X getout(2);
X }
X EMSG("Cannot allocate buffer, using other one...");
X enter_buffer(curbuf);
X return FAIL;
X }
X if (curbuf->b_filename != NULL)
X {
X if (readfile(curbuf->b_filename, curbuf->b_sfilename, (linenr_t)0,
X TRUE, (linenr_t)0, MAXLNUM) == FAIL)
X return FAIL;
X }
X else
X MSG("Empty Buffer");
X UNCHANGED(curbuf);
X curbuf->b_neverloaded = FALSE;
X return OK;
X}
X
X/*
X * Close the link to a buffer. If "free_buf" is TRUE free the buffer if it
X * becomes unreferenced. The caller should get a new buffer very soon!
X * if 'remove' is TRUE, remove the buffer from the buffer list.
X */
X void
Xclose_buffer(buf, free_buf, remove)
X BUF *buf;
X int free_buf;
X int remove;
X{
X if (buf->b_nwindows > 0)
X --buf->b_nwindows;
X if (buf->b_nwindows > 0 || !free_buf)
X {
X if (buf == curbuf)
X u_sync(); /* sync undo before going to another buffer */
X return;
X }
X
X buf_freeall(buf); /* free all things allocated for this buffer */
X /*
X * If there is no file name, remove the buffer from the list
X */
X if (buf->b_filename == NULL || remove)
X {
X free(buf->b_filename);
X free(buf->b_sfilename);
X if (buf->b_prev == NULL)
X firstbuf = buf->b_next;
X else
X buf->b_prev->b_next = buf->b_next;
X if (buf->b_next == NULL)
X lastbuf = buf->b_prev;
X else
X buf->b_next->b_prev = buf->b_prev;
X free(buf);
X }
X else
X buf_clear(buf);
X}
X
X/*
X * buf_clear() - make buffer empty
X */
X void
Xbuf_clear(buf)
X BUF *buf;
X{


X buf->b_ml.ml_line_count = 1;

X buf->b_changed = FALSE;
X#ifndef MSDOS
X buf->b_shortname = FALSE;
X#endif
X buf->b_p_eol = TRUE;
X buf->b_ml.ml_mfp = NULL;
X buf->b_ml.ml_flags = ML_EMPTY; /* empty buffer */
X}
X
X/*
X * buf_freeall() - free all things allocated for the buffer
X */
X void
Xbuf_freeall(buf)
X BUF *buf;
X{
X u_blockfree(buf); /* free the memory allocated for undo */
X ml_close(buf); /* close and delete the memline/memfile */
X buf->b_ml.ml_line_count = 0; /* no lines in buffer */
X u_clearall(buf); /* reset all undo information */
X}
X
X/*
X * Implementation of the command for the buffer list
X */
X int
Xdo_buffer(action, start, dir, count, forceit)
X int action; /* 0 = normal, 1 = split window, 2 = unload, 3 = delete */
X int start; /* 0 = current, 1 = first, 2 = last, 3 = modified */
X int dir; /* FORWARD or BACKWARD */
X int count; /* buffer number or number of buffers */
X int forceit; /* TRUE for :bdelete! */
X{
X BUF *buf;
X int retval;
X
X switch (start)
X {
X case 0: buf = curbuf;
X break;
X case 1: buf = firstbuf;
X break;
X case 2: buf = curbuf;
X while (buf->b_next != NULL)
X buf = buf->b_next;
X break;
X default: buf = curbuf;
X break;
X }
X if (start == 3) /* find next modified buffer */
X {
X while (count-- > 0)
X {
X do
X {
X buf = buf->b_next;


X if (buf == NULL)

X buf = firstbuf;
X }
X while (buf != curbuf && !buf->b_changed);
X }
X if (!buf->b_changed)
X {
X EMSG("No modified buffer found");


X return FAIL;
X }
X }

X else if (start == 1 && count) /* find specified buffer number */
X {
X while (buf != NULL && buf->b_fnum != count)
X buf = buf->b_next;
X }
X else
X {
X while (buf != NULL && count-- > 0)
X {
X if (dir == FORWARD)
X buf = buf->b_next;
X else
X buf = buf->b_prev;
X }
X }
X if (buf == NULL) /* could not find it */
X {
X if (start == 1)
X EMSG2("Cannot go to buffer %ld", (char_u *)count);
X else if (dir == FORWARD)
X EMSG("Cannot go beyond last buffer");
X else
X EMSG("Cannot go before first buffer");
X return FAIL;
X }
X /*
X * delete buffer buf from memory and/or the list
X */
X if (action == 2 || action == 3)
X {
X if (buf->b_nwindows > 1 || (buf != curbuf && buf->b_nwindows != 0))
X {
X EMSG2("Other window editing buffer %ld", (char_u *)buf->b_fnum);
X return FAIL;
X }
X if (!forceit && buf->b_changed)
X {
X EMSG2("No write since last change for buffer %ld (use ! to override)",
X (char_u *)buf->b_fnum);
X return FAIL;
X }
X /*
X * if deleting last buffer, make it empty
X */
X if (firstbuf->b_next == NULL)
X {
X buf = curbuf;
X retval = doecmd(NULL, NULL, NULL, FALSE, (linenr_t)1);
X /* the doecmd() may create a new buffer, then we have to
X * delete the old one */
X if (action == 3 && buf != curbuf)
X close_buffer(buf, TRUE, action == 3);
X return retval;
X }
X /*
X * If deleted buffer is not current one, delete it here.
X * Otherwise find buffer to go to and delete it below.
X */
X {


X if (buf != curbuf)
X {

X close_buffer(buf, TRUE, action == 3);
X return OK;
X }
X if (buf->b_next != NULL)
X buf = buf->b_next;
X else
X buf = buf->b_prev;
X }
X }
X/*
X * make buf current buffer
X */
X if (action == 1) /* split window first */
X {
X if (win_split(0L, FALSE) == FAIL)
X return FAIL;
X }
X buflist_altlnum(); /* remember curpos.lnum */
X close_buffer(curbuf, action == 2 || action == 3, action == 3);
X enter_buffer(buf);


X return OK;
X}
X
X/*

X * enter a new current buffer.
X * (old curbuf must have been freed already)


X */
X static void

Xenter_buffer(buf)
X BUF *buf;
X{
X int need_fileinfo = TRUE;
X
X if (buf->b_neverloaded)
X {
X buf_copy_options(curbuf, buf);
X buf->b_neverloaded = FALSE;
X }


X curwin->w_buffer = buf;
X curbuf = buf;

X ++curbuf->b_nwindows;
X if (curbuf->b_ml.ml_mfp == NULL) /* need to load the file */
X {
X open_buffer();
X need_fileinfo = FALSE;
X }
X buflist_getlnum(); /* restore curpos.lnum */
X maketitle();
X updateScreen(NOT_VALID);
X if (need_fileinfo)
X fileinfo(did_cd);
X}
X
X/*
X * functions for dealing with the buffer list
X */
X
X/*
X * Add a file name to the buffer list. Return a pointer to the buffer.
X * If the same file name already exists return a pointer to that buffer.
X * If it does not exist, or if fname == NULL, a new entry is created.
X * If use_curbuf is TRUE, may use current buffer.
X * This is the ONLY way to create a new buffer.
X */
X BUF *
Xbuflist_new(fname, sfname, lnum, use_curbuf)


X char_u *fname;
X char_u *sfname;

X linenr_t lnum;
X int use_curbuf;
X{
X static int top_file_num = 1; /* highest file number */
X BUF *buf;
X
X fname_expand(&fname, &sfname);
X
X/*
X * If file name already exists in the list, update the entry
X */
X if (fname != NULL && (buf = buflist_findname(fname)) != NULL)
X {
X if (lnum != 0)
X buflist_setlnum(buf, lnum);
X if (buf->b_neverloaded && curbuf != NULL && buf != curbuf)
X buf_copy_options(curbuf, buf);
X return buf;
X }
X
X/*
X * If the current buffer has no name and no contents, use the current buffer.
X * Otherwise: Need to allocate a new buffer structure.
X *
X * This is the ONLY place where a new buffer structure is allocated!
X */
X if (use_curbuf && curbuf != NULL && curbuf->b_filename == NULL &&
X curbuf->b_nwindows <= 1 &&
X (curbuf->b_ml.ml_mfp == NULL || curbuf->b_ml.ml_flags == ML_EMPTY))
X buf = curbuf;
X else
X {


X buf = (BUF *)alloc((unsigned)sizeof(BUF));

X if (buf == NULL)

X return NULL;
X memset((char *)buf, 0, sizeof(BUF));
X }
X
X if (fname != NULL)
X {
X buf->b_filename = strsave(fname);
X buf->b_sfilename = strsave(sfname);
X }
X if (buf->b_winlnum == NULL)
X buf->b_winlnum = (WINLNUM *)alloc((unsigned)sizeof(WINLNUM));
X if ((fname != NULL && (buf->b_filename == NULL || buf->b_sfilename == NULL)) ||
X buf->b_winlnum == NULL)
X {
X free(buf->b_filename);
X buf->b_filename = NULL;
X free(buf->b_sfilename);
X buf->b_sfilename = NULL;


X if (buf != curbuf)
X {

X free(buf->b_winlnum);
X free(buf);


X }
X return NULL;
X }
X

X if (buf == curbuf)
X {
X buf_freeall(buf); /* free all things allocated for this buffer */
X buf->b_nwindows = 0;
X }
X else
X {
X if (curbuf != NULL) /* don't do this for first buffer */
X buf_copy_options(curbuf, buf);
X
X /*
X * put new buffer at the end of the buffer list
X */
X buf->b_next = NULL;
X if (firstbuf == NULL) /* buffer list is empty */
X {
X buf->b_prev = NULL;
X firstbuf = buf;
X }
X else /* append new buffer at end of the list */
X {
X lastbuf->b_next = buf;
X buf->b_prev = lastbuf;
X }
X lastbuf = buf;
X
X buf->b_fnum = top_file_num++;
X if (top_file_num < 0) /* wrap around (may cause duplicates) */
X {
X EMSG("Warning: List of file names overflow");
X sleep(3); /* make sure it is noticed */
X top_file_num = 1;
X }
X
X buf->b_winlnum->wl_lnum = lnum;
X buf->b_winlnum->wl_next = NULL;
X buf->b_winlnum->wl_prev = NULL;
X buf->b_winlnum->wl_win = curwin;
X }
X
X if (did_cd)
X buf->b_xfilename = buf->b_filename;
X else
X buf->b_xfilename = buf->b_sfilename;
X buf->b_u_synced = TRUE;
X buf->b_neverloaded = TRUE;
X buf_clear(buf);
X clrallmarks(buf); /* clear marks */
X
X return buf;
X}
X
X/*
X * get alternate file n
X * set linenr to lnum or altlnum if lnum == 0
X * if (setpm) setpcmark
X * return FAIL for failure, OK for success
X */
X int
Xbuflist_getfile(n, lnum, setpm)
X int n;
X linenr_t lnum;
X int setpm;


X{
X BUF *buf;
X

X buf = buflist_findnr(n);


X if (buf == NULL)

X {
X emsg(e_noalt);
X return FAIL;
X }
X if (lnum == 0)
X lnum = buflist_findlnum(buf); /* altlnum may be changed by getfile() */
X RedrawingDisabled = TRUE;
X if (getfile(buf->b_filename, buf->b_sfilename, setpm, lnum) <= 0)
X {
X RedrawingDisabled = FALSE;
X return OK;
X }
X RedrawingDisabled = FALSE;


X return FAIL;
X}
X

X/*
X * go to the last know line number for the current buffer
X */
X void
Xbuflist_getlnum()
X{
X linenr_t lnum;
X


X curwin->w_cursor.lnum = 1;

X curwin->w_cursor.col = 0;

X lnum = buflist_findlnum(curbuf);
X if (lnum != 0 && lnum <= curbuf->b_ml.ml_line_count)


X curwin->w_cursor.lnum = lnum;
X}

X
X/*
X * find file in buffer list by name (it has to be for the current window)
X * 'fname' must have a full path.
X */
X static BUF *
Xbuflist_findname(fname)
X char_u *fname;


X{
X BUF *buf;
X

X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X if (buf->b_filename != NULL && fnamecmp(fname, buf->b_filename) == 0)
X return (buf);


X return NULL;
X}
X
X/*

X * find file in buffer name list by number
X */
X static BUF *
Xbuflist_findnr(nr)
X int nr;


X{
X BUF *buf;
X

X if (nr == 0)
X nr = curwin->w_alt_fnum;


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X if (buf->b_fnum == nr)
X return (buf);


X return NULL;
X}
X
X/*

X * get name of file 'n' in the buffer list
X */
X char_u *
Xbuflist_nr2name(n)
X int n;
X{
X BUF *buf;
X char_u *fname;
X
X buf = buflist_findnr(n);


X if (buf == NULL)

X return NULL;
X fname = did_cd ? buf->b_filename : buf->b_sfilename;
X home_replace(fname, NameBuff, MAXPATHL);
X return NameBuff;
X}
X
X/*
X * set the lnum for the buffer 'buf' and the current window


X */
X static void

Xbuflist_setlnum(buf, lnum)
X BUF *buf;
X linenr_t lnum;
X{
X WINLNUM *wlp;
X
X for (wlp = buf->b_winlnum; wlp != NULL; wlp = wlp->wl_next)
X if (wlp->wl_win == curwin)
X break;
X if (wlp == NULL) /* make new entry */
X {
X wlp = (WINLNUM *)alloc((unsigned)sizeof(WINLNUM));
X if (wlp == NULL)
X return;
X wlp->wl_win = curwin;
X }
X else /* remove entry from list */
X {
X if (wlp->wl_prev)
X wlp->wl_prev->wl_next = wlp->wl_next;
X else
X buf->b_winlnum = wlp->wl_next;
X if (wlp->wl_next)
X wlp->wl_next->wl_prev = wlp->wl_prev;
X }
X wlp->wl_lnum = lnum;
X/*
X * insert entry in front of the list
X */
X wlp->wl_next = buf->b_winlnum;
X buf->b_winlnum = wlp;
X wlp->wl_prev = NULL;
X if (wlp->wl_next)
X wlp->wl_next->wl_prev = wlp;
X
X return;
X}
X
X/*
X * find the lnum for the buffer 'buf' for the current window


X */
X static linenr_t

Xbuflist_findlnum(buf)
X BUF *buf;
X{
X WINLNUM *wlp;
X
X for (wlp = buf->b_winlnum; wlp != NULL; wlp = wlp->wl_next)
X if (wlp->wl_win == curwin)
X break;
X
X if (wlp == NULL) /* if no lnum for curwin, use the first in the list */
X wlp = buf->b_winlnum;
X
X if (wlp)
X return wlp->wl_lnum;
X else
X return (linenr_t)1;
X}
X
X/*
X * list all know file names (for :files and :buffers command)
X */
X void
Xbuflist_list()
X{
X BUF *buf;
X int len;
X
X gotocmdline(TRUE, NUL);
X for (buf = firstbuf; buf != NULL && !got_int; buf = buf->b_next)
X {
X if (buf != firstbuf)
X msg_outchar('\n');
X if (buf->b_xfilename == NULL)
X STRCPY(NameBuff, "No File");
X else
X /* careful: home_replace calls vimgetenv(), which uses IObuff! */
X home_replace(buf->b_xfilename, NameBuff, MAXPATHL);
X
X sprintf((char *)IObuff, "%3d %c%c%c \"",
X buf->b_fnum,
X buf == curbuf ? '%' :
X (curwin->w_alt_fnum == buf->b_fnum ? '#' : ' '),
X buf->b_ml.ml_mfp == NULL ? '-' :
X (buf->b_nwindows == 0 ? 'h' : ' '),
X buf->b_changed ? '+' : ' ');
X
X len = STRLEN(IObuff);
X STRNCPY(IObuff + len, NameBuff, (size_t)IOSIZE - 20 - len);
X
X len = STRLEN(IObuff);
X IObuff[len++] = '"';
X /*
X * try to put the "line" strings in column 40
X */
X do
X {
X IObuff[len++] = ' ';
X } while (len < 40 && len < IOSIZE - 18);
X sprintf((char *)IObuff + len, "line %ld",
X buf == curbuf ? curwin->w_cursor.lnum :
X (long)buflist_findlnum(buf));
X msg_outstr(IObuff);
X flushbuf(); /* output one line at a time */
X breakcheck();
X }
X msg_end();
X}
X
X/*
X * get file name and line number for file 'fnum'
X * used by DoOneCmd() for translating '%' and '#'
X * return FAIL if not found, OK for success
X */
X int
Xbuflist_name_nr(fnum, fname, lnum)
X int fnum;
X char_u **fname;
X linenr_t *lnum;


X{
X BUF *buf;
X

X buf = buflist_findnr(fnum);
X if (buf == NULL || buf->b_filename == NULL)
X return FAIL;
X
X if (did_cd)
X *fname = buf->b_filename;
X else
X *fname = buf->b_sfilename;
X *lnum = buflist_findlnum(buf);


X
X return OK;
X}
X
X/*

X * Set the current file name to 's', short file name to 'ss'.
X * The file name with the full path is also remembered, for when :cd is used.
X * Returns FAIL for failure (file name already in use by other buffer)
X * OK otherwise.
X */
X int
Xsetfname(fname, sfname, message)
X char_u *fname, *sfname;
X int message;


X{
X BUF *buf;
X

X if (fname == NULL || *fname == NUL)
X {
X curbuf->b_filename = NULL;
X curbuf->b_sfilename = NULL;
X }
X else
X {
X fname_expand(&fname, &sfname);
X /*
X * if the file name is already used in another buffer:
X * - if the buffer is loaded, fail
X * - if the buffer is not loaded, delete it from the list
X */
X buf = buflist_findname(fname);
X if (buf != NULL && buf != curbuf)
X {
X if (buf->b_ml.ml_mfp != NULL) /* it's loaded, fail */
X {
X if (message)
X EMSG("Buffer with this name already exists");
X return FAIL;
X }
X close_buffer(buf, TRUE, TRUE); /* delete from the list */
X }
X fname = strsave(fname);
X sfname = strsave(sfname);
X if (fname == NULL || sfname == NULL)
X {
X free(sfname);
X free(fname);
X return FAIL;
X }
X free(curbuf->b_filename);
X free(curbuf->b_sfilename);
X curbuf->b_filename = fname;
X curbuf->b_sfilename = sfname;
X }
X if (did_cd)
X curbuf->b_xfilename = curbuf->b_filename;
X else
X curbuf->b_xfilename = curbuf->b_sfilename;
X
X#ifndef MSDOS
X curbuf->b_shortname = FALSE;
X#endif


X return OK;
X}
X
X/*

X * set alternate file name for current window
X *
X * used by dowrite() and doecmd()
X */
X void
Xsetaltfname(fname, sfname, lnum)


X char_u *fname;
X char_u *sfname;

X linenr_t lnum;


X{
X BUF *buf;
X

X buf = buflist_new(fname, sfname, lnum, FALSE);
X if (buf != NULL)
X curwin->w_alt_fnum = buf->b_fnum;
X}
X
X/*
X * add a file name to the buflist and return its number
X *
X * used by qf_init(), main() and doarglist()
X */
X int
Xbuflist_add(fname)
X char_u *fname;


X{
X BUF *buf;
X

X buf = buflist_new(fname, NULL, (linenr_t)0, FALSE);
X if (buf != NULL)
X return buf->b_fnum;
X return 0;
X}
X
X/*
X * set alternate lnum for current window
X */
X void
Xbuflist_altlnum()
X{
X buflist_setlnum(curbuf, curwin->w_cursor.lnum);
X}
X
X/*
X * return nonzero if 'fname' is not the same file as current file
X * fname must have a full path (expanded by FullName)
X */
X int
Xotherfile(fname)
X char_u *fname;
X{ /* no name is different */
X if (fname == NULL || *fname == NUL || curbuf->b_filename == NULL)
X return TRUE;
X return fnamecmp(fname, curbuf->b_filename);
X}
X
X void
Xfileinfo(fullname)
X int fullname;
X{
X char_u *name;
X
X#if 0 /* this message is quite useless */
X if (bufempty())
X {
X MSG("Buffer Empty");
X return;
X }
X#endif


X
X if (curbuf->b_filename == NULL)

X STRCPY(IObuff, "\"No File");
X else
X {
X if (!fullname && curbuf->b_sfilename != NULL)
X name = curbuf->b_sfilename;
X else
X name = curbuf->b_filename;
X /* careful: home_replace cals vimgetenv(), which also uses IObuff! */
X home_replace(name, IObuff + 1, IOSIZE - 1);
X IObuff[0] = '"';
X }
X
X sprintf((char *)IObuff + STRLEN(IObuff),
X "\"%s%s%s line %ld of %ld --%d%%-- col %d",
X curbuf->b_changed ? " [Modified]" : "",
X curbuf->b_notedited ? " [Not edited]" : "",
X curbuf->b_p_ro ? " [readonly]" : "",
X (long)curwin->w_cursor.lnum,
X (long)curbuf->b_ml.ml_line_count,
X (int)(((long)curwin->w_cursor.lnum * 100L) / (long)curbuf->b_ml.ml_line_count),
X (int)curwin->w_cursor.col + 1);
X
X if (arg_count > 1)
X sprintf((char *)IObuff + STRLEN(IObuff), " (file %d of %d)", curwin->w_arg_idx + 1, arg_count);
X msg(IObuff);
X}
X
X/*
X * put filename in title bar of window and in icon title
X */
X
Xstatic char_u *lasttitle = NULL;
Xstatic char_u *lasticon = NULL;
X
X void
Xmaketitle()
X{
X char_u *t;
X char_u *i;
X
X if (!p_title && !p_icon)
X return;
X


X if (curbuf->b_filename == NULL)
X {

X t = (char_u *)"";
X i = (char_u *)"No File";
X }
X else
X {
X home_replace(curbuf->b_filename, IObuff, IOSIZE);
X if (arg_count > 1)
X sprintf((char *)IObuff + STRLEN(IObuff), " (%d of %d)", curwin->w_arg_idx + 1, arg_count);
X t = IObuff;
X i = gettail(curbuf->b_filename); /* use filename only for icon */
X }
X
X free(lasttitle);
X if (p_title)
X lasttitle = alloc((unsigned)(STRLEN(t) + 7));
X else
X lasttitle = NULL;
X if (lasttitle != NULL)
X sprintf((char *)lasttitle, "VIM - %s", (char *)t);
X
X free(lasticon);
X if (p_icon)
X lasticon = strsave(i);
X else
X lasticon = NULL;
X
X resettitle();


X}
X
X void
Xresettitle()
X{

X mch_settitle(lasttitle, lasticon);
X}
X
X/*
X * If fname is not a full path, make it a full path


X */
X char_u *

Xfix_fname(fname)
X char_u *fname;
X{
X if (fname != NameBuff) /* if not already expanded */
X {
X if (!isFullName(fname))
X {
X (void)FullName(fname, NameBuff, MAXPATHL);
X fname = NameBuff;
X }
X#ifdef AMIGA
X else
X {
X STRNCPY(NameBuff, fname, (size_t)MAXPATHL); /* make copy so we can change it */
X fname = NameBuff;
X fname_case(fname); /* set correct case for filename */
X }
X#endif
X }
X return fname;
X}
X
X/*
X * make fname a full file name, set sfname to fname if not NULL
X */
X void
Xfname_expand(fname, sfname)
X char_u **fname;
X char_u **sfname;
X{
X if (*fname == NULL) /* if no file name given, nothing to do */
X return;
X if (*sfname == NULL) /* if no short file name given, use fname */
X *sfname = *fname;
X *fname = fix_fname(*fname); /* expand to full path */
X}
X
X/*
X * do_arg_all: open a window for each argument
X */
X void
Xdo_arg_all()
X{
X int win_count;
X int i;
X
X if (arg_count <= 1)
X {
X EMSG("Argument list contains less than 2 files");
X return;
X }
X /*
X * 1. close all but first window
X * 2. make the desired number of windows
X * 3. start editing the first window (hide the current window contents)
X * 4. stuff commands to fill the other windows
X */
X close_others(FALSE);
X curwin->w_arg_idx = 0;
X win_count = make_windows(arg_count);
X for (i = 0; i < win_count; ++i)
X {
X /* edit file i */
X (void)doecmd(arg_files[i], NULL, NULL, TRUE, (linenr_t)1);
X curwin->w_arg_idx = i;
X if (curwin->w_next == NULL) /* just checking */
X break;
X win_enter(curwin->w_next, FALSE);
X }
X win_enter(firstwin, FALSE); /* back to first window */
X}
X
X/*
X * do_arg_all: open a window for each buffer
X *
X * when 'all' is TRUE, also load inactive buffers
X */
X void
Xdo_buffer_all(all)
X int all;
X{
X int win_count;
X BUF *buf;


X int i;
X
X/*

X * count number of desired windows
X */
X win_count = 0;

X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X if (all || buf->b_ml.ml_mfp != NULL)
X ++win_count;
X
X if (win_count == 0) /* Cannot happen? */
X {
X EMSG("No relevant entries in buffer list");
X return;
X }
X
X /*
X * 1. close all but first window
X * 2. make the desired number of windows
X * 3. stuff commands to fill the windows
X */
X close_others(FALSE);
X curwin->w_arg_idx = 0;
X win_count = make_windows(win_count);
X buf = firstbuf;
X for (i = 0; i < win_count; ++i)
X {
X for ( ; buf != NULL; buf = buf->b_next)
X if (all || buf->b_ml.ml_mfp != NULL)
X break;
X if (buf == NULL) /* Cannot happen? */
X break;
X if (i != 0)
X stuffReadbuff((char_u *)"\n\027\027:"); /* CTRL-W CTRL-W */
X stuffReadbuff((char_u *)":buf "); /* edit Nth buffer */
X stuffnumReadbuff((long)buf->b_fnum);
X buf = buf->b_next;
X }
X stuffReadbuff((char_u *)"\n100\027k"); /* back to first window */
X}
END_OF_FILE
if test 22119 -ne `wc -c <'vim/src/buffer.c'`; then
echo shar: \"'vim/src/buffer.c'\" unpacked with wrong size!
fi
# end of 'vim/src/buffer.c'
fi
if test -f 'vim/src/proto/mark.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/mark.pro'\"
else
echo shar: Extracting \"'vim/src/proto/mark.pro'\" \(439 characters\)
sed "s/^X//" >'vim/src/proto/mark.pro' <<'END_OF_FILE'
X/* mark.c */
Xint setmark __PARMS((int c));
Xvoid setpcmark __PARMS((void));
Xvoid checkpcmark __PARMS((void));
Xstruct fpos *movemark __PARMS((int count));
Xstruct fpos *getmark __PARMS((int c, int changefile));
Xvoid clrallmarks __PARMS((struct buffer *buf));
Xunsigned char *fm_getname __PARMS((struct filemark *fmark));
Xvoid domarks __PARMS((void));
Xvoid dojumps __PARMS((void));
Xvoid mark_adjust __PARMS((long line1, long line2, long inc));
END_OF_FILE
if test 439 -ne `wc -c <'vim/src/proto/mark.pro'`; then
echo shar: \"'vim/src/proto/mark.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/mark.pro'
fi
echo shar: End of archive 9 \(of 26\).
cp /dev/null ark9isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:14 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 29
Archive-name: vim/part10

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/digraph.doc.UU vim/src/misccmds.c vim/src/normal.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:04 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 10 (of 26)."'
if test -f 'vim/doc/digraph.doc.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/digraph.doc.UU'\"
else
echo shar: Extracting \"'vim/doc/digraph.doc.UU'\" \(3112 characters\)
sed "s/^X//" >'vim/doc/digraph.doc.UU' <<'END_OF_FILE'
Xbegin 644 vim/doc/digraph.doc
XM5&AE<V4@87)E('1H92!D969A=6QT(&1I9W)A<&@@8VAA<F%C=&5R<R!F;W(@
XM5FEM+@H*0F5S:61E<R!T:&4@9&EG<F%P:',@;&ES=&5D(&)E;&]W+"!M971A
XM(&-H87)A8W1E<G,@8V%N(&)E(&5N=&5R960@=VET:"!#5%),+4L*/%-004-%
XM/B![8VAA<GTN($]N;'D@15-#(&-A;FYO="!B92!U<V5D(&9O<B![8VAA<GTN
XM(%5S92!#5%),+58@,34U(&9O<B!T:&ES+@H*5&AE(&9I<G-T('1W;R!C:&%R
XM86-T97)S(&EN(&5A8V@@8V]L=6UN(&%R92!T:&4@8VAA<F%C=&5R<R!Y;W4@
XM:&%V92!T;R!T>7!E('1O"F5N=&5R(&$@9&EG<F%P:"X*"DEN('1H92!M:61D
XM;&4@;V8@96%C:"!C;VQU;6X@:7,@=&AE(')E<W5L=&EN9R!C:&%R86-T97(N
XM(%1H:7,@;6%Y(&)E(&UA;F=L960*:68@>6]U(&QO;VL@870@=&AI<R!F:6QE
XM(&]N('-O;65T:&EN9R!E;'-E('1H86X@=&AE('-Y<W1E;2!T:&%T('1H97D@
XM=V5R90IM96%N="!F;W(@;W(@=VAE;B!Y;W4@<')I;G0@:70N"@I4:&4@9&5C
XM:6UA;"!N=6UB97(@:7,@=&AE($%30TE)(&-O9&4@9F]R('1H92!C:&%R86-T
XM97(N"@I$969A=6QT(&1I9W)A<&AS(&]N('1H92!!;6EG83H*?B$@H2 Q-C$@
XM("!C?""B(#$V,B @("0D(*,@,38S(" @;W@@I" Q-C0@("!9+2"E(#$V-2 @
XM('Q\(*8@,38V(" @<&$@IR Q-C<*(B(@J" Q-C@@("!C3R"I(#$V.2 @(&$M
XM(*H@,3<P(" @/#P@JR Q-S$@(" M+2"M(#$W,R @(')/(*X@,3<T(" @+3T@
XMKR Q-S4*?F\@L" Q-S8@(" K+2"Q(#$W-R @(#(R(+(@,3<X(" @,S,@LR Q
XM-SD@(" G)R"T(#$X," @(&IU(+4@,3@Q(" @<' @MB Q.#(*?BX@MR Q.#,@
XM(" L+""X(#$X-" @(#$Q(+D@,3@U(" @;RT@NB Q.#8@(" ^/B"[(#$X-R @
XM(#$T(+P@,3@X(" @,3(@O2 Q.#D*,S0@OB Q.3 @("!^/R"_(#$Y,2 @($%@
XM(, @,3DR(" @02<@P2 Q.3,@("!!7B#"(#$Y-" @($%^(,,@,3DU(" @02(@
XMQ" Q.38*04 @Q2 Q.3<@("!!12#&(#$Y." @($,L(,<@,3DY(" @16 @R" R
XM,# @("!%)R#)(#(P,2 @($5>(,H@,C R(" @12(@RR R,#,*26 @S" R,#0@
XM("!))R#-(#(P-2 @($E>(,X@,C V(" @22(@SR R,#<@(" M1"#0(#(P." @
XM($Y^(-$@,C Y(" @3V @TB R,3 *3R<@TR R,3$@("!/7B#4(#(Q,B @($]^
XM(-4@,C$S(" @3R(@UB R,30@(" O7"#7(#(Q-2 @($\O(-@@,C$V(" @56 @
XMV2 R,3<*52<@VB R,3@@("!57B#;(#(Q.2 @(%4B(-P@,C(P(" @62<@W2 R
XM,C$@("!)<"#>(#(R,B @('-S(-\@,C(S(" @86 @X" R,C0*82<@X2 R,C4@
XM("!A7B#B(#(R-B @(&%^(.,@,C(W(" @82(@Y" R,C@@("!A0"#E(#(R.2 @
XM(&%E(.8@,C,P(" @8RP@YR R,S$*96 @Z" R,S(@("!E)R#I(#(S,R @(&5>
XM(.H@,C,T(" @92(@ZR R,S4@("!I8"#L(#(S-B @(&DG(.T@,C,W(" @:5X@
XM[B R,S@*:2(@[R R,SD@(" M9"#P(#(T," @(&Y^(/$@,C0Q(" @;V @\B R
XM-#(@("!O)R#S(#(T,R @(&]>(/0@,C0T(" @;WX@]2 R-#4*;R(@]B R-#8@
XM(" Z+2#W(#(T-R @(&\O(/@@,C0X(" @=6 @^2 R-#D@("!U)R#Z(#(U," @
XM('5>(/L@,C4Q(" @=2(@_" R-3(*>2<@_2 R-3,@("!I<"#^(#(U-" @('DB
XM(/\@,C4U"@I$969A=6QT(&1I9W)A<&AS(&]N($U31$]3.@I#+"" (#$R." @
XM('4B(($@,3(Y(" @92<@@B Q,S @("!A7B"#(#$S,2 @(&$B((0@,3,R(" @
XM86 @A2 Q,S,@("!A0""&(#$S- IC+""'(#$S-2 @(&5>((@@,3,V(" @92(@
XMB2 Q,S<@("!E8""*(#$S." @(&DB((L@,3,Y(" @:5X@C" Q-# @("!I8""-
XM(#$T,0I!(B".(#$T,B @($% ((\@,30S(" @12<@D" Q-#0@("!A92"1(#$T
XM-2 @($%%()(@,30V(" @;UX@DR Q-#<@("!O(B"4(#$T. IO8""5(#$T.2 @
XM('5>()8@,34P(" @=6 @ER Q-3$@("!Y(B"8(#$U,B @($\B()D@,34S(" @
XM52(@FB Q-30@("!C?"";(#$U-0HD)""<(#$U-B @(%DM()T@,34W(" @4'0@
XMGB Q-3@@("!F9B"?(#$U.2 @(&$G(* @,38P(" @:2<@H2 Q-C$@("!O)R"B
XM(#$V,@IU)R"C(#$V,R @(&Y^(*0@,38T(" @3GX@I2 Q-C4@("!A82"F(#$V
XM-B @(&]O(*<@,38W(" @?C\@J" Q-C@@(" M82"I(#$V.0IA+2"J(#$W," @
XM(#$R(*L@,3<Q(" @,30@K" Q-S(@("!^(2"M(#$W,R @(#P\(*X@,3<T(" @
XM/CX@KR Q-S4@("!S<R#A(#(R-0IJ=2#F(#(S," @(&\O(.T@,C,W(" @*RT@
XM\2 R-#$@(" ^/2#R(#(T,B @(#P](/,@,C0S(" @.BT@]B R-#8@("!^?B#W
X9(#(T-PI^;R#X(#(T." @(#(R(/T@,C4S"C0S
X
Xend
END_OF_FILE
if test 3112 -ne `wc -c <'vim/doc/digraph.doc.UU'`; then
echo shar: \"'vim/doc/digraph.doc.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/doc/digraph.doc'\" \(2230 characters\)
cat vim/doc/digraph.doc.UU | uudecode
if test 2230 -ne `wc -c <'vim/doc/digraph.doc'`; then
echo shar: \"'vim/doc/digraph.doc'\" uudecoded with wrong size!
else
rm vim/doc/digraph.doc.UU
fi
fi
# end of 'vim/doc/digraph.doc.UU'
fi
if test -f 'vim/src/misccmds.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/misccmds.c'\"
else
echo shar: Extracting \"'vim/src/misccmds.c'\" \(20128 characters\)
sed "s/^X//" >'vim/src/misccmds.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * misccmds.c: functions that didn't seem to fit elsewhere


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic void check_status __ARGS((BUF *));
X
Xstatic char_u *(si_tab[]) = {(char_u *)"if", (char_u *)"else", (char_u *)"while", (char_u *)"for", (char_u *)"do"};
X
X/*
X * count the size of the indent in the current line
X */
X int
Xget_indent()
X{
X register char_u *ptr;
X register int count = 0;
X
X for (ptr = ml_get(curwin->w_cursor.lnum); *ptr; ++ptr)
X {
X if (*ptr == TAB) /* count a tab for what it is worth */
X count += (int)curbuf->b_p_ts - (count % (int)curbuf->b_p_ts);
X else if (*ptr == ' ')
X ++count; /* count a space for one */
X else
X break;
X }
X return (count);
X}
X
X/*
X * set the indent of the current line
X * leaves the cursor on the first non-blank in the line
X */
X void
Xset_indent(size, delete)
X register int size;
X int delete;
X{
X int oldstate = State;
X register int c;
X
X State = INSERT; /* don't want REPLACE for State */


X curwin->w_cursor.col = 0;

X if (delete) /* delete old indent */
X {
X while ((c = gchar_cursor()), iswhite(c))
X (void)delchar(FALSE);
X }
X if (!curbuf->b_p_et) /* if 'expandtab' is set, don't use TABs */
X while (size >= (int)curbuf->b_p_ts)
X {
X inschar(TAB);
X size -= (int)curbuf->b_p_ts;
X }
X while (size)
X {
X inschar(' ');
X --size;
X }
X State = oldstate;
X}
X
X/*
X * Opencmd
X *
X * Add a blank line below or above the current line.
X *
X * Return TRUE for success, FALSE for failure
X */
X
X int
XOpencmd(dir, redraw, delspaces)
X int dir;
X int redraw;
X int delspaces;
X{
X char_u *ptr, *p_extra;
X FPOS old_cursor; /* old cursor position */
X int newcol = 0; /* new cursor column */
X int newindent = 0; /* auto-indent of the new line */
X int n;
X int truncate = FALSE; /* truncate current line afterwards */
X int no_si = FALSE; /* reset did_si afterwards */
X int retval = FALSE; /* return value, default is FAIL */
X
X ptr = strsave(ml_get(curwin->w_cursor.lnum));
X if (ptr == NULL) /* out of memory! */
X return FALSE;
X
X u_clearline(); /* cannot do "U" command when adding lines */
X did_si = FALSE;
X if (curbuf->b_p_ai || curbuf->b_p_si)
X {
X /*
X * count white space on current line
X */
X newindent = get_indent();
X if (newindent == 0)
X newindent = old_indent; /* for ^^D command in insert mode */
X old_indent = 0;
X
X /*
X * If we just did an auto-indent, then we didn't type anything on the
X * prior line, and it should be truncated.
X */
X if (dir == FORWARD && did_ai)
X truncate = TRUE;
X else if (curbuf->b_p_si && *ptr != NUL)
X {
X char_u *p;
X char_u *pp;
X int i, save;


X
X if (dir == FORWARD)

X {
X p = ptr + STRLEN(ptr) - 1;
X while (p > ptr && isspace(*p)) /* find last non-blank in line */
X --p;
X if (*p == '{') /* line ends in '{': do indent */
X {
X did_si = TRUE;
X no_si = TRUE;
X }
X else /* look for "if" and the like */
X {
X p = ptr;
X skipspace(&p);
X for (pp = p; islower(*pp); ++pp)
X ;
X if (!isidchar(*pp)) /* careful for vars starting with "if" */
X {
X save = *pp;
X *pp = NUL;
X for (i = sizeof(si_tab)/sizeof(char_u *); --i >= 0; )
X if (STRCMP(p, si_tab[i]) == 0)
X {
X did_si = TRUE;
X break;
X }
X *pp = save;
X }
X }
X }
X else
X {
X p = ptr;
X skipspace(&p);
X if (*p == '}') /* if line starts with '}': do indent */
X did_si = TRUE;
X }
X }
X did_ai = TRUE;
X if (curbuf->b_p_si)
X can_si = TRUE;
X }
X if (State == INSERT || State == REPLACE) /* only when dir == FORWARD */
X {
X p_extra = ptr + curwin->w_cursor.col;
X if (curbuf->b_p_ai && delspaces)
X skipspace(&p_extra);
X if (*p_extra != NUL)
X did_ai = FALSE; /* append some text, don't trucate now */
X }
X else
X p_extra = (char_u *)""; /* append empty line */
X
X old_cursor = curwin->w_cursor;
X if (dir == BACKWARD)
X --curwin->w_cursor.lnum;
X if (ml_append(curwin->w_cursor.lnum, p_extra, (colnr_t)0, FALSE) == FAIL)
X goto theend;
X mark_adjust(curwin->w_cursor.lnum + 1, MAXLNUM, 1L);
X if (newindent || did_si)
X {
X ++curwin->w_cursor.lnum;
X if (did_si)
X {
X if (p_sr)
X newindent -= newindent % (int)curbuf->b_p_sw;
X newindent += (int)curbuf->b_p_sw;
X }
X set_indent(newindent, FALSE);
X newcol = curwin->w_cursor.col;
X if (no_si)
X did_si = FALSE;
X }
X curwin->w_cursor = old_cursor;


X
X if (dir == FORWARD)

X {
X if (truncate || State == INSERT || State == REPLACE)
X {
X if (truncate)
X *ptr = NUL;
X else
X *(ptr + curwin->w_cursor.col) = NUL; /* truncate current line at cursor */
X ml_replace(curwin->w_cursor.lnum, ptr, FALSE);
X ptr = NULL;
X }
X
X /*
X * Get the cursor to the start of the line, so that 'curwin->w_row' gets
X * set to the right physical line number for the stuff that
X * follows...
X */


X curwin->w_cursor.col = 0;
X

X if (redraw)
X {
X n = RedrawingDisabled;
X RedrawingDisabled = TRUE;
X cursupdate(); /* don't want it to update srceen */
X RedrawingDisabled = n;
X
X /*
X * If we're doing an open on the last logical line, then go ahead and
X * scroll the screen up. Otherwise, just insert a blank line at the
X * right place. We use calls to plines() in case the cursor is
X * resting on a long line.
X */
X n = curwin->w_row + plines(curwin->w_cursor.lnum);
X if (n == curwin->w_height)
X scrollup(1L);
X else
X win_ins_lines(curwin, n, 1, TRUE, TRUE);
X }
X ++curwin->w_cursor.lnum; /* cursor moves down */
X }
X else if (redraw) /* insert physical line above current line */
X win_ins_lines(curwin, curwin->w_row, 1, TRUE, TRUE);
X
X curwin->w_cursor.col = newcol;
X if (redraw)
X {
X updateScreen(VALID_TO_CURSCHAR);
X cursupdate(); /* update curwin->w_row */
X }
X CHANGED;
X
X retval = TRUE; /* success! */
Xtheend:
X free(ptr);


X return retval;
X}
X

X/*
X * plines(p) - return the number of physical screen lines taken by line 'p'
X */
X int
Xplines(p)
X linenr_t p;
X{
X return plines_win(curwin, p);
X}
X
X int
Xplines_win(wp, p)
X WIN *wp;
X linenr_t p;
X{
X register long col = 0;
X register char_u *s;
X register int lines;
X
X if (!wp->w_p_wrap)
X return 1;
X
X s = ml_get_buf(wp->w_buffer, p, FALSE);
X if (*s == NUL) /* empty line */
X return 1;
X
X while (*s != NUL)
X col += chartabsize(*s++, col);
X
X /*
X * If list mode is on, then the '$' at the end of the line takes up one
X * extra column.
X */
X if (wp->w_p_list)
X col += 1;
X
X /*
X * If 'number' mode is on, add another 8.
X */
X if (wp->w_p_nu)
X col += 8;
X
X lines = (col + (Columns - 1)) / Columns;
X if (lines <= wp->w_height)
X return lines;
X return (int)(wp->w_height); /* maximum length */
X}
X
X/*
X * Count the physical lines (rows) for the lines "first" to "last" inclusive.
X */
X int
Xplines_m(first, last)
X linenr_t first, last;
X{
X return plines_m_win(curwin, first, last);
X}
X
X int
Xplines_m_win(wp, first, last)
X WIN *wp;
X linenr_t first, last;
X{
X int count = 0;
X
X while (first <= last)
X count += plines_win(wp, first++);
X return (count);
X}
X
X/*
X * insert or replace a single character at the cursor position
X */
X void
Xinschar(c)
X int c;


X{
X register char_u *p;

X int rir0; /* reverse replace in column 0 */
X char_u *new;
X char_u *old;
X int oldlen;
X int extra;
X colnr_t col = curwin->w_cursor.col;
X linenr_t lnum = curwin->w_cursor.lnum;
X
X old = ml_get(lnum);
X oldlen = STRLEN(old) + 1;
X
X rir0 = (State == REPLACE && p_ri && col == 0);
X if (rir0 || State != REPLACE || *(old + col) == NUL)
X extra = 1;
X else
X extra = 0;
X
X new = alloc((unsigned)(oldlen + extra));
X if (new == NULL)
X return;
X memmove((char *)new, (char *)old, (size_t)col);
X p = new + col;
X memmove((char *)p + extra, (char *)old + col, (size_t)(oldlen - col));
X if (rir0) /* reverse replace in column 0 */
X {
X *(p + 1) = c; /* replace the char that was in column 0 */
X c = ' '; /* insert a space */
X extraspace = TRUE;
X }
X *p = c;
X ml_replace(lnum, new, FALSE);
X
X /*
X * If we're in insert mode and showmatch mode is set, then check for
X * right parens and braces. If there isn't a match, then beep. If there
X * is a match AND it's on the screen, then flash to it briefly. If it
X * isn't on the screen, don't do anything.
X */
X if (p_sm && State == INSERT && (c == ')' || c == '}' || c == ']'))
X {
X FPOS *lpos, csave;
X
X if ((lpos = showmatch(NUL)) == NULL) /* no match, so beep */
X beep();
X else if (lpos->lnum >= curwin->w_topline)
X {
X updateScreen(VALID_TO_CURSCHAR); /* show the new char first */
X csave = curwin->w_cursor;
X curwin->w_cursor = *lpos; /* move to matching char */
X cursupdate();
X showruler(0);
X setcursor();
X cursor_on(); /* make sure that the cursor is shown */
X flushbuf();
X vim_delay(); /* brief pause */
X curwin->w_cursor = csave; /* restore cursor position */
X cursupdate();
X }
X }
X if (!p_ri) /* normal insert: cursor right */
X ++curwin->w_cursor.col;
X else if (State == REPLACE && !rir0) /* reverse replace mode: cursor left */
X --curwin->w_cursor.col;
X CHANGED;
X}
X
X/*
X * insert a string at the cursor position
X */
X void
Xinsstr(s)
X register char_u *s;
X{
X register char_u *old, *new;
X register int newlen = STRLEN(s);
X int oldlen;
X colnr_t col = curwin->w_cursor.col;
X linenr_t lnum = curwin->w_cursor.lnum;
X
X old = ml_get(lnum);
X oldlen = STRLEN(old);
X new = alloc((unsigned)(oldlen + newlen + 1));
X if (new == NULL)
X return;
X memmove((char *)new, (char *)old, (size_t)col);
X memmove((char *)new + col, (char *)s, (size_t)newlen);
X memmove((char *)new + col + newlen, (char *)old + col, (size_t)(oldlen - col + 1));
X ml_replace(lnum, new, FALSE);
X curwin->w_cursor.col += newlen;
X CHANGED;
X}
X
X/*
X * delete one character under the cursor
X *


X * return FAIL for failure, OK otherwise
X */
X int

Xdelchar(fixpos)
X int fixpos; /* if TRUE fix the cursor position when done */
X{
X char_u *old, *new;
X int oldlen;
X linenr_t lnum = curwin->w_cursor.lnum;
X colnr_t col = curwin->w_cursor.col;
X int was_alloced;
X
X old = ml_get(lnum);
X oldlen = STRLEN(old);
X
X if (col >= oldlen) /* can't do anything (happens with replace mode) */
X return FAIL;
X
X/*
X * If the old line has been allocated the deleteion can be done in the
X * existing line. Otherwise a new line has to be allocated
X */
X was_alloced = ml_line_alloced(); /* check if old was allocated */
X if (was_alloced)
X new = old; /* use same allocated memory */
X else
X {
X new = alloc((unsigned)oldlen); /* need to allocated a new line */
X if (new == NULL)
X return FAIL;
X memmove((char *)new, (char *)old, (size_t)col);
X }
X memmove((char *)new + col, (char *)old + col + 1, (size_t)(oldlen - col));
X if (!was_alloced)
X ml_replace(lnum, new, FALSE);
X
X /*
X * If we just took off the last character of a non-blank line, we don't
X * want to end up positioned at the newline.
X */
X if (fixpos && curwin->w_cursor.col > 0 && col == oldlen - 1)
X --curwin->w_cursor.col;
X
X CHANGED;


X return OK;
X}
X

X void
Xdellines(nlines, dowindow, undo)
X long nlines; /* number of lines to delete */
X int dowindow; /* if true, update the window */
X int undo; /* if true, prepare for undo */
X{
X int num_plines = 0;
X
X if (nlines <= 0)
X return;
X /*
X * There's no point in keeping the window updated if we're deleting more
X * than a window's worth of lines.
X */
X if (nlines > (curwin->w_height - curwin->w_row) && dowindow)
X {
X dowindow = FALSE;
X /* flaky way to clear rest of window */
X win_del_lines(curwin, curwin->w_row, curwin->w_height, TRUE, TRUE);
X }
X if (undo && !u_savedel(curwin->w_cursor.lnum, nlines))
X return;
X
X mark_adjust(curwin->w_cursor.lnum, curwin->w_cursor.lnum + nlines - 1, MAXLNUM);
X mark_adjust(curwin->w_cursor.lnum + nlines, MAXLNUM, -nlines);
X
X while (nlines-- > 0)
X {
X if (bufempty()) /* nothing to delete */
X break;
X
X /*
X * Set up to delete the correct number of physical lines on the
X * window
X */
X if (dowindow)
X num_plines += plines(curwin->w_cursor.lnum);
X
X ml_delete(curwin->w_cursor.lnum);
X
X CHANGED;
X
X /* If we delete the last line in the file, stop */


X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)

X {
X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X break;
X }
X }


X curwin->w_cursor.col = 0;

X /*
X * Delete the correct number of physical lines on the window
X */
X if (dowindow && num_plines > 0)
X win_del_lines(curwin, curwin->w_row, num_plines, TRUE, TRUE);
X}
X
X int
Xgchar(pos)
X FPOS *pos;
X{
X return (int)(*(ml_get_pos(pos)));
X}
X
X int
Xgchar_cursor()
X{
X return (int)(*(ml_get_cursor()));
X}
X
X/*
X * Write a character at the current cursor position.
X * It is directly written into the block.
X */
X void
Xpchar_cursor(c)
X int c;
X{
X *(ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE) + curwin->w_cursor.col) = c;
X}
X
X/*
X * return TRUE if the cursor is before or on the first non-blank in the line
X */
X int
Xinindent()
X{
X register char_u *ptr;
X register int col;
X
X for (col = 0, ptr = ml_get(curwin->w_cursor.lnum); iswhite(*ptr); ++col)
X ++ptr;
X if (col >= curwin->w_cursor.col)
X return TRUE;
X else
X return FALSE;
X}
X
X/*
X * skipspace: skip over ' ' and '\t'.
X *
X * note: you must give a pointer to a char_u pointer!
X */
X void
Xskipspace(pp)
X char_u **pp;


X{
X register char_u *p;
X

X for (p = *pp; *p == ' ' || *p == '\t'; ++p) /* skip to next non-white */
X ;
X *pp = p;
X}
X
X/*
X * skiptospace: skip over text until ' ' or '\t'.
X *
X * note: you must give a pointer to a char_u pointer!
X */
X void
Xskiptospace(pp)
X char_u **pp;


X{
X register char_u *p;
X

X for (p = *pp; *p != ' ' && *p != '\t' && *p != NUL; ++p)
X ;
X *pp = p;
X}
X
X/*
X * skiptodigit: skip over text until digit found
X *
X * note: you must give a pointer to a char_u pointer!
X */
X void
Xskiptodigit(pp)
X char_u **pp;


X{
X register char_u *p;
X

X for (p = *pp; !isdigit(*p) && *p != NUL; ++p)
X ;
X *pp = p;
X}
X
X/*
X * getdigits: get a number from a string and skip over it
X *
X * note: you must give a pointer to a char_u pointer!
X */
X
X long
Xgetdigits(pp)
X char_u **pp;


X{
X register char_u *p;

X long retval;
X
X p = *pp;
X retval = atol((char *)p);
X while (isdigit(*p)) /* skip to next non-digit */
X ++p;
X *pp = p;


X return retval;
X}
X

X char_u *
Xplural(n)
X long n;
X{
X static char_u buf[2] = "s";
X
X if (n == 1)
X return &(buf[1]);
X return &(buf[0]);
X}
X
X/*
X * set_Changed is called when something in the current buffer is changed
X */
X void
Xset_Changed()
X{
X if (!curbuf->b_changed)
X {
X change_warning();
X curbuf->b_changed = TRUE;
X check_status(curbuf);
X }
X}
X
X/*
X * unset_Changed is called when the changed flag must be reset for buffer 'buf'
X */
X void
Xunset_Changed(buf)
X BUF *buf;
X{
X if (buf->b_changed)
X {
X buf->b_changed = 0;
X check_status(buf);
X }
X}
X
X/*
X * check_status: called when the status bars for the buffer 'buf'
X * need to be updated


X */
X static void

Xcheck_status(buf)
X BUF *buf;
X{
X WIN *wp;
X int i;
X
X i = 0;
X for (wp = firstwin; wp != NULL; wp = wp->w_next)
X if (wp->w_buffer == buf && wp->w_status_height)


X {
X wp->w_redr_status = TRUE;

X ++i;
X }
X if (i && must_redraw < NOT_VALID) /* redraw later */
X must_redraw = NOT_VALID;
X}
X
X/*
X * If the file is readonly, give a warning message with the first change.
X * Don't use emsg(), because it flushes the macro buffer.
X * If we have undone all changes b_changed will be FALSE, but b_did_warn
X * will be TRUE.
X */
X void
Xchange_warning()
X{
X if (curbuf->b_did_warn == FALSE && curbuf->b_changed == 0 && curbuf->b_p_ro)
X {
X curbuf->b_did_warn = TRUE;
X MSG("Warning: Changing a readonly file");
X sleep(1); /* give him some time to think about it */
X }
X}
X
X/*
X * ask for a reply from the user, a 'y' or a 'n'.
X * No other characters are accepted, the message is repeated until a valid
X * reply is entered or CTRL-C is hit.
X *
X * return the 'y' or 'n'
X */
X int
Xask_yesno(str)
X char_u *str;
X{
X int r = ' ';
X
X while (r != 'y' && r != 'n')
X {
X (void)set_highlight('r'); /* same highlighting as for wait_return */
X msg_highlight = TRUE;
X smsg((char_u *)"%s (y/n)?", str);
X r = vgetc();
X if (r == Ctrl('C'))
X r = 'n';
X msg_outchar(r); /* show what you typed */
X flushbuf();
X }


X return r;
X}
X

X void
Xmsgmore(n)
X long n;
X{
X long pn;
X
X if (global_busy) /* no messages now, wait until global is finished */
X return;
X
X if (n > 0)
X pn = n;
X else
X pn = -n;
X
X if (pn > p_report)
X smsg((char_u *)"%ld %s line%s %s", pn, n > 0 ? "more" : "fewer", plural(pn),
X got_int ? "(Interrupted)" : "");
X}
X
X/*
X * give a warning for an error
X */
X void
Xbeep()
X{
X flush_buffers(FALSE); /* flush internal buffers */
X if (p_vb)
X {
X if (T_VB && *T_VB)
X outstr(T_VB);
X else
X { /* very primitive visual bell */
X MSG(" ^G");
X MSG(" ^G");
X MSG(" ^G ");
X MSG(" ^G");
X MSG(" ");
X showmode(); /* may have deleted the mode message */
X }
X }
X else
X outchar('\007');
X}
X
X/*
X * Expand environment variable with path name.
X * "~/" is also expanded, like $HOME.
X * If anything fails no expansion is done and dst equals src.
X */
X void
Xexpand_env(src, dst, dstlen)
X char_u *src; /* input string e.g. "$HOME/vim.hlp" */
X char_u *dst; /* where to put the result */
X int dstlen; /* maximum length of the result */
X{
X char_u *tail;
X int c;
X char_u *var;
X
X if (*src == '$' || (*src == '~' && STRCHR("/ \t\n", src[1]) != NULL))
X {
X/*
X * The variable name is copied into dst temporarily, because it may be
X * a string in read-only memory.
X */
X if (*src == '$')
X {
X tail = src + 1;
X var = dst;
X c = dstlen - 1;
X while (c-- > 0 && *tail && isidchar(*tail))
X *var++ = *tail++;
X *var = NUL;
X/*
X * It is possible that vimgetenv() uses IObuff for the expansion, and that the
X * 'dst' is also IObuff. This works, as long as 'var' is the first to be copied
X * to 'dst'!
X */
X var = vimgetenv(dst);
X }
X else
X {
X var = vimgetenv((char_u *)"HOME");
X tail = src + 1;
X }
X if (var && (STRLEN(var) + STRLEN(tail) + 1 < (unsigned)dstlen))
X {
X STRCPY(dst, var);
X STRCAT(dst, tail);
X return;
X }
X }
X STRNCPY(dst, src, (size_t)dstlen);
X}
X
X/*
X * Replace home directory by "~/"
X * If anything fails dst equals src.
X */
X void
Xhome_replace(src, dst, dstlen)
X char_u *src; /* input file name */
X char_u *dst; /* where to put the result */
X int dstlen; /* maximum length of the result */
X{
X char_u *home;
X size_t len;
X
X /*
X * If there is no "HOME" environment variable, or when it
X * is very short, don't replace anything.
X */
X if ((home = vimgetenv((char_u *)"HOME")) == NULL || (len = STRLEN(home)) <= 1)
X STRNCPY(dst, src, (size_t)dstlen);
X else
X {
X skipspace(&src);
X while (*src && dstlen > 0)
X {
X if (STRNCMP(src, home, len) == 0)
X {
X src += len;
X if (--dstlen > 0)
X *dst++ = '~';
X }
X while (*src && *src != ' ' && --dstlen > 0)
X *dst++ = *src++;
X while (*src == ' ' && --dstlen > 0)
X *dst++ = *src++;
X }
X *dst = NUL;
X }
X}
X
X/*
X * Compare two file names and return TRUE if they are different files.
X * For the first name environment variables are expanded
X */
X int
Xfullpathcmp(s1, s2)
X char_u *s1, *s2;
X{
X#ifdef UNIX
X struct stat st1, st2;
X char_u buf1[MAXPATHL];
X
X expand_env(s1, buf1, MAXPATHL);
X if (stat((char *)buf1, &st1) == 0 && stat((char *)s2, &st2) == 0 &&
X st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
X return FALSE;
X return TRUE;
X#else
X char_u buf1[MAXPATHL];
X char_u buf2[MAXPATHL];
X
X expand_env(s1, buf2, MAXPATHL);
X if (FullName(buf2, buf1, MAXPATHL) == OK && FullName(s2, buf2, MAXPATHL) == OK)
X return STRCMP(buf1, buf2);
X /*
X * one of the FullNames() failed, file probably doesn't exist.
X */
X return TRUE;
X#endif
X}
X
X/*
X * get the tail of a path: the file name.


X */
X char_u *

Xgettail(fname)
X char_u *fname;
X{
X register char_u *p1, *p2;
X
X for (p1 = p2 = fname; *p2; ++p2) /* find last part of path */
X {
X if (ispathsep(*p2))
X p1 = p2 + 1;
X }
X return p1;
X}
X
X/*
X * return TRUE if 'c' is a path separator.
X */
X int
Xispathsep(c)
X int c;
X{
X#ifdef UNIX
X return (c == PATHSEP); /* UNIX has ':' inside file names */
X#else
X# ifdef MSDOS
X return (c == ':' || c == PATHSEP || c == '/');
X# else
X return (c == ':' || c == PATHSEP);
X# endif
X#endif
X}
END_OF_FILE
if test 20128 -ne `wc -c <'vim/src/misccmds.c'`; then
echo shar: \"'vim/src/misccmds.c'\" unpacked with wrong size!
fi
# end of 'vim/src/misccmds.c'
fi
if test -f 'vim/src/normal.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/normal.c'\"
else
echo shar: Extracting \"'vim/src/normal.c'\" \(41440 characters\)
sed "s/^X//" >'vim/src/normal.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Contains the main routine for processing characters in command mode.
X * Communicates closely with the code in ops.c to handle the operators.


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

X#undef EXTERN
X#undef INIT
X#define EXTERN
X#define INIT(x) x
X#include "ops.h"
X
X/*
X * Generally speaking, every command in normal() should either clear any
X * pending operator (with CLEAROP), or set the motion type variable.
X */
X
X#define CLEAROP (operator = NOP) /* clear any pending operator */
X#define CLEAROPBEEP clearopbeep() /* CLEAROP plus a beep() */
X#define CHECKCLEAROP if (checkclearop()) break;
X#define CHECKCLEAROPQ if (checkclearopq()) break;
X
X/*
X * If a count is given before the operator, it is saved in opnum.
X */
Xstatic linenr_t opnum = 0;
Xstatic linenr_t Prenum; /* The (optional) number before a command. */
Xint redo_Visual_busy = FALSE; /* TRUE when redo-ing a visual */
X
Xstatic void prep_redo __ARGS((long, int, int, int));
Xstatic int checkclearop __ARGS((void));
Xstatic int checkclearopq __ARGS((void));
Xstatic void clearopbeep __ARGS((void));
Xstatic void premsg __ARGS((int, int));
X
Xextern int restart_edit; /* this is in edit.c */
X
X/*
X * normal
X *
X * Execute a command in normal mode.
X *
X * This is basically a big switch with the cases arranged in rough categories
X * in the following order:
X *
X * 0. Macros (q, @)
X * 1. Screen positioning commands (^U, ^D, ^F, ^B, ^E, ^Y, z)
X * 2. Control commands (:, <help>, ^L, ^G, ^^, ZZ, *, ^], ^T)
X * 3. Cursor motions (G, H, M, L, l, K_RARROW, , h, K_LARROW, ^H, k, K_UARROW, ^P, +, CR, LF, j, K_DARROW, ^N, _, |, B, b, W, w, E, e, $, ^, 0)
X * 4. Searches (?, /, n, N, T, t, F, f, ,, ;, ], [, %, (, ), {, })
X * 5. Edits (., u, K_UNDO, ^R, U, r, J, p, P, ^A, ^S)
X * 6. Inserts (A, a, I, i, o, O, R)
X * 7. Operators (~, d, c, y, >, <, !, =, Q)
X * 8. Abbreviations (x, X, D, C, s, S, Y, &)
X * 9. Marks (m, ', `, ^O, ^I)
X * 10. Buffer setting (")
X * 11. Visual (v, V, ^V)
X * 12. Suspend (^Z)
X * 13. Window commands (^W)
X * 14. extended commands (starting with 'g')


X */
X
X void

Xnormal()
X{
X register int c;
X long n;
X int flag = FALSE;
X int flag2 = FALSE;
X int type = 0; /* type of operation */
X int dir = FORWARD; /* search direction */
X int nchar = NUL;
X int finish_op;
X linenr_t Prenum1;
X char_u searchbuff[CMDBUFFSIZE];/* buffer for search string */
X FPOS *pos = NULL; /* init for gcc */
X register char_u *ptr;
X int command_busy = FALSE;
X static int didwarn = FALSE; /* warned for broken inversion */
X int modified = FALSE; /* changed current buffer */
X int ctrl_w = FALSE; /* got CTRL-W command */
X
X /* the visual area is remembered for reselection */
X static linenr_t resel_Visual_nlines; /* number of lines */
X static int resel_Visual_type = 0; /* type 'v', 'V' or CTRL-V */
X static colnr_t resel_Visual_col; /* number of columns or end column */
X /* the visual area is remembered for redo */
X static linenr_t redo_Visual_nlines; /* number of lines */
X static int redo_Visual_type = 0; /* type 'v', 'V' or CTRL-V */
X static colnr_t redo_Visual_col; /* number of columns or end column */
X static long redo_Visual_Prenum; /* Prenum for operator */
X
X Prenum = 0;
X /*
X * If there is an operator pending, then the command we take this time
X * will terminate it. Finish_op tells us to finish the operation before
X * returning this time (unless the operation was cancelled).
X */
X finish_op = (operator != NOP);
X
X if (!finish_op && !yankbuffer)
X opnum = 0;
X
X if (p_sc && (vpeekc() == NUL || KeyTyped == TRUE))
X premsg(NUL, NUL);
X State = NORMAL_BUSY;
X c = vgetc();
X
Xgetcount:
X /* Pick up any leading digits and compute 'Prenum' */
X while ((c >= '1' && c <= '9') || (Prenum != 0 && (c == DEL || c == '0')))
X {
X if (c == DEL)
X Prenum /= 10;
X else
X Prenum = Prenum * 10 + (c - '0');
X if (Prenum < 0) /* got too large! */
X Prenum = 999999999;
X premsg(ctrl_w ? Ctrl('W') : ' ', NUL);
X c = vgetc();
X }
X
X/*
X * If we got CTRL-W there may be a/another count
X */
X if (c == Ctrl('W') && !ctrl_w)
X {
X ctrl_w = TRUE;
X opnum = Prenum; /* remember first count */
X Prenum = 0;
X State = ONLYKEY; /* no mapping for nchar, but keys */
X premsg(c, NUL);
X c = vgetc(); /* get next character */
X goto getcount; /* jump back */
X }
X
X /*
X * If we're in the middle of an operator (including after entering a yank
X * buffer with ") AND we had a count before the
X * operator, then that count overrides the current value of Prenum. What
X * this means effectively, is that commands like "3dw" get turned into
X * "d3w" which makes things fall into place pretty neatly.
X * If you give a count before AND after the operator, they are multiplied.
X */
X if (opnum != 0)
X {
X if (Prenum)
X Prenum *= opnum;
X else
X Prenum = opnum;
X opnum = 0;
X }
X
X Prenum1 = (Prenum == 0 ? 1 : Prenum); /* Prenum often defaults to 1 */
X premsg(c, NUL);
X
X /*
X * get an additional character if we need one
X * for CTRL-W we already got it when looking for a count
X */
X if (ctrl_w)
X {
X nchar = c;
X c = Ctrl('W');
X premsg(c, nchar);
X }
X else if (strchr("@zZtTfF[]mg'`\"", c) || (c == 'q' && !Recording && !Exec_reg) ||
X (c == 'r' && !VIsual.lnum))
X {
X State = NOMAPPING;
X nchar = vgetc(); /* no macro mapping for this char */
X premsg(c, nchar);
X }
X if (p_sc)
X flushbuf(); /* flush the premsg() characters onto the screen so we can
X see them while the command is being executed */
X
X/*
X * For commands that don't get another character we can put the State back to
X * NORMAL and check for a window size change.
X */
X if (STRCHR("z:/?", c) == NULL)
X State = NORMAL;
X if (nchar == ESC)
X {
X CLEAROP;
X goto normal_end;
X }
X switch (c)
X {
X
X/*
X * 0: Macros
X */
X case 'q': /* (stop) recording into a named register */
X CHECKCLEAROP;
X /* command is ignored while executing a register */
X if (!Exec_reg && dorecord(nchar) == FAIL)
X CLEAROPBEEP;
X break;
X
X case '@': /* execute a named buffer */
X CHECKCLEAROP;
X while (Prenum1--)
X {
X if (doexecbuf(nchar) == FAIL)
X {
X CLEAROPBEEP;
X break;
X }
X }
X break;
X
X/*
X * 1: Screen positioning commands
X */
X case Ctrl('D'):
X flag = TRUE;
X
X case Ctrl('U'):
X CHECKCLEAROP;
X if (Prenum)
X curwin->w_p_scroll = (Prenum > curwin->w_height) ? curwin->w_height : Prenum;
X n = (curwin->w_p_scroll <= curwin->w_height) ? curwin->w_p_scroll : curwin->w_height;
X if (flag)
X {
X curwin->w_topline += n;


X if (curwin->w_topline > curbuf->b_ml.ml_line_count)
X curwin->w_topline = curbuf->b_ml.ml_line_count;

X comp_Botline(curwin); /* compute curwin->w_botline */
X (void)onedown(n);
X }
X else
X {
X if (n >= curwin->w_cursor.lnum)
X n = curwin->w_cursor.lnum - 1;
X Prenum1 = curwin->w_cursor.lnum - n;
X scrolldown(n);
X if (Prenum1 < curwin->w_cursor.lnum)
X curwin->w_cursor.lnum = Prenum1;
X }
X beginline(TRUE);
X updateScreen(VALID);
X break;
X
X case Ctrl('B'):
X case K_SUARROW:
X dir = BACKWARD;
X
X case Ctrl('F'):
X case K_SDARROW:
X CHECKCLEAROP;
X (void)onepage(dir, Prenum1);
X break;
X
X case Ctrl('E'):
X CHECKCLEAROP;
X scrollup(Prenum1);
X /* We may have moved to another line -- webb */
X coladvance(curwin->w_curswant);
X updateScreen(VALID);
X break;
X
X case Ctrl('Y'):
X CHECKCLEAROP;
X scrolldown(Prenum1);
X /* We may have moved to another line -- webb */
X coladvance(curwin->w_curswant);
X updateScreen(VALID);
X break;
X
X case 'z':
X CHECKCLEAROP;
X if (isdigit(nchar))
X {
X /*
X * we misuse some variables to be able to call premsg()
X */
X operator = c;
X opnum = Prenum;
X Prenum = nchar - '0';


X for (;;)
X {

X premsg(' ', NUL);
X nchar = vgetc();
X State = NORMAL;
X if (nchar == DEL)
X Prenum /= 10;
X else if (isdigit(nchar))
X Prenum = Prenum * 10 + (nchar - '0');
X else if (nchar == CR)
X {
X win_setheight((int)Prenum);
X break;
X }
X else
X {
X CLEAROPBEEP;
X break;
X }
X }
X operator = NOP;
X break;
X }
X
X if (Prenum && Prenum != curwin->w_cursor.lnum) /* line number given */
X {
X setpcmark();
X if (Prenum > curbuf->b_ml.ml_line_count)
X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X else
X curwin->w_cursor.lnum = Prenum;
X }
X State = NORMAL; /* for updateScreen() */
X switch (nchar)
X {
X case NL: /* put curwin->w_cursor at top of screen */
X case CR:
X beginline(TRUE);
X case 't':


X curwin->w_topline = curwin->w_cursor.lnum;

X break;
X
X case '.': /* put curwin->w_cursor in middle of screen */
X case 'z':
X n = (curwin->w_height + plines(curwin->w_cursor.lnum)) / 2;
X goto dozcmd;
X
X case '-': /* put curwin->w_cursor at bottom of screen */
X case 'b':
X n = curwin->w_height;
X /* FALLTHROUGH */
X
X dozcmd:
X {
X register linenr_t lp = curwin->w_cursor.lnum;
X register long l = plines(lp);
X
X do
X {
X curwin->w_topline = lp;
X if (--lp == 0)
X break;
X l += plines(lp);
X } while (l <= n);
X }
X if (nchar != 'z' && nchar != 'b')
X beginline(TRUE);
X break;
X
X case Ctrl('S'): /* ignore CTRL-S and CTRL-Q to avoid problems */
X case Ctrl('Q'): /* with terminals that use xon/xoff */


X break;
X
X default:

X CLEAROPBEEP;
X }
X updateScreen(VALID);
X break;
X
X/*
X * 2: Control commands
X */
X case ':':
X if (VIsual.lnum)
X goto dooperator;
X CHECKCLEAROP;
X /*
X * translate "count:" into ":.,.+(count - 1)"
X */
X if (Prenum)
X {
X stuffReadbuff((char_u *)".");
X if (Prenum > 1)
X {
X stuffReadbuff((char_u *)",.+");
X stuffnumReadbuff((long)Prenum - 1L);
X }
X }
X docmdline(NULL);
X modified = TRUE;
X break;
X
X case K_HELP:
X CHECKCLEAROP;


X help();
X break;
X

X case Ctrl('L'):
X CHECKCLEAROP;
X updateScreen(CLEAR);
X break;
X
X case Ctrl('G'):
X CHECKCLEAROP;
X fileinfo(did_cd || Prenum); /* print full name if count given or :cd used */
X break;
X
X case K_CCIRCM: /* CTRL-^, short for ":e #" */
X CHECKCLEAROPQ;
X (void)buflist_getfile((int)Prenum, (linenr_t)0, TRUE);
X break;
X
X case 'Z': /* write, if changed, and exit */
X CHECKCLEAROPQ;
X if (nchar != 'Z')
X {
X CLEAROPBEEP;
X break;
X }
X stuffReadbuff((char_u *)":x\n");
X break;
X
X case Ctrl(']'): /* :ta to current identifier */
X CHECKCLEAROPQ;
X case '*': /* / to current identifier or string */
X case '#': /* ? to current identifier or string */
X case 'K': /* run program for current identifier */
X {
X register int col;
X register int i;
X
X /*
X * if i == 0: try to find an identifier
X * if i == 1: try to find any string
X */
X ptr = ml_get(curwin->w_cursor.lnum);
X for (i = 0; i < 2; ++i)
X {
X /*
X * skip to start of identifier/string
X */
X col = curwin->w_cursor.col;
X while (ptr[col] != NUL &&
X (i == 0 ? !isidchar(ptr[col]) : iswhite(ptr[col])))
X ++col;
X
X /*
X * Back up to start of identifier/string. This doesn't match the
X * real vi but I like it a little better and it shouldn't bother
X * anyone.
X */
X while (col > 0 && (i == 0 ? isidchar(ptr[col - 1]) :
X (!iswhite(ptr[col - 1]) && !isidchar(ptr[col - 1]))))
X --col;
X
X /*
X * if identifier found or not '*' or '#' command, stop searching
X */
X if (isidchar(ptr[col]) || (c != '*' && c != '#'))
X break;
X }
X /*
X * did't find an identifier of string
X */
X if (ptr[col] == NUL || (!isidchar(ptr[col]) && i == 0))
X {
X CLEAROPBEEP;
X break;
X }
X
X if (Prenum)
X stuffnumReadbuff(Prenum);
X switch (c)
X {
X case '*':
X stuffReadbuff((char_u *)"/");
X goto sow;
X
X case '#':
X stuffReadbuff((char_u *)"?");
Xsow: if (i == 0)
X stuffReadbuff((char_u *)"\\<");
X break;
X
X case 'K':
X stuffReadbuff((char_u *)":! ");
X stuffReadbuff(p_kp);
X stuffReadbuff((char_u *)" ");
X break;
X default:
X stuffReadbuff((char_u *)":ta ");
X }
X
X /*
X * Now grab the chars in the identifier
X */
X while (i == 0 ? isidchar(ptr[col]) :
X (ptr[col] != NUL && !iswhite(ptr[col])))
X {
X stuffcharReadbuff(ptr[col]);
X ++col;
X }
X if ((c == '*' || c == '#') && i == 0)
X stuffReadbuff((char_u *)"\\>");
X stuffReadbuff((char_u *)"\n");
X }
X break;
X
X case Ctrl('T'): /* backwards in tag stack */
X CHECKCLEAROPQ;
X dotag((char_u *)"", 2, (int)Prenum1);
X break;
X
X/*
X * Cursor motions
X */
X case 'G':
X mtype = MLINE;
X setpcmark();
X if (Prenum == 0 || Prenum > curbuf->b_ml.ml_line_count)
X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X else
X curwin->w_cursor.lnum = Prenum;
X beginline(TRUE);
X break;
X
X case 'H':
X case 'M':
X if (c == 'M')
X n = (curwin->w_height - curwin->w_empty_rows) / 2;
X else
X n = Prenum;
X mtype = MLINE;
X setpcmark();


X curwin->w_cursor.lnum = curwin->w_topline;

X while (n && onedown((long)1) == OK)
X --n;
X beginline(TRUE);
X break;
X
X case 'L':
X mtype = MLINE;
X setpcmark();
X curwin->w_cursor.lnum = curwin->w_botline - 1;
X for (n = Prenum; n && oneup((long)1) == OK; n--)
X ;
X beginline(TRUE);
X break;
X
X case 'l':
X case K_RARROW:
X case ' ':
X mtype = MCHAR;
X mincl = FALSE;
X n = Prenum1;
X while (n--)
X {
X if (oneright() == FAIL)
X {
X /* space wraps to next line if 'whichwrap' bit 1 set */
X /* 'l' wraps to next line if 'whichwrap' bit 2 set */
X /* CURS_RIGHT wraps to next line if 'whichwrap' bit 3 set */
X if (((c == ' ' && (p_ww & 2)) ||
X (c == 'l' && (p_ww & 4)) ||
X (c == K_RARROW && (p_ww & 8))) &&
X curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
X {
X ++curwin->w_cursor.lnum;


X curwin->w_cursor.col = 0;

X curwin->w_set_curswant = TRUE;
X continue;
X }
X if (operator == NOP)
X beep();
X else
X {
X if (lineempty(curwin->w_cursor.lnum))
X CLEAROPBEEP;
X else
X {
X mincl = TRUE;
X if (n)
X beep();
X }


X }
X break;
X }
X }

X break;
X
X case Ctrl('H'):
X case 'h':
X case K_LARROW:
X case DEL:
X mtype = MCHAR;
X mincl = FALSE;
X n = Prenum1;
X while (n--)
X {
X if (oneleft() == FAIL)
X {
X /* backspace and del wrap to previous line if 'whichwrap'
X * bit 0 set */
X /* 'h' wraps to previous line if 'whichwrap' bit 2 set */
X /* CURS_LEFT wraps to previous line if 'whichwrap' bit 3 set */
X if ((((c == Ctrl('H') || c == DEL) && (p_ww & 1)) ||
X (c == 'h' && (p_ww & 4)) ||
X (c == K_LARROW && (p_ww & 8))) &&
X curwin->w_cursor.lnum > 1)
X {
X --(curwin->w_cursor.lnum);
X coladvance(MAXCOL);
X curwin->w_set_curswant = TRUE;
X continue;
X }
X else if (operator != DELETE && operator != CHANGE)
X beep();
X else if (Prenum1 == 1)
X CLEAROPBEEP;
X break;
X }
X }
X break;
X
X case '-':
X flag = TRUE;
X /* FALLTHROUGH */
X
X case 'k':
X case K_UARROW:
X case Ctrl('P'):
X mtype = MLINE;
X if (oneup(Prenum1) == FAIL)
X CLEAROPBEEP;
X else if (flag)
X beginline(TRUE);
X break;
X
X case '+':
X case CR:
X flag = TRUE;
X /* FALLTHROUGH */
X
X case 'j':
X case K_DARROW:
X case Ctrl('N'):
X case NL:
X mtype = MLINE;
X if (onedown(Prenum1) == FAIL)
X CLEAROPBEEP;
X else if (flag)
X beginline(TRUE);
X break;
X
X /*
X * This is a strange motion command that helps make operators more
X * logical. It is actually implemented, but not documented in the
X * real 'vi'. This motion command actually refers to "the current
X * line". Commands like "dd" and "yy" are really an alternate form of
X * "d_" and "y_". It does accept a count, so "d3_" works to delete 3
X * lines.
X */
X case '_':
Xlineop:
X mtype = MLINE;
X if (onedown((long)(Prenum1 - 1)) == FAIL)
X CLEAROPBEEP;
X if (operator != YANK) /* 'Y' does not move cursor */
X beginline(TRUE);
X break;
X
X case '|':
X mtype = MCHAR;
X mincl = TRUE;
X beginline(FALSE);
X if (Prenum > 0)
X coladvance((colnr_t)(Prenum - 1));
X curwin->w_curswant = (colnr_t)(Prenum - 1);
X /* keep curswant at the column where we wanted to go, not where
X we ended; differs is line is too short */


X curwin->w_set_curswant = FALSE;

X break;
X
X /*
X * Word Motions
X */
X
X case 'B':
X type = 1;
X /* FALLTHROUGH */
X
X case 'b':
X case K_SLARROW:
X mtype = MCHAR;
X mincl = FALSE;
X curwin->w_set_curswant = TRUE;
X if (bck_word(Prenum1, type))
X CLEAROPBEEP;
X break;
X
X case 'E':
X type = 1;
X /* FALLTHROUGH */
X
X case 'e':
X mincl = TRUE;
X goto dowrdcmd;
X
X case 'W':
X type = 1;
X /* FALLTHROUGH */
X
X case 'w':
X case K_SRARROW:
X mincl = FALSE;
X flag = TRUE;
X /*
X * This is a little strange. To match what the real vi does, we
X * effectively map 'cw' to 'ce', and 'cW' to 'cE', provided that we are
X * not on a space or a TAB. This seems
X * impolite at first, but it's really more what we mean when we say
X * 'cw'.
X * Another strangeness: When standing on the end of a word "ce" will
X * change until the end of the next wordt, but "cw" will change only
X * one character! This is done by setting type to 2.
X */
X if (operator == CHANGE && (n = gchar_cursor()) != ' ' && n != TAB &&
X n != NUL)
X {
X mincl = TRUE;
X flag = FALSE;
X flag2 = TRUE;
X }
X
Xdowrdcmd:
X mtype = MCHAR;
X curwin->w_set_curswant = TRUE;
X if (flag)
X n = fwd_word(Prenum1, type, operator != NOP);
X else
X n = end_word(Prenum1, type, flag2);
X if (n)
X {
X CLEAROPBEEP;
X break;
X }
X#if 0
X /*
X * If we do a 'dw' for the last word in a line, we only delete the rest
X * of the line, not joining the two lines, unless the current line is empty.
X */
X if (operator == DELETE && Prenum1 == 1 &&
X curbuf->b_startop.lnum != curwin->w_cursor.lnum && !lineempty(startop.lnum))
X {
X curwin->w_cursor = curbuf->b_startop;
X while (oneright() == OK)
X ;
X mincl = TRUE;
X }
X#endif
X break;
X
X case '$':
X mtype = MCHAR;
X mincl = TRUE;
X curwin->w_curswant = MAXCOL; /* so we stay at the end */
X if (onedown((long)(Prenum1 - 1)) == FAIL)
X {
X CLEAROPBEEP;


X break;
X }
X break;
X

X case '^':
X flag = TRUE;
X /* FALLTHROUGH */
X
X case '0':
X mtype = MCHAR;
X mincl = FALSE;
X beginline(flag);
X break;
X
X/*
X * 4: Searches
X */
X case '?':
X case '/':
X if (!getcmdline(c, searchbuff))
X {
X CLEAROP;
X break;
X }
X mtype = MCHAR;
X mincl = FALSE;
X curwin->w_set_curswant = TRUE;
X
X n = dosearch(c, searchbuff, FALSE, Prenum1, TRUE, TRUE);
X if (n == 0)
X CLEAROP;
X else if (n == 2)
X mtype = MLINE;
X break;
X
X case 'N':
X flag = 1;
X
X case 'n':
X mtype = MCHAR;
X mincl = FALSE;
X curwin->w_set_curswant = TRUE;
X if (!dosearch(0, NULL, flag, Prenum1, TRUE, TRUE))
X CLEAROP;
X break;
X
X /*
X * Character searches
X */
X case 'T':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case 't':
X type = 1;
X goto docsearch;
X
X case 'F':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case 'f':
Xdocsearch:
X mtype = MCHAR;
X if (dir == BACKWARD)
X mincl = FALSE;
X else
X mincl = TRUE;
X curwin->w_set_curswant = TRUE;
X if (!searchc(nchar, dir, type, Prenum1))
X CLEAROPBEEP;
X break;
X
X case ',':
X flag = 1;
X /* FALLTHROUGH */
X
X case ';':
X dir = flag;
X goto docsearch; /* nchar == NUL, thus repeat previous search */
X
X /*
X * section or C function searches
X */
X case '[':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case ']':
X mtype = MCHAR;
X mincl = FALSE;
X
X /*
X * "[f" or "]f" : Edit file under the cursor (same as "gf")
X */
X if ((c == ']' || c == '[') && nchar == 'f')
X goto gotofile;
X
X /*
X * "[{", "[(", "]}" or "])": go to Nth unclosed '{', '(', '}' or ')'
X */
X if ((c == '[' && (nchar == '{' || nchar == '(')) ||
X ((c == ']' && (nchar == '}' || nchar == ')'))))
X {
X FPOS old_pos;
X
X old_pos = curwin->w_cursor;
X while (Prenum1--)
X {
X if ((pos = showmatch(nchar)) == NULL)
X {
X CLEAROPBEEP;
X break;
X }
X curwin->w_cursor = *pos;
X }
X curwin->w_cursor = old_pos;
X if (pos != NULL)
X {
X setpcmark();
X curwin->w_cursor = *pos;
X curwin->w_set_curswant = TRUE;
X }
X break;
X }
X
X /*
X * "[[", "[]", "]]" and "][": move to start or end of function
X */
X if (nchar == '[' || nchar == ']')
X {
X if (nchar == c) /* "]]" or "[[" */
X flag = '{';
X else
X flag = '}'; /* "][" or "[]" */
X
X curwin->w_set_curswant = TRUE;
X /*
X * Imitate strange vi behaviour: When using "]]" with an operator we
X * also stop at '}'.
X */
X if (!findpar(dir, Prenum1, flag,
X (operator != NOP && dir == FORWARD && flag == '{')))
X CLEAROPBEEP;
X break;
X }
X
X /*
X * "[p" and "]p": put with indent adjustment
X */
X if (nchar == 'p')
X {
X doput((c == ']') ? FORWARD : BACKWARD, Prenum1, TRUE);
X modified = TRUE;
X break;
X }
X
X /*
X * end of '[' and ']': not a valid nchar
X */
X CLEAROPBEEP;
X break;
X
X case '%':
X mincl = TRUE;
X if (Prenum) /* {cnt}% : goto {cnt} percentage in file */
X {
X if (Prenum > 100)
X CLEAROPBEEP;
X else
X {
X mtype = MLINE;
X setpcmark();
X /* round up, so CTRL-G will give same value */
X curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count * Prenum + 99) / 100;
X beginline(TRUE);
X }
X }
X else /* % : go to matching paren */
X {
X mtype = MCHAR;
X if ((pos = showmatch(NUL)) == NULL)
X CLEAROPBEEP;
X else
X {
X setpcmark();
X curwin->w_cursor = *pos;
X curwin->w_set_curswant = TRUE;
X }
X }
X break;
X
X case '(':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case ')':
X mtype = MCHAR;
X if (c == ')')
X mincl = FALSE;
X else
X mincl = TRUE;
X curwin->w_set_curswant = TRUE;
X
X if (!findsent(dir, Prenum1))
X CLEAROPBEEP;
X break;
X
X case '{':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case '}':
X mtype = MCHAR;
X mincl = FALSE;
X curwin->w_set_curswant = TRUE;
X if (!findpar(dir, Prenum1, NUL, FALSE))
X CLEAROPBEEP;
X break;
X
X/*
X * 5: Edits
X */
X case '.':
X CHECKCLEAROPQ;
X if (start_redo(Prenum) == FAIL)
X CLEAROPBEEP;
X modified = TRUE;
X break;
X
X case 'u':
X if (VIsual.lnum)
X goto dooperator;
X case K_UNDO:
X CHECKCLEAROPQ;
X u_undo((int)Prenum1);
X curwin->w_set_curswant = TRUE;
X modified = TRUE;
X break;
X
X case Ctrl('R'):
X CHECKCLEAROPQ;
X u_redo((int)Prenum1);
X curwin->w_set_curswant = TRUE;
X modified = TRUE;
X break;
X
X case 'U':
X if (VIsual.lnum)
X goto dooperator;
X CHECKCLEAROPQ;
X u_undoline();
X curwin->w_set_curswant = TRUE;
X modified = TRUE;
X break;
X
X case 'r':
X if (VIsual.lnum)
X {
X c = 'c';
X goto dooperator;
X }
X CHECKCLEAROPQ;
X ptr = ml_get_cursor();
X if (STRLEN(ptr) < (unsigned)Prenum1) /* not enough characters to replace */
X {
X CLEAROPBEEP;
X break;
X }
X /*
X * Replacing with a line break or tab is done by edit(), because it
X * is complicated.
X * Other characters are done below to avoid problems with things like
X * CTRL-V 048 (for edit() this would be R CTRL-V 0 ESC).
X */
X if (nchar == '\r' || nchar == '\n' || nchar == '\t')
X {
X prep_redo(Prenum1, 'r', nchar, NUL);
X stuffnumReadbuff(Prenum1);
X stuffcharReadbuff('R');
X stuffcharReadbuff(nchar);
X stuffcharReadbuff(ESC);
X break;
X }
X
X if (nchar == Ctrl('V')) /* get another character */
X {
X c = Ctrl('V');
X nchar = get_literal(&type);
X if (type) /* typeahead */
X stuffcharReadbuff(type);
X }
X else
X c = NUL;
X prep_redo(Prenum1, 'r', c, nchar);
X if (!u_save_cursor()) /* save line for undo */
X break;
X /*
X * Get ptr again, because u_save will have released the line.
X * At the same time we let know that the line will be changed.
X */
X ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE) + curwin->w_cursor.col;
X curwin->w_cursor.col += Prenum1 - 1;
X while (Prenum1--) /* replace the characters */
X *ptr++ = nchar;
X curwin->w_set_curswant = TRUE;
X CHANGED;
X updateline();
X modified = TRUE;
X break;
X
X case 'J':
X if (VIsual.lnum) /* join the visual lines */
X {
X if (curwin->w_cursor.lnum > VIsual.lnum)
X {
X Prenum = curwin->w_cursor.lnum - VIsual.lnum + 1;
X curwin->w_cursor.lnum = VIsual.lnum;
X }
X else
X Prenum = VIsual.lnum - curwin->w_cursor.lnum + 1;
X VIsual.lnum = 0;
X }
X CHECKCLEAROP;
X if (Prenum <= 1)
X Prenum = 2; /* default for join is two lines! */
X if (curwin->w_cursor.lnum + Prenum - 1 > curbuf->b_ml.ml_line_count) /* beyond last line */
X {
X CLEAROPBEEP;
X break;
X }
X
X prep_redo(Prenum, 'J', NUL, NUL);
X dodojoin(Prenum, TRUE, TRUE);
X modified = TRUE;
X break;
X
X case 'P':
X dir = BACKWARD;
X /* FALLTHROUGH */
X
X case 'p':
X CHECKCLEAROPQ;
X prep_redo(Prenum, c, NUL, NUL);
X doput(dir, Prenum1, FALSE);
X modified = TRUE;
X break;
X
X case Ctrl('A'): /* add to number */
X case Ctrl('X'): /* subtract from number */
X CHECKCLEAROPQ;
X if (doaddsub((int)c, Prenum1) == OK)
X prep_redo(Prenum1, c, NUL, NUL);
X modified = TRUE;
X break;
X
X/*
X * 6: Inserts
X */
X case 'A':
X curwin->w_set_curswant = TRUE;
X while (oneright() == OK)
X ;
X /* FALLTHROUGH */
X
X case 'a':
X CHECKCLEAROPQ;
X /* Works just like an 'i'nsert on the next character. */
X if (u_save_cursor())
X {
X if (!lineempty(curwin->w_cursor.lnum))
X inc_cursor();
X startinsert(c, FALSE, Prenum1);
X modified = TRUE;
X command_busy = TRUE;
X }
X break;
X
X case 'I':
X beginline(TRUE);
X /* FALLTHROUGH */
X
X case 'i':
X CHECKCLEAROPQ;
X if (u_save_cursor())
X {
X startinsert(c, FALSE, Prenum1);
X modified = TRUE;
X command_busy = TRUE;
X }
X break;
X
X case 'o':
X if (VIsual.lnum) /* switch start and end of visual */
X {
X Prenum = VIsual.lnum;
X VIsual.lnum = curwin->w_cursor.lnum;
X curwin->w_cursor.lnum = Prenum;
X if (VIsual.col != VISUALLINE)
X {
X n = VIsual.col;
X VIsual.col = curwin->w_cursor.col;
X curwin->w_cursor.col = (int)n;
X curwin->w_set_curswant = TRUE;
X }
X break;
X }
X CHECKCLEAROP;
X if (u_save(curwin->w_cursor.lnum, (linenr_t)(curwin->w_cursor.lnum + 1)) &&
X Opencmd(FORWARD, TRUE, TRUE))
X {
X startinsert('o', TRUE, Prenum1);
X modified = TRUE;
X command_busy = TRUE;
X }
X break;
X
X case 'O':
X CHECKCLEAROPQ;
X if (u_save((linenr_t)(curwin->w_cursor.lnum - 1), curwin->w_cursor.lnum) && Opencmd(BACKWARD, TRUE, TRUE))
X {
X startinsert('O', TRUE, Prenum1);
X modified = TRUE;
X command_busy = TRUE;
X }
X break;
X
X case 'R':
X if (VIsual.lnum)
X {
X c = 'c';
X VIsual.col = VISUALLINE;
X goto dooperator;
X }
X CHECKCLEAROPQ;
X if (u_save_cursor())
X {
X startinsert('R', FALSE, Prenum1);
X modified = TRUE;
X command_busy = TRUE;
X }
X break;
X
X/*
X * 7: Operators
X */
X case '~': /* swap case */
X /*
X * if tilde is not an operator and Visual is off: swap case
X * of a single character
X */
X if (!p_to && !VIsual.lnum)
X {
X CHECKCLEAROPQ;
X if (lineempty(curwin->w_cursor.lnum))
X {
X CLEAROPBEEP;
X break;
X }
X prep_redo(Prenum, '~', NUL, NUL);
X
X if (!u_save_cursor())
X break;
X
X for (; Prenum1 > 0; --Prenum1)
X {
X if (gchar_cursor() == NUL)
X break;
X swapchar(&curwin->w_cursor);
X inc_cursor();
X }
X
X curwin->w_set_curswant = TRUE;
X CHANGED;
X updateline();
X modified = TRUE;
X break;
X }
X /*FALLTHROUGH*/
X
X case 'd':
X case 'c':
X case 'y':
X case '>':
X case '<':
X case '!':
X case '=':
X case 'Q':
Xdooperator:
X n = STRCHR(opchars, c) - opchars + 1;
X if (n == operator) /* double operator works on lines */
X goto lineop;
X CHECKCLEAROP;
X if (Prenum != 0)
X opnum = Prenum;
X curbuf->b_startop = curwin->w_cursor;
X operator = (int)n;
X break;
X
X/*
X * 8: Abbreviations
X */
X
X /* when Visual the next commands are operators */
X case 'S':
X case 'Y':
X case 'D':
X case 'C':
X case 'x':
X case 'X':
X case 's':
X if (VIsual.lnum)
X {
X static char_u trans[] = "ScYyDdCcxdXdsc";
X
X if (isupper(c) && !Visual_block) /* uppercase means linewise */
X VIsual.col = VISUALLINE;
X c = *(STRCHR(trans, c) + 1);
X goto dooperator;
X }
X
X case '&':
X CHECKCLEAROPQ;
X if (Prenum)
X stuffnumReadbuff(Prenum);
X
X if (c == 'Y' && p_ye)
X c = 'Z';
X {
X static char_u *(ar[9]) = {(char_u *)"dl", (char_u *)"dh", (char_u *)"d$", (char_u *)"c$", (char_u *)"cl", (char_u *)"cc", (char_u *)"yy", (char_u *)"y$", (char_u *)":s\r"};
X static char_u *str = (char_u *)"xXDCsSYZ&";
X
X stuffReadbuff(ar[(int)(STRCHR(str, c) - str)]);
X }
X break;
X
X/*
X * 9: Marks
X */
X
X case 'm':
X CHECKCLEAROP;
X if (setmark(nchar) == FAIL)
X CLEAROPBEEP;
X break;
X
X case '\'':
X flag = TRUE;
X /* FALLTHROUGH */
X
X case '`':
X pos = getmark(nchar, (operator == NOP));
X if (pos == (FPOS *)-1) /* jumped to other file */
X {
X if (flag)
X beginline(TRUE);
X break;
X }
X
X if (pos != NULL)
X setpcmark();
X
Xcursormark:
X if (pos == NULL || pos->lnum == 0)
X CLEAROPBEEP;
X else
X {
X curwin->w_cursor = *pos;
X if (flag)
X beginline(TRUE);
X }
X mtype = flag ? MLINE : MCHAR;
X mincl = FALSE; /* ignored if not MCHAR */
X curwin->w_set_curswant = TRUE;
X break;
X
X case Ctrl('O'): /* goto older pcmark */
X Prenum1 = -Prenum1;
X /* FALLTHROUGH */
X
X case Ctrl('I'): /* goto newer pcmark */
X CHECKCLEAROPQ;
X pos = movemark((int)Prenum1);
X if (pos == (FPOS *)-1) /* jump to other file */
X {
X curwin->w_set_curswant = TRUE;
X break;
X }
X goto cursormark;
X
X/*
X * 10. Buffer setting
X */
X case '"':
X CHECKCLEAROP;
X if (nchar != NUL && is_yank_buffer(nchar, FALSE))
X {
X yankbuffer = nchar;
X opnum = Prenum; /* remember count before '"' */
X }
X else
X CLEAROPBEEP;
X break;
X
X/*
X * 11. Visual
X */
X case 'v':
X case 'V':
X case Ctrl('V'):
X CHECKCLEAROP;
X Visual_block = FALSE;
X
X /* stop Visual */
X if (VIsual.lnum)
X {
X VIsual.lnum = 0;
X updateScreen(NOT_VALID); /* delete the inversion */
X }
X /* start Visual */
X else
X {
X if (!didwarn && set_highlight('v') == FAIL)/* cannot highlight */
X {
X EMSG("Warning: terminal cannot highlight");
X didwarn = TRUE;
X }
X if (Prenum) /* use previously selected part */
X {
X if (!resel_Visual_type) /* there is none */


X {
X beep();
X break;
X }

X VIsual = curwin->w_cursor;
X if (resel_Visual_nlines > 1)
X curwin->w_cursor.lnum += resel_Visual_nlines * Prenum - 1;
X switch (resel_Visual_type)
X {
X case 'V': VIsual.col = VISUALLINE;
X break;
X
X case Ctrl('V'):
X Visual_block = TRUE;
X break;
X
X case 'v':
X if (resel_Visual_nlines <= 1)
X curwin->w_cursor.col += resel_Visual_col * Prenum - 1;
X else
X curwin->w_cursor.col = resel_Visual_col;
X break;
X }
X if (resel_Visual_col == MAXCOL)
X {
X curwin->w_curswant = MAXCOL;
X coladvance(MAXCOL);
X }
X else if (Visual_block)
X coladvance((colnr_t)(curwin->w_virtcol + resel_Visual_col * Prenum - 1));
X curs_columns(TRUE); /* recompute w_virtcol */
X updateScreen(NOT_VALID); /* show the inversion */
X }
X else
X {
X VIsual = curwin->w_cursor;
X if (c == 'V') /* linewise */
X VIsual.col = VISUALLINE;
X else if (c == Ctrl('V')) /* blockwise */
X Visual_block = TRUE;
X updateline(); /* start the inversion */


X }
X }
X break;
X

X/*
X * 12. Suspend
X */
X
X case Ctrl('Z'):
X CLEAROP;
X VIsual.lnum = 0; /* stop Visual */
X stuffReadbuff((char_u *)":st\r"); /* with autowrite */
X break;
X
X/*
X * 13. Window commands
X */
X
X case Ctrl('W'):
X CHECKCLEAROP;
X do_window(nchar, Prenum); /* everything is in window.c */
X break;
X
X/*
X * 14. extended commands (starting with 'g')
X */
X case 'g':
X switch (nchar)
X {
X /*
X * "gf": goto file, edit file under cursor
X * "]f" and "[f": can also be used.
X */
X case 'f':
Xgotofile:
X ptr = file_name_at_cursor();
X /* do autowrite if necessary */
X if (curbuf->b_changed && curbuf->b_nwindows <= 1 && !p_hid)
X autowrite(curbuf);
X if (ptr != NULL)
X {
X setpcmark();
X stuffReadbuff((char_u *) ":e ");
X stuffReadbuff(ptr);
X stuffReadbuff((char_u *) "\n");
X free(ptr);
X }
X else
X CLEAROPBEEP;
X break;
X
X /*
X * "gs": goto sleep
X */
X case 's': while (Prenum1-- && !got_int)
X {
X sleep(1);
X breakcheck();
X }
X break;
X
X default: CLEAROPBEEP;


X break;
X }
X break;

X
X/*
X * The end
X */
X case ESC:
X if (VIsual.lnum)
X {
X VIsual.lnum = 0; /* stop Visual */
X updateScreen(NOT_VALID);
X CLEAROP; /* don't beep */
X break;
X }
X /* Don't drop through and beep if we are canceling a command: */
X else if (operator != NOP || opnum || Prenum || yankbuffer)
X {
X CLEAROP; /* don't beep */
X break;
X }
X /* FALLTHROUGH */
X
X default: /* not a known command */
X CLEAROPBEEP;
X break;
X
X } /* end of switch on command character */
X
X/*
X * if we didn't start or finish an operator, reset yankbuffer, unless we
X * need it later.
X */
X if (!finish_op && !operator && strchr("\"DCYSsXx.", c) == NULL)
X yankbuffer = 0;
X
X /*
X * If an operation is pending, handle it...
X */
X if ((VIsual.lnum || finish_op) && operator != NOP)
X {
X if (operator != YANK && !VIsual.lnum) /* can't redo yank */
X {
X prep_redo(Prenum, opchars[operator - 1], c, nchar);
X if (c == '/' || c == '?') /* was a search */
X {
X AppendToRedobuff(searchbuff);
X AppendToRedobuff(NL_STR);
X }
X }
X
X if (redo_Visual_busy)
X {
X curbuf->b_startop = curwin->w_cursor;
X curwin->w_cursor.lnum += redo_Visual_nlines - 1;
X switch (redo_Visual_type)
X {
X case 'V': VIsual.col = VISUALLINE;
X break;
X
X case Ctrl('V'):
X Visual_block = TRUE;
X break;
X
X case 'v':
X if (redo_Visual_nlines <= 1)
X curwin->w_cursor.col += redo_Visual_col - 1;
X else
X curwin->w_cursor.col = redo_Visual_col;
X break;
X }
X if (redo_Visual_col == MAXCOL)
X {
X curwin->w_curswant = MAXCOL;
X coladvance(MAXCOL);
X }
X Prenum = redo_Visual_Prenum;
X if (Prenum == 0)
X Prenum1 = 1L;
X else
X Prenum1 = Prenum;
X }
X else if (VIsual.lnum)
X curbuf->b_startop = VIsual;
X
X if (lt(curbuf->b_startop, curwin->w_cursor))
X {
X curbuf->b_endop = curwin->w_cursor;
X curwin->w_cursor = curbuf->b_startop;
X }
X else
X {
X curbuf->b_endop = curbuf->b_startop;
X curbuf->b_startop = curwin->w_cursor;
X }
X nlines = curbuf->b_endop.lnum - curbuf->b_startop.lnum + 1;
X
X if (VIsual.lnum || redo_Visual_busy)


X {
X if (Visual_block) /* block mode */
X {

X startvcol = getvcol(curwin, &(curbuf->b_startop), 2);
X n = getvcol(curwin, &(curbuf->b_endop), 2);
X if (n < startvcol)
X startvcol = (colnr_t)n;
X
X /* if '$' was used, get endvcol from longest line */
X if (curwin->w_curswant == MAXCOL)
X {
X curwin->w_cursor.col = MAXCOL;
X endvcol = 0;
X for (curwin->w_cursor.lnum = curbuf->b_startop.lnum; curwin->w_cursor.lnum <= curbuf->b_endop.lnum; ++curwin->w_cursor.lnum)
X if ((n = getvcol(curwin, &curwin->w_cursor, 3)) > endvcol)
X endvcol = (colnr_t)n;
X curwin->w_cursor = curbuf->b_startop;
X }
X else if (redo_Visual_busy)
X endvcol = startvcol + redo_Visual_col - 1;
X else
X {
X endvcol = getvcol(curwin, &(curbuf->b_startop), 3);
X n = getvcol(curwin, &(curbuf->b_endop), 3);
X if (n > endvcol)
X endvcol = (colnr_t)n;
X }
X coladvance(startvcol);
X }
X
X /*
X * prepare to reselect and redo Visual: this is based on the size
X * of the Visual text
X */
X if (Visual_block)
X resel_Visual_type = Ctrl('V');
X else if (VIsual.col == VISUALLINE)
X resel_Visual_type = 'V';
X else
X resel_Visual_type = 'v';
X if (curwin->w_curswant == MAXCOL)
X resel_Visual_col = MAXCOL;
X else if (Visual_block)
X resel_Visual_col = endvcol - startvcol + 1;
X else if (nlines > 1)
X resel_Visual_col = curbuf->b_endop.col;
X else
X resel_Visual_col = curbuf->b_endop.col - curbuf->b_startop.col + 1;
X resel_Visual_nlines = nlines;
X if (operator != YANK && operator != COLON) /* can't redo yank and : */
X {
X prep_redo(0L, 'v', opchars[operator - 1], NUL);
X redo_Visual_type = resel_Visual_type;
X redo_Visual_col = resel_Visual_col;
X redo_Visual_nlines = resel_Visual_nlines;
X redo_Visual_Prenum = Prenum;
X }
X
X /*
X * Mincl defaults to TRUE.
X * If endop is on a NUL (empty line) mincl becomes FALSE
X * This makes "d}P" and "v}dP" work the same.
X */
X mincl = TRUE;


X if (VIsual.col == VISUALLINE)

X mtype = MLINE;
X else
X {
X mtype = MCHAR;
X if (*ml_get_pos(&(curbuf->b_endop)) == NUL)
X mincl = FALSE;
X }
X
X redo_Visual_busy = FALSE;
X /*
X * Switch Visual off now, so screen updating does
X * not show inverted text when the screen is redrawn.
X * With YANK and sometimes with COLON and FILTER there is no screen
X * redraw, so it is done here to remove the inverted part.
X */
X VIsual.lnum = 0;
X if (operator == YANK || operator == COLON || operator == FILTER)
X updateScreen(NOT_VALID);
X }
X else if (operator == LSHIFT || operator == RSHIFT)
X Prenum1 = 1L; /* if not visual mode: shift one indent */
X
X curwin->w_set_curswant = 1;
X
X /* no_op is set when start and end are the same */
X no_op = (mtype == MCHAR && !mincl && equal(curbuf->b_startop, curbuf->b_endop));
X
X /*
X * If the end of an operator is in column one while mtype is MCHAR and mincl
X * is FALSE, we put endop after the last character in the previous line.
X * If startop is on or before the first non-blank in the line, the operator
X * becomes linewise (strange, but that's the way vi does it).
X */
X if (mtype == MCHAR && mincl == FALSE && curbuf->b_endop.col == 0 && nlines > 1)
X {
X --nlines;
X --curbuf->b_endop.lnum;
X if (inindent())
X mtype = MLINE;
X else
X {
X curbuf->b_endop.col = STRLEN(ml_get(curbuf->b_endop.lnum));
X if (curbuf->b_endop.col)
X {
X --curbuf->b_endop.col;
X mincl = TRUE;
X }
X }
X }
X switch (operator)
X {
X case LSHIFT:
X case RSHIFT:
X doshift(operator, TRUE, (int)Prenum1);
X modified = TRUE;
X break;
X
X case DELETE:
X if (!no_op)
X {
X dodelete();
X modified = TRUE;
X }
X break;
X
X case YANK:
X if (!no_op)
X (void)doyank(FALSE);
X break;
X
X case CHANGE:
X dochange();
X modified = TRUE;
X command_busy = TRUE;
X break;
X
X case FILTER:
X bangredo = TRUE; /* dobang() will put cmd in redo buffer */
X
X case INDENT:
X case COLON:
Xdofilter:
X sprintf((char *)IObuff, ":%ld,%ld", (long)curbuf->b_startop.lnum, (long)curbuf->b_endop.lnum);
X stuffReadbuff(IObuff);
X if (operator != COLON)
X stuffReadbuff((char_u *)"!");
X if (operator == INDENT)
X {
X stuffReadbuff(p_ep);
X stuffReadbuff((char_u *)"\n");
X }
X else if (operator == FORMAT)
X {
X stuffReadbuff(p_fp);
X stuffReadbuff((char_u *)"\n");
X }
X /* docmdline() does the rest */
X break;
X
X case TILDE:
X case UPPER:
X case LOWER:
X if (!no_op)
X {
X dotilde();
X modified = TRUE;
X }
X break;
X
X case FORMAT:
X if (*p_fp != NUL)
X goto dofilter; /* use external command */
X doformat(); /* use internal function */
X modified = TRUE;
X break;
X
X default:
X CLEAROPBEEP;
X }
X operator = NOP;
X Visual_block = FALSE;
X yankbuffer = 0;
X }
X
Xnormal_end:
X premsg(-1, NUL);
X
X if (restart_edit && operator == NOP && VIsual.lnum == 0 && !command_busy && stuff_empty() && yankbuffer == 0)
X {
X startinsert(restart_edit, FALSE, 1L);
X modified = TRUE;
X }
X
X checkpcmark(); /* check if we moved since setting pcmark */
X
X/*
X * TEMPORARY: update the other windows for the current buffer if modified
X */
X if (modified)


X {
X WIN *wp;
X
X for (wp = firstwin; wp; wp = wp->w_next)

X if (wp != curwin && wp->w_buffer == curbuf)
X {
X cursor_off();


X wp->w_redr_type = NOT_VALID;

X win_update(wp);
X }
X }


X}
X
X static void

Xprep_redo(num, cmd, c, nchar)
X long num;
X int cmd;
X int c;
X int nchar;
X{
X ResetRedobuff();
X if (yankbuffer != 0) /* yank from specified buffer */
X {
X AppendCharToRedobuff('\"');
X AppendCharToRedobuff(yankbuffer);
X }
X if (num)
X AppendNumberToRedobuff(num);
X AppendCharToRedobuff(cmd);
X if (c != NUL)
X AppendCharToRedobuff(c);
X if (nchar != NUL)
X AppendCharToRedobuff(nchar);
X}
X
X/*
X * check for operator active
X *
X * return TRUE if operator was active


X */
X static int

Xcheckclearop()
X{
X if (operator == NOP)
X return (FALSE);
X clearopbeep();
X return (TRUE);
X}
X
X/*
X * check for operator or Visual active
X *
X * return TRUE if operator was active


X */
X static int

Xcheckclearopq()
X{
X if (operator == NOP && VIsual.lnum == 0)
X return (FALSE);
X clearopbeep();
X return (TRUE);


X}
X
X static void

Xclearopbeep()
X{
X CLEAROP;
X beep();
X}
X
X/*
X * display, on the last line of the window, the characters typed before
X * the last command character, plus 'c1' and 'c2'


X */
X static void

Xpremsg(c1, c2)


X int c1, c2;
X{

X char_u buf[40];
X char_u *p;
X
X if (!p_sc || !(KeyTyped || c1 == -1 || c1 == ' '))
X return;
X
X cursor_off();
X msg_pos((int)Rows - 1, sc_col);
X if (c1 == -1)
X msg_outstr((char_u *)" "); /* look in comp_col() for the number of spaces */
X else
X {
X p = buf;
X if (opnum)
X {
X sprintf((char *)p, "%ld", (long)opnum);
X p = p + STRLEN(buf);
X }
X if (yankbuffer)
X {
X *p++ = '"';
X *p++ = yankbuffer;
X }
X if (c1 == Ctrl('W')) /* ^W is in between counts */
X {
X *p++ = '^';
X *p++ = 'W';
X c1 = NUL;
X }
X else if (operator == 'z')
X *p++ = 'z';
X else if (operator)
X *p++ = opchars[operator - 1];
X if (Prenum)
X {
X sprintf((char *)p, "%ld", (long)Prenum);
X p = p + STRLEN(p);
X }
X *p = NUL;
X if (c1)
X STRCPY(p, transchar(c1));
X if (c2)
X STRCAT(p, transchar(c2));
X buf[10] = NUL; /* truncate at maximal length */
X msg_outstr(buf);
X }
X setcursor();
X /* cursor_on(); */
X}
END_OF_FILE
if test 41440 -ne `wc -c <'vim/src/normal.c'`; then
echo shar: \"'vim/src/normal.c'\" unpacked with wrong size!
fi
# end of 'vim/src/normal.c'
fi
echo shar: End of archive 10 \(of 26\).
cp /dev/null ark10isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:18 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 30
Archive-name: vim/part11

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/regexp.c vim/src/undo.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:05 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 11 (of 26)."'
if test -f 'vim/src/regexp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/regexp.c'\"
else
echo shar: Extracting \"'vim/src/regexp.c'\" \(40070 characters\)
sed "s/^X//" >'vim/src/regexp.c' <<'END_OF_FILE'
X/* vi:ts=4:sw=4
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *
X * This is NOT the original regular expression code as written by
X * Henry Spencer. This code has been modified specifically for use
X * with the VIM editor, and should not be used apart from compiling
X * VIM. If you want a good regular expression library, get the
X * original code. The copyright notice that follows is from the
X * original.
X *
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *
X *
X * regcomp and regexec -- regsub and regerror are elsewhere
X *
X * Copyright (c) 1986 by University of Toronto.
X * Written by Henry Spencer. Not derived from licensed software.
X *
X * Permission is granted to anyone to use this software for any
X * purpose on any computer system, and to redistribute it freely,
X * subject to the following restrictions:
X *
X * 1. The author is not responsible for the consequences of use of
X * this software, no matter how awful, even if they arise
X * from defects in it.
X *
X * 2. The origin of this software must not be misrepresented, either
X * by explicit claim or by omission.
X *
X * 3. Altered versions must be plainly marked as such, and must not
X * be misrepresented as being the original software.
X *
X * Beware that some of this code is subtly aware of the way operator
X * precedence is structured in regular expressions. Serious changes in
X * regular-expression syntax might require a total rethink.
X *
X * $Log: regexp.c,v $
X * Revision 1.2 88/04/28 08:09:45 tony
X * First modification of the regexp library. Added an external variable
X * 'reg_ic' which can be set to indicate that case should be ignored.
X * Added a new parameter to regexec() to indicate that the given string
X * comes from the beginning of a line and is thus eligible to match
X * 'beginning-of-line'.
X *
X * Revisions by Olaf 'Rhialto' Seibert, rhi...@cs.kun.nl:
X * Changes for vi: (the semantics of several things were rather different)
X * - Added lexical analyzer, because in vi magicness of characters
X * is rather difficult, and may change over time.
X * - Added support for \< \> \1-\9 and ~
X * - Left some magic stuff in, but only backslashed: \| \+
X * - * and \+ still work after \) even though they shouldn't.
X */


X#include "vim.h"
X#include "globals.h"
X#include "proto.h"

X#undef DEBUG
X
X#include <stdio.h>
X#include "regexp.h"
X#include "regmagic.h"
X#include "param.h"
X
X/*
X * The "internal use only" fields in regexp.h are present to pass info from
X * compile to execute that permits the execute phase to run lots faster on
X * simple cases. They are:
X *
X * regstart char that must begin a match; '\0' if none obvious
X * reganch is the match anchored (at beginning-of-line only)?
X * regmust string (pointer into program) that match must include, or NULL
X * regmlen length of regmust string
X *
X * Regstart and reganch permit very fast decisions on suitable starting points
X * for a match, cutting down the work a lot. Regmust permits fast rejection
X * of lines that cannot possibly match. The regmust tests are costly enough
X * that regcomp() supplies a regmust only if the r.e. contains something
X * potentially expensive (at present, the only such thing detected is * or +
X * at the start of the r.e., which can involve a lot of backup). Regmlen is
X * supplied because the test in regexec() needs it and regcomp() is computing
X * it anyway.
X */
X
X/*
X * Structure for regexp "program". This is essentially a linear encoding
X * of a nondeterministic finite-state machine (aka syntax charts or
X * "railroad normal form" in parsing technology). Each node is an opcode
X * plus a "next" pointer, possibly plus an operand. "Next" pointers of
X * all nodes except BRANCH implement concatenation; a "next" pointer with
X * a BRANCH on both ends of it is connecting two alternatives. (Here we
X * have one of the subtle syntax dependencies: an individual BRANCH (as
X * opposed to a collection of them) is never concatenated with anything
X * because of operator precedence.) The operand of some types of node is
X * a literal string; for others, it is a node leading into a sub-FSM. In
X * particular, the operand of a BRANCH node is the first node of the branch.
X * (NB this is *not* a tree structure: the tail of the branch connects
X * to the thing following the set of BRANCHes.) The opcodes are:
X */
X
X/* definition number opnd? meaning */
X#define END 0 /* no End of program. */
X#define BOL 1 /* no Match "" at beginning of line. */
X#define EOL 2 /* no Match "" at end of line. */
X#define ANY 3 /* no Match any one character. */
X#define ANYOF 4 /* str Match any character in this string. */
X#define ANYBUT 5 /* str Match any character not in this
X * string. */
X#define BRANCH 6 /* node Match this alternative, or the
X * next... */
X#define BACK 7 /* no Match "", "next" ptr points backward. */
X#define EXACTLY 8 /* str Match this string. */
X#define NOTHING 9 /* no Match empty string. */
X#define STAR 10 /* node Match this (simple) thing 0 or more
X * times. */
X#define PLUS 11 /* node Match this (simple) thing 1 or more
X * times. */
X#define BOW 12 /* no Match "" after [^a-zA-Z0-9_] */
X#define EOW 13 /* no Match "" at [^a-zA-Z0-9_] */
X#define MOPEN 20 /* no Mark this point in input as start of
X * #n. */
X /* MOPEN+1 is number 1, etc. */
X#define MCLOSE 30 /* no Analogous to MOPEN. */
X#define BACKREF 40 /* node Match same string again \1-\9 */
X
X#define Magic(x) ((x)|('\\'<<8))
X
X/*
X * Opcode notes:
X *
X * BRANCH The set of branches constituting a single choice are hooked
X * together with their "next" pointers, since precedence prevents
X * anything being concatenated to any individual branch. The
X * "next" pointer of the last BRANCH in a choice points to the
X * thing following the whole choice. This is also where the
X * final "next" pointer of each individual branch points; each
X * branch starts with the operand node of a BRANCH node.
X *
X * BACK Normal "next" pointers all implicitly point forward; BACK
X * exists to make loop structures possible.
X *
X * STAR,PLUS '=', and complex '*' and '+', are implemented as circular
X * BRANCH structures using BACK. Simple cases (one character
X * per match) are implemented with STAR and PLUS for speed
X * and to minimize recursive plunges.
X *
X * MOPEN,MCLOSE ...are numbered at compile time.
X */
X
X/*
X * A node is one char of opcode followed by two chars of "next" pointer.
X * "Next" pointers are stored as two 8-bit pieces, high order first. The
X * value is a positive offset from the opcode of the node containing it.
X * An operand, if any, simply follows the node. (Note that much of the
X * code generation knows about this implicit relationship.)
X *
X * Using two bytes for the "next" pointer is vast overkill for most things,
X * but allows patterns to get big without disasters.
X */
X#define OP(p) (*(p))
X#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
X#define OPERAND(p) ((p) + 3)
X
X/*
X * See regmagic.h for one further detail of program structure.
X */
X
X
X/*
X * Utility definitions.
X */
X#ifndef CHARBITS
X#define UCHARAT(p) ((int)*(unsigned char *)(p))
X#else
X#define UCHARAT(p) ((int)*(p)&CHARBITS)
X#endif
X
X#define EMSG_RETURN(m) { emsg(m); return NULL; }
X
Xstatic int ismult __ARGS((int));
X
X static int
Xismult(c)
X int c;
X{
X return (c == Magic('*') || c == Magic('+') || c == Magic('='));
X}
X
X/*
X * Flags to be passed up and down.
X */
X#define HASWIDTH 01 /* Known never to match null string. */
X#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
X#define SPSTART 04 /* Starts with * or +. */
X#define WORST 0 /* Worst case. */
X
X/*
X * The following allows empty REs, meaning "the same as the previous RE".
X * per the ed(1) manual.
X */
X/* #define EMPTY_RE */ /* this is done outside of regexp */
X#ifdef EMPTY_RE
Xchar_u *reg_prev_re;
X#endif
X
X#define TILDE
X#ifdef TILDE
Xchar_u *reg_prev_sub;
X#endif
X
X/*
X * This if for vi's "magic" mode. If magic is false, only ^$\ are magic.
X */
X
Xint reg_magic = 1;
X
X/*
X * Global work variables for regcomp().
X */
X
Xstatic char_u *regparse; /* Input-scan pointer. */
Xstatic int regnpar; /* () count. */
Xstatic char_u regdummy;
Xstatic char_u *regcode; /* Code-emit pointer; &regdummy = don't. */
Xstatic long regsize; /* Code size. */
Xstatic char_u **regendp; /* Ditto for endp. */
X
X/*
X * META contains all characters that may be magic, except '^' and '$'.
X * This depends on the configuration options TILDE, BACKREF.
X * (could be done simpler for compilers that know string concatenation)
X */
X
X#ifdef TILDE
X# ifdef BACKREF
X static char_u META[] = ".[()|=+*<>~123456789";
X# else
X static char_u META[] = ".[()|=+*<>~";
X# endif
X#else
X# ifdef BACKREF
X static char_u META[] = ".[()|=+*<>123456789";
X# else
X static char_u META[] = ".[()|=+*<>";
X# endif
X#endif
X
X/*
X * Forward declarations for regcomp()'s friends.
X */
Xstatic void initchr __ARGS((char_u *));
Xstatic int getchr __ARGS((void));
Xstatic int peekchr __ARGS((void));
X#define PeekChr() curchr /* shortcut only when last action was peekchr() */
Xstatic int curchr;
Xstatic void skipchr __ARGS((void));
Xstatic void ungetchr __ARGS((void));
Xstatic char_u *reg __ARGS((int, int *));
Xstatic char_u *regbranch __ARGS((int *));
Xstatic char_u *regpiece __ARGS((int *));
Xstatic char_u *regatom __ARGS((int *));
Xstatic char_u *regnode __ARGS((int));
Xstatic char_u *regnext __ARGS((char_u *));
Xstatic void regc __ARGS((int));
Xstatic void unregc __ARGS((void));
Xstatic void reginsert __ARGS((int, char_u *));
Xstatic void regtail __ARGS((char_u *, char_u *));
Xstatic void regoptail __ARGS((char_u *, char_u *));
X
X#undef STRCSPN
X#ifdef STRCSPN
Xstatic int strcspn __ARGS((const char_u *, const char_u *));
X#endif
X
X/*
X * skip past regular expression
X * stop at end of 'p' of where 'dirc' is found ('/', '?', etc)
X * take care of characters with a backslash in front of it
X * skip strings inside [ and ].


X */
X char_u *

Xskip_regexp(p, dirc)
X char_u *p;
X int dirc;
X{
X int in_range = FALSE;
X
X for (; p[0] != NUL; ++p)
X {
X if (p[0] == dirc && !in_range) /* found end of regexp */
X break;
X if ((p[0] == '[' && p_magic) || (p[0] == '\\' && p[1] == '[' && !p_magic))
X {
X in_range = TRUE;
X if (p[0] == '\\')
X ++p;
X /* "[^]" and "[]" are not the end of a range */
X if (p[1] == '^')
X ++p;
X if (p[1] == ']')
X ++p;
X }
X else if (p[0] == '\\' && p[1] != NUL)
X ++p; /* skip next character */
X else if (p[0] == ']')
X in_range = FALSE;
X }
X return p;
X}
X
X/*
X - regcomp - compile a regular expression into internal code
X *
X * We can't allocate space until we know how big the compiled form will be,
X * but we can't compile it (and thus know how big it is) until we've got a
X * place to put the code. So we cheat: we compile it twice, once with code
X * generation turned off and size counting turned on, and once "for real".
X * This also means that we don't allocate space until we are sure that the
X * thing really will compile successfully, and we never have to move the
X * code and thus invalidate pointers into it. (Note that it has to be in
X * one piece because free() must be able to free it all.)
X *
X * Beware that the optimization-preparation code in here knows about some
X * of the structure of the compiled regexp.
X */
X regexp *
Xregcomp(exp)
X char_u *exp;
X{
X register regexp *r;
X register char_u *scan;
X register char_u *longest;
X register int len;
X int flags;
X/* extern char *malloc();*/
X
X if (exp == NULL) {
X EMSG_RETURN(e_null);
X }
X
X#ifdef EMPTY_RE /* this is done outside of regexp */
X if (*exp == '\0') {
X if (reg_prev_re) {
X exp = reg_prev_re;
X } else {
X EMSG_RETURN(e_noprevre);
X }
X }
X#endif
X
X /* First pass: determine size, legality. */
X initchr((char_u *)exp);
X regnpar = 1;
X regsize = 0L;
X regcode = &regdummy;
X regendp = NULL;
X regc(MAGIC);
X if (reg(0, &flags) == NULL)
X return NULL;
X
X /* Small enough for pointer-storage convention? */
X if (regsize >= 32767L) /* Probably could be 65535L. */
X EMSG_RETURN(e_toolong);
X
X /* Allocate space. */
X/* r = (regexp *) malloc((unsigned) (sizeof(regexp) + regsize));*/
X r = (regexp *) alloc((unsigned) (sizeof(regexp) + regsize));
X if (r == NULL)
X EMSG_RETURN(e_outofmem);
X
X#ifdef EMPTY_RE /* this is done outside of regexp */
X if (exp != reg_prev_re) {
X free(reg_prev_re);
X if (reg_prev_re = alloc(STRLEN(exp) + 1))
X STRCPY(reg_prev_re, exp);
X }
X#endif
X
X /* Second pass: emit code. */
X initchr((char_u *)exp);
X regnpar = 1;
X regcode = r->program;
X regendp = r->endp;
X regc(MAGIC);
X if (reg(0, &flags) == NULL) {
X free(r);
X return NULL;
X }
X
X /* Dig out information for optimizations. */
X r->regstart = '\0'; /* Worst-case defaults. */
X r->reganch = 0;
X r->regmust = NULL;
X r->regmlen = 0;
X scan = r->program + 1; /* First BRANCH. */
X if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
X scan = OPERAND(scan);
X
X /* Starting-point info. */
X if (OP(scan) == EXACTLY)
X r->regstart = *OPERAND(scan);
X else if (OP(scan) == BOL)
X r->reganch++;
X
X /*
X * If there's something expensive in the r.e., find the longest
X * literal string that must appear and make it the regmust. Resolve
X * ties in favor of later strings, since the regstart check works
X * with the beginning of the r.e. and avoiding duplication
X * strengthens checking. Not a strong reason, but sufficient in the
X * absence of others.
X */
X /*
X * When the r.e. starts with BOW, it is faster to look for a regmust
X * first. Used a lot for "#" and "*" commands. (Added by mool).
X */
X if (flags & SPSTART || OP(scan) == BOW) {
X longest = NULL;
X len = 0;
X for (; scan != NULL; scan = regnext(scan))
X if (OP(scan) == EXACTLY && STRLEN(OPERAND(scan)) >= (size_t)len) {
X longest = OPERAND(scan);
X len = STRLEN(OPERAND(scan));
X }
X r->regmust = longest;
X r->regmlen = len;
X }
X }
X#ifdef DEBUG
X regdump(r);
X#endif


X return r;
X}
X

X/*
X - reg - regular expression, i.e. main body or parenthesized thing
X *
X * Caller must absorb opening parenthesis.
X *
X * Combining parenthesis handling with the base level of regular expression
X * is a trifle forced, but the need to tie the tails of the branches to what
X * follows makes it hard to avoid.


X */
X static char_u *

Xreg(paren, flagp)
X int paren; /* Parenthesized? */
X int *flagp;
X{
X register char_u *ret;
X register char_u *br;
X register char_u *ender;
X register int parno = 0;
X int flags;
X
X *flagp = HASWIDTH; /* Tentatively. */
X
X /* Make an MOPEN node, if parenthesized. */
X if (paren) {
X if (regnpar >= NSUBEXP)
X EMSG_RETURN(e_toombra);
X parno = regnpar;
X regnpar++;
X ret = regnode(MOPEN + parno);
X if (regendp)
X regendp[parno] = NULL; /* haven't seen the close paren yet */
X } else
X ret = NULL;
X
X /* Pick up the branches, linking them together. */
X br = regbranch(&flags);
X if (br == NULL)
X return NULL;
X if (ret != NULL)
X regtail(ret, br); /* MOPEN -> first. */
X else
X ret = br;
X if (!(flags & HASWIDTH))
X *flagp &= ~HASWIDTH;
X *flagp |= flags & SPSTART;
X while (peekchr() == Magic('|')) {
X skipchr();
X br = regbranch(&flags);
X if (br == NULL)
X return NULL;
X regtail(ret, br); /* BRANCH -> BRANCH. */
X if (!(flags & HASWIDTH))
X *flagp &= ~HASWIDTH;
X *flagp |= flags & SPSTART;
X }
X
X /* Make a closing node, and hook it on the end. */
X ender = regnode((paren) ? MCLOSE + parno : END);
X regtail(ret, ender);
X
X /* Hook the tails of the branches to the closing node. */
X for (br = ret; br != NULL; br = regnext(br))
X regoptail(br, ender);
X
X /* Check for proper termination. */
X if (paren && getchr() != Magic(')')) {
X EMSG_RETURN(e_toombra);
X } else if (!paren && peekchr() != '\0') {
X if (PeekChr() == Magic(')')) {
X EMSG_RETURN(e_toomket);
X } else
X EMSG_RETURN(e_trailing);/* "Can't happen". */
X /* NOTREACHED */
X }
X /*
X * Here we set the flag allowing back references to this set of
X * parentheses.
X */
X if (paren && regendp)
X regendp[parno] = ender; /* have seen the close paren */
X return ret;
X}
X
X/*
X - regbranch - one alternative of an | operator
X *
X * Implements the concatenation operator.


X */
X static char_u *

Xregbranch(flagp)
X int *flagp;
X{
X register char_u *ret;
X register char_u *chain;
X register char_u *latest;
X int flags;
X
X *flagp = WORST; /* Tentatively. */
X
X ret = regnode(BRANCH);
X chain = NULL;
X while (peekchr() != '\0' && PeekChr() != Magic('|') && PeekChr() != Magic(')')) {
X latest = regpiece(&flags);
X if (latest == NULL)
X return NULL;
X *flagp |= flags & HASWIDTH;
X if (chain == NULL) /* First piece. */
X *flagp |= flags & SPSTART;
X else
X regtail(chain, latest);
X chain = latest;
X }
X if (chain == NULL) /* Loop ran zero times. */
X (void) regnode(NOTHING);
X
X return ret;
X}
X
X/*
X - regpiece - something followed by possible [*+=]
X *
X * Note that the branching code sequences used for = and the general cases
X * of * and + are somewhat optimized: they use the same NOTHING node as
X * both the endmarker for their branch list and the body of the last branch.
X * It might seem that this node could be dispensed with entirely, but the
X * endmarker role is not redundant.
X */
Xstatic char_u *
Xregpiece(flagp)
X int *flagp;
X{
X register char_u *ret;
X register int op;
X register char_u *next;
X int flags;
X
X ret = regatom(&flags);
X if (ret == NULL)
X return NULL;
X
X op = peekchr();
X if (!ismult(op)) {
X *flagp = flags;
X return ret;
X }
X if (!(flags & HASWIDTH) && op != Magic('='))
X EMSG_RETURN((char_u *)"*+ operand could be empty");
X *flagp = (op != Magic('+')) ? (WORST | SPSTART) : (WORST | HASWIDTH);
X
X if (op == Magic('*') && (flags & SIMPLE))
X reginsert(STAR, ret);
X else if (op == Magic('*')) {
X /* Emit x* as (x&|), where & means "self". */
X reginsert(BRANCH, ret); /* Either x */
X regoptail(ret, regnode(BACK)); /* and loop */
X regoptail(ret, ret); /* back */
X regtail(ret, regnode(BRANCH)); /* or */
X regtail(ret, regnode(NOTHING)); /* null. */
X } else if (op == Magic('+') && (flags & SIMPLE))
X reginsert(PLUS, ret);
X else if (op == Magic('+')) {
X /* Emit x+ as x(&|), where & means "self". */
X next = regnode(BRANCH); /* Either */
X regtail(ret, next);
X regtail(regnode(BACK), ret); /* loop back */
X regtail(next, regnode(BRANCH)); /* or */
X regtail(ret, regnode(NOTHING)); /* null. */
X } else if (op == Magic('=')) {
X /* Emit x= as (x|) */
X reginsert(BRANCH, ret); /* Either x */
X regtail(ret, regnode(BRANCH)); /* or */
X next = regnode(NOTHING);/* null. */
X regtail(ret, next);
X regoptail(ret, next);
X }
X skipchr();
X if (ismult(peekchr()))
X EMSG_RETURN((char_u *)"Nested *=+");
X
X return ret;
X}
X
X/*
X - regatom - the lowest level
X *
X * Optimization: gobbles an entire sequence of ordinary characters so that
X * it can turn them into a single node, which is smaller to store and
X * faster to run.
X */
Xstatic char_u *
Xregatom(flagp)
X int *flagp;
X{
X register char_u *ret;
X int flags;
X
X *flagp = WORST; /* Tentatively. */
X
X switch (getchr()) {
X case Magic('^'):
X ret = regnode(BOL);
X break;
X case Magic('$'):
X ret = regnode(EOL);
X break;
X case Magic('<'):
X ret = regnode(BOW);
X break;
X case Magic('>'):
X ret = regnode(EOW);
X break;
X case Magic('.'):
X ret = regnode(ANY);
X *flagp |= HASWIDTH | SIMPLE;
X break;
X case Magic('['):{
X /*
X * In a character class, different parsing rules apply.
X * Not even \ is special anymore, nothing is.
X */
X if (*regparse == '^') { /* Complement of range. */
X ret = regnode(ANYBUT);
X regparse++;
X } else
X ret = regnode(ANYOF);
X if (*regparse == ']' || *regparse == '-')
X regc(*regparse++);
X while (*regparse != '\0' && *regparse != ']') {
X if (*regparse == '-') {
X regparse++;
X if (*regparse == ']' || *regparse == '\0')
X regc('-');
X else {
X register int class;
X register int classend;
X
X class = UCHARAT(regparse - 2) + 1;
X classend = UCHARAT(regparse);
X if (class > classend + 1)
X EMSG_RETURN(e_invrange);
X for (; class <= classend; class++)
X regc(class);
X regparse++;
X }
X } else if (*regparse == '\\' && regparse[1]) {
X regparse++;
X regc(*regparse++);
X } else
X regc(*regparse++);
X }
X regc('\0');
X if (*regparse != ']')
X EMSG_RETURN(e_toomsbra);
X skipchr(); /* let's be friends with the lexer again */
X *flagp |= HASWIDTH | SIMPLE;
X }
X break;
X case Magic('('):
X ret = reg(1, &flags);
X if (ret == NULL)
X return NULL;
X *flagp |= flags & (HASWIDTH | SPSTART);


X break;
X case '\0':

X case Magic('|'):
X case Magic(')'):
X EMSG_RETURN(e_internal); /* Supposed to be caught earlier. */
X /* break; Not Reached */
X case Magic('='):
X case Magic('+'):
X case Magic('*'):
X EMSG_RETURN((char_u *)"=+* follows nothing");
X /* break; Not Reached */
X#ifdef TILDE
X case Magic('~'): /* previous substitute pattern */
X if (reg_prev_sub) {


X register char_u *p;
X

X ret = regnode(EXACTLY);
X p = reg_prev_sub;
X while (*p) {
X regc(*p++);
X }
X regc('\0');
X if (p - reg_prev_sub) {
X *flagp |= HASWIDTH;
X if ((p - reg_prev_sub) == 1)
X *flagp |= SIMPLE;
X }
X } else
X EMSG_RETURN(e_nopresub);
X break;
X#endif
X#ifdef BACKREF
X case Magic('1'):
X case Magic('2'):
X case Magic('3'):
X case Magic('4'):
X case Magic('5'):
X case Magic('6'):
X case Magic('7'):
X case Magic('8'):
X case Magic('9'): {
X int refnum;
X
X ungetchr();
X refnum = getchr() - Magic('0');
X /*
X * Check if the back reference is legal. We use the parentheses
X * pointers to mark encountered close parentheses, but this
X * is only available in the second pass. Checking opens is
X * always possible.
X * Should also check that we don't refer to something that
X * is repeated (+*=): what instance of the repetition should
X * we match? TODO.
X */
X if (refnum < regnpar &&
X (regendp == NULL || regendp[refnum] != NULL))
X ret = regnode(BACKREF + refnum);
X else
X EMSG_RETURN((char_u *)"Illegal back reference");
X }
X break;
X#endif
X default:{
X register int len;
X int chr;
X
X ungetchr();
X len = 0;
X ret = regnode(EXACTLY);
X while ((chr = peekchr()) != '\0' && (chr < Magic(0)))
X {
X regc(chr);
X skipchr();
X len++;
X }
X#ifdef DEBUG


X if (len == 0)

X EMSG_RETURN((char_u *)"Unexpected magic character; check META.");
X#endif
X /*
X * If there is a following *, \+ or \= we need the character
X * in front of it as a single character operand
X */
X if (len > 1 && ismult(chr))
X {
X unregc(); /* Back off of *+= operand */
X ungetchr(); /* and put it back for next time */
X --len;
X }
X regc('\0');
X *flagp |= HASWIDTH;
X if (len == 1)
X *flagp |= SIMPLE;


X }
X break;
X }
X

X return ret;
X}
X
X/*
X - regnode - emit a node
X */
Xstatic char_u * /* Location. */
Xregnode(op)
X int op;
X{
X register char_u *ret;


X register char_u *ptr;
X

X ret = regcode;
X if (ret == &regdummy) {
X regsize += 3;
X return ret;
X }
X ptr = ret;
X *ptr++ = op;
X *ptr++ = '\0'; /* Null "next" pointer. */
X *ptr++ = '\0';
X regcode = ptr;
X
X return ret;
X}
X
X/*
X - regc - emit (if appropriate) a byte of code
X */
Xstatic void
Xregc(b)
X int b;
X{
X if (regcode != &regdummy)
X *regcode++ = b;
X else
X regsize++;
X}
X
X/*
X - unregc - take back (if appropriate) a byte of code
X */
Xstatic void
Xunregc()
X{
X if (regcode != &regdummy)
X regcode--;
X else
X regsize--;
X}
X
X/*
X - reginsert - insert an operator in front of already-emitted operand
X *
X * Means relocating the operand.
X */
Xstatic void
Xreginsert(op, opnd)
X int op;
X char_u *opnd;
X{
X register char_u *src;
X register char_u *dst;
X register char_u *place;
X
X if (regcode == &regdummy) {
X regsize += 3;
X return;
X }
X src = regcode;
X regcode += 3;
X dst = regcode;
X while (src > opnd)
X *--dst = *--src;
X
X place = opnd; /* Op node, where operand used to be. */
X *place++ = op;
X *place++ = '\0';
X *place = '\0';
X}
X
X/*
X - regtail - set the next-pointer at the end of a node chain
X */
Xstatic void
Xregtail(p, val)
X char_u *p;
X char_u *val;
X{
X register char_u *scan;
X register char_u *temp;
X register int offset;
X
X if (p == &regdummy)
X return;
X
X /* Find last node. */
X scan = p;
X for (;;) {
X temp = regnext(scan);
X if (temp == NULL)
X break;
X scan = temp;
X }
X
X if (OP(scan) == BACK)
X offset = (int)(scan - val);
X else
X offset = (int)(val - scan);
X *(scan + 1) = (char_u) ((offset >> 8) & 0377);
X *(scan + 2) = (char_u) (offset & 0377);
X}
X
X/*
X - regoptail - regtail on operand of first argument; nop if operandless
X */
Xstatic void
Xregoptail(p, val)
X char_u *p;
X char_u *val;
X{
X /* "Operandless" and "op != BRANCH" are synonymous in practice. */
X if (p == NULL || p == &regdummy || OP(p) != BRANCH)
X return;
X regtail(OPERAND(p), val);
X}
X
X/*
X - getchr() - get the next character from the pattern. We know about
X * magic and such, so therefore we need a lexical analyzer.
X */
X
X/* static int curchr; */
Xstatic int prevchr;
Xstatic int nextchr; /* used for ungetchr() */
X
Xstatic void
Xinitchr(str)
Xchar_u *str;
X{
X regparse = str;
X curchr = prevchr = nextchr = -1;
X}
X
Xstatic int
Xpeekchr()
X{
X if (curchr < 0) {
X switch (curchr = regparse[0]) {
X case '.':
X case '*':
X /* case '+':*/
X /* case '=':*/
X case '[':
X case '~':
X if (reg_magic)
X curchr = Magic(curchr);


X break;
X case '^':

X /* ^ is only magic as the very first character */
X if (prevchr < 0)
X curchr = Magic('^');
X break;
X case '$':
X /* $ is only magic as the very last character and in front of '\|' */
X if (regparse[1] == NUL || (regparse[1] == '\\' && regparse[2] == '|'))
X curchr = Magic('$');
X break;
X case '\\':
X regparse++;
X if (regparse[0] == NUL)
X curchr = '\\'; /* trailing '\' */
X else if (STRCHR(META, regparse[0]))
X {
X /*
X * META contains everything that may be magic sometimes, except
X * ^ and $ ("\^" and "\$" are never magic).
X * We now fetch the next character and toggle its magicness.
X * Therefore, \ is so meta-magic that it is not in META.
X */
X curchr = -1;
X peekchr();
X curchr ^= Magic(0);
X }
X else
X {
X /*
X * Next character can never be (made) magic?
X * Then backslashing it won't do anything.
X */
X curchr = regparse[0];


X }
X break;
X }
X }
X

X return curchr;
X}
X
Xstatic void
Xskipchr()
X{
X regparse++;
X prevchr = curchr;
X curchr = nextchr; /* use previously unget char, or -1 */
X nextchr = -1;
X}
X
Xstatic int
Xgetchr()
X{
X int chr;
X
X chr = peekchr();
X skipchr();
X
X return chr;
X}
X
X/*
X * put character back. Works only once!
X */
Xstatic void
Xungetchr()
X{
X nextchr = curchr;
X curchr = prevchr;
X /*
X * Backup regparse as well; not because we will use what it points at,
X * but because skipchr() will bump it again.
X */
X regparse--;
X}
X
X/*
X * regexec and friends
X */
X
X/*
X * Global work variables for regexec().
X */
Xstatic char_u *reginput; /* String-input pointer. */
Xstatic char_u *regbol; /* Beginning of input, for ^ check. */
Xstatic char_u **regstartp; /* Pointer to startp array. */
X/* static char_u **regendp; */ /* Ditto for endp. */
X
X/*
X * Forwards.
X */
Xstatic int regtry __ARGS((regexp *, char_u *));
Xstatic int regmatch __ARGS((char_u *));
Xstatic int regrepeat __ARGS((char_u *));
X
X#ifdef DEBUG
Xint regnarrate = 1;
Xvoid regdump __ARGS((regexp *));
Xstatic char_u *regprop __ARGS((char_u *));
X#endif
X
X/*
X - regexec - match a regexp against a string
X */
Xint
Xregexec(prog, string, at_bol)
X register regexp *prog;
X register char_u *string;
X int at_bol;
X{


X register char_u *s;
X

X /* Be paranoid... */
X if (prog == NULL || string == NULL) {
X emsg(e_null);
X return 0;
X }
X /* Check validity of program. */
X if (UCHARAT(prog->program) != MAGIC) {
X emsg(e_re_corr);
X return 0;
X }
X /* If there is a "must appear" string, look for it. */
X if (prog->regmust != NULL) {
X s = string;
X while ((s = cstrchr(s, prog->regmust[0])) != NULL) {
X if (cstrncmp(s, prog->regmust, prog->regmlen) == 0)
X break; /* Found it. */
X s++;
X }
X if (s == NULL) /* Not present. */
X return 0;
X }
X /* Mark beginning of line for ^ . */
X if (at_bol)
X regbol = string; /* is possible to match bol */
X else
X regbol = NULL; /* we aren't there, so don't match it */
X
X /* Simplest case: anchored match need be tried only once. */
X if (prog->reganch)
X return regtry(prog, string);
X
X /* Messy cases: unanchored match. */
X s = string;
X if (prog->regstart != '\0')
X /* We know what char it must start with. */
X while ((s = cstrchr(s, prog->regstart)) != NULL) {
X if (regtry(prog, s))
X return 1;
X s++;
X }
X else
X /* We don't -- general case. */
X do {
X if (regtry(prog, s))
X return 1;
X } while (*s++ != '\0');
X
X /* Failure. */


X return 0;
X}
X
X/*

X - regtry - try match at specific point
X */
Xstatic int /* 0 failure, 1 success */
Xregtry(prog, string)
X regexp *prog;
X char_u *string;
X{
X register int i;
X register char_u **sp;
X register char_u **ep;
X
X reginput = string;
X regstartp = prog->startp;
X regendp = prog->endp;
X
X sp = prog->startp;
X ep = prog->endp;
X for (i = NSUBEXP; i > 0; i--) {
X *sp++ = NULL;
X *ep++ = NULL;
X }
X if (regmatch(prog->program + 1)) {
X prog->startp[0] = string;
X prog->endp[0] = reginput;
X return 1;
X } else


X return 0;
X}
X
X/*

X - regmatch - main matching routine
X *
X * Conceptually the strategy is simple: check to see whether the current
X * node matches, call self recursively to see whether the rest matches,
X * and then act accordingly. In practice we make some effort to avoid
X * recursion, in particular by going through "ordinary" nodes (that don't
X * need to know whether the rest of the match failed) by a loop instead of
X * by recursion.
X */
Xstatic int /* 0 failure, 1 success */
Xregmatch(prog)
X char_u *prog;
X{
X register char_u *scan; /* Current node. */
X char_u *next; /* Next node. */
X
X scan = prog;
X#ifdef DEBUG
X if (scan != NULL && regnarrate)
X fprintf(stderr, "%s(\n", regprop(scan));
X#endif
X while (scan != NULL) {
X#ifdef DEBUG
X if (regnarrate) {
X fprintf(stderr, "%s...\n", regprop(scan));
X }
X#endif
X next = regnext(scan);
X switch (OP(scan)) {
X case BOL:
X if (reginput != regbol)
X return 0;
X break;
X case EOL:
X if (*reginput != '\0')
X return 0;
X break;
X case BOW: /* \<word; reginput points to w */
X#define isidchar(x) (isalnum(x) || ((x) == '_'))
X if (reginput != regbol && isidchar(reginput[-1]))
X return 0;
X if (!reginput[0] || !isidchar(reginput[0]))
X return 0;
X break;
X case EOW: /* word\>; reginput points after d */
X if (reginput == regbol || !isidchar(reginput[-1]))
X return 0;
X if (reginput[0] && isidchar(reginput[0]))
X return 0;
X break;
X case ANY:
X if (*reginput == '\0')
X return 0;
X reginput++;
X break;
X case EXACTLY:{
X register int len;
X register char_u *opnd;
X
X opnd = OPERAND(scan);
X /* Inline the first character, for speed. */
X if (*opnd != *reginput && (!reg_ic || TO_UPPER(*opnd) != TO_UPPER(*reginput)))
X return 0;
X len = STRLEN(opnd);
X if (len > 1 && cstrncmp(opnd, reginput, len) != 0)
X return 0;
X reginput += len;
X }
X break;
X case ANYOF:
X if (*reginput == '\0' || cstrchr(OPERAND(scan), *reginput) == NULL)
X return 0;
X reginput++;
X break;
X case ANYBUT:
X if (*reginput == '\0' || cstrchr(OPERAND(scan), *reginput) != NULL)
X return 0;
X reginput++;
X break;
X case NOTHING:
X break;
X case BACK:
X break;
X case MOPEN + 1:
X case MOPEN + 2:
X case MOPEN + 3:
X case MOPEN + 4:
X case MOPEN + 5:
X case MOPEN + 6:
X case MOPEN + 7:
X case MOPEN + 8:
X case MOPEN + 9:{
X register int no;
X register char_u *save;
X
X no = OP(scan) - MOPEN;
X save = regstartp[no];
X regstartp[no] = reginput; /* Tentatively */
X#ifdef DEBUG
X printf("MOPEN %d pre @'%s' ('%s' )'%s'\n",
X no, save,
X regstartp[no] ? regstartp[no] : "NULL",
X regendp[no] ? regendp[no] : "NULL");
X#endif
X
X if (regmatch(next)) {
X#ifdef DEBUG
X printf("MOPEN %d post @'%s' ('%s' )'%s'\n",
X no, save,
X regstartp[no] ? regstartp[no] : "NULL",
X regendp[no] ? regendp[no] : "NULL");
X#endif
X return 1;
X }
X regstartp[no] = save; /* We were wrong... */
X return 0;
X }
X /* break; Not Reached */
X case MCLOSE + 1:
X case MCLOSE + 2:
X case MCLOSE + 3:
X case MCLOSE + 4:
X case MCLOSE + 5:
X case MCLOSE + 6:
X case MCLOSE + 7:
X case MCLOSE + 8:
X case MCLOSE + 9:{
X register int no;
X register char_u *save;
X
X no = OP(scan) - MCLOSE;
X save = regendp[no];
X regendp[no] = reginput; /* Tentatively */
X#ifdef DEBUG
X printf("MCLOSE %d pre @'%s' ('%s' )'%s'\n",
X no, save,
X regstartp[no] ? regstartp[no] : "NULL",
X regendp[no] ? regendp[no] : "NULL");
X#endif
X
X if (regmatch(next)) {
X#ifdef DEBUG
X printf("MCLOSE %d post @'%s' ('%s' )'%s'\n",
X no, save,
X regstartp[no] ? regstartp[no] : "NULL",
X regendp[no] ? regendp[no] : "NULL");
X#endif
X return 1;
X }
X regendp[no] = save; /* We were wrong... */
X return 0;
X }
X /* break; Not Reached */
X#ifdef BACKREF
X case BACKREF + 1:
X case BACKREF + 2:
X case BACKREF + 3:
X case BACKREF + 4:
X case BACKREF + 5:
X case BACKREF + 6:
X case BACKREF + 7:
X case BACKREF + 8:
X case BACKREF + 9:{
X register int no;
X int len;
X
X no = OP(scan) - BACKREF;
X if (regendp[no] != NULL) {
X len = (int)(regendp[no] - regstartp[no]);
X if (cstrncmp(regstartp[no], reginput, len) != 0)
X return 0;
X reginput += len;
X } else {
X /*emsg("backref to 0-repeat");*/
X /*return 0;*/
X }
X }
X break;
X#endif
X case BRANCH:{
X register char_u *save;
X
X if (OP(next) != BRANCH) /* No choice. */
X next = OPERAND(scan); /* Avoid recursion. */
X else {
X do {
X save = reginput;
X if (regmatch(OPERAND(scan)))
X return 1;
X reginput = save;
X scan = regnext(scan);
X } while (scan != NULL && OP(scan) == BRANCH);
X return 0;
X /* NOTREACHED */
X }
X }
X break;
X case STAR:
X case PLUS:{
X register int nextch;
X register int no;
X register char_u *save;
X register int min;
X
X /*
X * Lookahead to avoid useless match attempts when we know
X * what character comes next.
X */
X nextch = '\0';
X if (OP(next) == EXACTLY)
X {
X nextch = *OPERAND(next);
X if (reg_ic)
X nextch = TO_UPPER(nextch);
X }
X min = (OP(scan) == STAR) ? 0 : 1;
X save = reginput;
X no = regrepeat(OPERAND(scan));
X while (no >= min)
X {
X /* If it could work, try it. */
X if (nextch == '\0' || (*reginput == nextch ||
X (reg_ic && TO_UPPER(*reginput) == nextch)))
X if (regmatch(next))
X return 1;
X /* Couldn't or didn't -- back up. */
X no--;
X reginput = save + no;
X }
X return 0;
X }
X /* break; Not Reached */
X case END:
X return 1; /* Success! */
X /* break; Not Reached */
X default:
X emsg(e_re_corr);
X return 0;
X /* break; Not Reached */
X }
X
X scan = next;
X }
X
X /*
X * We get here only if there's trouble -- normally "case END" is the
X * terminating point.
X */
X emsg(e_re_corr);


X return 0;
X}
X
X/*

X - regrepeat - repeatedly match something simple, report how many
X */
Xstatic int
Xregrepeat(p)
X char_u *p;
X{


X register int count = 0;

X register char_u *scan;
X register char_u *opnd;
X
X scan = reginput;
X opnd = OPERAND(p);
X switch (OP(p)) {
X case ANY:
X count = STRLEN(scan);
X scan += count;
X break;
X case EXACTLY:
X while (*opnd == *scan || (reg_ic && TO_UPPER(*opnd) == TO_UPPER(*scan)))
X {
X count++;
X scan++;
X }
X break;
X case ANYOF:
X while (*scan != '\0' && cstrchr(opnd, *scan) != NULL)
X {
X count++;
X scan++;
X }
X break;
X case ANYBUT:
X while (*scan != '\0' && cstrchr(opnd, *scan) == NULL) {
X count++;
X scan++;
X }
X break;
X default: /* Oh dear. Called inappropriately. */
X emsg(e_re_corr);
X count = 0; /* Best compromise. */
X break;
X }
X reginput = scan;
X
X return count;
X}
X
X/*
X - regnext - dig the "next" pointer out of a node
X */
Xstatic char_u *
Xregnext(p)


X register char_u *p;
X{

X register int offset;
X
X if (p == &regdummy)
X return NULL;
X
X offset = NEXT(p);
X if (offset == 0)
X return NULL;
X
X if (OP(p) == BACK)
X return p - offset;
X else
X return p + offset;
X}
X
X#ifdef DEBUG
X
X/*
X - regdump - dump a regexp onto stdout in vaguely comprehensible form
X */
Xvoid
Xregdump(r)
X regexp *r;
X{
X register char_u *s;
X register int op = EXACTLY; /* Arbitrary non-END op. */
X register char_u *next;
X /*extern char_u *strchr();*/
X
X
X s = r->program + 1;
X while (op != END) { /* While that wasn't END last time... */
X op = OP(s);
X printf("%2d%s", s - r->program, regprop(s)); /* Where, what. */
X next = regnext(s);
X if (next == NULL) /* Next ptr. */
X printf("(0)");
X else
X printf("(%d)", (s - r->program) + (next - s));
X s += 3;
X if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
X /* Literal string, where present. */
X while (*s != '\0') {
X putchar(*s);
X s++;
X }
X s++;
X }
X putchar('\n');
X }
X
X /* Header fields of interest. */
X if (r->regstart != '\0')
X printf("start `%c' ", r->regstart);
X if (r->reganch)
X printf("anchored ");
X if (r->regmust != NULL)
X printf("must have \"%s\"", r->regmust);
X printf("\n");
X}
X
X/*
X - regprop - printable representation of opcode
X */
Xstatic char_u *
Xregprop(op)
X char_u *op;


X{
X register char_u *p;

X static char_u buf[50];
X
X (void) strcpy(buf, ":");
X
X switch (OP(op)) {
X case BOL:
X p = "BOL";
X break;
X case EOL:
X p = "EOL";
X break;
X case ANY:
X p = "ANY";
X break;
X case ANYOF:
X p = "ANYOF";
X break;
X case ANYBUT:
X p = "ANYBUT";
X break;
X case BRANCH:
X p = "BRANCH";
X break;
X case EXACTLY:
X p = "EXACTLY";
X break;
X case NOTHING:
X p = "NOTHING";
X break;
X case BACK:
X p = "BACK";
X break;
X case END:
X p = "END";
X break;
X case MOPEN + 1:
X case MOPEN + 2:
X case MOPEN + 3:
X case MOPEN + 4:
X case MOPEN + 5:
X case MOPEN + 6:
X case MOPEN + 7:
X case MOPEN + 8:
X case MOPEN + 9:
X sprintf(buf + STRLEN(buf), "MOPEN%d", OP(op) - MOPEN);
X p = NULL;
X break;
X case MCLOSE + 1:
X case MCLOSE + 2:
X case MCLOSE + 3:
X case MCLOSE + 4:
X case MCLOSE + 5:
X case MCLOSE + 6:
X case MCLOSE + 7:
X case MCLOSE + 8:
X case MCLOSE + 9:
X sprintf(buf + STRLEN(buf), "MCLOSE%d", OP(op) - MCLOSE);
X p = NULL;
X break;
X case BACKREF + 1:
X case BACKREF + 2:
X case BACKREF + 3:
X case BACKREF + 4:
X case BACKREF + 5:
X case BACKREF + 6:
X case BACKREF + 7:
X case BACKREF + 8:
X case BACKREF + 9:
X sprintf(buf + STRLEN(buf), "BACKREF%d", OP(op) - BACKREF);
X p = NULL;
X break;
X case STAR:
X p = "STAR";
X break;
X case PLUS:
X p = "PLUS";
X break;
X default:
X sprintf(buf + STRLEN(buf), "corrupt %d", OP(op));
X p = NULL;
X break;
X }
X if (p != NULL)
X (void) strcat(buf, p);
X return buf;
X}
X#endif
X
X/*
X * The following is provided for those people who do not have strcspn() in
X * their C libraries. They should get off their butts and do something
X * about it; at least one public-domain implementation of those (highly
X * useful) string routines has been published on Usenet.
X */
X#ifdef STRCSPN
X/*
X * strcspn - find length of initial segment of s1 consisting entirely
X * of characters not from s2
X */
X
Xstatic int
Xstrcspn(s1, s2)
X const char_u *s1;
X const char_u *s2;
X{
X register char_u *scan1;
X register char_u *scan2;
X register int count;
X
X count = 0;
X for (scan1 = s1; *scan1 != '\0'; scan1++) {
X for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
X if (*scan1 == *scan2++)
X return count;
X count++;
X }
X return count;
X}
X#endif
X
X/*
X * Compare two strings, ignore case if reg_ic set.
X * Return 0 if strings match, non-zero otherwise.
X */
X int
Xcstrncmp(s1, s2, n)
X char_u *s1, *s2;
X int n;
X{
X if (!reg_ic)
X return STRNCMP(s1, s2, (size_t)n);
X
X return vim_strnicmp(s1, s2, (size_t)n);
X}
X
X/*
X * cstrchr: This function is used a lot for simple searches, keep it fast!


X */
X char_u *

Xcstrchr(s, c)
X char_u *s;
X register int c;


X{
X register char_u *p;
X

X if (!reg_ic)
X return STRCHR(s, c);
X
X c = TO_UPPER(c);
X
X for (p = s; *p; p++)
X {
X if (TO_UPPER(*p) == c)
X return p;


X }
X return NULL;
X}

END_OF_FILE
if test 40070 -ne `wc -c <'vim/src/regexp.c'`; then
echo shar: \"'vim/src/regexp.c'\" unpacked with wrong size!
fi
# end of 'vim/src/regexp.c'
fi
if test -f 'vim/src/undo.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/undo.c'\"
else
echo shar: Extracting \"'vim/src/undo.c'\" \(24811 characters\)
sed "s/^X//" >'vim/src/undo.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * undo.c: multi level undo facility
X *
X * The saved lines are stored in a list of lists (one for each buffer):
X *
X * b_u_oldhead------------------------------------------------+
X * |
X * V
X * +--------------+ +--------------+ +--------------+
X * b_u_newhead--->| u_header | | u_header | | u_header |
X * | uh_next------>| uh_next------>| uh_next---->NULL
X * NULL<--------uh_prev |<---------uh_prev |<---------uh_prev |
X * | uh_entry | | uh_entry | | uh_entry |
X * +--------|-----+ +--------|-----+ +--------|-----+
X * | | |
X * V V V
X * +--------------+ +--------------+ +--------------+
X * | u_entry | | u_entry | | u_entry |
X * | ue_next | | ue_next | | ue_next |
X * +--------|-----+ +--------|-----+ +--------|-----+
X * | | |
X * V V V
X * +--------------+ NULL NULL
X * | u_entry |
X * | ue_next |
X * +--------|-----+
X * |
X * V
X * etc.
X *
X * Each u_entry list contains the information for one undo or redo.
X * curbuf->b_u_curhead points to the header of the last undo (the next redo), or is
X * NULL if nothing has been undone.
X *
X * All data is allocated with u_alloc_line(), thus it will be freed as soon as
X * we switch files!


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic void u_getbot __ARGS((void));
Xstatic int u_savecommon __ARGS((linenr_t, linenr_t, linenr_t));
Xstatic void u_undoredo __ARGS((void));
Xstatic void u_undo_end __ARGS((void));
Xstatic void u_freelist __ARGS((struct u_header *));
Xstatic void u_freeentry __ARGS((struct u_entry *, long));
X
Xstatic char_u *u_blockalloc __ARGS((long_u));
Xstatic void u_free_line __ARGS((char_u *));
Xstatic char_u *u_alloc_line __ARGS((unsigned));
Xstatic char_u *u_save_line __ARGS((linenr_t));
X
Xstatic long u_newcount, u_oldcount;
X
X/*
X * save the current line for both the "u" and "U" command
X */
X int
Xu_save_cursor()
X{
X return (u_save((linenr_t)(curwin->w_cursor.lnum - 1), (linenr_t)(curwin->w_cursor.lnum + 1)));
X}
X
X/*
X * Save the lines between "top" and "bot" for both the "u" and "U" command.
X * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
X * Returns FALSE when lines could not be saved.
X */
X int
Xu_save(top, bot)
X linenr_t top, bot;
X{
X if (top > curbuf->b_ml.ml_line_count || top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
X return FALSE; /* rely on caller to do error messages */
X
X if (top + 2 == bot)
X u_saveline((linenr_t)(top + 1));
X
X return (u_savecommon(top, bot, (linenr_t)0));
X}
X
X/*
X * save the line "lnum" (used by :s command)
X * The line is replaced, so the new bottom line is lnum + 1.
X */
X int
Xu_savesub(lnum)
X linenr_t lnum;
X{
X return (u_savecommon(lnum - 1, lnum + 1, lnum + 1));
X}
X
X/*
X * a new line is inserted before line "lnum" (used by :s command)
X * The line is inserted, so the new bottom line is lnum + 1.
X */
X int
Xu_inssub(lnum)
X linenr_t lnum;
X{
X return (u_savecommon(lnum - 1, lnum, lnum + 1));
X}
X
X/*
X * save the lines "lnum" - "lnum" + nlines (used by delete command)
X * The lines are deleted, so the new bottom line is lnum.
X */
X int
Xu_savedel(lnum, nlines)
X linenr_t lnum;
X long nlines;
X{
X return (u_savecommon(lnum - 1, lnum + nlines, lnum));


X}
X
X static int

Xu_savecommon(top, bot, newbot)
X linenr_t top, bot;
X linenr_t newbot;
X{
X linenr_t lnum;
X long i;
X struct u_header *uhp;
X struct u_entry *uep;
X long size;
X
X /*
X * if curbuf->b_u_synced == TRUE make a new header
X */
X if (curbuf->b_u_synced)
X {
X /*
X * if we undid more than we redid, free the entry lists before and
X * including curbuf->b_u_curhead
X */
X while (curbuf->b_u_curhead != NULL)
X u_freelist(curbuf->b_u_newhead);
X
X /*
X * free headers to keep the size right
X */
X while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
X u_freelist(curbuf->b_u_oldhead);
X
X if (p_ul < 0) /* no undo at all */
X return TRUE;
X
X /*
X * make a new header entry
X */
X uhp = (struct u_header *)u_alloc_line((unsigned)sizeof(struct u_header));
X if (uhp == NULL)
X goto nomem;
X uhp->uh_prev = NULL;
X uhp->uh_next = curbuf->b_u_newhead;
X if (curbuf->b_u_newhead != NULL)
X curbuf->b_u_newhead->uh_prev = uhp;
X uhp->uh_entry = NULL;
X uhp->uh_cursor = curwin->w_cursor; /* save cursor position for undo */
X uhp->uh_changed = curbuf->b_changed; /* save changed flag for undo */
X /* save named marks for undo */
X memmove((char *)uhp->uh_namedm, (char *)curbuf->b_namedm, sizeof(FPOS) * NMARKS);
X curbuf->b_u_newhead = uhp;
X if (curbuf->b_u_oldhead == NULL)
X curbuf->b_u_oldhead = uhp;
X ++curbuf->b_u_numhead;
X }
X else /* find line number for ue_bot for previous u_save() */
X u_getbot();
X
X size = bot - top - 1;
X#ifndef UNIX
X /*
X * With Amiga and MSDOS we can't handle big undo's, because then
X * u_alloc_line would have to allocate a block larger than 32K
X */
X if (size >= 8000)
X goto nomem;
X#endif
X
X /*
X * add lines in front of entry list
X */
X uep = (struct u_entry *)u_alloc_line((unsigned)sizeof(struct u_entry));
X if (uep == NULL)
X goto nomem;
X
X uep->ue_size = size;
X uep->ue_top = top;
X uep->ue_lcount = 0;
X if (newbot)
X uep->ue_bot = newbot;
X /*
X * use 0 for ue_bot if bot is below last line or if the buffer is empty, in
X * which case the last line may be replaced (e.g. with 'O' command).
X */
X else if (bot > curbuf->b_ml.ml_line_count || bufempty())
X uep->ue_bot = 0;
X else
X uep->ue_lcount = curbuf->b_ml.ml_line_count; /* we have to compute ue_bot later */
X
X if (size)
X {
X if ((uep->ue_array = (char_u **)u_alloc_line((unsigned)(sizeof(char_u *) * size))) == NULL)
X {
X u_freeentry(uep, 0L);
X goto nomem;
X }
X for (i = 0, lnum = top + 1; i < size; ++i)
X {
X if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL)
X {
X u_freeentry(uep, i);
X goto nomem;
X }
X }
X }
X uep->ue_next = curbuf->b_u_newhead->uh_entry;
X curbuf->b_u_newhead->uh_entry = uep;
X curbuf->b_u_synced = FALSE;
X return TRUE;
X
Xnomem:
X if (ask_yesno((char_u *)"no undo possible; continue anyway") == 'y')
X return TRUE;


X return FALSE;
X}
X

X void
Xu_undo(count)
X int count;
X{
X /*
X * If we get an undo command while executing a macro, we behave like the
X * original vi. If this happens twice in one macro the result will not
X * be compatible.
X */
X if (curbuf->b_u_synced == FALSE)
X {
X u_sync();
X count = 1;
X }
X
X curbuf->b_startop.lnum = 0; /* unset '[ mark */
X curbuf->b_endop.lnum = 0; /* unset '] mark */
X u_newcount = 0;
X u_oldcount = 0;
X while (count--)
X {
X if (curbuf->b_u_curhead == NULL) /* first undo */
X curbuf->b_u_curhead = curbuf->b_u_newhead;
X else if (p_ul > 0) /* multi level undo */
X curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next; /* get next undo */
X
X if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL) /* nothing to undo */
X {
X curbuf->b_u_curhead = curbuf->b_u_oldhead; /* stick curbuf->b_u_curhead at end */


X beep();
X break;
X }
X

X u_undoredo();
X }
X u_undo_end();
X}
X
X void
Xu_redo(count)
X int count;
X{
X u_newcount = 0;
X u_oldcount = 0;
X while (count--)
X {
X if (curbuf->b_u_curhead == NULL || p_ul <= 0) /* nothing to redo */


X {
X beep();
X break;
X }
X

X u_undoredo();
X
X curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev; /* advance for next redo */
X }
X u_undo_end();
X}
X
X/*
X * u_undoredo: common code for undo and redo
X *
X * The lines in the file are replaced by the lines in the entry list at curbuf->b_u_curhead.
X * The replaced lines in the file are saved in the entry list for the next undo/redo.


X */
X static void

Xu_undoredo()
X{
X char_u **newarray = NULL;
X linenr_t oldsize;
X linenr_t newsize;
X linenr_t top, bot;
X linenr_t lnum;
X linenr_t newlnum = MAXLNUM;
X long i;
X struct u_entry *uep, *nuep;
X struct u_entry *newlist = NULL;
X int changed = curbuf->b_changed;
X FPOS namedm[NMARKS];
X
X if (curbuf->b_u_curhead->uh_changed)
X CHANGED;
X else
X UNCHANGED(curbuf);
X /*
X * save marks before undo/redo
X */
X memmove((char *)namedm, (char *)curbuf->b_namedm, sizeof(FPOS) * NMARKS);
X
X for (uep = curbuf->b_u_curhead->uh_entry; uep != NULL; uep = nuep)
X {
X top = uep->ue_top;
X bot = uep->ue_bot;
X if (bot == 0)
X bot = curbuf->b_ml.ml_line_count + 1;
X if (top > curbuf->b_ml.ml_line_count || top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
X {
X EMSG("u_undo: line numbers wrong");
X CHANGED; /* don't want UNCHANGED now */
X return;
X }
X
X if (top < newlnum)
X {
X newlnum = top;
X curwin->w_cursor.lnum = top + 1;
X }
X oldsize = bot - top - 1; /* number of lines before undo */
X
X newsize = uep->ue_size; /* number of lines after undo */
X
X /* delete the lines between top and bot and save them in newarray */
X if (oldsize)
X {
X if ((newarray = (char_u **)u_alloc_line((unsigned)(sizeof(char_u *) * oldsize))) == NULL)
X {
X /*
X * We have messed up the entry list, repair is impossible.
X * we have to free the rest of the list.
X */
X while (uep != NULL)
X {
X nuep = uep->ue_next;
X u_freeentry(uep, uep->ue_size);
X uep = nuep;
X }
X break;
X }
X /* delete backwards, it goes faster in most cases */
X for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum)
X {
X newarray[i] = u_save_line(lnum);
X ml_delete(lnum);
X }
X }
X
X /* insert the lines in u_array between top and bot */
X if (newsize)
X {
X for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
X {
X ml_append(lnum, uep->ue_array[i], (colnr_t)0, FALSE);
X u_free_line(uep->ue_array[i]);
X }
X u_free_line((char_u *)uep->ue_array);
X }
X
X /* adjust marks */
X if (oldsize != newsize)
X {
X mark_adjust(top, top + oldsize - 1, MAXLNUM);
X mark_adjust(top + oldsize, MAXLNUM, (long)newsize - (long)oldsize);
X }
X
X u_newcount += newsize;
X u_oldcount += oldsize;
X uep->ue_size = oldsize;
X uep->ue_array = newarray;
X uep->ue_bot = top + newsize + 1;
X
X /*
X * insert this entry in front of the new entry list
X */
X nuep = uep->ue_next;
X uep->ue_next = newlist;
X newlist = uep;
X }
X
X curbuf->b_u_curhead->uh_entry = newlist;
X curbuf->b_u_curhead->uh_changed = changed;
X
X /*
X * restore marks from before undo/redo
X */
X for (i = 0; i < NMARKS; ++i)
X if (curbuf->b_u_curhead->uh_namedm[i].lnum)
X {
X curbuf->b_namedm[i] = curbuf->b_u_curhead->uh_namedm[i];
X curbuf->b_u_curhead->uh_namedm[i] = namedm[i];
X }
X
X if (curbuf->b_u_curhead->uh_cursor.lnum == curwin->w_cursor.lnum)
X curwin->w_cursor.col = curbuf->b_u_curhead->uh_cursor.col;
X else
X curwin->w_cursor.col = 0;
X}
X
X/*
X * If we deleted or added lines, report the number of less/more lines.
X * Otherwise, report the number of changes (this may be incorrect
X * in some cases, but it's better than nothing).


X */
X static void

Xu_undo_end()
X{
X if ((u_oldcount -= u_newcount) != 0)
X msgmore(-u_oldcount);
X else if (u_newcount > p_report)
X smsg((char_u *)"%ld change%s", u_newcount, plural(u_newcount));
X
X updateScreen(CURSUPD);
X}
X
X/*
X * u_sync: stop adding to the current entry list
X */
X void
Xu_sync()
X{
X if (curbuf->b_u_synced)
X return; /* already synced */
X u_getbot(); /* compute ue_bot of previous u_save */
X curbuf->b_u_curhead = NULL;
X}
X
X/*
X * Called after writing the file and setting b_changed to FALSE.
X * Now an undo means that the buffer is modified.
X */
X void
Xu_unchanged(buf)
X BUF *buf;
X{
X register struct u_header *uh;
X
X for (uh = buf->b_u_newhead; uh; uh = uh->uh_next)
X uh->uh_changed = 1;
X buf->b_did_warn = FALSE;
X}
X
X/*
X * u_getbot(): compute the line number of the previous u_save
X * It is called only when b_u_synced is FALSE.


X */
X static void

Xu_getbot()
X{
X register struct u_entry *uep;
X
X if (curbuf->b_u_newhead == NULL || (uep = curbuf->b_u_newhead->uh_entry) == NULL)
X {
X EMSG("undo list corrupt");
X return;
X }
X
X if (uep->ue_lcount != 0)
X {
X /*
X * the new ue_bot is computed from the number of lines that has been
X * inserted (0 - deleted) since calling u_save. This is equal to the old
X * line count subtracted from the current line count.
X */
X uep->ue_bot = uep->ue_top + uep->ue_size + 1 + (curbuf->b_ml.ml_line_count - uep->ue_lcount);
X if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
X {
X EMSG("undo line missing");
X uep->ue_bot = uep->ue_top + 1; /* assume all lines deleted, will get
X * all the old lines back without
X * deleting the current ones */
X }
X uep->ue_lcount = 0;
X }
X
X curbuf->b_u_synced = TRUE;
X}
X
X/*
X * u_freelist: free one entry list and adjust the pointers


X */
X static void

Xu_freelist(uhp)
X struct u_header *uhp;
X{
X register struct u_entry *uep, *nuep;
X
X for (uep = uhp->uh_entry; uep != NULL; uep = nuep)
X {
X nuep = uep->ue_next;
X u_freeentry(uep, uep->ue_size);
X }
X
X if (curbuf->b_u_curhead == uhp)
X curbuf->b_u_curhead = NULL;
X
X if (uhp->uh_next == NULL)
X curbuf->b_u_oldhead = uhp->uh_prev;
X else
X uhp->uh_next->uh_prev = uhp->uh_prev;
X
X if (uhp->uh_prev == NULL)
X curbuf->b_u_newhead = uhp->uh_next;
X else
X uhp->uh_prev->uh_next = uhp->uh_next;
X
X u_free_line((char_u *)uhp);
X --curbuf->b_u_numhead;
X}
X
X/*
X * free entry 'uep' and 'n' lines in uep->ue_array[]


X */
X static void

Xu_freeentry(uep, n)
X struct u_entry *uep;
X register long n;
X{
X while (n)
X u_free_line(uep->ue_array[--n]);
X u_free_line((char_u *)uep);
X}
X
X/*
X * invalidate the undo buffer; called when storage has already been released
X */
X void
Xu_clearall(buf)
X BUF *buf;
X{
X buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;


X buf->b_u_synced = TRUE;

X buf->b_u_numhead = 0;
X buf->b_u_line_ptr = NULL;
X buf->b_u_line_lnum = 0;
X}
X
X/*
X * save the line "lnum" for the "U" command
X */
X void
Xu_saveline(lnum)
X linenr_t lnum;
X{
X if (lnum == curbuf->b_u_line_lnum) /* line is already saved */
X return;
X if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
X return;
X u_clearline();
X curbuf->b_u_line_lnum = lnum;
X if (curwin->w_cursor.lnum == lnum)
X curbuf->b_u_line_colnr = curwin->w_cursor.col;
X else
X curbuf->b_u_line_colnr = 0;
X curbuf->b_u_line_ptr = u_save_line(lnum); /* when out of mem alloc() will give a warning */
X}
X
X/*
X * clear the line saved for the "U" command
X * (this is used externally for crossing a line while in insert mode)
X */
X void
Xu_clearline()
X{
X if (curbuf->b_u_line_ptr != NULL)
X {
X u_free_line(curbuf->b_u_line_ptr);
X curbuf->b_u_line_ptr = NULL;
X curbuf->b_u_line_lnum = 0;
X }
X}
X
X/*
X * Implementation of the "U" command.
X * Differentiation from vi: "U" can be undone with the next "U".
X * We also allow the cursor to be in another line.
X */
X void
Xu_undoline()
X{
X colnr_t t;
X char_u *old;
X
X if (curbuf->b_u_line_ptr == NULL || curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
X {
X beep();
X return;
X }
X /* first save the line for the 'u' command */
X u_savecommon(curbuf->b_u_line_lnum - 1, curbuf->b_u_line_lnum + 1, (linenr_t)0);
X old = u_save_line(curbuf->b_u_line_lnum);
X if (old == NULL)
X return;
X ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
X u_free_line(curbuf->b_u_line_ptr);
X curbuf->b_u_line_ptr = old;
X
X t = curbuf->b_u_line_colnr;
X if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
X curbuf->b_u_line_colnr = curwin->w_cursor.col;
X curwin->w_cursor.col = t;
X curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
X cursupdate();
X updateScreen(VALID_TO_CURSCHAR);
X}
X
X/*
X * storage allocation for the undo lines and blocks of the current file
X */
X
X/*
X * Memory is allocated in relatively large blocks. These blocks are linked
X * in the allocated block list, headed by curbuf->b_block_head. They are all freed
X * when abandoning a file, so we don't have to free every single line. The
X * list is kept sorted on memory address.
X * block_alloc() allocates a block.
X * m_blockfree() frees all blocks.
X *
X * The available chunks of memory are kept in free chunk lists. There is
X * one free list for each block of allocated memory. The list is kept sorted
X * on memory address.
X * u_alloc_line() gets a chunk from the free lists.
X * u_free_line() returns a chunk to the free lists.
X * curbuf->b_m_search points to the chunk before the chunk that was
X * freed/allocated the last time.
X * curbuf->b_mb_current points to the b_head where curbuf->b_m_search
X * points into the free list.
X *
X *
X * b_block_head /---> block #1 /---> block #2
X * mb_next ---/ mb_next ---/ mb_next ---> NULL
X * mb_info mb_info mb_info
X * | | |
X * V V V
X * NULL free chunk #1.1 free chunk #2.1
X * | |
X * V V
X * free chunk #1.2 NULL
X * |
X * V
X * NULL
X *
X * When a single free chunk list would have been used, it could take a lot
X * of time in u_free_line() to find the correct place to insert a chunk in the
X * free list. The single free list would become very long when many lines are
X * changed (e.g. with :%s/^M$//).


X */
X
X /*

X * this blocksize is used when allocating new lines
X */
X#define MEMBLOCKSIZE 2044
X
X/*
X * The size field contains the size of the chunk, including the size field itself.
X *
X * When the chunk is not in-use it is preceded with the m_info structure.
X * The m_next field links it in one of the free chunk lists.
X *
X * On most unix systems structures have to be longword (32 or 64 bit) aligned.
X * On most other systems they are short (16 bit) aligned.
X */
X
X/* the structure definitions are now in structs.h */
X
X#ifdef ALIGN_LONG
X /* size of m_size */
X# define M_OFFSET (sizeof(long_u))
X#else
X /* size of m_size */
X# define M_OFFSET (sizeof(short_u))
X#endif
X
X/*
X * Allocate a block of memory and link it in the allocated block list.
X */
X static char_u *
Xu_blockalloc(size)
X long_u size;
X{
X struct m_block *p;
X struct m_block *mp, *next;
X
X p = (struct m_block *)lalloc(size + sizeof(struct m_block), TRUE);
X if (p != NULL)
X {
X /* Insert the block into the allocated block list, keeping it
X sorted on address. */
X for (mp = &curbuf->b_block_head; (next = mp->mb_next) != NULL && next < p; mp = next)
X ;
X p->mb_next = next; /* link in block list */
X mp->mb_next = p;
X p->mb_info.m_next = NULL; /* clear free list */
X p->mb_info.m_size = 0;
X curbuf->b_mb_current = p; /* remember current block */
X curbuf->b_m_search = NULL;
X p++; /* return usable memory */
X }
X return (char_u *)p;
X}
X
X/*
X * free all allocated memory blocks for the buffer 'buf'
X */
X void
Xu_blockfree(buf)
X BUF *buf;
X{
X struct m_block *p, *np;
X
X for (p = buf->b_block_head.mb_next; p != NULL; p = np)
X {
X np = p->mb_next;
X free(p);
X }
X buf->b_block_head.mb_next = NULL;
X buf->b_m_search = NULL;
X buf->b_mb_current = NULL;
X}
X
X/*
X * Free a chunk of memory.
X * Insert the chunk into the correct free list, keeping it sorted on address.


X */
X static void

Xu_free_line(ptr)
X char_u *ptr;
X{
X register info_t *next;
X register info_t *prev, *curr;
X register info_t *mp;
X struct m_block *nextb;
X
X if (ptr == NULL || ptr == IObuff)
X return; /* illegal address can happen in out-of-memory situations */
X
X mp = (info_t *)(ptr - M_OFFSET);
X
X /* find block where chunk could be a part off */
X /* if we change curbuf->b_mb_current, curbuf->b_m_search is set to NULL */
X if (curbuf->b_mb_current == NULL || mp < (info_t *)curbuf->b_mb_current)
X {
X curbuf->b_mb_current = curbuf->b_block_head.mb_next;
X curbuf->b_m_search = NULL;
X }
X if ((nextb = curbuf->b_mb_current->mb_next) != NULL && (info_t *)nextb < mp)
X {
X curbuf->b_mb_current = nextb;
X curbuf->b_m_search = NULL;
X }
X while ((nextb = curbuf->b_mb_current->mb_next) != NULL && (info_t *)nextb < mp)
X curbuf->b_mb_current = nextb;
X
X curr = NULL;
X /*
X * If mp is smaller than curbuf->b_m_search->m_next go to the start of
X * the free list
X */
X if (curbuf->b_m_search == NULL || mp < (curbuf->b_m_search->m_next))
X next = &(curbuf->b_mb_current->mb_info);
X else
X next = curbuf->b_m_search;
X /*
X * The following loop is executed very often.
X * Therefore it has been optimized at the cost of readability.
X * Keep it fast!
X */
X#ifdef SLOW_BUT_EASY_TO_READ
X do
X {
X prev = curr;
X curr = next;
X next = next->m_next;
X }
X while (mp > next && next != NULL);
X#else
X do /* first, middle, last */
X {
X prev = next->m_next; /* curr, next, prev */
X if (prev == NULL || mp <= prev)
X {
X prev = curr;
X curr = next;
X next = next->m_next;
X break;
X }
X curr = prev->m_next; /* next, prev, curr */
X if (curr == NULL || mp <= curr)
X {
X prev = next;
X curr = prev->m_next;
X next = curr->m_next;
X break;
X }
X next = curr->m_next; /* prev, curr, next */
X }
X while (mp > next && next != NULL);
X#endif
X
X/* if *mp and *next are concatenated, join them into one chunk */
X if ((char_u *)mp + mp->m_size == (char_u *)next)
X {
X mp->m_size += next->m_size;
X mp->m_next = next->m_next;
X }
X else
X mp->m_next = next;
X
X/* if *curr and *mp are concatenated, join them */
X if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
X {
X curr->m_size += mp->m_size;
X curr->m_next = mp->m_next;
X curbuf->b_m_search = prev;
X }
X else
X {
X curr->m_next = mp;
X curbuf->b_m_search = curr; /* put curbuf->b_m_search before freed chunk */
X }
X}
X
X/*
X * Allocate and initialize a new line structure with room for at least
X * 'size' characters plus a terminating NUL.


X */
X static char_u *

Xu_alloc_line(size)
X register unsigned size;
X{
X register info_t *mp, *mprev, *mp2;
X struct m_block *mbp;
X int size_align;
X
X/*
X * Add room for size field and trailing NUL byte.
X * Adjust for minimal size (must be able to store info_t
X * plus a trailing NUL, so the chunk can be released again)
X */
X size += M_OFFSET + 1;
X if (size < sizeof(info_t) + 1)
X size = sizeof(info_t) + 1;
X
X/*
X * round size up for alignment
X */
X size_align = (size + ALIGN_MASK) & ~ALIGN_MASK;
X
X/*
X * If curbuf->b_m_search is NULL (uninitialized free list) start at
X * curbuf->b_block_head
X */
X if (curbuf->b_mb_current == NULL || curbuf->b_m_search == NULL)
X {
X curbuf->b_mb_current = &curbuf->b_block_head;
X curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
X }
X
X/* search for space in free list */
X mprev = curbuf->b_m_search;
X mbp = curbuf->b_mb_current;
X mp = curbuf->b_m_search->m_next;
X if (mp == NULL)
X {
X if (mbp->mb_next)
X mbp = mbp->mb_next;
X else
X mbp = &curbuf->b_block_head;
X mp = curbuf->b_m_search = &(mbp->mb_info);
X }
X while (mp->m_size < size)
X {
X if (mp == curbuf->b_m_search) /* back where we started in free chunk list */
X {
X if (mbp->mb_next)
X mbp = mbp->mb_next;
X else
X mbp = &curbuf->b_block_head;
X mp = curbuf->b_m_search = &(mbp->mb_info);
X if (mbp == curbuf->b_mb_current) /* back where we started in block list */
X {
X int n = (size_align > (MEMBLOCKSIZE / 4) ? size_align : MEMBLOCKSIZE);
X
X mp = (info_t *)u_blockalloc((long_u)n);
X if (mp == NULL)
X return (NULL);
X mp->m_size = n;
X u_free_line((char_u *)mp + M_OFFSET);
X mp = curbuf->b_m_search;
X mbp = curbuf->b_mb_current;
X }
X }
X mprev = mp;
X if ((mp = mp->m_next) == NULL) /* at end of the list */
X mp = &(mbp->mb_info); /* wrap around to begin */
X }
X
X/* if the chunk we found is large enough, split it up in two */
X if ((long)mp->m_size - size_align >= (long)(sizeof(info_t) + 1))
X {
X mp2 = (info_t *)((char_u *)mp + size_align);
X mp2->m_size = mp->m_size - size_align;
X mp2->m_next = mp->m_next;
X mprev->m_next = mp2;
X mp->m_size = size_align;
X }
X else /* remove *mp from the free list */
X {
X mprev->m_next = mp->m_next;
X }
X curbuf->b_m_search = mprev;
X curbuf->b_mb_current = mbp;
X
X mp = (info_t *)((char_u *)mp + M_OFFSET);
X *(char_u *)mp = NUL; /* set the first byte to NUL */
X
X return ((char_u *)mp);
X}
X
X/*
X * u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum' into it.


X */
X static char_u *

Xu_save_line(lnum)
X linenr_t lnum;
X{
X register char_u *src;
X register char_u *dst;
X register unsigned len;
X
X src = ml_get(lnum);
X len = STRLEN(src);
X if ((dst = u_alloc_line(len)) != NULL)
X memmove((char *)dst, (char *)src, (size_t)(len + 1));
X return (dst);
X}
END_OF_FILE
if test 24811 -ne `wc -c <'vim/src/undo.c'`; then
echo shar: \"'vim/src/undo.c'\" unpacked with wrong size!
fi
# end of 'vim/src/undo.c'
fi
echo shar: End of archive 11 \(of 26\).
cp /dev/null ark11isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:23 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 31
Archive-name: vim/part12

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/vim.1 vim/src/ops.c vim/src/proto/normal.pro
# vim/src/term.c


# Wrapped by kent@sparky on Mon Aug 15 21:44:05 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 12 (of 26)."'
if test -f 'vim/doc/vim.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/vim.1'\"
else
echo shar: Extracting \"'vim/doc/vim.1'\" \(5252 characters\)
sed "s/^X//" >'vim/doc/vim.1' <<'END_OF_FILE'
X.TH VIM 1 "1994 August 12"
X.SH NAME
Xvim \- Vi IMproved, a programmers text editor
X.SH SYNOPSIS
X.B vim
X[options] [file ..]
X.br
X.B vim
X[options] \-t tag
X.br
X.B vim
X[options] \-e [errorfile]
X.SH DESCRIPTION
X.B Vim
Xis a text editor that is upwards compatible to vi. It can be used to edit any
XASCII text. It is especially useful for editing programs.
X.PP
XThere are a lot of enhancements above vi: multi level undo,
Xmulti windows and buffers, command line
Xediting, filename completion, on-line help, visual selection, etc..
XRead difference.doc
Xfor a summary of the differences between vi and Vim.
X.PP
XMost often
X.B Vim
Xis started to edit a single file with the command
X.PP
X vim file
X.PP
XMore generally VIM is started with:
X.PP
X vim [options] [filelist]
X.PP


XIf the filelist is missing, the editor will start with an empty buffer.

XOtherwise exactly one out of the following three may be used to choose one or
Xmore files to be edited.
X.TP 12
Xfile ..
XA list of file names. The first one (alphabetically) will be
Xthe current file and read into the buffer. The cursor will be
Xpositioned on the first line of the buffer. You can get to the other files
Xwith the ":next" command.
X.TP
X-t {tag}
XThe file to edit and the initial cursor position depends on a "tag", a sort
Xof goto label. {tag} is looked up in the tags file, the associated file
Xbecomes the current file and the associated command is executed. Mostly this
Xis used for C programs. {tag} then should be a function name. The effect is
Xthat the file containing that function becomes the current file and the
Xcursor is positioned on the start of the function (see reference.doc,
Xsection "tag searches").
X.TP
X-e [errorfile]
XStart in quickFix mode. The file [errorfile]
Xis read and the first error is displayed. If [errorfile] is omitted the file
Xname is obtained from the 'errorfile' option (defaults to "AztecC.Err" for
Xthe Amiga, "errors" on other systems). Further errors can be jumped to
Xwith the ":cn" command. See reference.doc section 5.5.
X.SH OPTIONS


XThe options, if present, must precede the filelist. The options may be given
Xin any order.

X.TP 12
X-r
XRecovery mode. The swap file is used to recover a crashed editing session. The
Xswap file is a file with the same file name as the text file with ".swp"
Xappended. See reference.doc, chapter "Recovery after a crash".
X.TP
X-v
XView mode. The 'readonly' option will be set. You can still
Xedit the buffer, but will be prevented from accidently
Xoverwriting a file. If you do want to overwrite a file, add
Xan exclamation mark to the Ex command, as in ":w!".
XThe -v option also implies the -n option (see below).
XThe 'readonly' option can be reset with ":set noro" (see reference.doc,
Xoptions chapter).
X.TP
X-b
XBinary. A few options will be set that makes it possible to edit a binary or
Xexecutable file.
X.TP
X+[num]
XFor the first file the cursor will be positioned on line
X"num". If "num" is missing, the cursor will be positioned on
Xthe last line.
X.TP
X+/pat
XFor the first file the cursor will be positioned on the
Xfirst occurrence of "pat" (see reference.doc,
Xsection "pattern searches" for the available search
Xpatterns).
X.TP
X+{command}
X.TP
X-c {command}
X{command} will be executed after the
Xfirst file has been read. {command} is interpreted as an Ex
Xcommand. If the {command} contains spaces it must
Xbe enclosed in double quotes (this depends on the shell that
Xis used).
XExample: Vim "+set si" main.c
X.TP
X-x
X(Amiga only) Vim is not restarted to open a new window. This option should
Xbe used when Vim is executed by a program that will wait for the edit
Xsession to finish (e.g. mail). The ":sh" and ":!" commands will not work.
X.TP
X-o[N]
XOpen N windows. When N is omitted, open one window for each file.
X.TP
X-n
XNo swap file will be used. Recovery after a crash
Xwill be impossible. Handy if you want to edit a file on a
Xvery slow medium (e.g. floppy). Can also be done with ":set
Xuc=0". Can be undone with ":set uc=200".
X.TP
X-s {scriptin}
XThe script file {scriptin} is read. The characters in the
Xfile are interpreted as if you had typed them. The same can
Xbe done with the command ":source! {scriptin}". If the end
Xof the file is reached before the editor exits, further
Xcharacters are read from the keyboard.
X.TP
X-w {scriptout}
XAll the characters that you type are recorded in the file
X{scriptout}, until you exit VIM. This is useful if you want
Xto create a script file to be used with "vim -s" or
X":source!".
X.TP
X-T terminal
XTells Vim the name of the terminal you are using. Should be a terminal known
Xto Vim (builtin) or defined in the termcap file.
X.TP
X-d device
XOpen "device" for use as a terminal. Only on the Amiga. Example:
X"\-d con:20/30/600/150".
X.SH SEE ALSO
XVim documentation:
X.TP 12
Xreference.doc:
XA complete reference of Vim (long)
X.TP
Xwindows.doc:
XExplanation of the multi windows and buffers commands and options
X.TP
Xindex:
XOverview of all command characters (useful when adding new mappings)
X.TP
Xdifference.doc:
XOverview of the differences between vi and Vim
X.TP
Xunix.doc:
XUnix-specific comments
X.TP
Xvim.hlp:
XFile used by the on-line help (short)
X.SH AUTHOR
XMost of VIM was made by Bram Moolenaar.
X.br
XVIM is based on Stevie, worked on by: Tim Thompson,
XTony Andrews and G.R. (Fred) Walter
X.SH BUGS
XProbably.
END_OF_FILE
if test 5252 -ne `wc -c <'vim/doc/vim.1'`; then
echo shar: \"'vim/doc/vim.1'\" unpacked with wrong size!
fi
# end of 'vim/doc/vim.1'
fi
if test -f 'vim/src/ops.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/ops.c'\"
else
echo shar: Extracting \"'vim/src/ops.c'\" \(39495 characters\)
sed "s/^X//" >'vim/src/ops.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * ops.c: implementation of various operators: doshift, dodelete, dotilde,
X * dochange, doyank, doput, dojoin


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"

X#include "ops.h"
X
X/*
X * We have one yank buffer for normal yanks and puts, nine yank buffers for
X * deletes and 26 yank buffers for use by name.
X * Each yank buffer is an array of pointers to lines.
X */
Xstatic struct yankbuf
X{
X char_u **y_array; /* pointer to array of line pointers */
X linenr_t y_size; /* number of lines in y_array */
X char_u y_type; /* MLINE, MCHAR or MBLOCK */
X} y_buf[36]; /* 0..9 = number buffers, 10..35 = char buffers */
X
Xstatic struct yankbuf *y_current; /* ptr to current yank buffer */
Xstatic int yankappend; /* TRUE when appending */
Xstatic struct yankbuf *y_previous = NULL; /* ptr to last written yank buffer */
X
Xstatic void get_yank_buffer __ARGS((int));
Xstatic int stuff_yank __ARGS((int, char_u *));
Xstatic void free_yank __ARGS((long));
Xstatic void free_yank_all __ARGS((void));
Xstatic void block_prep __ARGS((linenr_t, int));
X
X/* variables use by block_prep, dodelete and doyank */
Xstatic int startspaces;
Xstatic int endspaces;
Xstatic int textlen;
Xstatic char_u *textstart;
Xstatic colnr_t textcol;
X
X/*
X * doshift - handle a shift operation
X */
X void
Xdoshift(op, curs_top, amount)
X int op;
X int curs_top;
X int amount;
X{
X register long i;
X int first_char;
X
X if (!u_save((linenr_t)(curwin->w_cursor.lnum - 1), (linenr_t)(curwin->w_cursor.lnum + nlines)))
X return;
X
X for (i = nlines; --i >= 0; )
X {
X first_char = *ml_get(curwin->w_cursor.lnum);
X if (first_char == NUL) /* empty line */


X curwin->w_cursor.col = 0;

X /*
X * Don't move the line right if it starts with # and p_si is set.
X */
X else if (!curbuf->b_p_si || first_char != '#')
X {
X /* if (Visual_block)
X shift the block, not the whole line
X else */
X shift_line(op == LSHIFT, p_sr, amount);


X }
X ++curwin->w_cursor.lnum;
X }

X
X if (curs_top) /* put cursor on first line, for ">>" */
X curwin->w_cursor.lnum -= nlines;
X else
X --curwin->w_cursor.lnum; /* put cursor on last line, for ":>" */
X updateScreen(CURSUPD);
X
X if (nlines > p_report)
X smsg((char_u *)"%ld line%s %ced", nlines, plural(nlines),
X (op == RSHIFT) ? '>' : '<');
X}
X
X/*
X * shift the current line one shiftwidth left (if left != 0) or right
X * leaves cursor on first blank in the line
X */
X void
Xshift_line(left, round, amount)
X int left;
X int round;
X int amount;
X{
X register int count;
X register int i, j;
X int p_sw = (int)curbuf->b_p_sw;
X
X count = get_indent(); /* get current indent */
X
X if (round) /* round off indent */
X {
X i = count / p_sw; /* number of p_sw rounded down */
X j = count % p_sw; /* extra spaces */
X if (j && left) /* first remove extra spaces */
X --amount;
X if (left)
X {
X i -= amount;
X if (i < 0)


X i = 0;
X }

X else
X i += amount;
X count = i * p_sw;
X }
X else /* original vi indent */
X {
X if (left)
X {
X count -= p_sw * amount;
X if (count < 0)


X count = 0;
X }

X else
X count += p_sw * amount;
X }
X set_indent(count, TRUE); /* set new indent */
X}
X
X/*
X * check if character is name of yank buffer
X * Note: There is no check for 0 (default register), caller should do this
X */
X int
Xis_yank_buffer(c, write)
X int c;
X int write; /* if TRUE check for writable buffers */
X{
X if (isalnum(c) || (!write && strchr(".%:", c) != NULL) || c == '"')


X return TRUE;
X return FALSE;
X}
X

X/*
X * Set y_current and yankappend, according to the value of yankbuffer.
X *
X * If yankbuffer is 0 and writing, use buffer 0
X * If yankbuffer is 0 and reading, use previous buffer


X */
X static void

Xget_yank_buffer(writing)
X int writing;


X{
X register int i;
X

X yankappend = FALSE;
X if (((yankbuffer == 0 && !writing) || yankbuffer == '"') && y_previous != NULL)
X {
X y_current = y_previous;
X return;
X }
X i = yankbuffer;
X if (isdigit(i))
X i -= '0';
X else if (islower(i))
X i -= 'a' - 10;
X else if (isupper(i))
X {
X i -= 'A' - 10;
X yankappend = TRUE;
X }
X else /* not 0-9, a-z or A-Z: use buffer 0 */
X i = 0;
X y_current = &(y_buf[i]);
X if (writing) /* remember the buffer we write into for doput() */
X y_previous = y_current;
X}
X
X/*
X * start or stop recording into a yank buffer


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xdorecord(c)
X int c;
X{
X char_u *p;
X static int bufname;
X int retval;
X
X if (Recording == FALSE) /* start recording */
X {
X if (!isalnum(c) && c != '"') /* registers 0-9, a-z and " are allowed */
X retval = FAIL;
X else
X {
X Recording = TRUE;
X showmode();
X bufname = c;
X retval = OK;
X }
X }
X else /* stop recording */
X {
X Recording = FALSE;
X MSG("");
X /* the trailing 'q' command will not have been put in the buffer */
X p = get_recorded();


X if (p == NULL)

X retval = FAIL;
X else
X retval = (stuff_yank(bufname, p));
X }
X return retval;
X}
X
X/*
X * stuff string 'p' into yank buffer 'bufname' (append if uppercase)
X * 'p' is assumed to be alloced.


X *
X * return FAIL for failure, OK otherwise
X */

X static int
Xstuff_yank(bufname, p)
X int bufname;
X char_u *p;
X{
X char_u *lp;
X char_u **pp;
X
X yankbuffer = bufname;
X /* check for read-only buffer */
X if (yankbuffer != 0 && !is_yank_buffer(yankbuffer, TRUE))
X return FAIL;
X get_yank_buffer(TRUE);
X if (yankappend && y_current->y_array != NULL)
X {
X pp = &(y_current->y_array[y_current->y_size - 1]);
X lp = lalloc((long_u)(STRLEN(*pp) + STRLEN(p) + 1), TRUE);
X if (lp == NULL)
X {
X free(p);
X return FAIL;
X }
X STRCPY(lp, *pp);
X STRCAT(lp, p);
X free(p);
X free(*pp);
X *pp = lp;
X }
X else
X {
X free_yank_all();
X if ((y_current->y_array = (char_u **)alloc((unsigned)sizeof(char_u *))) == NULL)
X {
X free(p);
X return FAIL;
X }
X y_current->y_array[0] = p;
X y_current->y_size = 1;
X y_current->y_type = MCHAR; /* used to be MLINE, why? */
X }
X return OK;
X}
X
X/*
X * execute a yank buffer (register): copy it into the stuff buffer


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xdoexecbuf(c)
X int c;
X{
X static int lastc = NUL;
X long i;
X
X if (c == '@') /* repeat previous one */
X c = lastc;
X if (!is_yank_buffer(c, FALSE)) /* check for valid buffer */
X return FAIL;
X lastc = c;
X
X if (c == ':') /* use last command line */
X {
X if (last_cmdline == NULL)
X {
X EMSG(e_nolastcmd);
X return FAIL;
X }
X free(new_last_cmdline); /* don't keep the command line containing @: */
X new_last_cmdline = NULL;
X if (ins_typestr((char_u *)"\n", FALSE) == FAIL)
X return FAIL;
X if (ins_typestr(last_cmdline, FALSE) == FAIL)
X return FAIL;
X }
X else
X {
X yankbuffer = c;
X get_yank_buffer(FALSE);
X if (y_current->y_array == NULL)
X return FAIL;
X
X for (i = y_current->y_size; --i >= 0; )
X {
X /* insert newline between lines and after last line if type is MLINE */
X if (y_current->y_type == MLINE || i < y_current->y_size - 1)
X {
X if (ins_typestr((char_u *)"\n", FALSE) == FAIL)
X return FAIL;
X }
X if (ins_typestr(y_current->y_array[i], FALSE) == FAIL)
X return FAIL;
X }
X Exec_reg = TRUE; /* disable the 'q' command */
X }
X return OK;
X}
X
X/*
X * insert a yank buffer: copy it into the Read buffer
X * used by CTRL-R command in insert mode


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xinsertbuf(c)
X int c;
X{
X long i;
X
X /*
X * It is possible to get into an endless loop by having CTRL-R a in
X * register a and then, in insert mode, doing CTRL-R a.
X * If you hit CTRL-C, the loop will be broken here.
X */


X breakcheck();
X if (got_int)

X return FAIL;
X
X if (!is_yank_buffer(c, FALSE)) /* check for valid buffer */
X return FAIL;
X
X if (c == '.') /* insert last inserted text */
X {
X stuff_inserted(NUL, 1L, TRUE);


X return OK;
X }
X

X if (c == '%') /* insert file name */
X {
X if (check_fname() == FAIL)
X return FAIL;
X stuffReadbuff(curbuf->b_xfilename);


X return OK;
X }
X

X if (c == ':') /* insert last command line */
X {
X if (last_cmdline == NULL)
X {
X EMSG(e_nolastcmd);
X return FAIL;
X }
X stuffReadbuff(last_cmdline);


X return OK;
X }
X

X yankbuffer = c;
X get_yank_buffer(FALSE);
X if (y_current->y_array == NULL)
X return FAIL;
X
X for (i = 0; i < y_current->y_size; ++i)
X {
X stuffReadbuff(y_current->y_array[i]);
X /* insert newline between lines and after last line if type is MLINE */
X if (y_current->y_type == MLINE || i < y_current->y_size - 1)


X stuffReadbuff((char_u *)"\n");
X }

X return OK;
X}
X
X/*
X * dodelete - handle a delete operation
X */
X void
Xdodelete()
X{
X register int n;
X linenr_t lnum;
X char_u *ptr;
X char_u *new, *old;
X linenr_t old_lcount = curbuf->b_ml.ml_line_count;
X int did_yank = FALSE;
X
X /*
X * Imitate the strange Vi behaviour: If the delete spans more than one line
X * and mtype == MCHAR and the result is a blank line, make the delete
X * linewise. Don't do this for the change command.
X */
X if (mtype == MCHAR && nlines > 1 && operator == DELETE)
X {
X ptr = ml_get(curbuf->b_endop.lnum) + curbuf->b_endop.col + mincl;
X skipspace(&ptr);
X if (*ptr == NUL && inindent())
X mtype = MLINE;
X }
X
X/*
X * If a yank buffer was specified, put the deleted text into that buffer
X */
X if (yankbuffer != 0)
X {
X /* check for read-only buffer */
X if (!is_yank_buffer(yankbuffer, TRUE))


X {
X beep();
X return;
X }

X get_yank_buffer(TRUE); /* yank into specified buffer */
X if (doyank(TRUE) == OK)
X did_yank = TRUE;
X }
X
X/*
X * Put deleted text into register 1 and shift number buffers if
X * the delete contains a line break.
X * Overruled when a yankbuffer has been specified!
X */
X if (yankbuffer != 0 || mtype == MLINE || nlines > 1)
X {
X y_current = &y_buf[9];
X free_yank_all(); /* free buffer nine */
X for (n = 9; n > 1; --n)
X y_buf[n] = y_buf[n - 1];
X y_previous = y_current = &y_buf[1];
X y_buf[1].y_array = NULL; /* set buffer one to empty */


X yankbuffer = 0;
X }

X else if (yankbuffer == 0) /* yank into unnamed buffer */
X get_yank_buffer(TRUE);
X
X /*
X * Do a yank of whatever we're about to delete. If there's too much stuff
X * to fit in the yank buffer, then get a confirmation before doing the
X * delete. This is crude, but simple. And it avoids doing a delete of
X * something we can't put back if we want.
X */
X if (yankbuffer == 0 && doyank(TRUE) == OK)
X did_yank = TRUE;
X
X if (!did_yank)
X {
X if (ask_yesno((char_u *)"cannot yank; delete anyway") != 'y')
X {
X emsg(e_abort);


X return;
X }
X }
X

X/*
X * block mode


X */
X if (Visual_block)

X {
X if (!u_save((linenr_t)(curbuf->b_startop.lnum - 1), (linenr_t)(curbuf->b_endop.lnum + 1)))
X return;
X
X for (lnum = curwin->w_cursor.lnum; curwin->w_cursor.lnum <= curbuf->b_endop.lnum; ++curwin->w_cursor.lnum)
X {
X block_prep(curwin->w_cursor.lnum, TRUE);
X if (textlen == 0) /* nothing to delete */
X continue;
X
X /*
X * If we delete a TAB, it may be replaced by several characters.
X * Thus the number of characters may increase!
X */
X n = textlen - startspaces - endspaces; /* number of chars deleted */
X old = ml_get(curwin->w_cursor.lnum);
X new = alloc((unsigned)STRLEN(old) + 1 - n);


X if (new == NULL)

X continue;
X /* copy up to deleted part */
X memmove((char *)new, (char *)old, (size_t)textcol);
X /* insert spaces */
X copy_spaces(new + textcol, (size_t)(startspaces + endspaces));
X /* copy the part after the deleted part */
X old += textcol + textlen;
X memmove((char *)new + textcol + startspaces + endspaces,
X (char *)old, STRLEN(old) + 1);
X /* replace the line */
X ml_replace(curwin->w_cursor.lnum, new, FALSE);
X }
X curwin->w_cursor.lnum = lnum;
X CHANGED;
X updateScreen(VALID_TO_CURSCHAR);
X nlines = 0; /* no lines deleted */
X }
X else if (mtype == MLINE)
X {
X if (operator == CHANGE)
X {
X dellines((long)(nlines - 1), TRUE, TRUE);
X if (!u_save_cursor())
X return;
X if (curbuf->b_p_ai) /* don't delete indent */
X {
X beginline(TRUE); /* put cursor on first non-white */
X did_ai = TRUE; /* delete the indent when ESC hit */
X }
X while (delchar(FALSE) == OK) /* slow but simple */
X ;
X if (curwin->w_cursor.col > 0)
X --curwin->w_cursor.col; /* put cursor on last char in line */
X }
X else
X {
X dellines(nlines, TRUE, TRUE);
X }
X u_clearline(); /* "U" command should not be possible after "dd" */
X beginline(TRUE);
X }
X else if (nlines == 1) /* delete characters within one line */
X {
X if (!u_save_cursor())
X return;
X n = curbuf->b_endop.col - curbuf->b_startop.col + 1 - !mincl;
X while (n-- > 0)
X if (delchar(TRUE) == FAIL)
X break;
X }
X else /* delete characters between lines */
X {
X if (!u_save_cursor()) /* save first line for undo */
X return;
X n = curwin->w_cursor.col;
X while (curwin->w_cursor.col >= n) /* delete from cursor to end of line */
X if (delchar(TRUE) == FAIL)
X break;
X
X curbuf->b_startop = curwin->w_cursor; /* remember curwin->w_cursor */
X ++curwin->w_cursor.lnum;
X dellines((long)(nlines - 2), TRUE, TRUE); /* includes save for undo */
X
X if (!u_save_cursor()) /* save last line for undo */
X return;
X n = curbuf->b_endop.col - !mincl;


X curwin->w_cursor.col = 0;

X while (n-- >= 0) /* delete from start of line until endop */
X if (delchar(TRUE) == FAIL)
X break;
X curwin->w_cursor = curbuf->b_startop; /* restore curwin->w_cursor */
X (void)dojoin(FALSE, TRUE);
X }
X
X if ((mtype == MCHAR && nlines == 1) || operator == CHANGE)
X {
X cursupdate();
X updateline();
X }
X else
X updateScreen(CURSUPD);
X
X msgmore(curbuf->b_ml.ml_line_count - old_lcount);
X
X /* correct endop for deleted text (for "']" command) */
X if (Visual_block)
X curbuf->b_endop.col = curbuf->b_startop.col;
X else


X curbuf->b_endop = curbuf->b_startop;

X}
X
X/*
X * dotilde - handle the (non-standard vi) tilde operator
X */
X void
Xdotilde()
X{
X FPOS pos;
X
X if (!u_save((linenr_t)(curbuf->b_startop.lnum - 1), (linenr_t)(curbuf->b_endop.lnum + 1)))
X return;
X
X pos = curbuf->b_startop;


X if (Visual_block) /* block mode */
X {

X for (; pos.lnum <= curbuf->b_endop.lnum; ++pos.lnum)
X {
X block_prep(pos.lnum, FALSE);
X pos.col = textcol;
X while (--textlen >= 0)
X {
X swapchar(&pos);
X if (inc(&pos) == -1) /* at end of file */
X break;
X }
X }
X }
X else /* not block mode */
X {
X if (mtype == MLINE)
X {
X pos.col = 0;


X curbuf->b_endop.col = STRLEN(ml_get(curbuf->b_endop.lnum));
X if (curbuf->b_endop.col)

X --curbuf->b_endop.col;
X }
X else if (!mincl)
X dec(&(curbuf->b_endop));
X
X while (ltoreq(pos, curbuf->b_endop))
X {
X swapchar(&pos);
X if (inc(&pos) == -1) /* at end of file */
X break;
X }
X }
X
X if (mtype == MCHAR && nlines == 1 && !Visual_block)
X {
X cursupdate();
X updateline();
X }
X else
X updateScreen(CURSUPD);
X
X if (nlines > p_report)
X smsg((char_u *)"%ld line%s ~ed", nlines, plural(nlines));
X}
X
X/*
X * If operator == UPPER: make uppercase,
X * if operator == LOWER: make lowercase,
X * else swap case of character at 'pos'
X */
X void
Xswapchar(pos)
X FPOS *pos;
X{
X int c;
X
X c = gchar(pos);
X if (islower(c) && operator != LOWER)
X {
X pchar(*pos, toupper(c));
X CHANGED;
X }
X else if (isupper(c) && operator != UPPER)
X {
X pchar(*pos, tolower(c));
X CHANGED;
X }
X}
X
X/*
X * dochange - handle a change operation
X */
X void
Xdochange()
X{
X register colnr_t l;
X
X l = curbuf->b_startop.col;
X
X if (!no_op)
X dodelete();
X
X if ((l > curwin->w_cursor.col) && !lineempty(curwin->w_cursor.lnum))
X inc_cursor();
X
X startinsert(NUL, FALSE, (linenr_t)1);
X}
X
X/*
X * set all the yank buffers to empty (called from main())
X */
X void
Xinit_yank()


X{
X register int i;
X

X for (i = 0; i < 36; ++i)
X y_buf[i].y_array = NULL;
X}
X
X/*
X * Free "n" lines from the current yank buffer.
X * Called for normal freeing and in case of error.


X */
X static void

Xfree_yank(n)
X long n;
X{
X if (y_current->y_array != NULL)
X {
X register long i;
X
X for (i = n; --i >= 0; )
X {
X if (i % 1000 == 999) /* this may take a while */
X smsg((char_u *)"freeing %ld lines", i + 1);
X free(y_current->y_array[i]);
X }
X free(y_current->y_array);
X y_current->y_array = NULL;
X if (n >= 1000)
X MSG("");


X }
X}
X
X static void

Xfree_yank_all()
X{
X free_yank(y_current->y_size);
X}
X
X/*
X * Yank the text between curwin->w_cursor and startpos into a yank buffer.
X * If we are to append ("uppercase), we first yank into a new yank buffer and
X * then concatenate the old and the new one (so we keep the old one in case
X * of out-of-memory).


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xdoyank(deleting)
X int deleting;
X{
X long i; /* index in y_array[] */
X struct yankbuf *curr; /* copy of y_current */
X struct yankbuf new; /* new yank buffer when appending */
X char_u **new_ptr;
X register linenr_t lnum; /* current line number */
X long j;
X int yanktype = mtype;
X long yanklines = nlines;
X linenr_t yankendlnum = curbuf->b_endop.lnum;
X
X char_u *pnew;
X
X /* check for read-only buffer */
X if (yankbuffer != 0 && !is_yank_buffer(yankbuffer, TRUE))
X {
X beep();
X return FAIL;
X }
X if (!deleting) /* dodelete() already set y_current */
X get_yank_buffer(TRUE);
X
X curr = y_current;
X if (yankappend && y_current->y_array != NULL) /* append to existing contents */
X y_current = &new;
X else
X free_yank_all(); /* free previously yanked lines */
X
X/*
X * If the cursor was in column 1 before and after the movement, the
X * yank is always linewise.
X */
X if (mtype == MCHAR && curbuf->b_startop.col == 0 && curbuf->b_endop.col == 0 && nlines > 1)
X {
X yanktype = MLINE;
X if (mincl == FALSE && yankendlnum > curbuf->b_startop.lnum)
X {
X --yankendlnum;
X --yanklines;
X }
X }
X
X y_current->y_size = yanklines;
X y_current->y_type = yanktype; /* set the yank buffer type */
X y_current->y_array = (char_u **)lalloc((long_u)(sizeof(char_u *) * yanklines), TRUE);
X
X if (y_current->y_array == NULL)
X {
X y_current = curr;
X return FAIL;
X }


X
X i = 0;

X lnum = curbuf->b_startop.lnum;
X
X if (Visual_block)
X {
X/*
X * block mode
X */
X y_current->y_type = MBLOCK; /* set the yank buffer type */
X for ( ; lnum <= yankendlnum; ++lnum)
X {
X block_prep(lnum, FALSE);
X if ((pnew = alloc(startspaces + endspaces + textlen + 1)) == NULL)
X goto fail;
X y_current->y_array[i++] = pnew;
X copy_spaces(pnew, (size_t)startspaces);
X pnew += startspaces;
X STRNCPY(pnew, textstart, (size_t)textlen);
X pnew += textlen;
X copy_spaces(pnew, (size_t)endspaces);
X pnew += endspaces;
X *pnew = NUL;
X }
X }
X else
X {
X/*
X * there are three parts for non-block mode:
X * 1. if yanktype != MLINE yank last part of the top line
X * 2. yank the lines between startop and endop, inclusive when yanktype == MLINE
X * 3. if yanktype != MLINE yank first part of the bot line
X */
X if (yanktype != MLINE)
X {
X if (yanklines == 1) /* startop and endop on same line */
X {
X j = curbuf->b_endop.col - curbuf->b_startop.col + 1 - !mincl;
X if ((y_current->y_array[0] = strnsave(ml_get(lnum) + curbuf->b_startop.col, (int)j)) == NULL)
X {
X fail:
X free_yank(i); /* free the lines that we allocated */
X y_current = curr;
X return FAIL;
X }
X goto success;
X }
X if ((y_current->y_array[0] = strsave(ml_get(lnum++) + curbuf->b_startop.col)) == NULL)
X goto fail;
X ++i;
X }
X
X while (yanktype == MLINE ? (lnum <= yankendlnum) : (lnum < yankendlnum))
X {
X if ((y_current->y_array[i] = strsave(ml_get(lnum++))) == NULL)
X goto fail;
X ++i;
X }
X if (yanktype != MLINE)
X {
X if ((y_current->y_array[i] = strnsave(ml_get(yankendlnum), curbuf->b_endop.col + 1 - !mincl)) == NULL)
X goto fail;
X }
X }
X
Xsuccess:
X if (curr != y_current) /* append the new block to the old block */
X {
X new_ptr = (char_u **)lalloc((long_u)(sizeof(char_u *) * (curr->y_size + y_current->y_size)), TRUE);
X if (new_ptr == NULL)
X goto fail;
X for (j = 0; j < curr->y_size; ++j)
X new_ptr[j] = curr->y_array[j];
X free(curr->y_array);
X curr->y_array = new_ptr;
X
X if (yanktype == MLINE) /* MLINE overrides MCHAR and MBLOCK */
X curr->y_type = MLINE;
X if (curr->y_type == MCHAR) /* concatenate the last line of the old
X block with the first line of the new block */
X {
X pnew = lalloc((long_u)(STRLEN(curr->y_array[curr->y_size - 1]) + STRLEN(y_current->y_array[0]) + 1), TRUE);
X if (pnew == NULL)
X {
X i = y_current->y_size - 1;
X goto fail;
X }
X STRCPY(pnew, curr->y_array[--j]);
X STRCAT(pnew, y_current->y_array[0]);
X free(curr->y_array[j]);
X free(y_current->y_array[0]);
X curr->y_array[j++] = pnew;
X i = 1;
X }
X else
X i = 0;
X while (i < y_current->y_size)
X curr->y_array[j++] = y_current->y_array[i++];
X curr->y_size = j;
X free(y_current->y_array);
X y_current = curr;
X }
X if (operator == YANK) /* don't do this when deleting */
X {
X if (yanktype == MCHAR && !Visual_block)
X --yanklines;
X if (yanklines > p_report)
X {
X cursupdate(); /* redisplay now, so message is not deleted */
X smsg((char_u *)"%ld line%s yanked", yanklines, plural(yanklines));
X }
X }
X
X return OK;
X}
X
X/*
X * put contents of register into the text
X */
X void
Xdoput(dir, count, fix_indent)
X int dir; /* BACKWARD for 'P', FORWARD for 'p' */
X long count;
X int fix_indent; /* make indent look nice */
X{
X char_u *ptr;
X char_u *new, *old;
X int yanklen;
X int oldlen;
X int totlen = 0; /* init for gcc */
X linenr_t lnum;
X int col;
X long i; /* index in y_array[] */
X int y_type;
X long y_size;
X char_u **y_array;
X long nlines = 0;
X int vcol;
X int delchar;
X int incr = 0;
X long j;
X FPOS new_cursor;
X int commandchar;
X char_u temp[2];
X int indent;
X int orig_indent = 0; /* init for gcc */
X int indent_diff = 0; /* init for gcc */
X int first_indent = TRUE;
X
X if (fix_indent)
X orig_indent = get_indent();
X
X curbuf->b_startop = curwin->w_cursor; /* default for "'[" command */
X if (dir == FORWARD)
X curbuf->b_startop.col++;
X curbuf->b_endop = curwin->w_cursor; /* default for "']" command */
X commandchar = (dir == FORWARD ? (count == -1 ? 'o' : 'a') : (count == -1 ? 'O' : 'i'));
X if (yankbuffer == '.') /* use inserted text */
X {
X stuff_inserted(commandchar, count, FALSE);
X return;
X }
X else if (yankbuffer == '%') /* use file name */
X {
X if (check_fname() == OK)
X {
X stuffcharReadbuff(commandchar);
X stuffReadbuff(curbuf->b_xfilename);
X stuffcharReadbuff(ESC);
X }
X return;
X }
X else if (yankbuffer == ':') /* use last command line */
X {
X if (last_cmdline == NULL)
X EMSG(e_nolastcmd);
X else
X {
X stuffcharReadbuff(commandchar);
X stuffReadbuff(last_cmdline);
X stuffcharReadbuff(ESC);
X }
X return;
X }
X
X get_yank_buffer(FALSE);
X
X y_type = y_current->y_type;
X y_size = y_current->y_size;
X y_array = y_current->y_array;
X
X if (count == -1) /* :put command */
X {
X y_type = MLINE;


X count = 1;
X }
X

X if (y_size == 0 || y_array == NULL)
X {
X temp[0] = yankbuffer;
X temp[1] = NUL;
X EMSG2("Nothing in register %s", temp);
X return;
X }
X
X if (y_type == MBLOCK)
X {
X lnum = curwin->w_cursor.lnum + y_size + 1;
X if (lnum > curbuf->b_ml.ml_line_count)
X lnum = curbuf->b_ml.ml_line_count + 1;
X if (!u_save(curwin->w_cursor.lnum - 1, lnum))
X return;
X }
X else if (!u_save_cursor())
X return;
X
X yanklen = STRLEN(y_array[0]);
X CHANGED;
X
X lnum = curwin->w_cursor.lnum;
X col = curwin->w_cursor.col;
X
X/*
X * block mode
X */
X if (y_type == MBLOCK)
X {
X if (dir == FORWARD && gchar_cursor() != NUL)
X {
X col = getvcol(curwin, &curwin->w_cursor, 3) + 1;
X ++curwin->w_cursor.col;
X }
X else
X col = getvcol(curwin, &curwin->w_cursor, 2);
X for (i = 0; i < y_size; ++i)
X {
X startspaces = 0;
X endspaces = 0;
X textcol = 0;
X vcol = 0;
X delchar = 0;
X
X /* add a new line */


X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
X {

X ml_append(curbuf->b_ml.ml_line_count, (char_u *)"", (colnr_t)1, FALSE);
X ++nlines;
X }
X old = ml_get(curwin->w_cursor.lnum);
X oldlen = STRLEN(old);
X for (ptr = old; vcol < col && *ptr; ++ptr)
X {
X /* Count a tab for what it's worth (if list mode not on) */
X incr = chartabsize(*ptr, (long)vcol);
X vcol += incr;
X ++textcol;
X }
X if (vcol < col) /* line too short, padd with spaces */
X {
X startspaces = col - vcol;
X }
X else if (vcol > col)
X {
X endspaces = vcol - col;
X startspaces = incr - endspaces;
X --textcol;
X delchar = 1;
X }
X yanklen = STRLEN(y_array[i]);
X totlen = count * yanklen + startspaces + endspaces;
X new = alloc((unsigned)totlen + oldlen + 1);
X if (new == NULL)
X break;
X /* copy part up to cursor to new line */
X ptr = new;
X memmove((char *)ptr, (char *)old, (size_t)textcol);
X ptr += textcol;
X /* may insert some spaces before the new text */
X copy_spaces(ptr, (size_t)startspaces);
X ptr += startspaces;
X /* insert the new text */
X for (j = 0; j < count; ++j)
X {
X STRNCPY(ptr, y_array[i], (size_t)yanklen);
X ptr += yanklen;
X }
X /* may insert some spaces after the new text */
X copy_spaces(ptr, (size_t)endspaces);
X ptr += endspaces;
X /* move the text after the cursor to the end of the line. */
X memmove((char *)ptr, (char *)old + textcol + delchar,
X (size_t)(oldlen - textcol - delchar + 1));
X ml_replace(curwin->w_cursor.lnum, new, FALSE);
X
X ++curwin->w_cursor.lnum;
X if (i == 0)
X curwin->w_cursor.col += startspaces;
X }
X curbuf->b_endop.lnum = curwin->w_cursor.lnum - 1; /* for "']" command */
X curbuf->b_endop.col = textcol + totlen - 1;
X curwin->w_cursor.lnum = lnum;


X cursupdate();
X updateScreen(VALID_TO_CURSCHAR);
X }

X else /* not block mode */
X {
X if (y_type == MCHAR)
X {
X /* if type is MCHAR, FORWARD is the same as BACKWARD on the next character */
X if (dir == FORWARD && gchar_cursor() != NUL)
X {
X ++col;
X if (yanklen)
X {
X ++curwin->w_cursor.col;
X ++curbuf->b_endop.col;
X }
X }
X new_cursor = curwin->w_cursor;
X }
X else if (dir == BACKWARD)
X /* if type is MLINE, BACKWARD is the same as FORWARD on the previous line */
X --lnum;
X
X/*
X * simple case: insert into current line
X */
X if (y_type == MCHAR && y_size == 1)
X {
X totlen = count * yanklen;
X if (totlen)


X {
X old = ml_get(lnum);

X new = alloc((unsigned)(STRLEN(old) + totlen + 1));


X if (new == NULL)

X return; /* alloc() will give error message */


X memmove((char *)new, (char *)old, (size_t)col);

X ptr = new + col;
X for (i = 0; i < count; ++i)
X {
X memmove((char *)ptr, (char *)y_array[0], (size_t)yanklen);
X ptr += yanklen;
X }
X memmove((char *)ptr, (char *)old + col, STRLEN(old + col) + 1);
X ml_replace(lnum, new, FALSE);
X curwin->w_cursor.col += (colnr_t)(totlen - 1); /* put cursor on last putted char */


X }
X curbuf->b_endop = curwin->w_cursor;

X updateline();
X }
X else
X {
X if (y_type == MCHAR)
X --y_size;
X while (--count >= 0)


X {
X i = 0;

X if (y_type == MCHAR)
X {
X /*
X * Split the current line in two at the insert position.
X * First insert y_array[size - 1] in front of second line.
X * Then append y_array[0] to first line.
X */
X ptr = ml_get(lnum) + col;
X totlen = STRLEN(y_array[y_size]);
X new = alloc((unsigned)(STRLEN(ptr) + totlen + 1));


X if (new == NULL)

X goto error;
X STRCPY(new, y_array[y_size]);
X STRCAT(new, ptr);
X ml_append(lnum, new, (colnr_t)0, FALSE); /* insert second line */
X free(new);
X ++nlines;


X
X old = ml_get(lnum);

X new = alloc((unsigned)(col + yanklen + 1));


X if (new == NULL)

X goto error;
X /* copy first part of line */


X memmove((char *)new, (char *)old, (size_t)col);

X /* append to first line */
X memmove((char *)new + col, (char *)y_array[0],
X (size_t)(yanklen + 1));


X ml_replace(lnum, new, FALSE);
X

X curwin->w_cursor.lnum = lnum;

X i = 1;
X }
X
X while (i < y_size)
X {
X if (ml_append(lnum++, y_array[i++], (colnr_t)0, FALSE) == FAIL)
X goto error;
X if (fix_indent)
X {
X curwin->w_cursor.lnum = lnum;
X if (curbuf->b_p_si && *ml_get(lnum) == '#')
X indent = 0; /* Leave # lines at start */
X else if (first_indent)
X {
X indent_diff = orig_indent - get_indent();
X indent = orig_indent;
X first_indent = FALSE;
X }
X else if ((indent = get_indent() + indent_diff) < 0)
X indent = 0;
X set_indent(indent, TRUE);
X }
X ++nlines;
X }
X if (y_type == MCHAR)
X ++lnum; /* lnum is now number of line below inserted lines */
X }
X
X curbuf->b_endop.lnum = lnum; /* for "']" command */
X if (y_type == MLINE)
X {


X curwin->w_cursor.col = 0;

X curbuf->b_endop.col = 0;


X if (dir == FORWARD)
X {

X updateScreen(NOT_VALID); /* recompute curwin->w_botline */
X ++curwin->w_cursor.lnum;
X }
X /* put cursor on first non-blank in last inserted line */
X beginline(TRUE);
X }
X else /* put cursor on first inserted character */
X {
X if (col > 1)
X curbuf->b_endop.col = col - 1;
X else
X curbuf->b_endop.col = 0;
X curwin->w_cursor = new_cursor;
X }
X
Xerror:
X if (y_type == MLINE) /* for '[ */
X {
X curbuf->b_startop.col = 0;


X if (dir == FORWARD)

X curbuf->b_startop.lnum++;
X }
X mark_adjust(curbuf->b_startop.lnum + (y_type == MCHAR), MAXLNUM, nlines);
X updateScreen(CURSUPD);
X }
X }
X
X msgmore(nlines);
X curwin->w_set_curswant = TRUE;
X}
X
X/*
X * display the contents of the yank buffers
X */
X void
Xdodis()
X{
X register int i, n;
X register long j;
X register char_u *p;
X register struct yankbuf *yb;


X
X gotocmdline(TRUE, NUL);
X

X msg_outstr((char_u *)"--- Registers ---");
X for (i = -1; i < 36; ++i)
X {
X if (i == -1)
X {
X if (y_previous != NULL)
X yb = y_previous;
X else
X yb = &(y_buf[0]);
X }
X else
X yb = &(y_buf[i]);
X if (yb->y_array != NULL)
X {
X msg_outchar('\n');
X if (i == -1)
X msg_outstr((char_u *)"\"\"");
X else
X {
X msg_outchar('"');
X if (i < 10)
X msg_outchar(i + '0');
X else
X msg_outchar(i + 'a' - 10);
X }
X msg_outstr((char_u *)" ");
X
X n = (int)Columns - 6;
X for (j = 0; j < yb->y_size && n > 1; ++j)
X {
X if (j)
X {
X msg_outstr((char_u *)"^J");
X n -= 2;
X }
X for (p = yb->y_array[j]; *p && (n -= charsize(*p)) >= 0; ++p)
X msg_outtrans(p, 1);
X }
X flushbuf(); /* show one line at a time */


X }
X }
X
X /*

X * display last inserted text
X */
X if ((p = get_last_insert()) != NULL)
X {
X msg_outstr((char_u *)"\n\". ");
X dis_msg(p, TRUE);
X }
X
X /*
X * display last command line
X */
X if (last_cmdline != NULL)
X {
X msg_outstr((char_u *)"\n\": ");
X dis_msg(last_cmdline, FALSE);
X }
X
X /*
X * display current file name
X */
X if (curbuf->b_xfilename != NULL)
X {
X msg_outstr((char_u *)"\n\"% ");
X dis_msg(curbuf->b_xfilename, FALSE);
X }
X
X msg_end();
X}
X
X/*
X * display a string for dodis()
X * truncate at end of screen line
X */
X void
Xdis_msg(p, skip_esc)
X char_u *p;
X int skip_esc; /* if TRUE, ignore trailing ESC */
X{
X int n;
X
X n = (int)Columns - 6;
X while (*p && !(*p == ESC && skip_esc && *(p + 1) == NUL) &&
X (n -= charsize(*p)) >= 0)
X msg_outtrans(p++, 1);
X}
X
X/*
X * join 'count' lines (minimal 2), including u_save()
X */
X void
Xdodojoin(count, insert_space, redraw)
X long count;
X int insert_space;
X int redraw;
X{
X if (!u_save((linenr_t)(curwin->w_cursor.lnum - 1), (linenr_t)(curwin->w_cursor.lnum + count)))
X return;
X
X while (--count > 0)
X if (dojoin(insert_space, redraw) == FAIL)


X {
X beep();
X break;
X }
X

X if (redraw)


X updateScreen(VALID_TO_CURSCHAR);
X}
X
X/*

X * join two lines at the cursor position
X *
X * return FAIL for failure, OK ohterwise
X */
X int
Xdojoin(insert_space, redraw)
X int insert_space;
X int redraw;
X{
X char_u *curr;
X char_u *next;
X char_u *new;
X int endcurr1, endcurr2;
X int currsize; /* size of the current line */
X int nextsize; /* size of the next line */
X int spaces; /* number of spaces to insert */
X int rows_to_del; /* number of rows on screen to delete */
X linenr_t t;
X
X if (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count) /* on last line */
X return FAIL;
X
X rows_to_del = plines_m(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1);
X
X curr = ml_get(curwin->w_cursor.lnum);
X currsize = STRLEN(curr);
X endcurr1 = endcurr2 = NUL;
X if (currsize > 0)
X {
X endcurr1 = *(curr + currsize - 1);
X if (currsize > 1)
X endcurr2 = *(curr + currsize - 2);
X }
X
X next = ml_get((linenr_t)(curwin->w_cursor.lnum + 1));
X spaces = 0;
X if (insert_space)
X {
X skipspace(&next);
X spaces = 1;
X if (*next == ')' || currsize == 0)
X spaces = 0;
X else
X {
X if (endcurr1 == ' ' || endcurr1 == TAB)
X {
X spaces = 0;
X if (currsize > 1)
X endcurr1 = endcurr2;
X }
X if (p_js && strchr(".!?", endcurr1) != NULL)
X spaces = 2;
X }
X }
X nextsize = STRLEN(next);
X
X new = alloc((unsigned)(currsize + nextsize + spaces + 1));


X if (new == NULL)

X return FAIL;
X
X /*
X * Insert the next line first, because we already have that pointer.
X * Curr has to be obtained again, because getting next will have
X * invalidated it.
X */
X memmove((char *)new + currsize + spaces, (char *)next, (size_t)(nextsize + 1));
X
X curr = ml_get(curwin->w_cursor.lnum);
X memmove((char *)new, (char *)curr, (size_t)currsize);
X
X copy_spaces(new + currsize, (size_t)spaces);
X
X ml_replace(curwin->w_cursor.lnum, new, FALSE);
X
X /*
X * Delete the following line. To do this we move the cursor there
X * briefly, and then move it back. After dellines() the cursor may
X * have moved up (last line deleted), so the current lnum is kept in t.
X */
X t = curwin->w_cursor.lnum;
X ++curwin->w_cursor.lnum;
X dellines(1L, FALSE, FALSE);
X curwin->w_cursor.lnum = t;
X
X /*
X * the number of rows on the screen is reduced by the difference
X * in number of rows of the two old lines and the one new line
X */
X if (redraw)
X {
X rows_to_del -= plines(curwin->w_cursor.lnum);
X if (rows_to_del > 0)
X win_del_lines(curwin, curwin->w_row, rows_to_del, TRUE, TRUE);
X }
X
X /*
X * go to first character of the joined line
X */
X if (currsize == 0)


X curwin->w_cursor.col = 0;

X else
X {
X curwin->w_cursor.col = currsize - 1;
X (void)oneright();
X }
X CHANGED;
X
X return OK;
X}
X
X/*
X * implementation of the format operator 'Q'
X */
X void
Xdoformat()
X{
X /* prepare undo and join the lines */
X dodojoin((long)nlines, TRUE, FALSE);
X
X /* put cursor on last non-space */
X coladvance(MAXCOL);
X while (curwin->w_cursor.col && isspace(gchar_cursor()))
X dec_cursor();
X curs_columns(FALSE); /* update curwin->w_virtcol */
X
X /* do the formatting */
X State = INSERT; /* for Opencmd() */
X insertchar(NUL);
X State = NORMAL;
X updateScreen(NOT_VALID);
X}
X
X void
Xstartinsert(initstr, startln, count)
X int initstr;
X int startln; /* if set, insert at start of line */
X long count;
X{
X Insstart = curwin->w_cursor;
X if (startln)
X Insstart.col = 0;
X
X if (initstr != NUL)
X {
X ResetRedobuff();
X AppendNumberToRedobuff(count);
X AppendCharToRedobuff(initstr);
X }
X
X if (initstr == 'R')
X State = REPLACE;
X else
X State = INSERT;
X
X if (p_smd)
X showmode();
X
X change_warning(); /* give a warning if readonly */
X edit(count);
X}
X
X/*
X * prepare a few things for block mode yank/delete/tilde
X *
X * for delete:
X * - textlen includes the first/last char to be (partly) deleted
X * - start/endspaces is the number of columns that are taken by the
X * first/last deleted char minus the number of columns that have to be deleted.
X * for yank and tilde:
X * - textlen includes the first/last char to be wholly yanked
X * - start/endspaces is the number of columns of the first/last yanked char
X * that are to be yanked.


X */
X static void

Xblock_prep(lnum, delete)
X linenr_t lnum;
X int delete;
X{
X int vcol;
X int incr = 0;
X char_u *pend;
X
X startspaces = 0;
X endspaces = 0;
X textlen = 0;
X textcol = 0;
X vcol = 0;
X textstart = ml_get(lnum);
X while (vcol < startvcol && *textstart)
X {
X /* Count a tab for what it's worth (if list mode not on) */
X incr = chartabsize(*textstart, (long)vcol);
X vcol += incr;
X ++textstart;
X ++textcol;
X }
X if (vcol < startvcol) /* line too short */
X {
X if (!delete)
X endspaces = endvcol - startvcol + 1;
X }
X else /* vcol >= startvcol */
X {
X startspaces = vcol - startvcol;
X if (delete && vcol > startvcol)
X startspaces = incr - startspaces;
X pend = textstart;
X if (vcol > endvcol) /* it's all in one character */
X {
X startspaces = endvcol - startvcol + 1;
X if (delete)
X startspaces = incr - startspaces;
X }
X else
X {
X while (vcol <= endvcol && *pend)
X {
X /* Count a tab for what it's worth (if list mode not on) */
X incr = chartabsize(*pend, (long)vcol);
X vcol += incr;
X ++pend;
X }
X if (vcol < endvcol && !delete) /* line too short */
X {
X endspaces = endvcol - vcol;
X }
X else if (vcol > endvcol)
X {
X endspaces = vcol - endvcol - 1;
X if (!delete && pend != textstart && endspaces)
X --pend;
X }
X }
X if (delete && startspaces)
X {
X --textstart;
X --textcol;
X }
X textlen = (int)(pend - textstart);
X }
X}
X
X#define NUMBUFLEN 30
X
X/*
X * add or subtract 'Prenum1' from a number in a line
X * 'command' is CTRL-A for add, CTRL-X for subtract


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xdoaddsub(command, Prenum1)
X int command;
X linenr_t Prenum1;


X{
X register int col;

X char_u buf[NUMBUFLEN];
X int hex; /* 'x' or 'X': hexadecimal; '0': octal */
X static int hexupper = FALSE; /* 0xABC */
X long n;
X char_u *ptr;
X int i;
X int c;
X


X ptr = ml_get(curwin->w_cursor.lnum);

X col = curwin->w_cursor.col;
X
X /* first check if we are on a hexadecimal number */
X while (col > 0 && isxdigit(ptr[col]))
X --col;
X if (col > 0 && (ptr[col] == 'X' || ptr[col] == 'x') &&
X ptr[col - 1] == '0' && isxdigit(ptr[col + 1]))
X --col; /* found hexadecimal number */
X else
X {
X /* first search forward and then backward for start of number */


X col = curwin->w_cursor.col;
X

X while (ptr[col] != NUL && !isdigit(ptr[col]))
X ++col;
X
X while (col > 0 && isdigit(ptr[col - 1]))
X --col;
X }
X
X if (isdigit(ptr[col]) && u_save_cursor())
X {
X ptr = ml_get(curwin->w_cursor.lnum); /* get it again, because of undo */


X curwin->w_set_curswant = TRUE;
X

X hex = 0; /* default is decimal */
X if (ptr[col] == '0') /* could be hex or octal */
X {
X hex = TO_UPPER(ptr[col + 1]); /* assume hexadecimal */
X if (hex != 'X' || !isxdigit(ptr[col + 2]))
X {
X if (isdigit(hex))
X hex = '0'; /* octal */
X else
X hex = 0; /* 0 by itself is decimal */
X }
X }
X
X if (!hex && col > 0 && ptr[col - 1] == '-')
X --col;
X
X ptr += col;
X /*
X * we copy the number into a buffer because some versions of sscanf
X * cannot handle characters with the upper bit set, making some special
X * characters handled like digits.
X */
X for (i = 0; *ptr && !(*ptr & 0x80) && i < NUMBUFLEN - 1; ++i)
X buf[i] = *ptr++;
X buf[i] = NUL;
X
X if (hex == '0')
X sscanf((char *)buf, "%lo", &n);
X else if (hex)
X sscanf((char *)buf + 2, "%lx", &n); /* "%X" doesn't work! */
X else
X n = atol((char *)buf);
X
X if (command == Ctrl('A'))
X n += Prenum1;
X else
X n -= Prenum1;
X
X if (hex == 'X') /* skip the '0x' */
X col += 2;
X curwin->w_cursor.col = col;
X c = gchar_cursor();
X do /* delete the old number */
X {
X if (isalpha(c))
X {
X if (isupper(c))
X hexupper = TRUE;
X else
X hexupper = FALSE;
X }
X (void)delchar(FALSE);
X c = gchar_cursor();
X }
X while (hex ? (hex == '0' ? c >= '0' && c <= '7' : isxdigit(c)) : isdigit(c));
X
X if (hex == '0')
X sprintf((char *)buf, "0%lo", n);
X else if (hex && hexupper)
X sprintf((char *)buf, "%lX", n);
X else if (hex)
X sprintf((char *)buf, "%lx", n);
X else
X sprintf((char *)buf, "%ld", n);
X insstr(buf); /* insert the new number */
X --curwin->w_cursor.col;
X updateline();
X return OK;
X }
X else
X {
X beep();


X return FAIL;
X }
X}

END_OF_FILE
if test 39495 -ne `wc -c <'vim/src/ops.c'`; then
echo shar: \"'vim/src/ops.c'\" unpacked with wrong size!
fi
# end of 'vim/src/ops.c'
fi
if test -f 'vim/src/proto/normal.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/normal.pro'\"
else
echo shar: Extracting \"'vim/src/proto/normal.pro'\" \(44 characters\)
sed "s/^X//" >'vim/src/proto/normal.pro' <<'END_OF_FILE'
X/* normal.c */
Xvoid normal __PARMS((void));
END_OF_FILE
if test 44 -ne `wc -c <'vim/src/proto/normal.pro'`; then
echo shar: \"'vim/src/proto/normal.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/normal.pro'
fi
if test -f 'vim/src/term.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/term.c'\"
else
echo shar: Extracting \"'vim/src/term.c'\" \(19580 characters\)
sed "s/^X//" >'vim/src/term.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */

X/*
X *
X * term.c: functions for controlling the terminal
X *
X * primitive termcap support for Amiga and MSDOS included
X *
X * NOTE: padding and variable substitution is not performed,
X * when compiling without TERMCAP, we use tputs() and tgoto() dummies.


X */
X
X#include "vim.h"
X#include "globals.h"

X#include "param.h"
X#include "proto.h"
X#ifdef TERMCAP
X# ifdef linux
X# include <termcap.h>
X# if 0 /* only required for old versions, it's now in termcap.h */
X typedef int (*outfuntype) (int);
X# endif
X# define TPUTSFUNCAST (outfuntype)
X# else
X# define TPUTSFUNCAST
X# ifdef AMIGA
X# include "proto/termlib.pro"
X# endif
X# endif
X#endif
X
Xstatic void parse_builtin_tcap __ARGS((Tcarr *tc, char_u *s));
X
X/*
X * Builtin_tcaps must always contain DFLT_TCAP as the first entry!
X * DFLT_TCAP is used, when no terminal is specified with -T option or $TERM.
X * The entries are compact, therefore they normally are included even when
X * TERMCAP is defined.
X * When TERMCAP is defined, the builtin entries can be accessed with
X * "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
X */
Xstatic char_u *builtin_tcaps[] =
X{
X#ifndef NO_BUILTIN_TCAPS
X (char_u *)DFLT_TCAP, /* almost allways included */
X# if !defined(UNIX) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
X (char_u *)ANSI_TCAP, /* default for unix */
X# endif
X# if !defined(AMIGA) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
X (char_u *)AMIGA_TCAP, /* default for amiga */
X# endif
X# if !defined(MSDOS) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
X (char_u *)PCTERM_TCAP, /* default for MSdos */
X# endif
X# if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS)
X (char_u *)PCANSI_TCAP,
X# endif
X# if !defined(ATARI) && defined(ALL_BUILTIN_TCAPS)
X (char_u *)ATARI_TCAP, /* default for Atari */
X# endif
X# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS)
X (char_u *)XTERM_TCAP, /* always included on unix */
X# endif
X# ifdef ALL_BUILTIN_TCAPS
X (char_u *)VT52_TCAP,
X# endif
X# if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
X (char_u *)DEBUG_TCAP, /* always included when debugging */
X# endif
X#else /* NO_BUILTIN_TCAPS */
X (char_u *)DUMB_TCAP, /* minimal termcap, used when everything else fails */
X#endif /* NO_BUILTIN_TCAPS */
X NULL,
X};
X
X/*
X * Term_strings contains currently used terminal strings.
X * It is initialized with the default values by parse_builtin_tcap().
X * The values can be changed by setting the parameter with the same name.
X */
XTcarr term_strings;
X
X/*
X * Parsing of the builtin termcap entries.
X * The terminal's name is not set, as this is already done in termcapinit().
X * Chop builtin termcaps, string entries are already '\0' terminated.
X * not yet implemented:
X * boolean entries could be empty strings;
X * numeric entries would need a flag (e.g. high bit of the skip byte),
X * so that parse_builtin_tcap can handle them.


X */
X static void

Xparse_builtin_tcap(tc, s)
X Tcarr *tc;
X char_u *s;
X{
X char_u **p = &tc->t_name;
X
X p++;
X for (;;)
X {
X while (*s++)
X ;
X p += *s++;
X if (!*s)
X return;
X *p++ = s;
X }
X}
X
X#ifdef TERMCAP
X# ifndef linux /* included in <termlib.h> */
X# ifndef AMIGA /* included in proto/termlib.pro */
Xint tgetent();
Xint tgetnum();
Xchar *tgetstr();
Xint tgetflag();
Xint tputs();


X# endif /* AMIGA */

X# ifndef hpux
Xextern short ospeed;
X# endif
X# endif /* linux */
X# ifndef hpux
Xchar *UP, *BC, PC; /* should be extern, but some don't have them */
X# endif
X#endif /* TERMCAP */
X
X#ifdef linux
X# define TGETSTR(s, p) (char_u *)tgetstr((s), (char **)(p))
X#else
X# define TGETSTR(s, p) (char_u *)tgetstr((s), (char *)(p))
X#endif
X
X void
Xset_term(term)
X char_u *term;
X{
X char_u **p = builtin_tcaps;
X#ifdef TERMCAP
X int builtin = 0;
X#endif
X int width = 0, height = 0;
X
X if (!STRNCMP(term, "builtin_", (size_t)8))
X {
X term += 8;
X#ifdef TERMCAP
X builtin = 1;
X#endif
X }
X#ifdef TERMCAP
X else
X {
X char_u *p;
X static char_u tstrbuf[TBUFSZ];
X char_u tbuf[TBUFSZ];
X char_u *tp = tstrbuf;
X int i;
X
X i = tgetent(tbuf, term);
X if (i == -1)
X {
X EMSG("Cannot open termcap file");
X builtin = 1;
X }
X else if (i == 0)
X {
X EMSG("terminal entry not found");
X builtin = 1;
X }
X else
X {
X clear_termparam(); /* clear old parameters */
X /* output strings */
X T_EL = TGETSTR("ce", &tp);
X T_IL = TGETSTR("al", &tp);
X T_CIL = TGETSTR("AL", &tp);
X T_DL = TGETSTR("dl", &tp);
X T_CDL = TGETSTR("DL", &tp);
X T_CS = TGETSTR("cs", &tp);
X T_ED = TGETSTR("cl", &tp);
X T_CI = TGETSTR("vi", &tp);
X T_CV = TGETSTR("ve", &tp);
X T_CVV = TGETSTR("vs", &tp);
X T_TP = TGETSTR("me", &tp);
X T_TI = TGETSTR("mr", &tp);
X T_TB = TGETSTR("md", &tp);
X T_SE = TGETSTR("se", &tp);
X T_SO = TGETSTR("so", &tp);
X T_CM = TGETSTR("cm", &tp);
X T_SR = TGETSTR("sr", &tp);
X T_CRI = TGETSTR("RI", &tp);
X T_VB = TGETSTR("vb", &tp);
X T_KS = TGETSTR("ks", &tp);
X T_KE = TGETSTR("ke", &tp);
X T_TS = TGETSTR("ti", &tp);
X T_TE = TGETSTR("te", &tp);
X


X /* key codes */

X term_strings.t_ku = TGETSTR("ku", &tp);
X term_strings.t_kd = TGETSTR("kd", &tp);
X term_strings.t_kl = TGETSTR("kl", &tp);
X /* if cursor-left == backspace, ignore it (televideo 925) */
X if (term_strings.t_kl != NULL && *term_strings.t_kl == Ctrl('H'))
X term_strings.t_kl = NULL;
X term_strings.t_kr = TGETSTR("kr", &tp);
X /* term_strings.t_sku = TGETSTR("", &tp); termcap code unknown */
X /* term_strings.t_skd = TGETSTR("", &tp); termcap code unknown */
X#ifdef ARCHIE
X /* Termcap code made up! */
X term_strings.t_sku = tgetstr("su", &tp);
X term_strings.t_skd = tgetstr("sd", &tp);
X#else
X term_strings.t_sku = NULL;
X term_strings.t_skd = NULL;
X#endif
X term_strings.t_skl = TGETSTR("#4", &tp);
X term_strings.t_skr = TGETSTR("%i", &tp);
X term_strings.t_f1 = TGETSTR("k1", &tp);
X term_strings.t_f2 = TGETSTR("k2", &tp);
X term_strings.t_f3 = TGETSTR("k3", &tp);
X term_strings.t_f4 = TGETSTR("k4", &tp);
X term_strings.t_f5 = TGETSTR("k5", &tp);
X term_strings.t_f6 = TGETSTR("k6", &tp);
X term_strings.t_f7 = TGETSTR("k7", &tp);
X term_strings.t_f8 = TGETSTR("k8", &tp);
X term_strings.t_f9 = TGETSTR("k9", &tp);
X term_strings.t_f10 = TGETSTR("k;", &tp);
X term_strings.t_sf1 = TGETSTR("F1", &tp); /* really function keys 11-20 */
X term_strings.t_sf2 = TGETSTR("F2", &tp);
X term_strings.t_sf3 = TGETSTR("F3", &tp);
X term_strings.t_sf4 = TGETSTR("F4", &tp);
X term_strings.t_sf5 = TGETSTR("F5", &tp);
X term_strings.t_sf6 = TGETSTR("F6", &tp);
X term_strings.t_sf7 = TGETSTR("F7", &tp);
X term_strings.t_sf8 = TGETSTR("F8", &tp);
X term_strings.t_sf9 = TGETSTR("F9", &tp);
X term_strings.t_sf10 = TGETSTR("FA", &tp);
X term_strings.t_help = TGETSTR("%1", &tp);
X term_strings.t_undo = TGETSTR("&8", &tp);
X
X height = tgetnum("li");
X width = tgetnum("co");
X
X T_MS = tgetflag("ms") ? (char_u *)"yes" : (char_u *)NULL;
X
X# ifndef hpux
X BC = (char *)TGETSTR("bc", &tp);
X UP = (char *)TGETSTR("up", &tp);
X p = TGETSTR("pc", &tp);
X if (p)
X PC = *p;
X ospeed = 0;
X# endif
X }
X }
X if (builtin)
X#endif
X {
X while (*p && STRCMP(term, *p))
X p++;
X if (!*p)
X {
X fprintf(stderr, "'%s' not builtin. Available terminals are:\r\n", term);
X for (p = builtin_tcaps; *p; p++)
X#ifdef TERMCAP
X fprintf(stderr, "\tbuiltin_%s\r\n", *p);
X#else
X fprintf(stderr, "\t%s\r\n", *p);
X#endif
X if (!starting) /* when user typed :set term=xxx, quit here */
X {
X wait_return(TRUE);
X return;
X }
X sleep(2);
X fprintf(stderr, "defaulting to '%s'\r\n", *builtin_tcaps);
X sleep(2);
X p = builtin_tcaps;
X free(term_strings.t_name);
X term_strings.t_name = strsave(term = *p);
X }
X clear_termparam(); /* clear old parameters */
X parse_builtin_tcap(&term_strings, *p);
X }
X/*
X * special: There is no info in the termcap about whether the cursor positioning
X * is relative to the start of the screen or to the start of the scrolling region.
X * We just guess here. Only msdos pcterm is known to do it relative.
X */
X if (STRCMP(term, "pcterm") == 0)
X T_CSC = (char_u *)"yes";
X else
X T_CSC = NULL;
X
X#if defined(AMIGA) || defined(MSDOS)
X /* DFLT_TCAP indicates that it is the machine console. */
X if (STRCMP(term, *builtin_tcaps))
X term_console = FALSE;
X else
X {
X term_console = TRUE;
X# ifdef AMIGA
X win_resize_on(); /* enable window resizing reports */
X# endif
X }
X#endif
X ttest(TRUE);
X /* display initial screen after ttest() checking. jw. */
X if (width <= 0 || height <= 0)
X {
X /* termcap failed to report size */
X /* set defaults, in case mch_get_winsize also fails */
X width = 80;
X#ifdef MSDOS
X height = 25; /* console is often 25 lines */
X#else
X height = 24; /* most terminals are 24 lines */
X#endif
X }
X set_winsize(width, height, FALSE); /* may change Rows */
X}
X
X#if defined(TERMCAP) && defined(UNIX)
X/*
X * Get Columns and Rows from the termcap. Used after a window signal if the
X * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
X * and "li" entries never change. But this may happen on some systems.
X */
X void
Xgetlinecol()
X{
X char_u tbuf[TBUFSZ];
X
X if (term_strings.t_name != NULL && tgetent(tbuf, term_strings.t_name) > 0)
X {
X if (Columns == 0)
X Columns = tgetnum("co");
X if (Rows == 0)
X Rows = tgetnum("li");
X }
X}
X#endif
X
Xstatic char_u *tltoa __PARMS((unsigned long));
X
X static char_u *
Xtltoa(i)
X unsigned long i;
X{
X static char_u buf[16];
X char_u *p;
X
X p = buf + 15;
X *p = '\0';
X do
X {
X --p;
X *p = i % 10 + '0';
X i /= 10;
X }
X while (i > 0 && p > buf);


X return p;
X}
X

X#ifndef TERMCAP
X
X/*
X * minimal tgoto() implementation.
X * no padding and we only parse for %i %d and %+char
X */
X
X char *
Xtgoto(cm, x, y)
X char *cm;
X int x, y;
X{
X static char buf[30];
X char *p, *s, *e;


X
X if (!cm)
X return "OOPS";

X e = buf + 29;
X for (s = buf; s < e && *cm; cm++)
X {
X if (*cm != '%')
X {
X *s++ = *cm;
X continue;
X }
X switch (*++cm)
X {
X case 'd':
X p = (char *)tltoa((unsigned long)y);
X y = x;
X while (*p)
X *s++ = *p++;


X break;
X case 'i':

X x++;
X y++;


X break;
X case '+':

X *s++ = (char)(*++cm + y);
X y = x;


X break;
X case '%':

X *s++ = *cm;
X break;
X default:


X return "OOPS";
X }
X }

X *s = '\0';


X return buf;
X}
X

X#endif /* TERMCAP */
X
X/*
X * Termcapinit is called from main() to initialize the terminal.
X * The optional argument is given with the -T command line option.
X */
X void
Xtermcapinit(term)
X char_u *term;
X{
X if (!term)
X term = vimgetenv((char_u *)"TERM");
X if (!term || !*term)
X term = *builtin_tcaps;
X term_strings.t_name = strsave(term);
X set_term(term);
X}
X
X/*
X * the number of calls to mch_write is reduced by using the buffer "outbuf"
X */
X#undef BSIZE /* hpux has BSIZE in sys/param.h */
X#define BSIZE 2048
Xstatic char_u outbuf[BSIZE];
Xstatic int bpos = 0; /* number of chars in outbuf */
X
X/*
X * flushbuf(): flush the output buffer
X */
X void
Xflushbuf()
X{
X if (bpos != 0)
X {
X mch_write(outbuf, bpos);
X bpos = 0;
X }
X}
X
X/*
X * outchar(c): put a character into the output buffer.
X * Flush it if it becomes full.
X */
X void
Xoutchar(c)
X unsigned c;
X{
X#ifdef UNIX
X if (c == '\n') /* turn LF into CR-LF (CRMOD does not seem to do this) */
X outchar('\r');
X#endif
X
X outbuf[bpos] = c;
X
X if (p_nb) /* for testing: unbuffered screen output (not for MSDOS) */
X mch_write(outbuf, 1);
X else
X ++bpos;
X
X if (bpos >= BSIZE)
X flushbuf();
X}
X
X/*
X * a never-padding outstr.
X * use this whenever you don't want to run the string through tputs.
X * tputs above is harmless, but tputs from the termcap library
X * is likely to strip off leading digits, that it mistakes for padding
X * information. (jw)
X */
X void
Xoutstrn(s)
X char_u *s;
X{
X if (bpos > BSIZE - 20) /* avoid terminal strings being split up */
X flushbuf();
X while (*s)
X outchar(*s++);
X}
X
X/*
X * outstr(s): put a string character at a time into the output buffer.
X * If TERMCAP is defined use the termcap parser. (jw)
X */
X void
Xoutstr(s)


X register char_u *s;
X{

X if (bpos > BSIZE - 20) /* avoid terminal strings being split up */
X flushbuf();
X if (s)
X#ifdef TERMCAP
X tputs(s, 1, TPUTSFUNCAST outchar);
X#else
X while (*s)
X outchar(*s++);
X#endif
X}
X
X/*
X * cursor positioning using termcap parser. (jw)
X */
X void
Xwindgoto(row, col)


X int row;
X int col;
X{

X OUTSTR(tgoto((char *)T_CM, col, row));
X}
X
X/*
X * Set cursor to current position.
X * Should be optimized for minimal terminal output.


X */
X
X void

Xsetcursor()
X{
X if (!RedrawingDisabled)
X windgoto(curwin->w_winpos + curwin->w_row, curwin->w_col);
X}
X
X void
Xttest(pairs)
X int pairs;
X{
X char buf[70];
X char *s = "terminal capability %s required.\n";
X char *t = NULL;
X
X /* hard requirements */
X if (!T_ED || !*T_ED) /* erase display */
X t = "cl";
X if (!T_CM || !*T_CM) /* cursor motion */
X t = "cm";
X
X if (t)
X {
X sprintf(buf, s, t);
X EMSG(buf);
X }
X
X/*
X * if "cs" defined, use a scroll region, it's faster.
X */
X if (T_CS && *T_CS != NUL)
X scroll_region = TRUE;
X else
X scroll_region = FALSE;
X
X if (pairs)
X {
X /* optional pairs */
X /* TP goes to normal mode for TI (invert) and TB (bold) */
X if ((!T_TP || !*T_TP))
X T_TP = T_TI = T_TB = NULL;
X if ((!T_SO || !*T_SO) ^ (!T_SE || !*T_SE))
X T_SO = T_SE = NULL;
X /* T_CV is needed even though T_CI is not defined */
X if ((!T_CV || !*T_CV))
X T_CI = NULL;
X /* if 'mr' or 'me' is not defined use 'so' and 'se' */
X if (T_TP == NULL || *T_TP == NUL)
X {
X T_TP = T_SE;
X T_TI = T_SO;
X T_TB = T_SO;
X }
X /* if 'so' or 'se' is not defined use 'mr' and 'me' */
X if (T_SO == NULL || *T_SO == NUL)
X {
X T_SE = T_TP;
X if (T_TI == NULL)
X T_SO = T_TB;
X else
X T_SO = T_TI;
X }
X }
X}
X
X/*
X * inchar() - get one character from
X * 1. a scriptfile
X * 2. the keyboard
X *
X * As much characters as we can get (upto 'maxlen') are put in buf and
X * NUL terminated (buffer length must be 'maxlen' + 1).
X *
X * If we got an interrupt all input is read until none is available.
X *
X * If time == 0 there is no waiting for the char.
X * If time == n we wait for n msec for a character to arrive.
X * If time == -1 we wait forever for a character to arrive.
X *
X * Return the number of obtained characters.


X */
X
X int

Xinchar(buf, maxlen, time)
X char_u *buf;
X int maxlen;
X int time; /* milli seconds */
X{
X int len;
X int retesc = FALSE; /* return ESC with gotint */
X register int c;


X register int i;
X

X if (time == -1 || time > 100) /* flush output before waiting */
X {
X cursor_on();
X flushbuf();
X }
X did_outofmem_msg = FALSE; /* display out of memory message (again) */
X
X/*
X * first try script file
X * If interrupted: Stop reading script files.
X */
Xretry:
X if (scriptin[curscript] != NULL)
X {
X if (got_int || (c = getc(scriptin[curscript])) < 0) /* reached EOF */
X {
X /* when reading script file is interrupted, return an ESC to
X get back to normal mode */
X if (got_int)
X retesc = TRUE;
X fclose(scriptin[curscript]);
X scriptin[curscript] = NULL;
X if (curscript > 0)
X --curscript;
X goto retry; /* may read other script if this one was nested */
X }
X if (c == 0)
X c = K_ZERO; /* replace ^@ with special code */
X *buf++ = c;
X *buf = NUL;


X return 1;
X }
X

X/*
X * If we got an interrupt, skip all previously typed characters and
X * return TRUE if quit reading script file.
X */
X if (got_int) /* skip typed characters */
X {
X while (GetChars(buf, maxlen, T_PEEK))
X ;
X return retesc;
X }
X len = GetChars(buf, maxlen, time);
X
X for (i = len; --i >= 0; ++buf)
X if (*buf == 0)
X *(char_u *)buf = K_ZERO; /* replace ^@ with special code */
X *buf = NUL; /* add trailing NUL */
X return len;
X}
X
X/*
X * Check if buf[] begins with a terminal key code.
X * Return 0 for no match, -1 for partial match, > 0 for full match.
X * With a match the replacement code is put in buf[0], the match is
X * removed and the number characters in buf is returned.
X *
X * Note: should always be called with buf == typestr!
X */
X int
Xcheck_termcode(buf)
X char_u *buf;
X{
X char_u **p;
X int slen;
X int len;
X
X len = STRLEN(buf);
X for (p = (char_u **)&term_strings.t_ku; p != (char_u **)&term_strings.t_undo + 1; ++p)
X {
X if (*p == NULL || (slen = STRLEN(*p)) == 0) /* empty entry */
X continue;
X if (STRNCMP(*p, buf, (size_t)(slen > len ? len : slen)) == 0)
X {
X if (len >= slen) /* got the complete sequence */
X {
X len -= slen;
X /* remove matched chars, taking care of noremap */
X del_typestr(slen - 1);
X /* this relies on the Key numbers to be consecutive! */
X buf[0] = K_UARROW + (p - (char_u **)&term_strings.t_ku);
X return (len + 1);
X }
X return -1; /* got a partial sequence */
X }
X }
X return 0; /* no match found */
X}
X
X/*
X * outnum - output a (big) number fast
X */
X void
Xoutnum(n)


X register long n;
X{

X OUTSTRN(tltoa((unsigned long)n));
X}
X
X void
Xcheck_winsize()
X{
X if (Columns < MIN_COLUMNS)
X Columns = MIN_COLUMNS;
X else if (Columns > MAX_COLUMNS)
X Columns = MAX_COLUMNS;
X if (Rows < MIN_ROWS + 1) /* need room for one window and command line */
X Rows = MIN_ROWS + 1;
X screen_new_rows(); /* may need to update window sizes */
X}
X
X/*
X * set window size
X * If 'mustset' is TRUE, we must set Rows and Columns, do not get real
X * window size (this is used for the :win command).
X * If 'mustset' is FALSE, we may try to get the real window size and if
X * it fails use 'width' and 'height'.
X */
X void
Xset_winsize(width, height, mustset)
X int width, height;
X int mustset;
X{
X register int tmp;
X
X if (width < 0 || height < 0) /* just checking... */
X return;
X
X if (State == HITRETURN || State == SETWSIZE) /* postpone the resizing */
X {
X State = SETWSIZE;
X return;
X }
X screenclear();
X#ifdef AMIGA
X flushbuf(); /* must do this before mch_get_winsize for some obscure reason */
X#endif /* AMIGA */
X if (mustset || mch_get_winsize() == FAIL)
X {
X Rows = height;
X Columns = width;
X check_winsize(); /* always check, to get p_scroll right */
X mch_set_winsize();
X }
X else
X check_winsize(); /* always check, to get p_scroll right */
X if (State == HELP)
X (void)redrawhelp();
X else if (!starting)
X {
X tmp = RedrawingDisabled;
X RedrawingDisabled = FALSE;
X comp_Botline_all();
X updateScreen(CURSUPD);
X RedrawingDisabled = tmp;
X if (State == CMDLINE)
X redrawcmdline();
X else
X setcursor();
X }
X flushbuf();
X}
X
X void
Xsettmode(raw)
X int raw;
X{
X static int oldraw = FALSE;
X
X if (oldraw == raw) /* skip if already in desired mode */
X return;
X oldraw = raw;
X
X mch_settmode(raw); /* machine specific function */
X}
X
X void
Xstarttermcap()
X{
X outstr(T_TS); /* start termcap mode */
X outstr(T_KS); /* start "keypad transmit" mode */
X flushbuf();
X termcap_active = TRUE;
X}
X
X void
Xstoptermcap()
X{
X outstr(T_KE); /* stop "keypad transmit" mode */
X flushbuf();
X termcap_active = FALSE;
X cursor_on(); /* just in case it is still off */
X outstr(T_TE); /* stop termcap mode */
X}
X
X/*
X * enable cursor, unless in Visual mode or no inversion possible
X */
Xstatic int cursor_is_off = FALSE;
X
X void
Xcursor_on()
X{
X if (cursor_is_off && (!VIsual.lnum || highlight == NULL))
X {
X outstr(T_CV);
X cursor_is_off = FALSE;
X }
X}
X
X void
Xcursor_off()
X{
X if (!cursor_is_off)
X outstr(T_CI); /* disable cursor */
X cursor_is_off = TRUE;
X}
X
X/*
X * set scrolling region for window 'wp'
X */
X void
Xscroll_region_set(wp)
X WIN *wp;
X{
X OUTSTR(tgoto((char *)T_CS, wp->w_winpos + wp->w_height - 1, wp->w_winpos));
X}
X
X/*
X * reset scrolling region to the whole screen
X */
X void
Xscroll_region_reset()
X{
X OUTSTR(tgoto((char *)T_CS, (int)Rows - 1, 0));
X}
END_OF_FILE
if test 19580 -ne `wc -c <'vim/src/term.c'`; then
echo shar: \"'vim/src/term.c'\" unpacked with wrong size!
fi
# end of 'vim/src/term.c'
fi
echo shar: End of archive 12 \(of 26\).
cp /dev/null ark12isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:28 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 32
Archive-name: vim/part13

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/cmdline.c.A vim/src/memfile.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:06 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 13 (of 26)."'
if test -f 'vim/src/cmdline.c.A' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/cmdline.c.A'\"
else
echo shar: Extracting \"'vim/src/cmdline.c.A'\" \(38908 characters\)
sed "s/^X//" >'vim/src/cmdline.c.A' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * cmdline.c: functions for reading in the command line and executing it


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"

X#include "cmdtab.h"
X#include "ops.h" /* included because we call functions in ops.c */
X#include "fcntl.h" /* for chdir() */
X
X/*
X * variables shared between getcmdline() and redrawcmdline()
X */
Xstatic int cmdlen; /* number of chars on command line */
Xstatic int cmdpos; /* current cursor position */
Xstatic int cmdspos; /* cursor column on screen */
Xstatic int cmdfirstc; /* ':', '/' or '?' */
Xstatic char_u *cmdbuff; /* pointer to command line buffer */
X
X/*
X * The next two variables contain the bounds of any range given in a command.
X * They are set by docmdline().
X */
Xstatic linenr_t line1, line2;
X
Xstatic int forceit;
Xstatic int regname;
Xstatic int quitmore = 0;
Xstatic int cmd_numfiles = -1; /* number of files found by
X filename completion */
X
Xstatic void putcmdline __ARGS((int, char_u *));
Xstatic void cursorcmd __ARGS((void));
Xstatic int ccheck_abbr __ARGS((int));
Xstatic char_u *DoOneCmd __ARGS((char_u *));
Xstatic int buf_write_all __ARGS((BUF *));
Xstatic int dowrite __ARGS((char_u *, int));
Xstatic char_u *getargcmd __ARGS((char_u **));
Xstatic char_u *checknextcomm __ARGS((char_u *));
Xstatic void domake __ARGS((char_u *));
Xstatic int doarglist __ARGS((char_u *));
Xstatic int check_readonly __ARGS((void));
Xstatic int check_changed __ARGS((BUF *, int, int));
Xstatic int check_changed_any __ARGS((int));
Xstatic int check_more __ARGS((int));
X#ifdef WEBB_COMPLETE
Xstatic void vim_strncpy __ARGS((char_u *, char_u *, int));
Xstatic int nextwild __ARGS((char_u *, int));
Xstatic int showmatches __ARGS((char_u *));
Xstatic void set_expand_context __ARGS((int, char_u *));
Xstatic char_u *set_one_cmd_context __ARGS((int, char_u *));
Xstatic int ExpandFromContext __ARGS((char_u *, int *, char_u ***, int, int));
X#else
Xstatic void nextwild __ARGS((char_u *, int));
Xstatic void showmatches __ARGS((char_u *, int));
X#endif /* WEBB_COMPLETE */
Xstatic char_u *addstar __ARGS((char_u *, int));
Xstatic linenr_t get_address __ARGS((char_u **));
X
X/*
X * getcmdline() - accept a command line starting with ':', '!', '/', or '?'
X *
X * For searches the optional matching '?' or '/' is removed.
X *
X * Return OK if there is a commandline, FAIL if not


X */
X
X int

Xgetcmdline(firstc, buff)


X int firstc; /* either ':', '/', or '?' */

X char_u *buff; /* buffer for command string */
X{
X register char_u c;
X int cc;
X int nextc = 0;
X register int i;
X int retval;
X int hiscnt; /* current history line in use */
X static char_u **history = NULL; /* history table */
X static int hislen = 0; /* actual lengt of history table */
X int newlen; /* new length of history table */
X static int hisidx = -1; /* last entered entry */
X char_u **temp;
X char_u *lookfor = NULL; /* string to match */
X int j = -1;
X int gotesc = FALSE; /* TRUE when last char typed was <ESC> */
X int do_abbr; /* when TRUE check for abbr. */
X
X/*
X * set some variables for redrawcmd()
X */
X cmdfirstc = firstc;
X cmdbuff = buff;
X cmdlen = cmdpos = 0;
X cmdspos = 1;
X State = CMDLINE;
X gotocmdline(TRUE, firstc);
X
X/*
X * if size of history table changed, reallocate it
X */
X newlen = (int)p_hi;
X if (newlen != hislen) /* history length changed */
X {
X if (newlen)
X temp = (char_u **)lalloc((long_u)(newlen * sizeof(char_u *)), TRUE);
X else
X temp = NULL;
X if (newlen == 0 || temp != NULL)
X {
X if (newlen > hislen) /* array becomes bigger */
X {
X for (i = 0; i <= hisidx; ++i)
X temp[i] = history[i];
X j = i;
X for ( ; i <= newlen - (hislen - hisidx); ++i)
X temp[i] = NULL;
X for ( ; j < hislen; ++i, ++j)
X temp[i] = history[j];
X }
X else /* array becomes smaller */
X {
X j = hisidx;
X for (i = newlen - 1; ; --i)
X {
X if (i >= 0)
X temp[i] = history[j]; /* copy newest entries */
X else
X free(history[j]); /* remove older entries */
X if (--j < 0)
X j = hislen - 1;
X if (j == hisidx)
X break;
X }
X hisidx = newlen - 1;
X }
X free(history);
X history = temp;
X hislen = newlen;
X }
X }
X hiscnt = hislen; /* set hiscnt to impossible history value */
X
X#ifdef DIGRAPHS
X dodigraph(-1); /* init digraph typahead */
X#endif
X
X /* collect the command string, handling '\b', @ and much more */


X for (;;)
X {

X cursorcmd(); /* set the cursor on the right spot */
X if (nextc) /* character remaining from CTRL-V */
X {
X c = nextc;
X nextc = 0;
X }
X else
X {
X c = vgetc();
X if (c == Ctrl('C'))
X got_int = FALSE;
X }
X
X if (lookfor && c != K_SDARROW && c != K_SUARROW)
X {
X free(lookfor);
X lookfor = NULL;
X }
X
X if (cmd_numfiles != -1 && !(c == p_wc && KeyTyped) && c != Ctrl('N') &&
X c != Ctrl('P') && c != Ctrl('A') && c != Ctrl('L'))
X (void)ExpandOne(NULL, FALSE, -2); /* may free expanded file names */
X
X#ifdef DIGRAPHS
X c = dodigraph(c);
X#endif
X
X if (c == '\n' || c == '\r' || (c == ESC && !KeyTyped))
X {
X if (ccheck_abbr(c + 0x100))
X continue;
X outchar('\r'); /* show that we got the return */
X flushbuf();
X break;
X }
X
X /* hitting <ESC> twice means: abandon command line */
X /* wildcard expansion is only done when the key is really typed, not
X when it comes from a macro */
X if (c == p_wc && !gotesc && KeyTyped)
X {
X#ifdef WEBB_COMPLETE
X if (cmd_numfiles > 0) /* typed p_wc twice */
X i = nextwild(buff, 3);
X else /* typed p_wc first time */
X i = nextwild(buff, 0);
X if (c == ESC)
X gotesc = TRUE;
X if (i)
X continue;
X#else
X if (cmd_numfiles > 0) /* typed p_wc twice */
X nextwild(buff, 3);
X else /* typed p_wc first time */
X nextwild(buff, 0);
X if (c == ESC)
X gotesc = TRUE;
X continue;


X#endif /* WEBB_COMPLETE */
X }

X gotesc = FALSE;
X
X if (c == K_ZERO) /* NUL is stored as NL */
X c = '\n';
X
X do_abbr = TRUE; /* default: check for abbreviation */
X switch (c)
X {
X case BS:
X case DEL:
X case Ctrl('W'):
X /*
X * delete current character is the same as backspace on next
X * character, except at end of line
X */
X if (c == DEL && cmdpos != cmdlen)
X ++cmdpos;
X if (cmdpos > 0)
X {
X j = cmdpos;
X if (c == Ctrl('W'))
X {
X while (cmdpos && isspace(buff[cmdpos - 1]))
X --cmdpos;
X i = isidchar(buff[cmdpos - 1]);
X while (cmdpos && !isspace(buff[cmdpos - 1]) && isidchar(buff[cmdpos - 1]) == i)
X --cmdpos;
X }
X else
X --cmdpos;
X cmdlen -= j - cmdpos;
X i = cmdpos;
X while (i < cmdlen)
X buff[i++] = buff[j++];
X redrawcmd();
X }
X else if (cmdlen == 0 && c != Ctrl('W'))
X {
X retval = FAIL;
X msg_pos(-1, 0);
X msg_outchar(' '); /* delete ':' */
X goto returncmd; /* back to cmd mode */
X }
X continue;
X
X/* case '@': only in very old vi */


X case Ctrl('U'):

Xclearline:
X cmdpos = 0;
X cmdlen = 0;
X cmdspos = 1;
X redrawcmd();
X continue;
X
X case ESC: /* get here if p_wc != ESC or when ESC typed twice */
X case Ctrl('C'):
Xdo_esc:
X retval = FAIL;
X MSG("");
X goto returncmd; /* back to cmd mode */
X
X case Ctrl('D'):
X {
X#ifdef WEBB_COMPLETE
X /* set_expand_context() now finds start of the pattern, so
X * don't do it here -- webb
X */
X if (showmatches(buff) == FAIL)
X break; /* Use ^D as normal char instead */


X#else
X for (i = cmdpos; i > 0 && buff[i - 1] != ' '; --i)
X ;

X showmatches(&buff[i], cmdpos - i);


X#endif /* WEBB_COMPLETE */
X

X redrawcmd();
X continue;
X }
X
X case K_RARROW:
X case K_SRARROW:
X do
X {
X if (cmdpos >= cmdlen)
X break;
X cmdspos += charsize(buff[cmdpos]);
X ++cmdpos;
X }
X while (c == K_SRARROW && buff[cmdpos] != ' ');
X continue;
X
X case K_LARROW:
X case K_SLARROW:
X do
X {
X if (cmdpos <= 0)
X break;
X --cmdpos;
X cmdspos -= charsize(buff[cmdpos]);
X }
X while (c == K_SLARROW && buff[cmdpos - 1] != ' ');
X continue;
X
X case Ctrl('B'): /* begin of command line */
X cmdpos = 0;
X cmdspos = 1;
X continue;
X
X case Ctrl('E'): /* end of command line */
X cmdpos = cmdlen;
X buff[cmdlen] = NUL;
X cmdspos = strsize(buff) + 1;
X continue;
X
X case Ctrl('A'): /* all matches */
X#ifdef WEBB_COMPLETE
X if (!nextwild(buff, 4))
X break;
X#else
X nextwild(buff, 4);
X#endif /* WEBB_COMPLETE */
X continue;
X
X case Ctrl('L'): /* longest common part */
X#ifdef WEBB_COMPLETE
X if (!nextwild(buff, 5))
X break;
X#else
X nextwild(buff, 5);
X#endif /* WEBB_COMPLETE */
X continue;
X
X case Ctrl('N'): /* next match */
X case Ctrl('P'): /* previous match */


X if (cmd_numfiles > 0)
X {

X#ifdef WEBB_COMPLETE
X if (!nextwild(buff, (c == Ctrl('P')) ? 2 : 1))
X break;
X#else
X nextwild(buff, (c == Ctrl('P')) ? 2 : 1);
X#endif /* WEBB_COMPLETE */
X continue;
X }
X
X case K_UARROW:
X case K_DARROW:
X case K_SUARROW:
X case K_SDARROW:
X if (hislen == 0) /* no history */
X continue;
X
X i = hiscnt;
X
X /* save current command string */
X if (c == K_SUARROW || c == K_SDARROW)
X {
X buff[cmdpos] = NUL;
X if (lookfor == NULL && (lookfor = strsave(buff)) == NULL)
X continue;
X
X j = STRLEN(lookfor);
X }


X for (;;)
X {

X /* one step backwards */
X if (c == K_UARROW || c == K_SUARROW || c == Ctrl('P'))
X {
X if (hiscnt == hislen) /* first time */
X hiscnt = hisidx;
X else if (hiscnt == 0 && hisidx != hislen - 1)
X hiscnt = hislen - 1;
X else if (hiscnt != hisidx + 1)
X --hiscnt;
X else /* at top of list */
X break;
X }
X else /* one step forwards */
X {
X if (hiscnt == hisidx) /* on last entry, clear the line */
X {
X hiscnt = hislen;
X goto clearline;
X }
X if (hiscnt == hislen) /* not on a history line, nothing to do */
X break;
X if (hiscnt == hislen - 1) /* wrap around */
X hiscnt = 0;
X else
X ++hiscnt;
X }
X if (hiscnt < 0 || history[hiscnt] == NULL)
X {
X hiscnt = i;
X break;
X }
X if ((c != K_SUARROW && c != K_SDARROW) || hiscnt == i ||
X STRNCMP(history[hiscnt], lookfor, (size_t)j) == 0)
X break;
X }
X
X if (hiscnt != i) /* jumped to other entry */
X {
X STRCPY(buff, history[hiscnt]);
X cmdpos = cmdlen = STRLEN(buff);
X redrawcmd();
X }
X continue;


X
X case Ctrl('V'):

X putcmdline('^', buff);
X c = get_literal(&nextc); /* get next (two) character(s) */
X do_abbr = FALSE; /* don't do abbreviation now */
X break;
X
X#ifdef DIGRAPHS
X case Ctrl('K'):
X putcmdline('?', buff);
X c = vgetc();
X if (c == ESC)
X goto do_esc;
X if (charsize(c) == 1)
X putcmdline(c, buff);
X cc = vgetc();
X if (cc == ESC)
X goto do_esc;
X c = getdigraph(c, cc, TRUE);
X break;
X#endif /* DIGRAPHS */
X }
X
X /* we come here if we have a normal character */
X
X if (do_abbr && !isidchar(c) && ccheck_abbr(c))
X continue;
X
X if (cmdlen < CMDBUFFSIZE - 2)
X {
X for (i = cmdlen++; i > cmdpos; --i)
X buff[i] = buff[i - 1];
X buff[cmdpos] = c;
X msg_outtrans(buff + cmdpos, cmdlen - cmdpos);
X ++cmdpos;
X i = charsize(c);
X cmdspos += i;
X }
X msg_check();
X }
X retval = OK; /* when we get here we have a valid command line */
X
Xreturncmd:
X buff[cmdlen] = NUL;
X /*
X * put line in history buffer
X */
X if (cmdlen != 0)
X {
X if (hislen != 0)
X {
X if (++hisidx == hislen)
X hisidx = 0;
X free(history[hisidx]);
X history[hisidx] = strsave(buff);
X }
X if (firstc == ':')
X {
X free(new_last_cmdline);
X new_last_cmdline = strsave(buff);


X }
X }
X
X /*

X * If the screen was shifted up, redraw the whole screen (later).
X * If the line is too long, clear it, so ruler and shown command do
X * not get printed in the middle of it.
X */
X msg_check();
X State = NORMAL;


X return retval;
X}
X
X/*

X * put a character on the command line.
X * Used for CTRL-V and CTRL-K


X */
X static void

Xputcmdline(c, buff)
X int c;
X char_u *buff;


X{
X char_u buf[2];
X
X buf[0] = c;

X buf[1] = 0;
X msg_outtrans(buf, 1);
X msg_outtrans(buff + cmdpos, cmdlen - cmdpos);
X cursorcmd();
X}
X
X/*
X * this fuction is called when the screen size changes
X */
X void
Xredrawcmdline()


X{
X msg_scrolled = 0;

X compute_cmdrow();
X redrawcmd();
X cursorcmd();
X}
X
X void
Xcompute_cmdrow()
X{
X cmdline_row = lastwin->w_winpos + lastwin->w_height + lastwin->w_status_height;
X}
X
X/*
X * Redraw what is currently on the command line.
X */
X void
Xredrawcmd()


X{
X register int i;
X

X msg_start();
X msg_outchar(cmdfirstc);
X msg_outtrans(cmdbuff, cmdlen);
X msg_ceol();
X
X cmdspos = 1;
X for (i = 0; i < cmdlen && i < cmdpos; ++i)
X cmdspos += charsize(cmdbuff[i]);


X}
X
X static void

Xcursorcmd()
X{
X msg_pos(cmdline_row + (cmdspos / (int)Columns), cmdspos % (int)Columns);
X windgoto(msg_row, msg_col);
X}
X
X/*
X * Check the word in front of the cursor for an abbreviation.
X * Called when the non-id character "c" has been entered.
X * When an abbreviation is recognized it is removed from the text with
X * backspaces and the replacement string is inserted, followed by "c".


X */
X static int

Xccheck_abbr(c)
X int c;
X{
X if (p_paste || no_abbr) /* no abbreviations or in paste mode */
X return FALSE;
X
X return check_abbr(c, cmdbuff, cmdpos, 0);
X}
X
X/*
X * docmdline(): execute an Ex command line
X *
X * 1. If no line given, get one.
X * 2. Split up in parts separated with '|'.
X *


X * This function may be called recursively!

X *
X * return FAIL if commandline could not be executed, OK otherwise
X */
X int
Xdocmdline(cmdline)
X char_u *cmdline;
X{
X char_u buff[CMDBUFFSIZE]; /* command line */
X char_u *nextcomm;
X
X/*
X * 1. If no line given: get one.
X */
X if (cmdline == NULL)
X {
X if (getcmdline(':', buff) == FAIL)


X return FAIL;
X }
X else
X {

X if (STRLEN(cmdline) > (size_t)(CMDBUFFSIZE - 2))
X {
X emsg(e_toolong);
X return FAIL;
X }
X /* Make a copy of the command so we can mess with it. */
X STRCPY(buff, cmdline);
X }
X
X/*
X * 2. Loop for each '|' separated command.
X * DoOneCmd will set nextcommand to NULL if there is no trailing '|'.
X */


X for (;;)
X {

X nextcomm = DoOneCmd(buff);
X if (nextcomm == NULL)
X break;
X STRCPY(buff, nextcomm);
X }
X/*
X * If the command was typed, remember it for register :
X * Do this AFTER executing the command to make :@: work.
X */
X if (cmdline == NULL && new_last_cmdline != NULL)
X {
X free(last_cmdline);
X last_cmdline = new_last_cmdline;


X new_last_cmdline = NULL;
X }

X return OK;
X}
X
X/*

X * Execute one Ex command.
X *


X * 2. skip comment lines and leading space

X * 3. parse range


X * 4. parse command

X * 5. parse arguments

X * 6. switch on command name

X *


X * This function may be called recursively!

X */
X static char_u *

XDoOneCmd(buff)
X char_u *buff;
X{
X char_u cmdbuf[CMDBUFFSIZE]; /* for '%' and '#' expansion */
X char_u c;
X register char_u *p;
X char_u *q;
X char_u *cmd, *arg;
X char_u *editcmd = NULL; /* +command arg. for doecmd() */
X linenr_t doecmdlnum = 0; /* lnum in new file for doecmd() */
X int i = 0; /* init to shut up gcc */


X int cmdidx;
X int argt;

X register linenr_t lnum;
X long n;
X int addr_count; /* number of address specifications */
X FPOS pos;
X int append = FALSE; /* write with append */
X int usefilter = FALSE; /* filter instead of file name */
X char_u *nextcomm = NULL; /* no next command yet */
X int amount = 0; /* for ":>" and ":<"; init for gcc */
X
X if (quitmore)
X --quitmore; /* when not editing the last file :q has to be typed twice */


X/*
X * 2. skip comment lines and leading space, colons or bars
X */
X for (cmd = buff; *cmd && strchr(" \t:|", *cmd) != NULL; cmd++)
X ;
X

X if (*cmd == '"' || *cmd == NUL) /* ignore comment and empty lines */
X goto doend;


X
X/*
X * 3. parse a range specifier of the form: addr [,addr] [;addr] ..
X *

X * where 'addr' is:
X *
X * % (entire file)
X * $ [+-NUM]
X * 'x [+-NUM] (where x denotes a currently defined mark)
X * . [+-NUM]
X * [+-NUM]..
X * NUM
X *
X * The cmd pointer is updated to point to the first character following the
X * range spec. If an initial address is found, but no second, the upper bound
X * is equal to the lower.
X */
X
X addr_count = 0;


X --cmd;
X do
X {
X ++cmd; /* skip ',' or ';' */

X line1 = line2;
X line2 = curwin->w_cursor.lnum; /* default is current line number */
X skipspace(&cmd);
X lnum = get_address(&cmd);


X if (lnum == MAXLNUM)

X {
X if (*cmd == '%') /* '%' - all lines */
X {
X ++cmd;
X line1 = 1;
X line2 = curbuf->b_ml.ml_line_count;
X ++addr_count;
X }
X }
X else
X line2 = lnum;
X addr_count++;
X
X if (*cmd == ';')
X {
X if (line2 == 0)
X curwin->w_cursor.lnum = 1;
X else


X curwin->w_cursor.lnum = line2;
X }

X } while (*cmd == ',' || *cmd == ';');
X

X /* One address given: set start and end lines */
X if (addr_count == 1)
X {
X line1 = line2;
X /* ... but only implicit: really no address given */


X if (lnum == MAXLNUM)

X addr_count = 0;
X }
X
X/*


X * 4. parse command
X */
X
X skipspace(&cmd);

X
X /*
X * If we got a line, but no command, then go to the line.
X * If we find a '|' or '\n' we set nextcomm.
X */
X if (*cmd == NUL || *cmd == '"' ||
X ((*cmd == '|' || *cmd == '\n') &&
X (nextcomm = cmd + 1) != NULL)) /* just an assignment */
X {
X if (addr_count != 0)
X {
X /*
X * strange vi behaviour: ":3" jumps to line 3
X * ":3|..." prints line 3
X */
X if (*cmd == '|')
X {
X cmdidx = CMD_print;
X goto cmdswitch; /* UGLY goto */
X }
X if (line2 == 0)


X curwin->w_cursor.lnum = 1;

X else if (line2 > curbuf->b_ml.ml_line_count)


X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X else

X curwin->w_cursor.lnum = line2;


X curwin->w_cursor.col = 0;

X cursupdate();
X }
X goto doend;
X }
X
X /*


X * Isolate the command and search for it in the command table.
X * Exeptions:
X * - the 'k' command can directly be followed by any character.
X * - the 's' command can be followed directly by 'c', 'g' or 'r'

X * but :sre[wind] is another command.
X */


X if (*cmd == 'k')
X {
X cmdidx = CMD_k;

X p = cmd + 1;
X }
X else if (*cmd == 's' && strchr("cgr", cmd[1]) != NULL && STRNCMP("sre", cmd, (size_t)3) != 0)


X {
X cmdidx = CMD_substitute;

X p = cmd + 1;
X }
X else


X {
X p = cmd;

X while (isalpha(*p))
X ++p;


X if (p == cmd && strchr("@!=><&~#", *p) != NULL) /* non-alpha command */
X ++p;
X i = (int)(p - cmd);
X

X for (cmdidx = 0; cmdidx < CMD_SIZE; ++cmdidx)

X if (STRNCMP(cmdnames[cmdidx].cmd_name, (char *)cmd, (size_t)i) == 0)
X break;
X if (i == 0 || cmdidx == CMD_SIZE)
X {
X emsg(e_invcmd);
X goto doend;
X }
X }
X


X if (*p == '!') /* forced commands */
X {

X ++p;
X forceit = TRUE;
X }
X else
X forceit = FALSE;


X
X/*
X * 5. parse arguments
X */
X argt = cmdnames[cmdidx].cmd_argt;
X

X if (!(argt & RANGE) && addr_count)
X {
X emsg(e_norange);
X goto doend;
X }
X
X/*
X * If the range is backwards, ask for confirmation and, if given, swap
X * line1 & line2 so it's forwards again.
X * When global command is busy, don't ask, will fail below.
X */
X if (!global_busy && line1 > line2)
X {
X if (ask_yesno((char_u *)"Backwards range given, OK to swap") != 'y')
X goto doend;
X lnum = line1;
X line1 = line2;
X line2 = lnum;
X }
X /*
X * don't complain about the range if it is not used
X * (could happen if line_count is accidently set to 0)
X */
X if (line1 < 0 || line2 < 0 || line1 > line2 || ((argt & RANGE) &&
X !(argt & NOTADR) && line2 > curbuf->b_ml.ml_line_count))
X {
X emsg(e_invrange);
X goto doend;
X }
X
X if ((argt & NOTADR) && addr_count == 0) /* default is 1, not cursor */
X line2 = 1;
X
X if (!(argt & ZEROR)) /* zero in range not allowed */
X {
X if (line1 == 0)
X line1 = 1;
X if (line2 == 0)
X line2 = 1;
X }
X
X /*
X * for the :make command we insert the 'makeprg' option here,
X * so things like % get expanded
X */
X if (cmdidx == CMD_make)
X {
X if (STRLEN(p_mp) + STRLEN(p) + 2 >= (unsigned)CMDBUFFSIZE)
X {
X emsg(e_toolong);
X goto doend;
X }
X STRCPY(cmdbuf, p_mp);
X STRCAT(cmdbuf, " ");
X STRCAT(cmdbuf, p);
X STRCPY(buff, cmdbuf);
X p = buff;
X }


X
X arg = p; /* remember start of argument */
X skipspace(&arg);
X

X if ((argt & NEEDARG) && *arg == NUL)
X {
X emsg(e_argreq);
X goto doend;
X }
X


X if (cmdidx == CMD_write)
X {
X if (*arg == '>') /* append */
X {

X if (*++arg != '>') /* typed wrong */
X {
X EMSG("Use w or w>>");
X goto doend;
X }
X ++arg;
X skipspace(&arg);
X append = TRUE;
X }


X else if (*arg == '!') /* :w !filter */

X {
X ++arg;
X usefilter = TRUE;
X }
X }
X


X if (cmdidx == CMD_read)
X {

X usefilter = forceit; /* :r! filter if forceit */


X if (*arg == '!') /* :r !filter */

X {
X ++arg;
X usefilter = TRUE;
X }
X }
X


X if (cmdidx == CMD_lshift || cmdidx == CMD_rshift)
X {

X amount = 1;
X while (*arg == *cmd) /* count number of '>' or '<' */
X {
X ++arg;
X ++amount;
X }
X skipspace(&arg);
X }
X
X /*


X * Check for '|' to separate commands and '"' to start comments.

X * Don't do this for ":read !cmd" and ":write !cmd".
X */


X if ((argt & TRLBAR) && !usefilter)
X {
X p = arg;
X while (*p)

X {


X if (*p == Ctrl('V'))
X {

X if ((argt & USECTRLV) && p[1] != NUL) /* skip CTRL-V and next char */
X ++p;
X else /* remove CTRL-V and skip next char */
X STRCPY(p, p + 1);


X }
X else if ((*p == '"' && !(argt & NOTRLCOM)) || *p == '|' || *p == '\n')
X {

X if (*(p - 1) == '\\') /* remove the backslash */
X {
X STRCPY(p - 1, p);
X --p;
X }
X else
X {
X if (*p == '|' || *p == '\n')


X nextcomm = p + 1;

X *p = NUL;
X break;
X }
X }
X ++p;
X }
X if (!(argt & NOTRLCOM)) /* remove trailing spaces */
X del_spaces(arg);
X }
X
X if ((argt & DFLALL) && addr_count == 0)
X {
X line1 = 1;
X line2 = curbuf->b_ml.ml_line_count;
X }
X
X regname = 0;
X /* accept numbered register only when no count allowed (:put) */
X if ((argt & REGSTR) && *arg != NUL && is_yank_buffer(*arg, FALSE) && !((argt & COUNT) && isdigit(*arg)))
X {
X regname = *arg;


X ++arg;
X skipspace(&arg);
X }
X

X if ((argt & COUNT) && isdigit(*arg))
X {
X n = getdigits(&arg);
X skipspace(&arg);
X if (n <= 0)
X {
X emsg(e_zerocount);
X goto doend;
X }
X if (argt & NOTADR) /* e.g. :buffer 2, :sleep 3 */
X {
X line2 = n;
X if (addr_count == 0)
X addr_count = 1;
X }
X else
X {
X line1 = line2;
X line2 += n - 1;
X ++addr_count;
X }
X }
X


X if (!(argt & EXTRA) && strchr("|\"", *arg) == NULL) /* no arguments allowed */

X {
X emsg(e_trailing);
X goto doend;
X }
X
X /*
X * change '%' to curbuf->b_filename, '#' to curwin->w_altfile
X */


X if (argt & XFILE)

X {


X for (p = arg; *p; ++p)
X {

X c = *p;
X if (c != '%' && c != '#') /* nothing to expand */
X continue;
X if (*(p - 1) == '\\') /* remove escaped char */
X {
X STRCPY(p - 1, p);
X --p;
X continue;
X }
X
X if (c == '%') /* current file */


X {
X if (check_fname() == FAIL)

X goto doend;
X q = curbuf->b_xfilename;
X n = 1; /* length of what we expand */
X }
X else /* '#': alternate file */
X {
X q = p + 1;
X i = (int)getdigits(&q);
X n = q - p; /* length of what we expand */
X
X if (buflist_name_nr(i, &q, &doecmdlnum) == FAIL)
X {
X emsg(e_noalt);
X goto doend;
X }
X }
X i = STRLEN(arg) + STRLEN(q) + 3;
X if (nextcomm)
X i += STRLEN(nextcomm);
X if (i > CMDBUFFSIZE)
X {
X emsg(e_toolong);
X goto doend;
X }
X /*
X * we built the new argument in cmdbuf[], then copy it back to buff[]
X */
X *p = NUL; /* truncate at the '#' or '%' */
X STRCPY(cmdbuf, arg); /* copy up to there */
X i = p - arg; /* remember the lenght */
X STRCAT(cmdbuf, q); /* append the file name */
X if (*(p + n) == '<') /* may remove extension */
X {
X ++n;
X if ((arg = (char_u *)strrchr((char *)q, '.')) != NULL &&
X arg >= gettail(q))
X *(cmdbuf + (arg - q) + i) = NUL;
X }
X i = STRLEN(cmdbuf); /* remember the end of the filename */
X STRCAT(cmdbuf, p+n); /* append what is after '#' or '%' */
X p = buff + i - 1; /* remember where to continue */
X if (nextcomm) /* append next command */
X {
X i = STRLEN(cmdbuf) + 1;
X STRCPY(cmdbuf + i, nextcomm);
X nextcomm = buff + i;
X }
X STRCPY(buff, cmdbuf); /* copy back to buff[] */
X arg = buff;
X }
X
X /*
X * One file argument: expand wildcards.
X * Don't do this with ":r !command" or ":w !command".
X */
X if (argt & NOSPC)
X {
X if (has_wildcard(arg) && !usefilter)
X {
X if ((p = ExpandOne(arg, TRUE, -1)) == NULL)
X goto doend;
X if (STRLEN(p) + arg - buff < CMDBUFFSIZE - 2)
X STRCPY(arg, p);
X else
X emsg(e_toolong);
X free(p);


X }
X }
X }
X
X/*

X * 6. switch on command name
X */

Xcmdswitch:
X switch (cmdidx)
X {
X /*
X * quit current window, quit Vim if closed the last window
X */
X case CMD_quit:
X /* if more files or windows we won't exit */
X if (check_more(FALSE) == OK && firstwin == lastwin)
X exiting = TRUE;
X if (check_changed(curbuf, FALSE, FALSE) ||
X check_more(TRUE) == FAIL ||
X (firstwin == lastwin && check_changed_any(FALSE)))
X {
X exiting = FALSE;
X settmode(1);
X break;
X }
X if (firstwin == lastwin) /* quit last window */
X getout(0);
X close_window(TRUE); /* may free buffer */
X break;
X
X /*
X * try to quit all windows
X */
X case CMD_qall:
X exiting = TRUE;
X if (!check_changed_any(FALSE))
X getout(0);
X exiting = FALSE;
X settmode(1);
X break;
X
X /*
X * close current window, unless it is the last one
X */
X case CMD_close:
X close_window(FALSE); /* don't free buffer */
X break;
X
X /*
X * close all but current window, unless it is the last one
X */
X case CMD_only:
X close_others(TRUE);
X break;
X
X case CMD_stop:
X case CMD_suspend:
X if (!forceit)
X autowrite_all();
X gotocmdend();
X flushbuf();
X stoptermcap();
X mch_restore_title(3); /* restore window titles */
X mch_suspend(); /* call machine specific function */
X maketitle();
X starttermcap();
X if (T_CVV != NULL && *T_CVV)
X {
X /* Scroll screen down before drawing over it */
X outstr(T_CVV);
X outstr(T_CV);
X }
X must_redraw = CLEAR;
X break;
X
X case CMD_exit:
X case CMD_xit:
X case CMD_wq:
X /* if more files or windows we won't exit */
X if (check_more(FALSE) == OK && firstwin == lastwin)
X exiting = TRUE;
X if (((cmdidx == CMD_wq ||
X (curbuf->b_nwindows == 1 && curbuf->b_changed)) &&
X (check_readonly() || dowrite(arg, FALSE) == FAIL)) ||
X check_more(TRUE) == FAIL ||
X (firstwin == lastwin && check_changed_any(FALSE)))
X {
X exiting = FALSE;
X settmode(1);
X break;
X }
X if (firstwin == lastwin) /* quit last window, exit Vim */
X getout(0);
X close_window(TRUE); /* quit current window, may free buffer */
X break;
X
X case CMD_xall: /* write all changed files and exit */
X case CMD_wqall: /* write all changed files and quit */
X exiting = TRUE;


X /* FALLTHROUGH */
X

X case CMD_wall: /* write all changed files */
X {
X BUF *buf;
X int error = 0;
X


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X {
X if (buf->b_changed)
X {

X if (buf->b_filename == NULL)
X {
X emsg(e_noname);
X ++error;
X }
X else if (!forceit && buf->b_p_ro)
X {
X EMSG2("\"%s\" is readonly, use ! to write anyway", buf->b_xfilename);
X ++error;
X }
X else if (buf_write_all(buf) == FAIL)
X ++error;
X }
X }
X if (exiting)
X {
X if (!error)
X getout(0); /* exit Vim */
X exiting = FALSE;
X settmode(1);


X }
X }
X break;
X

X case CMD_preserve: /* put everything in .swp file */
X ml_preserve(curbuf, TRUE);
X break;
X
X case CMD_args:
X /*
X * ":args file": handle like :next
X */
X if (*arg != NUL && *arg != '|' && *arg != '\n')
X goto do_next;
X
X nextcomm = checknextcomm(arg); /* check for trailing command */
X if (arg_count == 0) /* no file name list */
X {
X if (check_fname() == OK) /* check for no file name at all */
X smsg((char_u *)"[%s]", curbuf->b_filename);
X break;
X }
X gotocmdline(TRUE, NUL);
X for (i = 0; i < arg_count; ++i)
X {
X if (i == curwin->w_arg_idx)
X msg_outchar('[');
X msg_outstr(arg_files[i]);
X if (i == curwin->w_arg_idx)
X msg_outchar(']');
X msg_outchar(' ');
X }
X if (msg_check()) /* if message too long */


X {
X msg_outchar('\n');

X wait_return(FALSE);
X }
X break;
X
X case CMD_wnext:
X case CMD_wNext:
X case CMD_wprevious:
X if (cmd[1] == 'n')
X i = curwin->w_arg_idx + (int)line2;
X else
X i = curwin->w_arg_idx - (int)line2;
X line1 = 1;
X line2 = curbuf->b_ml.ml_line_count;
X if (dowrite(arg, FALSE) == FAIL)
X break;
X goto donextfile;
X


X case CMD_next:
X case CMD_snext:

Xdo_next:
X /*
X * check for changed buffer now, if this fails the
X * argument list is not redefined.
X */
X if (!(p_hid || cmdidx == CMD_snext) &&
X check_changed(curbuf, TRUE, FALSE))
X break;
X
X editcmd = getargcmd(&arg); /* get +command argument */
X nextcomm = checknextcomm(arg); /* check for trailing command */
X if (*arg != NUL) /* redefine file list */
X {
X if (doarglist(arg) == FAIL)
X break;


X i = 0;
X }
X else

X i = curwin->w_arg_idx + (int)line2;
X
Xdonextfile: if (i < 0 || i >= arg_count)
X {
X if (arg_count == 1)
X EMSG("There is only one file to edit");
X else if (i < 0)
X EMSG("Cannot go before first file");
X else
X EMSG2("No more than %ld files to edit", (char_u *)(long)arg_count);
X break;
X }
X if (*cmd == 's') /* split window first */
X {
X if (win_split(0L, FALSE) == FAIL)


X break;
X }
X else

X {
X register int other = FALSE;
X
X /*
X * if 'hidden' set, only check for changed file when re-editing
X * the same buffer
X */
X other = TRUE;
X if (p_hid)
X other = otherfile(fix_fname(arg_files[i]));
X if ((!p_hid || !other) && check_changed(curbuf, TRUE, !other))
X break;
X }
X curwin->w_arg_idx = i;
X (void)doecmd(arg_files[curwin->w_arg_idx], NULL, editcmd, p_hid, (linenr_t)0);
X break;
X
X case CMD_previous:
X case CMD_sprevious:
X case CMD_Next:
X case CMD_sNext:
X i = curwin->w_arg_idx - (int)line2;
X goto doargument;
X
X case CMD_rewind:
X case CMD_srewind:
X i = 0;
X goto doargument;
X
X case CMD_last:
X case CMD_slast:
X i = arg_count - 1;
X goto doargument;
X
X case CMD_argument:
X case CMD_sargument:
X if (addr_count)
X i = line2 - 1;
X else
X i = curwin->w_arg_idx;
Xdoargument:
X editcmd = getargcmd(&arg); /* get +command argument */
X nextcomm = checknextcomm(arg); /* check for trailing command */
X goto donextfile;
X
X case CMD_all:
X case CMD_sall:
X do_arg_all(); /* open a window for each argument */
X break;
X
X case CMD_buffer: /* :[N]buffer [N] to buffer N */
X case CMD_sbuffer: /* :[N]sbuffer [N] to buffer N */
X if (addr_count == 0) /* default is current buffer */
X (void)do_buffer(*cmd == 's', 0, FORWARD, 0, 0);
X else
X (void)do_buffer(*cmd == 's', 1, FORWARD, (int)line2, 0);
X break;
X
X case CMD_bmodified: /* :[N]bmod [N] to next modified buffer */
X case CMD_sbmodified: /* :[N]sbmod [N] to next modified buffer */
X (void)do_buffer(*cmd == 's', 3, FORWARD, (int)line2, 0);
X break;
X
X case CMD_bnext: /* :[N]bnext [N] to next buffer */
X case CMD_sbnext: /* :[N]sbnext [N] to next buffer */
X (void)do_buffer(*cmd == 's', 0, FORWARD, (int)line2, 0);
X break;
X
X case CMD_bNext: /* :[N]bNext [N] to previous buffer */
X case CMD_bprevious: /* :[N]bprevious [N] to previous buffer */
X case CMD_sbNext: /* :[N]sbNext [N] to previous buffer */
X case CMD_sbprevious: /* :[N]sbprevious [N] to previous buffer */
X (void)do_buffer(*cmd == 's', 0, BACKWARD, (int)line2, 0);
X break;
X
X case CMD_brewind: /* :brewind to first buffer */
X case CMD_sbrewind: /* :sbrewind to first buffer */
X (void)do_buffer(*cmd == 's', 1, FORWARD, 0, 0);
X break;
X
X case CMD_blast: /* :blast to last buffer */
X case CMD_sblast: /* :sblast to last buffer */
X (void)do_buffer(*cmd == 's', 2, FORWARD, 0, 0);
X break;
X
X case CMD_bunload: /* :[N]bunload[!] [N] unload buffer */
X i = 2;
X case CMD_bdelete: /* :[N]bdelete[!] [N] delete buffer */
X if (cmdidx == CMD_bdelete)
X i = 3;
X /*
X * addr_count == 0: ":bdel" - delete current buffer
X * addr_count == 1: ":N bdel" or ":bdel N [N ..] - first delete
X * buffer 'line2', then any other arguments.
X * addr_count == 2: ":N,N bdel" - delete buffers in range
X */
X if (addr_count == 0)
X (void)do_buffer(i, 0, FORWARD, 0, forceit);
X else
X {
X int do_current = FALSE; /* delete current buffer? */
X
X if (addr_count == 2)
X n = line1;
X else
X n = line2;
X for ( ;!got_int; breakcheck())
X {
X /*
X * delete the current buffer last, otherwise when the
X * current buffer is deleted, the next buffer becomes
X * the current one and will be loaded, which may then
X * also be deleted, etc.
X */
X if (n == curbuf->b_fnum)
X do_current = TRUE;
X else
X (void)do_buffer(i, 1, FORWARD, (int)n, forceit);
X if (addr_count == 2)
X {
X if (++n > line2)


X break;
X }
X else

X {
X skipspace(&arg);
X if (*arg == NUL)
X break;
X if (!isdigit(*arg))
X {
X emsg(e_trailing);
X break;
X }
X n = getdigits(&arg);
X }
X }
X if (!got_int && do_current)
X (void)do_buffer(i, 1, FORWARD, (int)curbuf->b_fnum, forceit);
X }
X break;
X
X case CMD_unhide:
X case CMD_sunhide:
X (void)do_buffer_all(FALSE); /* open a window for loaded buffers */
X break;
X
X case CMD_ball:
X case CMD_sball:
X (void)do_buffer_all(TRUE); /* open a window for every buffer */
X break;
X
X case CMD_buffers:
X case CMD_files:
X buflist_list();
X break;
X
X case CMD_write:
X if (usefilter) /* input lines to shell command */
X dofilter(line1, line2, arg, TRUE, FALSE);
X else
X (void)dowrite(arg, append);
X break;
X
X /*
X * set screen mode
X * if no argument given, just get the screen size and redraw
X */
X case CMD_mode:
X if (*arg == NUL || mch_screenmode(arg) != FAIL)
X set_winsize(0, 0, FALSE);
X break;
X
X /*
X * set, increment or decrement current window height
X */
X case CMD_resize:
X n = atol((char *)arg);
X if (*arg == '-' || *arg == '+')
X win_setheight(curwin->w_height + (int)n);
X else
X {
X if (n == 0) /* default is very high */
X n = 9999;
X win_setheight((int)n);
X }
X break;
X
X /*
X * :split [[+command] file] split window with current or new file
X * :new [[+command] file] split window with no or new file
X */


X case CMD_split:
X case CMD_new:

X if (win_split(addr_count ? line2 : 0L, FALSE) == FAIL)
X break;
X /*FALLTHROUGH*/
X


X case CMD_edit:
X case CMD_ex:
X case CMD_visual:

X editcmd = getargcmd(&arg); /* get +command argument */
X nextcomm = checknextcomm(arg); /* check for trailing command */
X if ((cmdidx == CMD_new) && *arg == NUL)
X (void)doecmd(NULL, NULL, editcmd, TRUE, (linenr_t)1);
X else if (cmdidx != CMD_split || *arg != NUL)
X (void)doecmd(arg, NULL, editcmd, p_hid, doecmdlnum);
X else
X updateScreen(NOT_VALID);
X break;
X
X case CMD_file:


X if (*arg != NUL)
X {

X if (setfname(arg, NULL, TRUE) == FAIL)
X break;
X curbuf->b_notedited = TRUE;
X maketitle();
X }
X fileinfo(did_cd); /* print full filename if :cd used */
X break;
X
X case CMD_swapname:
X p = curbuf->b_ml.ml_mfp->mf_fname;


X if (p == NULL)

X MSG("No swap file");
X else
X msg(p);
X break;
X
X case CMD_mfstat: /* print memfile statistics, for debugging */
X mf_statistics();
X break;
X
X case CMD_read:
X if (usefilter)
X {
X dofilter(line1, line2, arg, FALSE, TRUE); /* :r!cmd */
X break;
X }
X if (!u_save(line2, (linenr_t)(line2 + 1)))
X break;


X if (*arg == NUL)

X {
X if (check_fname() == FAIL) /* check for no file name at all */
X break;
X i = readfile(curbuf->b_filename, curbuf->b_sfilename, line2, FALSE, (linenr_t)0, MAXLNUM);
X }
X else
X i = readfile(arg, NULL, line2, FALSE, (linenr_t)0, MAXLNUM);


X if (i == FAIL)

X {
X emsg2(e_notopen, arg);
X break;
X }
X updateScreen(NOT_VALID);
X break;
X
X case CMD_cd:
X case CMD_chdir:
X#ifdef UNIX
X /*
X * for UNIX ":cd" means: go to home directory
X */
X if (*arg == NUL) /* use cmdbuf for home directory name */
X {
X expand_env("$HOME", cmdbuf, CMDBUFFSIZE);
X arg = cmdbuf;
X }
X#endif


X if (*arg != NUL)
X {

X if (!did_cd)
X {
X BUF *buf;
X
X /* use full path from now on for names of files
X * being edited and swap files */


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X {


X buf->b_xfilename = buf->b_filename;

X mf_fullname(buf->b_ml.ml_mfp);
X }
X status_redraw_all();
X }
X did_cd = TRUE;
X if (chdir((char *)arg))
X emsg(e_failed);


X break;
X }
X /*FALLTHROUGH*/
X

X case CMD_pwd:
X if (vim_dirname(NameBuff, MAXPATHL) == OK)
X msg(NameBuff);
X else
X emsg(e_unknown);
X break;
X
X case CMD_equal:
X smsg((char_u *)"line %ld", (long)line2);
X break;
X
X case CMD_list:
X i = curwin->w_p_list;
X curwin->w_p_list = 1;
X case CMD_number: /* :nu */
X case CMD_pound: /* :# */
X case CMD_print: /* :p */
X gotocmdline(TRUE, NUL);
X cursor_off();
X for ( ;!got_int; breakcheck())
X {
X if (curwin->w_p_nu || cmdidx == CMD_number || cmdidx == CMD_pound)
X {
X sprintf((char *)IObuff, "%7ld ", (long)line1);
X msg_outstr(IObuff);
X }
X msg_prt_line(ml_get(line1));
X if (++line1 > line2)
X break;
X msg_outchar('\n');


X flushbuf(); /* show one line at a time */
X }
X

X if (cmdidx == CMD_list)
X curwin->w_p_list = i;
X
X /*
X * if we have one line that runs into the shown command,
X * or more than one line, call wait_return()
X * also do this when global_busy, so we remember to call
X * wait_return at the end of the global command.
X */
X if (msg_check() || global_busy)


X {
X msg_outchar('\n');

X wait_return(FALSE);
X }
X break;
X
X case CMD_shell:
X doshell(NULL);
X break;
X
X case CMD_sleep:
X sleep((int)line2);
X break;
X
X case CMD_tag:
X dotag(arg, 0, addr_count ? (int)line2 : 1);
X break;
X
X case CMD_pop:
X dotag((char_u *)"", 1, addr_count ? (int)line2 : 1);
X break;
X
X case CMD_tags:
X dotags();
X break;
X
X case CMD_marks:
X domarks();
X break;
X
X case CMD_jumps:
X dojumps();
X break;
X
X case CMD_digraphs:
X#ifdef DIGRAPHS
X if (*arg)
X putdigraph(arg);
X else
X listdigraphs();
X#else
X EMSG("No digraphs in this version");
X#endif /* DIGRAPHS */
END_OF_FILE
if test 38908 -ne `wc -c <'vim/src/cmdline.c.A'`; then
echo shar: \"'vim/src/cmdline.c.A'\" unpacked with wrong size!
elif test -f 'vim/src/cmdline.c.B'; then


echo shar: Combining \"'vim/src/cmdline.c'\" \(82989 characters\)
cat 'vim/src/cmdline.c.A' 'vim/src/cmdline.c.B' > 'vim/src/cmdline.c'
if test 82989 -ne `wc -c <'vim/src/cmdline.c'`; then

echo shar: \"'vim/src/cmdline.c'\" combined with wrong size!
else
rm vim/src/cmdline.c.A vim/src/cmdline.c.B
fi
fi
# end of 'vim/src/cmdline.c.A'
fi
if test -f 'vim/src/memfile.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/memfile.c'\"
else
echo shar: Extracting \"'vim/src/memfile.c'\" \(26671 characters\)
sed "s/^X//" >'vim/src/memfile.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X/* for debugging */
X#define CHECK(c, s) if (c) printf(s)
X
X/*
X * memfile.c: Contains the functions for handling blocks of memory which can
X * be stored in a file. This is the implementation of a sort of virtual memory.
X *
X * A memfile consists of a sequence of blocks. The blocks numbered from 0
X * upwards have been assigned a place in the actual file. The block number
X * is equal to the page number in the file. The
X * blocks with negative numbers are currently in memory only. They can be
X * assigned a place in the file when too much memory is being used. At that
X * moment they get a new, positive, number. A list is used for translation of
X * negative to positive numbers.
X *
X * The size of a block is a multiple of a page size, normally the page size of
X * the device the file is on. Most blocks are 1 page long. A Block of multiple
X * pages is used for a line that does not fit in a single page.
X *
X * Each block can be in memory and/or in a file. The blocks stays in memory
X * as long as it is locked. If it is no longer locked it can be swapped out to
X * the file. It is only written to the file if it has been changed.
X *
X * Under normal operation the file is created when opening the memory file and
X * deleted when closing the memory file. Only with recovery an existing memory
X * file is opened.
X */
X
X#ifdef MSDOS
X# include <io.h> /* for lseek(), must be before vim.h */
X#endif


X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"

X#include <fcntl.h>
X
X/*
X * Some systems have the page size in statfs, some in stat
X */
X#if defined(SCO) || defined(_SEQUENT_) || defined(__sgi) || defined(MIPS) || defined(MIPSEB) || defined(m88k)
X# include <sys/types.h>
X# include <sys/statfs.h>
X# define STATFS statfs
X# define F_BSIZE f_bsize
Xint fstatfs __ARGS((int, struct statfs *, int, int));
X#else
X# define STATFS stat
X# define F_BSIZE st_blksize
X# define fstatfs(fd, buf, len, nul) fstat((fd), (buf))
X#endif
X
X/*
X * for Amiga Dos 2.0x we use Flush
X */
X#ifdef AMIGA
X# ifndef NO_ARP
Xextern int dos2; /* this is in amiga.c */
X# endif
X# ifdef SASC
X# include <proto/dos.h>
X# include <ios1.h> /* for chkufb() */
X# endif
X#endif
X
X#define MEMFILE_PAGE_SIZE 4096 /* default page size */
X
Xstatic long total_mem_used = 0; /* total memory used for memfiles */
X
Xstatic void mf_ins_hash __ARGS((MEMFILE *, BHDR *));
Xstatic void mf_rem_hash __ARGS((MEMFILE *, BHDR *));
Xstatic BHDR *mf_find_hash __ARGS((MEMFILE *, blocknr_t));
Xstatic void mf_ins_used __ARGS((MEMFILE *, BHDR *));
Xstatic void mf_rem_used __ARGS((MEMFILE *, BHDR *));
Xstatic BHDR *mf_release __ARGS((MEMFILE *, int));
Xstatic BHDR *mf_alloc_bhdr __ARGS((MEMFILE *, int));
Xstatic void mf_free_bhdr __ARGS((BHDR *));
Xstatic void mf_ins_free __ARGS((MEMFILE *, BHDR *));
Xstatic BHDR *mf_rem_free __ARGS((MEMFILE *));
Xstatic int mf_read __ARGS((MEMFILE *, BHDR *));
Xstatic int mf_write __ARGS((MEMFILE *, BHDR *));
Xstatic int mf_trans_add __ARGS((MEMFILE *, BHDR *));
Xstatic void mf_do_open __ARGS((MEMFILE *, char_u *, int));
X
X/*
X * The functions for using a memfile:
X *
X * mf_open() open a new or existing memfile
X * mf_close() close (and delete) a memfile
X * mf_new() create a new block in a memfile and lock it
X * mf_get() get an existing block and lock it
X * mf_put() unlock a block, may be marked for writing
X * mf_free() remove a block
X * mf_sync() sync changed parts of memfile to disk
X * mf_release_all() release as much memory as possible
X * mf_trans_del() may translate negative to positive block number
X * mf_fullname() make file name full path (use before first :cd)
X */
X
X/*
X * mf_open: open an existing or new memory block file
X *
X * fname: name of file to use (NULL means no file at all)
X * Note: fname must have been allocated, it is not copied!
X * If opening the file fails, fname is freed.
X * new: if TRUE: file should be truncated when opening
X * fail_nofile: if TRUE: if file cannot be opened, fail.
X *
X * return value: identifier for this memory block file.
X */
X MEMFILE *
Xmf_open(fname, new, fail_nofile)
X char_u *fname;
X int new;
X int fail_nofile;
X{
X MEMFILE *mfp;
X int i;
X long size;
X#ifdef UNIX
X struct STATFS stf;
X#endif
X
X if ((mfp = (MEMFILE *)alloc((unsigned)sizeof(MEMFILE))) == NULL)
X {
X free(fname);


X return NULL;
X }
X

X if (fname == NULL) /* no file for this memfile, use memory only */
X {
X mfp->mf_fname = NULL;
X mfp->mf_xfname = NULL;
X mfp->mf_fd = -1;
X }
X else
X mf_do_open(mfp, fname, new); /* try to open the file */
X
X /*
X * if fail_nofile is set and there is no file, return here
X */
X if (mfp->mf_fd < 0 && fail_nofile)
X {
X free(mfp);


X return NULL;
X }
X

X mfp->mf_free_first = NULL; /* free list is empty */
X mfp->mf_used_first = NULL; /* used list is empty */
X mfp->mf_used_last = NULL;
X mfp->mf_dirty = FALSE;
X mfp->mf_used_count = 0;
X for (i = 0; i < MEMHASHSIZE; ++i)
X {
X mfp->mf_hash[i] = NULL; /* hash lists are empty */
X mfp->mf_trans[i] = NULL; /* trans lists are empty */
X }
X mfp->mf_page_size = MEMFILE_PAGE_SIZE;
X
X#ifdef UNIX
X /*
X * Try to set the page size equal to the block size of the device.
X * Speeds up I/O a lot.
X * NOTE: minimal block size depends on size of block 0 data!
X * The maximal block size is arbitrary.
X */
X if (mfp->mf_fd >= 0 &&
X fstatfs(mfp->mf_fd, &stf, sizeof(struct statfs), 0) == 0 &&
X stf.F_BSIZE >= 1048 && stf.F_BSIZE <= 50000)
X mfp->mf_page_size = stf.F_BSIZE;
X#endif
X
X if (mfp->mf_fd < 0 || new || (size = lseek(mfp->mf_fd, 0L, SEEK_END)) <= 0)


X mfp->mf_blocknr_max = 0; /* no file or empty file */
X else
X mfp->mf_blocknr_max = size / mfp->mf_page_size;

X mfp->mf_blocknr_min = -1;
X mfp->mf_neg_count = 0;


X mfp->mf_infile_count = mfp->mf_blocknr_max;

X if (mfp->mf_fd < 0)
X mfp->mf_used_count_max = 0; /* no limit */
X else
X mfp->mf_used_count_max = p_mm * 1024 / mfp->mf_page_size;
X
X return mfp;
X}
X
X/*
X * mf_open_file: open a file for an existing memfile. Used when updatecount
X * set from 0 to some value.
X *
X * fname: name of file to use (NULL means no file at all)
X * Note: fname must have been allocated, it is not copied!
X * If opening the file fails, fname is freed.
X *
X * return value: FAIL if file could not be opened, OK otherwise
X */
X int
Xmf_open_file(mfp, fname)
X MEMFILE *mfp;
X char_u *fname;
X{
X mf_do_open(mfp, fname, TRUE); /* try to open the file */
X
X if (mfp->mf_fd < 0)
X return FAIL;
X
X mfp->mf_dirty = TRUE;


X return OK;
X}
X
X/*

X * close a memory file and delete the associated file if 'delete' is TRUE
X */
X void
Xmf_close(mfp, delete)
X MEMFILE *mfp;
X int delete;
X{
X BHDR *hp, *nextp;
X NR_TRANS *tp, *tpnext;
X int i;
X
X if (mfp == NULL) /* safety check */
X return;
X if (mfp->mf_fd >= 0)
X {
X if (close(mfp->mf_fd) < 0)
X EMSG("Close error on swap file");
X }
X if (delete && mfp->mf_fname != NULL)
X remove((char *)mfp->mf_fname);
X /* free entries in used list */
X for (hp = mfp->mf_used_first; hp != NULL; hp = nextp)
X {
X nextp = hp->bh_next;
X mf_free_bhdr(hp);
X }
X while (mfp->mf_free_first != NULL) /* free entries in free list */
X (void)free(mf_rem_free(mfp));
X for (i = 0; i < MEMHASHSIZE; ++i) /* free entries in trans lists */
X for (tp = mfp->mf_trans[i]; tp != NULL; tp = tpnext)
X {
X tpnext = tp->nt_next;
X free(tp);
X }
X free(mfp->mf_fname);
X free(mfp->mf_xfname);
X free(mfp);
X}
X
X/*
X * get a new block
X *
X * negative: TRUE if negative block number desired (data block)
X */
X BHDR *
Xmf_new(mfp, negative, page_count)


X MEMFILE *mfp;
X int negative;
X int page_count;
X{

X BHDR *hp; /* new BHDR */
X BHDR *freep; /* first block in free list */
X char_u *p;
X
X /*
X * If we reached the maximum size for the used memory blocks, release one
X * If a BHDR is returned, use it and adjust the page_count if necessary.
X */
X hp = mf_release(mfp, page_count);
X
X/*
X * Decide on the number to use:
X * If there is a free block, use its number.
X * Otherwise use mf_block_min for a negative number, mf_block_max for


X * a positive number.

X */
X freep = mfp->mf_free_first;
X if (!negative && freep != NULL && freep->bh_page_count >= page_count)
X {
X /*
X * If the block in the free list has more pages, take only the number
X * of pages needed and allocate a new BHDR with data
X *
X * If the number of pages matches and mf_release did not return a BHDR,
X * use the BHDR from the free list and allocate the data
X *
X * If the number of pages matches and mf_release returned a BHDR,
X * just use the number and free the BHDR from the free list
X */
X if (freep->bh_page_count > page_count)
X {
X if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
X return NULL;
X hp->bh_bnum = freep->bh_bnum;
X freep->bh_bnum += page_count;
X freep->bh_page_count -= page_count;
X }
X else if (hp == NULL) /* need to allocate memory for this block */
X {
X if ((p = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
X return NULL;
X hp = mf_rem_free(mfp);
X hp->bh_data = p;
X }
X else /* use the number, remove entry from free list */
X {
X freep = mf_rem_free(mfp);
X hp->bh_bnum = freep->bh_bnum;
X free(freep);
X }
X }
X else /* get a new number */
X {
X if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
X return NULL;
X if (negative)
X {
X hp->bh_bnum = mfp->mf_blocknr_min--;
X mfp->mf_neg_count++;
X }
X else
X {
X hp->bh_bnum = mfp->mf_blocknr_max;
X mfp->mf_blocknr_max += page_count;
X }
X }
X hp->bh_flags = BH_LOCKED | BH_DIRTY; /* new block is always dirty */
X mfp->mf_dirty = TRUE;
X hp->bh_page_count = page_count;
X mf_ins_used(mfp, hp);
X mf_ins_hash(mfp, hp);
X
X return hp;
X}
X
X/*
X * get existing block 'nr' with 'page_count' pages
X *
X * Note: The caller should first check a negative nr with mf_trans_del()
X */
X BHDR *
Xmf_get(mfp, nr, page_count)
X MEMFILE *mfp;
X blocknr_t nr;


X int page_count;
X{
X BHDR *hp;

X /* doesn't exist */
X if (nr >= mfp->mf_blocknr_max || nr <= mfp->mf_blocknr_min)
X return NULL;
X
X /*
X * see if it is in the cache
X */
X hp = mf_find_hash(mfp, nr);
X if (hp == NULL) /* not in the hash list */
X {
X if (nr < 0 || nr >= mfp->mf_infile_count) /* can't be in the file */
X return NULL;
X
X /* could check here if the block is in the free list */
X
X /*
X * Check if we need to flush an existing block.
X * If so, use that block.
X * If not, allocate a new block.
X */
X hp = mf_release(mfp, page_count);
X if (hp == NULL && (hp = mf_alloc_bhdr(mfp, page_count)) == NULL)
X return NULL;
X
X hp->bh_bnum = nr;
X hp->bh_flags = 0;
X hp->bh_page_count = page_count;
X if (mf_read(mfp, hp) == FAIL) /* cannot read the block! */
X {
X mf_free_bhdr(hp);
X return NULL;


X }
X }
X else
X {

X mf_rem_used(mfp, hp); /* remove from list, insert in front below */
X mf_rem_hash(mfp, hp);
X }
X
X hp->bh_flags |= BH_LOCKED;
X mf_ins_used(mfp, hp); /* put in front of used list */
X mf_ins_hash(mfp, hp); /* put in front of hash list */
X
X return hp;
X}
X
X/*
X * release the block *hp
X *
X * dirty: Block must be written to file later
X * infile: Block should be in file (needed for recovery)
X *
X * no return value, function cannot fail
X */
X void
Xmf_put(mfp, hp, dirty, infile)
X MEMFILE *mfp;
X BHDR *hp;
X int dirty;
X int infile;
X{
X int flags;
X
X flags = hp->bh_flags;
X CHECK((flags & BH_LOCKED) == 0, "block was not locked");
X flags &= ~BH_LOCKED;
X if (dirty)
X {
X flags |= BH_DIRTY;
X mfp->mf_dirty = TRUE;
X }
X hp->bh_flags = flags;
X if (infile)
X mf_trans_add(mfp, hp); /* may translate negative in positive nr */
X}
X
X/*
X * block *hp is no longer in used, may put it in the free list of memfile *mfp
X */
X void
Xmf_free(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X free(hp->bh_data); /* free the memory */
X mf_rem_hash(mfp, hp); /* get *hp out of the hash list */
X mf_rem_used(mfp, hp); /* get *hp out of the used list */
X if (hp->bh_bnum < 0)
X {
X free(hp); /* don't want negative numbers in free list */
X mfp->mf_neg_count--;
X }
X else
X mf_ins_free(mfp, hp); /* put *hp in the free list */
X}
X
X/*
X * sync the memory file *mfp to disk
X * if 'all' is FALSE blocks with negative numbers are not synced, even when
X * they are dirty!
X * if 'check_char' is TRUE, stop syncing when a character becomes available,
X * but sync at least one block.
X *
X * Return FAIL for failure, OK otherwise
X */
X int
Xmf_sync(mfp, all, check_char)
X MEMFILE *mfp;
X int all;
X int check_char;
X{
X int status;
X BHDR *hp;
X#if defined(MSDOS) || defined(SCO)
X int fd;
X#endif
X
X if (mfp->mf_fd < 0) /* there is no file, nothing to do */
X {
X mfp->mf_dirty = FALSE;


X return FAIL;
X }
X

X /*
X * sync from last to first (may reduce the probability of an inconsistent file)
X * If a write fails, it is very likely caused by a full filesystem. Then we
X * only try to write blocks within the existing file. If that also fails then
X * we give up.
X */
X status = OK;
X for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
X if ((all || hp->bh_bnum >= 0) && (hp->bh_flags & BH_DIRTY) &&
X (status == OK || (hp->bh_bnum >= 0 &&
X hp->bh_bnum < mfp->mf_infile_count)))
X {
X if (mf_write(mfp, hp) == FAIL)
X {
X if (status == FAIL) /* double error: quit syncing */
X break;


X status = FAIL;
X }

X if (check_char && mch_char_avail()) /* char available now */
X break;
X }
X
X /*
X * If the whole list is flushed, the memfile is not dirty anymore.
X * In case of an error this flag is also set, to avoid trying all the time.
X */
X if (hp == NULL || status == FAIL)
X mfp->mf_dirty = FALSE;
X
X#if defined(UNIX) && !defined(SCO)
X# if !defined(SVR4) && (defined(MIPS) || defined(MIPSEB) || defined(m88k))
X sync(); /* Do we really need to sync()?? (jw) */
X# else
X /*
X * Unix has the very useful fsync() function, just what we need.
X */
X if (fsync(mfp->mf_fd))
X status = FAIL;
X# endif
X#endif
X#if defined(MSDOS) || defined(SCO)
X /*
X * MSdos is a bit more work: Duplicate the file handle and close it.
X * This should flush the file to disk.
X * Also use this for SCO, which has no fsync().
X */
X if ((fd = dup(mfp->mf_fd)) >= 0)
X close(fd);
X#endif
X#ifdef AMIGA
X /*
X * Flush() only exists for AmigaDos 2.0.
X * For 1.3 it should be done with close() + open(), but then the risk
X * is that the open() may fail and loose the file....
X */
X# ifndef NO_ARP
X if (dos2)
X# endif
X# ifdef SASC
X {
X struct UFB *fp = chkufb(mfp->mf_fd);
X
X if (fp != NULL)
X Flush(fp->ufbfh);
X }
X# else
X Flush(_devtab[mfp->mf_fd].fd);
X# endif
X#endif
X
X return status;
X}
X
X/*
X * insert block *hp in front of hashlist of memfile *mfp


X */
X static void

Xmf_ins_hash(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X BHDR *hhp;
X int hash;
X
X hash = MEMHASH(hp->bh_bnum);
X hhp = mfp->mf_hash[hash];
X hp->bh_hash_next = hhp;
X hp->bh_hash_prev = NULL;
X if (hhp != NULL)
X hhp->bh_hash_prev = hp;
X mfp->mf_hash[hash] = hp;
X}
X
X/*
X * remove block *hp from hashlist of memfile list *mfp


X */
X static void

Xmf_rem_hash(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X if (hp->bh_hash_prev == NULL)
X mfp->mf_hash[MEMHASH(hp->bh_bnum)] = hp->bh_hash_next;
X else
X hp->bh_hash_prev->bh_hash_next = hp->bh_hash_next;
X
X if (hp->bh_hash_next)
X hp->bh_hash_next->bh_hash_prev = hp->bh_hash_prev;
X}
X
X/*
X * look in hash lists of memfile *mfp for block header with number 'nr'


X */
X static BHDR *

Xmf_find_hash(mfp, nr)
X MEMFILE *mfp;
X blocknr_t nr;


X{
X BHDR *hp;
X

X for (hp = mfp->mf_hash[MEMHASH(nr)]; hp != NULL; hp = hp->bh_hash_next)
X if (hp->bh_bnum == nr)
X break;
X return hp;
X}
X
X/*
X * insert block *hp in front of used list of memfile *mfp


X */
X static void

Xmf_ins_used(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X hp->bh_next = mfp->mf_used_first;
X mfp->mf_used_first = hp;
X hp->bh_prev = NULL;
X if (hp->bh_next == NULL) /* list was empty, adjust last pointer */
X mfp->mf_used_last = hp;
X else
X hp->bh_next->bh_prev = hp;
X mfp->mf_used_count += hp->bh_page_count;
X total_mem_used += hp->bh_page_count * mfp->mf_page_size;
X}
X
X/*
X * remove block *hp from used list of memfile *mfp


X */
X static void

Xmf_rem_used(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X if (hp->bh_next == NULL) /* last block in used list */
X mfp->mf_used_last = hp->bh_prev;
X else
X hp->bh_next->bh_prev = hp->bh_prev;
X if (hp->bh_prev == NULL) /* first block in used list */
X mfp->mf_used_first = hp->bh_next;
X else
X hp->bh_prev->bh_next = hp->bh_next;
X mfp->mf_used_count -= hp->bh_page_count;
X total_mem_used -= hp->bh_page_count * mfp->mf_page_size;
X}
X
X/*
X * Release the least recently used block from the used list if the number
X * of used memory blocks gets to big.
X *
X * Return the block header to the caller, including the memory block, so
X * it can be re-used. Make sure the page_count is right.


X */
X static BHDR *

Xmf_release(mfp, page_count)
X MEMFILE *mfp;


X int page_count;
X{
X BHDR *hp;

X
X /*
X * don't release a block if
X * there is no file for this memfile
X * or
X * there is no limit to the number of blocks for this memfile or
X * the maximum is not reached yet
X * and
X * total memory used is not up to 'maxmemtot'
X */
X if (mfp->mf_fd < 0 || ((mfp->mf_used_count < mfp->mf_used_count_max ||
X mfp->mf_used_count_max == 0) &&
X (total_mem_used >> 10) < p_mmt))
X return NULL;
X
X for (hp = mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
X if (!(hp->bh_flags & BH_LOCKED))
X break;
X if (hp == NULL) /* not a single one that can be released */
X return NULL;
X
X /*
X * If the block is dirty, write it.
X * If the write fails we don't free it.
X */
X if ((hp->bh_flags & BH_DIRTY) && mf_write(mfp, hp) == FAIL)
X return NULL;
X
X mf_rem_used(mfp, hp);
X mf_rem_hash(mfp, hp);
X
X/*
X * If a BHDR is returned, make sure that the page_count of bh_data is right
X */
X if (hp->bh_page_count != page_count)
X {
X free(hp->bh_data);
X if ((hp->bh_data = alloc(mfp->mf_page_size * page_count)) == NULL)
X {
X free(hp);
X return NULL;
X }
X hp->bh_page_count = page_count;
X }
X return hp;
X}
X
X/*
X * release as many blocks as possible
X * Used in case of out of memory
X *
X * return TRUE if any memory was released
X */
X int
Xmf_release_all()
X{
X BUF *buf;
X MEMFILE *mfp;
X BHDR *hp;
X int retval = FALSE;
X


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)

X {
X mfp = buf->b_ml.ml_mfp;

X if (mfp != NULL && mfp->mf_fd >= 0) /* only if there is a memfile with a file */
X for (hp = mfp->mf_used_last; hp != NULL; )
X {
X if (!(hp->bh_flags & BH_LOCKED) &&
X (!(hp->bh_flags & BH_DIRTY) || mf_write(mfp, hp) != FAIL))
X {
X mf_rem_used(mfp, hp);
X mf_rem_hash(mfp, hp);
X mf_free_bhdr(hp);
X hp = mfp->mf_used_last; /* re-start, list was changed */
X retval = TRUE;
X }
X else
X hp = hp->bh_prev;
X }


X }
X return retval;
X}
X
X/*

X * Allocate a block header and a block of memory for it


X */
X static BHDR *

Xmf_alloc_bhdr(mfp, page_count)
X MEMFILE *mfp;


X int page_count;
X{
X BHDR *hp;
X

X if ((hp = (BHDR *)alloc((unsigned)sizeof(BHDR))) != NULL)
X {
X if ((hp->bh_data = (char_u *)alloc(mfp->mf_page_size * page_count)) == NULL)
X {
X free(hp); /* not enough memory */


X hp = NULL;
X }

X hp->bh_page_count = page_count;
X }
X return hp;
X}
X
X/*
X * Free a block header and the block of memory for it


X */
X static void

Xmf_free_bhdr(hp)
X BHDR *hp;
X{
X free(hp->bh_data);
X free(hp);
X}
X
X/*
X * insert entry *hp in the free list


X */
X static void

Xmf_ins_free(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X hp->bh_next = mfp->mf_free_first;
X mfp->mf_free_first = hp;
X}
X
X/*
X * remove the first entry from the free list and return a pointer to it
X * Note: caller must check that mfp->mf_free_first is not NULL!


X */
X static BHDR *

Xmf_rem_free(mfp)


X MEMFILE *mfp;
X{
X BHDR *hp;
X

X hp = mfp->mf_free_first;
X mfp->mf_free_first = hp->bh_next;
X return hp;
X}
X
X/*
X * read a block from disk
X *
X * Return FAIL for failure, OK otherwise


X */
X static int

Xmf_read(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X long_u offset;
X unsigned page_size;
X unsigned size;
X
X if (mfp->mf_fd < 0) /* there is no file, can't read */
X return FAIL;
X


X page_size = mfp->mf_page_size;

X offset = page_size * hp->bh_bnum;
X size = page_size * hp->bh_page_count;
X if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
X {
X EMSG("Seek error in swap file read");
X return FAIL;
X }
X if (read(mfp->mf_fd, hp->bh_data, (size_t)size) != size)
X {
X EMSG("Read error in swap file");
X return FAIL;
X }


X return OK;
X}
X
X/*

X * write a block to disk
X *
X * Return FAIL for failure, OK otherwise


X */
X static int

Xmf_write(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X long_u offset; /* offset in the file */
X blocknr_t nr; /* block nr which is being written */
X BHDR *hp2;
X unsigned page_size; /* number of bytes in a page */
X unsigned page_count; /* number of pages written */
X unsigned size; /* number of bytes written */
X
X if (mfp->mf_fd < 0) /* there is no file, can't write */
X return FAIL;
X
X if (hp->bh_bnum < 0) /* must assign file block number */
X if (mf_trans_add(mfp, hp) == FAIL)
X return FAIL;
X
X page_size = mfp->mf_page_size;
X
X /*
X * We don't want gaps in the file. Write the blocks in front of *hp
X * to extend the file.
X * If block 'mf_infile_count' is not in the hash list, it has been
X * freed. Fill the space in the file with data from the current block.
X */


X for (;;)
X {

X nr = hp->bh_bnum;
X if (nr > mfp->mf_infile_count) /* beyond end of file */
X {
X nr = mfp->mf_infile_count;
X hp2 = mf_find_hash(mfp, nr); /* NULL catched below */
X }
X else
X hp2 = hp;
X
X offset = page_size * nr;
X if (lseek(mfp->mf_fd, offset, SEEK_SET) != offset)
X {
X EMSG("Seek error in swap file write");
X return FAIL;
X }
X if (hp2 == NULL) /* freed block, fill with dummy data */
X page_count = 1;
X else
X page_count = hp2->bh_page_count;
X size = page_size * page_count;
X if (write(mfp->mf_fd, (hp2 == NULL ? hp : hp2)->bh_data,
X (size_t)size) != size)
X {
X EMSG("Write error in swap file");
X return FAIL;
X }
X if (hp2 != NULL) /* written a non-dummy block */
X hp2->bh_flags &= ~BH_DIRTY;
X
X if (nr + page_count > mfp->mf_infile_count) /* appended to the file */
X mfp->mf_infile_count = nr + page_count;
X if (nr == hp->bh_bnum) /* written the desired block */
X break;
X nr += page_count;


X }
X return OK;
X}
X
X/*

X * Make block number for *hp positive and add it to the translation list
X *
X * Return FAIL for failure, OK otherwise


X */
X static int

Xmf_trans_add(mfp, hp)
X MEMFILE *mfp;
X BHDR *hp;
X{
X BHDR *freep;
X blocknr_t new;
X int hash;
X NR_TRANS *np;
X int page_count;
X
X if (hp->bh_bnum >= 0) /* it's already positive */
X return OK;
X
X if ((np = (NR_TRANS *)alloc((unsigned)sizeof(NR_TRANS))) == NULL)
X return FAIL;
X
X/*
X * get a new number for the block.
X * If the first item in the free list has sufficient pages, use its number
X * Otherwise use mf_blocknr_max.
X */
X freep = mfp->mf_free_first;
X page_count = hp->bh_page_count;
X if (freep != NULL && freep->bh_page_count >= page_count)
X {
X new = freep->bh_bnum;
X /*
X * If the page count of the free block was larger, recude it.
X * If the page count matches, remove the block from the free list
X */
X if (freep->bh_page_count > page_count)
X {
X freep->bh_bnum += page_count;
X freep->bh_page_count -= page_count;
X }
X else
X {
X freep = mf_rem_free(mfp);
X free(freep);


X }
X }
X else
X {

X new = mfp->mf_blocknr_max;
X mfp->mf_blocknr_max += page_count;
X }
X
X np->nt_old_bnum = hp->bh_bnum; /* adjust number */
X np->nt_new_bnum = new;
X
X mf_rem_hash(mfp, hp); /* remove from old hash list */
X hp->bh_bnum = new;
X mf_ins_hash(mfp, hp); /* insert in new hash list */
X
X hash = MEMHASH(np->nt_old_bnum); /* insert in trans list */
X np->nt_next = mfp->mf_trans[hash];
X mfp->mf_trans[hash] = np;
X if (np->nt_next != NULL)
X np->nt_next->nt_prev = np;
X np->nt_prev = NULL;

X
X return OK;
X}
X
X/*

X * Lookup a tranlation from the trans lists and delete the entry
X *
X * Return the positive new number when found, the old number when not found
X */
X blocknr_t
Xmf_trans_del(mfp, old)
X MEMFILE *mfp;
X blocknr_t old;
X{
X int hash;
X NR_TRANS *np;
X blocknr_t new;
X
X hash = MEMHASH(old);
X for (np = mfp->mf_trans[hash]; np != NULL; np = np->nt_next)
X if (np->nt_old_bnum == old)
X break;
X if (np == NULL) /* not found */
X return old;
X
X mfp->mf_neg_count--;
X new = np->nt_new_bnum;
X if (np->nt_prev != NULL) /* remove entry from the trans list */
X np->nt_prev->nt_next = np->nt_next;
X else
X mfp->mf_trans[hash] = np->nt_next;
X if (np->nt_next != NULL)
X np->nt_next->nt_prev = np->nt_prev;
X free(np);
X
X return new;
X}
X
X/*
X * Make the name of the file used for the memfile a full path.
X * Used before doing a :cd
X */
X void
Xmf_fullname(mfp)
X MEMFILE *mfp;
X{
X if (mfp != NULL && mfp->mf_fname != NULL && mfp->mf_xfname != NULL)
X {
X free(mfp->mf_fname);
X mfp->mf_fname = mfp->mf_xfname;
X mfp->mf_xfname = NULL;
X }
X}
X
X/*
X * return TRUE if there are any translations pending for 'mfp'
X */
X int
Xmf_need_trans(mfp)
X MEMFILE *mfp;
X{
X return (mfp->mf_fname != NULL && mfp->mf_neg_count > 0);
X}
X
X#if 1 /* included for beta release, TODO: remove later */
X/*
X * print statistics for a memfile (for debugging)
X */
X void
Xmf_statistics()
X{
X MEMFILE *mfp;
X BHDR *hp;
X int used = 0;
X int locked = 0;
X int dirty = 0;
X int nfree = 0;
X int negative = 0;
X
X mfp = curbuf->b_ml.ml_mfp;
X if (mfp == NULL)
X MSG("No memfile");
X else
X {
X for (hp = mfp->mf_used_first; hp != NULL; hp = hp->bh_next)
X {
X ++used;
X if (hp->bh_flags & BH_LOCKED)
X ++locked;
X if (hp->bh_flags & BH_DIRTY)
X ++dirty;
X if (hp->bh_bnum < 0)
X ++negative;
X }
X for (hp = mfp->mf_free_first; hp != NULL; hp = hp->bh_next)
X ++nfree;
X sprintf((char *)IObuff, "%d used (%d locked, %d dirty, %d (%d) negative), %d free",
X used, locked, dirty, negative, (int)mfp->mf_neg_count, nfree);
X msg(IObuff);
X }
X}
X#endif
X
X/*
X * open a file for a memfile


X */
X static void

Xmf_do_open(mfp, fname, new)
X MEMFILE *mfp;
X char_u *fname;
X int new;
X{
X mfp->mf_fname = fname;
X /*
X * get the full path name before the open, because this is
X * not possible after the open on the Amiga.
X * fname cannot be NameBuff, because it has been allocated.
X */
X if (FullName(fname, NameBuff, MAXPATHL) == FAIL)
X mfp->mf_xfname = NULL;
X else
X mfp->mf_xfname = strsave(NameBuff);
X
X /*
X * try to open the file
X */
X mfp->mf_fd = open((char *)fname, new ? (O_CREAT | O_RDWR | O_TRUNC) : (O_RDONLY)
X
X#ifdef AMIGA /* Amiga has no mode argument */
X );
X#endif
X#ifdef UNIX /* open in rw------- mode */
X# ifdef SCO
X , (mode_t)0600);
X# else
X , 0600);
X# endif
X#endif
X#ifdef MSDOS /* open read/write */
X , S_IREAD | S_IWRITE);
X#endif
X /*
X * If the file cannot be opened, use memory only
X */
X if (mfp->mf_fd < 0)
X {
X free(fname);
X free(mfp->mf_xfname);
X mfp->mf_fname = NULL;
X mfp->mf_xfname = NULL;
X }
X}
END_OF_FILE
if test 26671 -ne `wc -c <'vim/src/memfile.c'`; then
echo shar: \"'vim/src/memfile.c'\" unpacked with wrong size!
fi
# end of 'vim/src/memfile.c'
fi
echo shar: End of archive 13 \(of 26\).
cp /dev/null ark13isdone

Bram Moolenaar

unread,
Aug 16, 1994, 10:18:35 PM8/16/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 33
Archive-name: vim/part14

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/macros/maze/maze_5.78 vim/src/param.c vim/src/tags
# Wrapped by kent@sparky on Mon Aug 15 21:44:07 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 14 (of 26)."'
if test -f 'vim/macros/maze/maze_5.78' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/maze_5.78'\"
else
echo shar: Extracting \"'vim/macros/maze/maze_5.78'\" \(626 characters\)
sed "s/^X//" >'vim/macros/maze/maze_5.78' <<'END_OF_FILE'
X._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
X| ._| . . ._| | |_._._. . ._|_._._._._. ._|_. ._|_._. ._| . ._|_. | . ._._. |
X| ._|_| |_. | | | | ._._|_._|_._. . |_. | | | ._._| |_._._| | ._. ._| . . |_|
X|_._._._. | ._|_. ._._._. | | ._. |_._. . | ._._| |_. | ._._._. |_. | |_|_| |
X| | . |_._| . ._._._| ._._. ._._| | | |_| . | |_. . ._|_| ._._. |_._|_| . | |
X|_._|_._._._|_._._._|_|_._._._|_._|_._._._|_._._._|_._._._|_._._._._._._|_._|
X
XSee Vim solve a maze!
X
X type ":so maze_mac<RETURN>" to load the macros
X
X type "g" to start
X
Xto interrupt type "<CTRL-C>"
X to quit type ":q!<RETURN>"
X
END_OF_FILE
if test 626 -ne `wc -c <'vim/macros/maze/maze_5.78'`; then
echo shar: \"'vim/macros/maze/maze_5.78'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/maze_5.78'
fi
if test -f 'vim/src/param.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/param.c'\"
else
echo shar: Extracting \"'vim/src/param.c'\" \(35665 characters\)
sed "s/^X//" >'vim/src/param.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Code to handle user-settable parameters. This is all pretty much table-
X * driven. To add a new parameter, put it in the params array, and add a
X * variable for it in param.h. If it's a numeric parameter, add any necessary
X * bounds checks to doset().


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstruct param
X{
X char *fullname; /* full parameter name */
X char *shortname; /* permissible abbreviation */
X short flags; /* see below */
X char_u *var; /* pointer to variable */
X};
X
X/*
X * Flags
X * Note: Don't use P_STRING and P_IND at the same time
X */
X#define P_BOOL 0x01 /* the parameter is boolean */
X#define P_NUM 0x02 /* the parameter is numeric */
X#define P_STRING 0x04 /* the parameter is a string */
X#define P_CHANGED 0x08 /* the parameter has been changed */
X#define P_EXPAND 0x10 /* environment expansion */
X#define P_IND 0x20 /* indirect, is in curwin or curbuf */
X
X/*
X * The options that are in curwin or curbuf have P_IND set and a var field
X * that contains one of the values below. The values are odd to make it very
X * unlikely that another variable has the same value.
X * Note: P_EXPAND and P_IND can never be used at the same time.
X * Note: P_IND cannot be used for a terminal option.
X */
X#define PV_LIST 1
X#define PV_NU 3
X#define PV_SCROLL 5
X#define PV_WRAP 7
X
X#define PV_AI 11
X#define PV_BIN 13
X#define PV_EOL 14
X#define PV_ET 15
X#define PV_ML 17
X#define PV_RO 19
X#define PV_SI 21
X#define PV_SN 23
X#define PV_SW 25
X#define PV_TS 27
X#define PV_TW 29
X#define PV_TX 31
X#define PV_WM 33
X
X/*
X * The param structure is initialized here.
X * The order of the parameters should be alfabetic
X * The parameters with a NULL variable are 'hidden': a set command for
X * them is ignored and they are not printed.
X */
Xstatic struct param params[] =
X{
X {"autoindent", "ai", P_BOOL|P_IND, (char_u *)PV_AI},
X {"autoprint", "ap", P_BOOL, (char_u *)NULL},
X {"autowrite", "aw", P_BOOL, (char_u *)&p_aw},
X {"backspace", "bs", P_NUM, (char_u *)&p_bs},
X {"backup", "bk", P_BOOL, (char_u *)&p_bk},
X#ifdef UNIX
X {"backupdir", "bdir", P_STRING|P_EXPAND, (char_u *)&p_bdir},
X#endif
X {"beautify", "bf", P_BOOL, (char_u *)NULL},
X {"binary", "bin", P_BOOL|P_IND, (char_u *)PV_BIN},
X#ifdef MSDOS
X {"bioskey", "biosk",P_BOOL, (char_u *)&p_biosk},
X#endif
X {"cmdheight", "ch", P_NUM, (char_u *)&p_ch},
X {"columns", "co", P_NUM, (char_u *)&Columns},
X {"compatible", "cp", P_BOOL, (char_u *)&p_cp},
X#ifdef DIGRAPHS
X {"digraph", "dg", P_BOOL, (char_u *)&p_dg},
X#endif /* DIGRAPHS */
X {"directory", "dir", P_STRING|P_EXPAND, (char_u *)&p_dir},
X {"edcompatible",NULL, P_BOOL, (char_u *)&p_ed},
X {"endofline", "eol", P_BOOL|P_IND, (char_u *)PV_EOL},
X {"equalalways", "ea", P_BOOL, (char_u *)&p_ea},
X {"equalprg", "ep", P_STRING|P_EXPAND, (char_u *)&p_ep},
X {"errorbells", "eb", P_BOOL, (char_u *)&p_eb},
X {"errorfile", "ef", P_STRING|P_EXPAND, (char_u *)&p_ef},
X {"errorformat", "efm", P_STRING, (char_u *)&p_efm},
X {"esckeys", "ek", P_BOOL, (char_u *)&p_ek},
X {"expandtab", "et", P_BOOL|P_IND, (char_u *)PV_ET},
X {"exrc", NULL, P_BOOL, (char_u *)&p_exrc},
X {"formatprg", "fp", P_STRING|P_EXPAND, (char_u *)&p_fp},
X {"gdefault", "gd", P_BOOL, (char_u *)&p_gd},
X {"graphic", "gr", P_BOOL, (char_u *)&p_gr},
X {"hardtabs", "ht", P_NUM, (char_u *)NULL},
X {"helpfile", "hf", P_STRING|P_EXPAND, (char_u *)&p_hf},
X {"hidden", "hid", P_BOOL, (char_u *)&p_hid},
X {"highlight", "hl", P_STRING, (char_u *)&p_hl},
X {"history", "hi", P_NUM, (char_u *)&p_hi},
X {"icon", NULL, P_BOOL, (char_u *)&p_icon},
X {"ignorecase", "ic", P_BOOL, (char_u *)&p_ic},
X {"insertmode", "im", P_BOOL, (char_u *)&p_im},
X {"joinspaces", "js", P_BOOL, (char_u *)&p_js},
X {"keywordprg", "kp", P_STRING|P_EXPAND, (char_u *)&p_kp},
X {"laststatus", "ls", P_NUM, (char_u *)&p_ls},
X {"lines", NULL, P_NUM, (char_u *)&Rows},
X {"lisp", NULL, P_BOOL, (char_u *)NULL},
X {"list", NULL, P_BOOL|P_IND, (char_u *)PV_LIST},
X {"magic", NULL, P_BOOL, (char_u *)&p_magic},
X {"makeprg", "mp", P_STRING|P_EXPAND, (char_u *)&p_mp},
X {"maxmem", "mm", P_NUM, (char_u *)&p_mm},
X {"maxmemtot", "mmt", P_NUM, (char_u *)&p_mmt},
X {"mesg", NULL, P_BOOL, (char_u *)NULL},
X {"modeline", "ml", P_BOOL|P_IND, (char_u *)PV_ML},
X {"modelines", "mls", P_NUM, (char_u *)&p_mls},
X {"more", NULL, P_BOOL, (char_u *)&p_more},
X {"nobuf", "nb", P_BOOL, (char_u *)&p_nb},
X {"number", "nu", P_BOOL|P_IND, (char_u *)PV_NU},
X {"open", NULL, P_BOOL, (char_u *)NULL},
X {"optimize", "opt", P_BOOL, (char_u *)NULL},
X {"paragraphs", "para", P_STRING, (char_u *)&p_para},
X {"paste", NULL, P_BOOL, (char_u *)&p_paste},
X {"patchmode", "pm", P_STRING, (char_u *)&p_pm},
X {"path", "pa", P_STRING|P_EXPAND, (char_u *)&p_path},
X {"prompt", NULL, P_BOOL, (char_u *)NULL},
X {"readonly", "ro", P_BOOL|P_IND, (char_u *)PV_RO},
X {"redraw", NULL, P_BOOL, (char_u *)NULL},
X {"remap", NULL, P_BOOL, (char_u *)&p_remap},
X {"report", NULL, P_NUM, (char_u *)&p_report},
X {"revins", "ri", P_BOOL, (char_u *)&p_ri},
X {"ruler", "ru", P_BOOL, (char_u *)&p_ru},
X {"scroll", NULL, P_NUM|P_IND, (char_u *)PV_SCROLL},
X {"scrolljump", "sj", P_NUM, (char_u *)&p_sj},
X {"sections", "sect", P_STRING, (char_u *)&p_sections},
X {"secure", NULL, P_BOOL, (char_u *)&p_secure},
X {"shell", "sh", P_STRING|P_EXPAND, (char_u *)&p_sh},
X {"shellpipe", "sp", P_STRING, (char_u *)&p_sp},
X {"shelltype", "st", P_NUM, (char_u *)&p_st},
X {"shiftround", "sr", P_BOOL, (char_u *)&p_sr},
X {"shiftwidth", "sw", P_NUM|P_IND, (char_u *)PV_SW},
X#ifndef MSDOS
X {"shortname", "sn", P_BOOL|P_IND, (char_u *)PV_SN},
X#endif
X {"showcmd", "sc", P_BOOL, (char_u *)&p_sc},
X {"showmatch", "sm", P_BOOL, (char_u *)&p_sm},
X {"showmode", "smd", P_BOOL, (char_u *)&p_smd},
X {"sidescroll", "ss", P_NUM, (char_u *)&p_ss},
X {"slowopen", "slow", P_BOOL, (char_u *)NULL},
X {"smartindent", "si", P_BOOL|P_IND, (char_u *)PV_SI},
X {"smarttab", "sta", P_BOOL, (char_u *)&p_sta},
X {"sourceany", NULL, P_BOOL, (char_u *)NULL},
X {"splitbelow", "sb", P_BOOL, (char_u *)&p_sb},
X {"suffixes", "su", P_STRING, (char_u *)&p_su},
X {"tabstop", "ts", P_NUM|P_IND, (char_u *)PV_TS},
X {"taglength", "tl", P_NUM, (char_u *)&p_tl},
X {"tagrelative", "tr", P_BOOL, (char_u *)&p_tr},
X {"tags", NULL, P_STRING|P_EXPAND, (char_u *)&p_tags},
X {"term", NULL, P_STRING|P_EXPAND, (char_u *)&term_strings.t_name},
X {"terse", NULL, P_BOOL, (char_u *)&p_terse},
X {"textauto", "ta", P_BOOL, (char_u *)&p_ta},
X {"textmode", "tx", P_BOOL|P_IND, (char_u *)PV_TX},
X {"textwidth", "tw", P_NUM|P_IND, (char_u *)PV_TW},
X {"tildeop", "to", P_BOOL, (char_u *)&p_to},
X {"timeout", NULL, P_BOOL, (char_u *)&p_timeout},
X {"timeoutlen", "tm", P_NUM, (char_u *)&p_tm},
X {"title", NULL, P_BOOL, (char_u *)&p_title},
X {"ttimeout", NULL, P_BOOL, (char_u *)&p_ttimeout},
X {"ttyfast", "tf", P_BOOL, (char_u *)&p_tf},
X {"ttytype", NULL, P_STRING, (char_u *)NULL},
X {"undolevels", "ul", P_NUM, (char_u *)&p_ul},
X {"updatecount", "uc", P_NUM, (char_u *)&p_uc},
X {"updatetime", "ut", P_NUM, (char_u *)&p_ut},
X {"visualbell", "vb", P_BOOL, (char_u *)&p_vb},
X {"w300", NULL, P_NUM, (char_u *)NULL},
X {"w1200", NULL, P_NUM, (char_u *)NULL},
X {"w9600", NULL, P_NUM, (char_u *)NULL},
X {"warn", NULL, P_BOOL, (char_u *)&p_warn},
X {"weirdinvert", "wi", P_BOOL, (char_u *)&p_wi},
X {"whichwrap", "ww", P_NUM, (char_u *)&p_ww},
X {"wildchar", "wc", P_NUM, (char_u *)&p_wc},
X {"window", NULL, P_NUM, (char_u *)NULL},
X {"winheight", "wh", P_NUM, (char_u *)&p_wh},
X {"wrap", NULL, P_BOOL|P_IND, (char_u *)PV_WRAP},
X {"wrapmargin", "wm", P_NUM|P_IND, (char_u *)PV_WM},
X {"wrapscan", "ws", P_BOOL, (char_u *)&p_ws},
X {"writeany", "wa", P_BOOL, (char_u *)&p_wa},
X {"writebackup", "wb", P_BOOL, (char_u *)&p_wb},
X {"yankendofline", "ye", P_BOOL, (char_u *)&p_ye},
X
X/* terminal output codes */
X {"t_cdl", NULL, P_STRING, (char_u *)&term_strings.t_cdl},
X {"t_ci", NULL, P_STRING, (char_u *)&term_strings.t_ci},
X {"t_cil", NULL, P_STRING, (char_u *)&term_strings.t_cil},
X {"t_cm", NULL, P_STRING, (char_u *)&term_strings.t_cm},
X {"t_cri", NULL, P_STRING, (char_u *)&term_strings.t_cri},
X {"t_cv", NULL, P_STRING, (char_u *)&term_strings.t_cv},
X {"t_cvv", NULL, P_STRING, (char_u *)&term_strings.t_cvv},
X {"t_dl", NULL, P_STRING, (char_u *)&term_strings.t_dl},
X {"t_cs", NULL, P_STRING, (char_u *)&term_strings.t_cs},
X {"t_ed", NULL, P_STRING, (char_u *)&term_strings.t_ed},
X {"t_el", NULL, P_STRING, (char_u *)&term_strings.t_el},
X {"t_il", NULL, P_STRING, (char_u *)&term_strings.t_il},
X {"t_ke", NULL, P_STRING, (char_u *)&term_strings.t_ke},
X {"t_ks", NULL, P_STRING, (char_u *)&term_strings.t_ks},
X {"t_ms", NULL, P_STRING, (char_u *)&term_strings.t_ms},
X {"t_se", NULL, P_STRING, (char_u *)&term_strings.t_se},
X {"t_so", NULL, P_STRING, (char_u *)&term_strings.t_so},
X {"t_ti", NULL, P_STRING, (char_u *)&term_strings.t_ti},
X {"t_tb", NULL, P_STRING, (char_u *)&term_strings.t_tb},
X {"t_tp", NULL, P_STRING, (char_u *)&term_strings.t_tp},
X {"t_sr", NULL, P_STRING, (char_u *)&term_strings.t_sr},
X {"t_te", NULL, P_STRING, (char_u *)&term_strings.t_te},
X {"t_ts", NULL, P_STRING, (char_u *)&term_strings.t_ts},
X {"t_vb", NULL, P_STRING, (char_u *)&term_strings.t_vb},
X
X/* terminal key codes */
X {"t_ku", NULL, P_STRING, (char_u *)&term_strings.t_ku},
X {"t_kd", NULL, P_STRING, (char_u *)&term_strings.t_kd},
X {"t_kr", NULL, P_STRING, (char_u *)&term_strings.t_kr},
X {"t_kl", NULL, P_STRING, (char_u *)&term_strings.t_kl},
X {"t_sku", NULL, P_STRING, (char_u *)&term_strings.t_sku},
X {"t_skd", NULL, P_STRING, (char_u *)&term_strings.t_skd},
X {"t_skr", NULL, P_STRING, (char_u *)&term_strings.t_skr},
X {"t_skl", NULL, P_STRING, (char_u *)&term_strings.t_skl},
X {"t_f1", NULL, P_STRING, (char_u *)&term_strings.t_f1},
X {"t_f2", NULL, P_STRING, (char_u *)&term_strings.t_f2},
X {"t_f3", NULL, P_STRING, (char_u *)&term_strings.t_f3},
X {"t_f4", NULL, P_STRING, (char_u *)&term_strings.t_f4},
X {"t_f5", NULL, P_STRING, (char_u *)&term_strings.t_f5},
X {"t_f6", NULL, P_STRING, (char_u *)&term_strings.t_f6},
X {"t_f7", NULL, P_STRING, (char_u *)&term_strings.t_f7},
X {"t_f8", NULL, P_STRING, (char_u *)&term_strings.t_f8},
X {"t_f9", NULL, P_STRING, (char_u *)&term_strings.t_f9},
X {"t_f10", NULL, P_STRING, (char_u *)&term_strings.t_f10},
X {"t_sf1", NULL, P_STRING, (char_u *)&term_strings.t_sf1},
X {"t_sf2", NULL, P_STRING, (char_u *)&term_strings.t_sf2},
X {"t_sf3", NULL, P_STRING, (char_u *)&term_strings.t_sf3},
X {"t_sf4", NULL, P_STRING, (char_u *)&term_strings.t_sf4},
X {"t_sf5", NULL, P_STRING, (char_u *)&term_strings.t_sf5},
X {"t_sf6", NULL, P_STRING, (char_u *)&term_strings.t_sf6},
X {"t_sf7", NULL, P_STRING, (char_u *)&term_strings.t_sf7},
X {"t_sf8", NULL, P_STRING, (char_u *)&term_strings.t_sf8},
X {"t_sf9", NULL, P_STRING, (char_u *)&term_strings.t_sf9},
X {"t_sf10", NULL, P_STRING, (char_u *)&term_strings.t_sf10},
X {"t_help", NULL, P_STRING, (char_u *)&term_strings.t_help},
X {"t_undo", NULL, P_STRING, (char_u *)&term_strings.t_undo},
X {"t_csc", NULL, P_STRING, (char_u *)&term_strings.t_csc},
X {NULL, NULL, 0, NULL} /* end marker */
X};
X
X#define PARAM_COUNT (sizeof(params) / sizeof(struct param))
X
Xstatic void param_expand __ARGS((int, int));
Xstatic int findparam __ARGS((char_u *));
Xstatic void showparams __ARGS((int));
Xstatic void showonep __ARGS((struct param *));
Xstatic int istermparam __ARGS((struct param *));
Xstatic char_u *get_varp __ARGS((struct param *));
X
X/*
X * Initialize the shell parameter and scroll size.
X */
X void
Xset_init()
X{
X char_u *p;
X int i;
X
X if ((p = vimgetenv((char_u *)"SHELL")) != NULL
X#ifdef MSDOS
X || (p = vimgetenv((char_u *)"COMSPEC")) != NULL
X#endif
X )
X {
X p = strsave(p);
X if (p != NULL) /* we don't want a NULL */
X p_sh = p;
X }


X
X#ifdef UNIX
X /*

X * Default for p_sp is "| tee".
X * For known shells it is changed here to include stderr.
X */
X p = gettail(p_sh);
X if ( STRCMP(p, "csh") == 0 ||
X STRCMP(p, "tcsh") == 0 ||
X STRCMP(p, "zsh") == 0)
X p_sp = (char_u *)"|& tee";
X else if (STRCMP(p, "sh") == 0 ||
X STRCMP(p, "ksh") == 0 ||
X STRCMP(p, "bash") == 0)
X p_sp = (char_u *)"2>&1| tee";
X#endif
X
X curwin->w_p_scroll = (Rows >> 1);
X comp_col();
X
X/*
X * set the options in curwin and curbuf that are non-zero
X */
X curwin->w_p_wrap = TRUE;
X curbuf->b_p_ml = TRUE;
X curbuf->b_p_sw = 8;
X curbuf->b_p_ts = 8;
X#ifdef MSDOS
X curbuf->b_p_tx = TRUE; /* texmode is default for MSDOS */
X#endif
X
X /*
X * expand environment variables in some string options
X */
X for (i = 0; params[i].fullname != NULL; i++)
X param_expand(i, FALSE);
X
X /*
X * may adjust p_mmt and p_mm for available memory
X */
X if (p_mmt == 0)
X {
X p_mmt = (mch_avail_mem(FALSE) >> 11);
X if (p_mm > p_mmt)
X p_mm = p_mmt;
X }
X}
X
X/*
X * parse 'arg' for option settings
X * 'arg' may be IObuff, but only when no errors can be present and parameter
X * does not need to be expanded with param_expand().
X *
X * return FAIL if errors are detected, OK otherwise
X */
X int
Xdoset(arg)
X char_u *arg; /* parameter string (may be written to!) */


X{
X register int i;

X char_u *s;
X char_u *errmsg;
X char_u *startarg;
X int prefix; /* 0: nothing, 1: "no", 2: "inv" in front of name */
X int nextchar;
X int len;
X int flags; /* flags for current option */
X char_u *varp; /* pointer to variable for current option */
X int errcnt = 0; /* number of errornous entries */
X long oldRows = Rows; /* remember old Rows */
X int oldpaste = p_paste; /* remember old paste option */
X long oldch = p_ch; /* remember old command line height */
X int oldea = p_ea; /* remember old 'equalalways' */
X long olduc = p_uc; /* remember old 'updatecount' */
X static int save_sm = 0; /* saved options for 'paste' */
X static int save_ru = 0;
X static int save_ri = 0;
X int did_show = FALSE; /* already showed one value */
X WIN *wp;
X
X if (*arg == NUL)
X {
X showparams(0);
X return OK;
X }
X if (STRNCMP(arg, "all", (size_t)3) == 0)
X {
X showparams(1);
X return OK;
X }
X if (STRNCMP(arg, "termcap", (size_t)7) == 0)
X {
X showparams(2);


X return OK;
X }
X

X while (*arg) /* loop to process all parameters */
X {
X errmsg = NULL;
X startarg = arg; /* remember for error message */
X prefix = 1;
X if (STRNCMP(arg, "no", (size_t)2) == 0)
X {
X prefix = 0;
X arg += 2;
X }
X else if (STRNCMP(arg, "inv", (size_t)3) == 0)
X {
X prefix = 2;
X arg += 3;
X }
X /* find end of name */
X for (len = 0; isalnum(arg[len]) || arg[len] == '_'; ++len)
X ;
X nextchar = arg[len];
X arg[len] = 0; /* name ends with 0 */
X i = findparam(arg);
X arg[len] = nextchar; /* restore nextchar */
X
X if (i == -1) /* found a mismatch: skip the rest */
X {
X errmsg = (char_u *)"Unknown option";
X goto skip;
X }
X
X if (!params[i].var) /* hidden option */
X goto skip;
X
X flags = params[i].flags;
X varp = get_varp(&(params[i]));
X
X /*
X * allow '=' and ':' as MSDOS command.com allows only one
X * '=' character per "set" command line. grrr. (jw)
X */
X if (nextchar == '?' ||
X (prefix == 1 && nextchar != '=' &&
X nextchar != ':' && !(flags & P_BOOL)))
X { /* print value */
X if (did_show)
X msg_outchar('\n'); /* cursor below last one */
X else
X {
X gotocmdline(TRUE, NUL); /* cursor at status line */
X did_show = TRUE; /* remember that we did a line */
X }
X showonep(&params[i]);
X }
X else
X {
X if (nextchar != NUL && strchr("=: \t", nextchar) == NULL)
X {
X errmsg = e_invarg;
X goto skip;
X }
X else if (flags & P_BOOL) /* boolean */
X {
X if (nextchar == '=' || nextchar == ':')
X {
X errmsg = e_invarg;
X goto skip;
X }
X /*
X * in secure mode, setting of the secure option is not allowed
X */
X if (secure && (int *)varp == &p_secure)
X {
X errmsg = (char_u *)"not allowed here";
X goto skip;
X }
X if (prefix == 2)
X *(int *)(varp) ^= 1; /* invert it */
X else
X *(int *)(varp) = prefix;
X /* handle compatible option here */
X if ((int *)varp == &p_cp && p_cp)
X {
X p_bs = 0; /* normal backspace */
X p_ww = 0; /* backspace and space do not wrap */
X p_bk = 0; /* no backup file */
X#ifdef DIGRAPHS
X p_dg = 0; /* no digraphs */
X#endif /* DIGRAPHS */
X p_ek = 0; /* no ESC keys in insert mode */
X curbuf->b_p_et = 0; /* no expansion of tabs */
X p_gd = 0; /* /g is not default for :s */
X p_hi = 0; /* no history */
X p_im = 0; /* do not start in insert mode */
X p_js = 1; /* insert 2 spaces after period */
X curbuf->b_p_ml = 0; /* no modelines */
X p_more = 0; /* no -- more -- for listings */
X p_ru = 0; /* no ruler */
X p_ri = 0; /* no reverse insert */
X p_sj = 1; /* no scrolljump */
X p_sr = 0; /* do not round indent to shiftwidth */
X p_sc = 0; /* no showcommand */
X p_smd = 0; /* no showmode */
X curbuf->b_p_si = 0; /* no smartindent */
X p_sta = 0; /* no smarttab */
X p_ta = 0; /* no automatic textmode detection */
X curbuf->b_p_tw = 0; /* no automatic line wrap */
X p_to = 0; /* no tilde operator */
X p_ttimeout = 0; /* no terminal timeout */
X p_tr = 0; /* tag file names not relative */
X p_ul = 0; /* no multilevel undo */
X p_uc = 0; /* no autoscript file */
X p_wb = 0; /* no backup file */
X if (p_wc == TAB)
X p_wc = Ctrl('E'); /* normal use for TAB */
X p_ye = 0; /* no yank to end of line */
X }
X if ((int *)varp == &curbuf->b_p_bin && curbuf->b_p_bin) /* handle bin */
X {
X curbuf->b_p_tw = 0; /* no automatic line wrap */
X curbuf->b_p_wm = 0; /* no automatic line wrap */
X curbuf->b_p_tx = 0; /* no text mode */
X p_ta = 0; /* no text auto */
X curbuf->b_p_ml = 0; /* no modelines */
X curbuf->b_p_et = 0; /* no expandtab */
X }
X if ((int *)varp == &p_paste) /* handle paste here */


X {
X BUF *buf;
X

X if (p_paste && !oldpaste) /* paste switched on */
X {
X /* save and set options for all buffers */


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X {

X buf->b_p_tw_save = buf->b_p_tw;
X buf->b_p_wm_save = buf->b_p_wm;
X buf->b_p_ai_save = buf->b_p_ai;
X buf->b_p_si_save = buf->b_p_si;
X buf->b_p_tw = 0; /* textwidth is 0 */
X buf->b_p_wm = 0; /* wrapmargin is 0 */
X buf->b_p_ai = 0; /* no auto-indent */
X buf->b_p_si = 0; /* no smart-indent */
X }
X /* save and set global options */
X save_sm = p_sm;
X save_ru = p_ru;
X save_ri = p_ri;
X p_sm = 0; /* no showmatch */
X p_ru = 0; /* no ruler */
X p_ri = 0; /* no reverse insert */
X }
X else if (!p_paste && oldpaste) /* paste switched off */
X {
X /* restore options for all buffers */


X for (buf = firstbuf; buf != NULL; buf = buf->b_next)
X {

X buf->b_p_tw = buf->b_p_tw_save;
X buf->b_p_ai = buf->b_p_ai_save;
X buf->b_p_si = buf->b_p_si_save;
X }
X /* restore global options */
X p_sm = save_sm;
X p_ru = save_ru;
X p_ri = save_ri;
X }
X }
X if (!starting && ((int *)varp == &p_title ||
X (int *)varp == &p_icon))
X {
X if (*(int *)varp) /* Set window title NOW */
X maketitle();
X else /* Reset window title NOW */
X mch_restore_title((int *)varp == &p_title ? 1 : 2);
X }
X }
X else /* numeric or string */
X {
X if ((nextchar != '=' && nextchar != ':') || prefix != 1)
X {
X errmsg = e_invarg;
X goto skip;
X }
X if (flags & P_NUM) /* numeric */
X {
X *(long *)(varp) = atol((char *)arg + len + 1);
X
X if ((long *)varp == &p_wh)
X {
X if (p_wh < 0)
X {
X errmsg = e_positive;
X p_wh = 0;
X }
X /* Change window height NOW */
X if (p_wh && lastwin != firstwin)
X {
X win_equal(curwin, FALSE);


X must_redraw = CLEAR;
X }

X }
X if ((long *)varp == &p_ls)
X last_status(); /* (re)set last window status line */
X }
X else /* string */
X {
X arg += len + 1; /* jump to after the '=' */
X s = alloc((unsigned)(STRLEN(arg) + 1)); /* get a bit too much */
X if (s == NULL)
X break;
X if (flags & P_CHANGED)
X free(*(char **)(varp));
X *(char_u **)(varp) = s;
X /* copy the string */
X while (*arg && *arg != ' ')
X {
X if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */
X ++arg;
X *s++ = *arg++;
X }
X *s = NUL;
X param_expand(i, TRUE); /* expand environment variables and ~ */
X /*
X * options that need some action
X * to perform when changed (jw)
X */
X if (varp == (char_u *)&term_strings.t_name)
X set_term(term_strings.t_name);
X else if (istermparam(&params[i]))
X {
X ttest(FALSE);
X if (varp == (char_u *)&term_strings.t_tp)
X {
X outstr(T_TP);
X updateScreen(CLEAR);
X }
X }
X }
X }
X params[i].flags |= P_CHANGED;
X }
X
Xskip:
X /*
X * Check the bounds for numeric parameters here
X */
X if (Rows < 2)
X {
X Rows = 2;
X errmsg = (char_u *)"Need at least 2 lines";
X }
X /*
X * If the screenheight has been changed, assume it is the physical
X * screenheight.
X */
X if (oldRows != Rows)
X {
X screen_new_rows();
X#ifdef MSDOS
X set_window(); /* active window may have changed */
X#endif
X }
X
X if (curbuf->b_p_ts <= 0)
X {
X errmsg = e_positive;
X curbuf->b_p_ts = 8;
X }
X if (p_tm < 0)
X {
X errmsg = e_positive;
X p_tm = 0;
X }
X if (curwin->w_p_scroll <= 0 || curwin->w_p_scroll > curwin->w_height)
X {
X if (curwin->w_p_scroll != 0)
X errmsg = e_scroll;
X win_comp_scroll(curwin);
X }
X if (p_report < 0)
X {
X errmsg = e_positive;
X p_report = 1;
X }
X if (p_sj < 0 || p_sj >= Rows)
X {
X errmsg = e_scroll;
X p_sj = 1;
X }
X if (p_uc < 0)
X {
X errmsg = e_positive;
X p_uc = 100;
X }
X if (p_ch < 1)
X {
X errmsg = e_positive;
X p_ch = 1;
X }
X if (p_ut < 0)
X {
X errmsg = e_positive;
X p_ut = 2000;
X }
X if (p_ss < 0)
X {
X errmsg = e_positive;
X p_ss = 0;
X }
X if (errmsg)
X {
X STRCPY(IObuff, errmsg);
X STRCAT(IObuff, ": ");
X s = IObuff + STRLEN(IObuff);
X while (*startarg && !isspace(*startarg))
X *s++ = *startarg++;
X *s = NUL;
X did_show = TRUE; /* error message counts as show */
X ++no_wait_return; /* wait_return done below */
X emsg(IObuff);
X --no_wait_return;
X arg = startarg; /* skip to next argument */
X ++errcnt; /* count number of errors */
X }
X skiptospace(&arg); /* skip to next white space */
X skipspace(&arg); /* skip spaces */
X }
X
X /*
X * when 'updatecount' changes from zero to non-zero, open swap files
X */
X if (p_uc && !olduc)
X ml_open_files();
X
X if (p_ch != oldch) /* p_ch changed value */
X command_height();
X comp_col();
X
X /*
X * Update the screen in case we changed something like "tabstop" or
X * "lines" or "list" that will change its appearance.
X * If we messed up the screen by showing more than one line of param
X * values or an error message, call wait_return(), which will also
X * update the screen.
X */


X for (wp = firstwin; wp; wp = wp->w_next)

X wp->w_redr_status = TRUE; /* mark all status lines dirty */
X if (p_ea && !oldea)
X win_equal(curwin, FALSE);
X if (did_show && msg_check())


X {
X msg_outchar('\n');

X wait_return(TRUE);
X }
X else
X updateScreen(NOT_VALID);
X return (errcnt == 0 ? OK : FAIL);
X}
X
X/*
X * expand environment variable at the start of some string options


X */
X static void

Xparam_expand(i, dofree)
X int i;
X int dofree;
X{
X char_u *p;
X
X if ((params[i].flags & P_EXPAND) &&
X (p = *(char_u **)(params[i].var)) != NULL &&
X (*p == '$' || *p == '~'))
X {
X expand_env(*(char_u **)(params[i].var), IObuff, IOSIZE);
X p = strsave(IObuff);
X if (p)
X {
X if (dofree)
X free(*(char_u **)(params[i].var));
X *(char_u **)(params[i].var) = p;


X }
X }
X}
X
X/*

X * find index for option 'arg'
X * return -1 if not found
X */
X static int
Xfindparam(arg)
X char_u *arg;
X{
X int i;
X char *s;
X
X for (i = 0; (s = params[i].fullname) != NULL; i++)
X {
X if (STRCMP(arg, s) == 0) /* match full name */
X break;
X }
X if (s == NULL)
X {
X for (i = 0; params[i].fullname != NULL; i++)
X {
X s = params[i].shortname;
X if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
X break;
X s = NULL;
X }
X }
X if (s == NULL)
X i = -1;
X return i;
X}
X
X/*
X * mark option 'arg' changed
X */
X void
Xparamchanged(arg)
X char_u *arg;
X{
X int i;
X
X i = findparam(arg);


X if (i >= 0)

X params[i].flags |= P_CHANGED;
X}
X
X/*
X * if 'all' == 0: show changed parameters
X * if 'all' == 1: show all normal parameters
X * if 'all' == 2: show all terminal parameters


X */
X static void

Xshowparams(all)
X int all;
X{
X struct param *p;
X int col;
X int isterm;
X char_u *varp;
X struct param *(items[PARAM_COUNT]);
X int item_count;
X int run;
X int row, rows;
X int cols;
X int i;
X int len;
X
X#define INC 19
X
X gotocmdline(TRUE, NUL);
X msg_outstr((char_u *)"--- Parameters ---\n");
X
X /*
X * do the loop two times:
X * 1. display the short items (non-strings and short strings)
X * 2. display the long items (strings)
X */
X for (run = 1; run <= 2 && !got_int; ++run)
X {
X /*
X * collect the items in items[]
X */
X item_count = 0;
X for (p = &params[0]; p->fullname != NULL && !got_int; p++)
X {
X isterm = istermparam(p);
X varp = get_varp(p);
X if (varp && (
X (all == 2 && isterm) ||
X (all == 1 && !isterm) ||
X (all == 0 && (p->flags & P_CHANGED))))
X {
X if ((p->flags & P_STRING) && *(char_u **)(varp) != NULL)
X len = STRLEN(p->fullname) + strsize(*(char_u **)(varp));
X else
X len = 1; /* a non-string is assumed to fit always */
X if ((len <= INC - 4 && run == 1) || (len > INC - 4 && run == 2))
X items[item_count++] = p;
X }
X breakcheck();
X }
X /*
X * display the items
X */
X if (run == 1)
X {
X cols = Columns / INC;
X if (cols == 0)
X cols = 1;
X rows = (item_count + cols - 1) / cols;
X }
X else /* run == 2 */
X rows = item_count;
X for (row = 0; row < rows && !got_int; ++row)
X {
X col = 0;
X for (i = row; i < item_count; i += rows)
X {
X msg_pos(-1, col); /* make columns */
X showonep(items[i]);
X col += INC;
X }
X msg_outchar('\n'); /* scroll screen one line up */
X flushbuf();
X breakcheck();
X }
X }
X
X wait_return(FALSE);
X}
X
X/*
X * showonep: show the value of one option
X * must not be called with a hidden option!


X */
X static void

Xshowonep(p)
X struct param *p;
X{
X char_u buf[64];
X char_u *varp;
X
X varp = get_varp(p);
X
X if ((p->flags & P_BOOL) && !*(int *)(varp))
X msg_outstr((char_u *)"no");
X else
X msg_outstr((char_u *)" ");
X msg_outstr((char_u *)p->fullname);
X if (!(p->flags & P_BOOL))
X {
X msg_outchar('=');
X if (p->flags & P_NUM)
X {
X sprintf((char *)buf, "%ld", *(long *)(varp));
X msg_outstr(buf);
X }
X else if (*(char_u **)(varp) != NULL)
X {
X if (p->flags & P_EXPAND)
X {
X home_replace(*(char_u **)(varp), NameBuff, MAXPATHL);
X msg_outtrans(NameBuff, -1);
X }
X else
X msg_outtrans(*(char_u **)(varp), -1);


X }
X }
X}
X
X/*

X * Write modified parameters as set command to a file.
X * Return FAIL on error, OK otherwise.
X */
X int
Xmakeset(fd)
X FILE *fd;
X{
X struct param *p;
X char_u *s;
X int e;
X char_u *varp;
X
X for (p = &params[0]; p->fullname != NULL; p++)
X if ((p->flags & P_CHANGED) && p->var)
X {
X varp = get_varp(p);
X if (p->flags & P_BOOL)
X fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no", p->fullname);
X else if (p->flags & P_NUM)
X fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
X else
X {
X fprintf(fd, "set %s=", p->fullname);
X s = *(char_u **)(varp);
X /* some characters hav to be escaped with CTRL-V or backslash */
X if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
X return FAIL;
X }
X#ifdef MSDOS
X putc('\r', fd);
X#endif
X /*
X * Only check error for this putc, should catch at least
X * the "disk full" situation.
X */
X e = putc('\n', fd);
X if (e < 0)
X return FAIL;
X }


X return OK;
X}
X
X/*

X * Clear all the terminal parameters.
X * If the parameter has been changed, free the allocated memory.
X * Reset the "changed" flag, so the new value will not be freed.
X */
X void
Xclear_termparam()
X{
X struct param *p;
X
X for (p = &params[0]; p->fullname != NULL; p++)
X if (istermparam(p)) /* terminal parameters must never be hidden */
X {
X if (p->flags & P_CHANGED)
X free(*(char_u **)(p->var));
X *(char_u **)(p->var) = NULL;
X p->flags &= ~P_CHANGED;
X }
X}
X
X/*
X * return TRUE if 'p' starts with 't_'


X */
X static int

Xistermparam(p)
X struct param *p;
X{
X return (p->fullname[0] == 't' && p->fullname[1] == '_');
X}
X
X/*
X * Compute columns for ruler and shown command. 'sc_col' is also used to
X * decide what the maximum length of a message on the status line can be.
X * If there is a status line for the last window, 'sc_col' is independent
X * of 'ru_col'.
X */
X
X#define COL_SHOWCMD 10 /* columns needed by shown command */
X#define COL_RULER 17 /* columns needed by ruler */
X
X void
Xcomp_col()
X{
X int last_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
X
X sc_col = 0;
X ru_col = 0;
X if (p_ru)
X {
X ru_col = COL_RULER + 1;
X /* no last status line, adjust sc_col */
X if (!last_status)
X sc_col = ru_col;
X }
X if (p_sc)
X {
X sc_col += COL_SHOWCMD;
X if (!p_ru || last_status) /* no need for separating space */
X ++sc_col;
X }
X sc_col = Columns - sc_col;
X ru_col = Columns - ru_col;
X if (sc_col <= 0) /* screen too narrow, will become a mess */
X sc_col = 1;
X if (ru_col <= 0)
X ru_col = 1;
X}
X
X static char_u *
Xget_varp(p)
X struct param *p;
X{
X if (!(p->flags & P_IND))
X return p->var;
X
X switch ((long)(p->var))
X {
X case PV_LIST: return (char_u *)&(curwin->w_p_list);
X case PV_NU: return (char_u *)&(curwin->w_p_nu);
X case PV_SCROLL: return (char_u *)&(curwin->w_p_scroll);
X case PV_WRAP: return (char_u *)&(curwin->w_p_wrap);
X
X case PV_AI: return (char_u *)&(curbuf->b_p_ai);
X case PV_BIN: return (char_u *)&(curbuf->b_p_bin);
X case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
X case PV_ET: return (char_u *)&(curbuf->b_p_et);
X case PV_ML: return (char_u *)&(curbuf->b_p_ml);
X case PV_RO: return (char_u *)&(curbuf->b_p_ro);
X case PV_SI: return (char_u *)&(curbuf->b_p_si);
X case PV_SN: return (char_u *)&(curbuf->b_p_sn);
X case PV_SW: return (char_u *)&(curbuf->b_p_sw);
X case PV_TS: return (char_u *)&(curbuf->b_p_ts);
X case PV_TW: return (char_u *)&(curbuf->b_p_tw);
X case PV_TX: return (char_u *)&(curbuf->b_p_tx);
X case PV_WM: return (char_u *)&(curbuf->b_p_wm);
X default: EMSG("get_varp ERROR");
X }
X /* always return a valid pointer to avoid a crash! */
X return (char_u *)&(curbuf->b_p_wm);
X}
X
X/*
X * Copy options from one window to another.
X * Used when creating a new window.
X */
X void
Xwin_copy_options(wp_from, wp_to)
X WIN *wp_from;
X WIN *wp_to;
X{
X wp_to->w_p_list = wp_from->w_p_list;
X wp_to->w_p_nu = wp_from->w_p_nu;
X wp_to->w_p_scroll = wp_from->w_p_scroll;
X wp_to->w_p_wrap = wp_from->w_p_wrap;
X}
X
X/*
X * Copy options from one buffer to another.
X * Used when creating a new buffer.
X */
X void
Xbuf_copy_options(bp_from, bp_to)
X BUF *bp_from;
X BUF *bp_to;
X{
X bp_to->b_p_ai = bp_from->b_p_ai;
X bp_to->b_p_si = bp_from->b_p_si;
X bp_to->b_p_ro = bp_from->b_p_ro;
X bp_to->b_p_sw = bp_from->b_p_sw;
X bp_to->b_p_ts = bp_from->b_p_ts;
X bp_to->b_p_tw = bp_from->b_p_tw;
X bp_to->b_p_wm = bp_from->b_p_wm;
X bp_to->b_p_bin = bp_from->b_p_bin;
X bp_to->b_p_et = bp_from->b_p_et;
X bp_to->b_p_ml = bp_from->b_p_ml;
X bp_to->b_p_sn = bp_from->b_p_sn;
X bp_to->b_p_tx = bp_from->b_p_tx;
X}
X
X#ifdef WEBB_COMPLETE
X void
Xset_context_in_set_cmd(arg)
X char_u *arg;
X{
X int nextchar;
X int flags;
X int i;
X char_u *p;
X char_u *after_blank = NULL;
X
X expand_context = EXPAND_SETTINGS;


X if (*arg == NUL)
X {

X expand_pattern = arg;
X return;
X }
X p = arg + STRLEN(arg) - 1;
X if (*p == ' ' && *(p - 1) != '\\')
X {
X expand_pattern = p + 1;
X return;
X }
X while (p != arg && (*p != ' ' || *(p - 1) == '\\'))
X {
X if (*p == ' ' && after_blank == NULL)
X after_blank = p + 1;
X p--;
X }
X if (p != arg)
X p++;
X if (STRNCMP(p, "no", (size_t) 2) == 0)
X {
X expand_context = EXPAND_BOOL_SETTINGS;
X p += 2;
X }
X if (STRNCMP(p, "inv", (size_t) 3) == 0)
X {
X expand_context = EXPAND_BOOL_SETTINGS;
X p += 3;
X }
X expand_pattern = arg = p;
X while (isalnum(*p) || *p == '_' || *p == '*') /* Allow * as wildcard */
X p++;


X if (*p == NUL)

X return;
X nextchar = *p;
X *p = NUL;
X i = findparam(arg);
X *p = nextchar;
X if (i == -1 || params[i].var == NULL)


X {
X expand_context = EXPAND_NOTHING;

X return;
X }
X flags = params[i].flags;
X if (flags & P_BOOL)


X {
X expand_context = EXPAND_NOTHING;

X return;
X }
X if ((nextchar != '=' && nextchar != ':')
X || expand_context == EXPAND_BOOL_SETTINGS)


X {
X expand_context = EXPAND_UNSUCCESSFUL;

X return;


X }
X expand_context = EXPAND_NOTHING;

X if (flags & P_NUM)
X return;
X if (after_blank != NULL)
X expand_pattern = after_blank;
X else
X expand_pattern = p + 1;
X if (flags & P_EXPAND)
X {
X p = params[i].var;
X if (
X#ifdef UNIX
X p == (char_u *)&p_bdir ||
X#endif
X p == (char_u *)&p_dir || p == (char_u *)&p_path)
X expand_context = EXPAND_DIRECTORIES;
X else
X expand_context = EXPAND_FILES;


X }
X return;
X}
X

X int
XExpandSettings(prog, num_file, file)
X regexp *prog;


X int *num_file;
X char_u ***file;

X{
X int num_normal = 0; /* Number of matching non-term-code settings */
X int num_term = 0; /* Number of matching terminal code settings */
X int i;
X int match;
X int count;
X char_u *str;
X
X if (expand_context != EXPAND_BOOL_SETTINGS)
X {
X if (regexec(prog, (char_u *)"all", TRUE))
X num_normal++;
X if (regexec(prog, (char_u *)"termcap", TRUE))
X num_normal++;
X }
X for (i = 0; (str = (char_u *)params[i].fullname) != NULL; i++)
X {
X if (params[i].var == NULL)
X continue;
X if (expand_context == EXPAND_BOOL_SETTINGS
X && !(params[i].flags & P_BOOL))
X continue;
X if (istermparam(&params[i]) && num_normal > 0)
X continue;
X match = FALSE;
X if (regexec(prog, str, TRUE))
X match = TRUE;
X else if (params[i].shortname != NULL
X && regexec(prog, (char_u *)params[i].shortname, TRUE))
X match = TRUE;
X if (match)
X {
X if (istermparam(&params[i]))
X num_term++;
X else
X num_normal++;
X }
X }
X if (num_normal > 0)
X *num_file = num_normal;
X else if (num_term > 0)
X *num_file = num_term;
X else
X return OK;
X *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));


X if (*file == NULL)

X {
X *file = (char_u **)"";

X return FAIL;
X }
X count = 0;
X if (expand_context != EXPAND_BOOL_SETTINGS)
X {
X if (regexec(prog, (char_u *)"all", TRUE))
X (*file)[count++] = strsave((char_u *)"all");
X if (regexec(prog, (char_u *)"termcap", TRUE))
X (*file)[count++] = strsave((char_u *)"termcap");
X }
X for (i = 0; (str = (char_u *)params[i].fullname) != NULL; i++)
X {
X if (params[i].var == NULL)
X continue;
X if (expand_context == EXPAND_BOOL_SETTINGS
X && !(params[i].flags & P_BOOL))
X continue;
X if (istermparam(&params[i]) && num_normal > 0)
X continue;
X match = FALSE;
X if (regexec(prog, str, TRUE))
X match = TRUE;
X else if (params[i].shortname != NULL
X && regexec(prog, (char_u *)params[i].shortname, TRUE))
X match = TRUE;
X if (match)
X (*file)[count++] = strsave(str);


X }
X return OK;
X}

X#endif /* WEBB_COMPLETE */
END_OF_FILE
if test 35665 -ne `wc -c <'vim/src/param.c'`; then
echo shar: \"'vim/src/param.c'\" unpacked with wrong size!
fi
# end of 'vim/src/param.c'
fi
if test -f 'vim/src/tags' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/tags'\"
else
echo shar: Extracting \"'vim/src/tags'\" \(29029 characters\)
sed "s/^X//" >'vim/src/tags' <<'END_OF_FILE'
XAppendCharToRedobuff getchar.c /^AppendCharToRedobuff(c)$/
XAppendNumberToRedobuff getchar.c /^AppendNumberToRedobuff(n)$/
XAppendToRedobuff getchar.c /^AppendToRedobuff(s)$/
XCHECK memfile.c /^#define CHECK(c, s) if (c) printf(s)$/
XChk_Abort amiga.c /^Chk_Abort()$/
XCtrl ascii.h /^#define Ctrl(x) ((x) & 0x1f)$/
XDoOneCmd cmdline.c /^DoOneCmd(buff)$/
XEMSG vim.h /^#define EMSG(s) emsg((char_u *)(s))$/
XEMSG2 vim.h /^#define EMSG2(s, p) emsg2((char_u *)(s), (char_u/
XEMSG_RETURN regexp.c /^#define EMSG_RETURN(m) { emsg(m); return NULL; }$/
XEXTERN param.h /^EXTERN char_u *p_ep INIT(= (char_u *)"indent"); \/*/
XExpandFromContext cmdline.c /^ExpandFromContext(pat, num_file, file, files_only,/
XExpandOne cmdline.c /^ExpandOne(str, list_notfound, mode)$/
XExpandSettings param.c /^ExpandSettings(prog, num_file, file)$/
XExpandTags tag.c /^ExpandTags(prog, num_file, file)$/
XExpandWildCards amiga.c /^ExpandWildCards(num_pat, pat, num_file, file, file/
XFreeWild amiga.c /^FreeWild(num, file)$/
XFullName amiga.c /^FullName(fname, buf, len)$/
XGetChars amiga.c /^GetChars(buf, maxlen, time)$/
XINIT normal.c /^#define INIT(x) x$/
XISSPECIAL edit.c /^#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL)$/
XMEMHASH structs.h /^#define MEMHASH(nr) ((nr) & (MEMHASHSIZE - 1))$/
XML_SIMPLE memline.c /^#define ML_SIMPLE(x) (x & 0x10) \/* DEL, INS or FIN/
XMP amiga.c /^#define MP(xx) ((struct MsgPort *)((struct FileHan/
XMSG vim.h /^#define MSG(s) msg((char_u *)(s))$/
XMaddcr addcr.c /^main(argc, argv) $/
XMagic regexp.c /^#define Magic(x) ((x)|('\\\\'<<8))$/
XMeta ascii.h /^#define Meta(x) ((x) | 0x80)$/
XMmain main.c /^main(argc, argv)$/
XMmkcmdtab mkcmdtab.c /^main(argc, argv)$/
XNEXT regexp.c /^#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&/
XOP regexp.c /^#define OP(p) (*(p))$/
XOPERAND regexp.c /^#define OPERAND(p) ((p) + 3)$/
XOUTSTR vim.h /^#define OUTSTR(s) outstr((char_u *)(s))$/
XOUTSTRN vim.h /^#define OUTSTRN(s) outstrn((char_u *)(s))$/
XOpencmd misccmds.c /^Opencmd(dir, redraw, delspaces)$/
XPERR winnt.c /^#define PERR(bSuccess, api) {if (!(bSuccess)) perr/
XPeekChr regexp.c /^#define PeekChr() curchr \/* shortcut only when las/
XRead archie.c /^Read(buf, maxlen)$/
XRealWaitForChar archie.c /^RealWaitForChar(ticks)$/
XResetRedobuff getchar.c /^ResetRedobuff()$/
XSTRCAT vim.h /^#define STRCAT(d, s) strcat((char *)(d), (char *)/
XSTRCHR vim.h /^#define STRCHR(s, c) (char_u *)strchr((char *)(s)/
XSTRCMP vim.h /^#define STRCMP(d, s) strcmp((char *)(d), (char *)/
XSTRCPY vim.h /^#define STRCPY(d, s) strcpy((char *)(d), (char *)/
XSTRLEN vim.h /^#define STRLEN(s) strlen((char *)(s))$/
XSTRNCMP vim.h /^#define STRNCMP(d, s, n) strncmp((char *)(d), (cha/
XSTRNCPY vim.h /^#define STRNCPY(d, s, n) strncpy((char *)(d), (cha/
XSTRRCHR vim.h /^#define STRRCHR(s, c) (char_u *)strrchr((char *)(/
XTGETSTR term.c /^# define TGETSTR(s, p) (char_u *)tgetstr((s), (cha/
XTO_LOWER macros.h /^# define TO_LOWER(c) (isupper(c) ? tolower(c) : (c/
XTO_UPPER macros.h /^# define TO_UPPER(c) (islower(c) ? toupper(c) : (c/
XUCHARAT regexp.c /^#define UCHARAT(p) ((int)*(unsigned char *)(p))$/
XUNCHANGED vim.h /^#define UNCHANGED(buf) unset_Changed(buf)$/
XWaitForChar archie.c /^WaitForChar(ticks)$/
X__ARGS regsub.c /^# define __ARGS(a) a$/
X__PARMS vim.h /^# define __PARMS(x) x$/
X_addfmt termlib.c /^_addfmt(buf, fmt, val) \/* add val to b/
X_find termlib.c /^_find(s, set) \/* finds next c in s that's a memb/
X_match termlib.c /^_match(s1, s2) \/* returns length o/
Xadd_buff getchar.c /^add_buff(buf, s)$/
Xadd_char_buff getchar.c /^add_char_buff(buf, c)$/
Xadd_num_buff getchar.c /^add_num_buff(buf, n)$/
Xaddfile msdos.c /^addfile(fl, f, isdir)$/
Xaddstar cmdline.c /^addstar(fname, len)$/
Xadjust_cursor linefunc.c /^adjust_cursor()$/
Xalloc alloc.c /^alloc(size)$/
Xask_yesno misccmds.c /^ask_yesno(str)$/
Xautowrite cmdline.c /^autowrite(buf)$/
Xautowrite_all cmdline.c /^autowrite_all()$/
Xbck_word search.c /^bck_word(count, type)$/
Xbeep misccmds.c /^beep()$/
Xbeginline edit.c /^beginline(flag)$/
Xblock_prep ops.c /^block_prep(lnum, delete)$/
Xbreakcheck amiga.c /^breakcheck()$/
Xbsdmemset alloc.c /^bsdmemset(ptr, c, size)$/
Xbuf_clear buffer.c /^buf_clear(buf)$/
Xbuf_copy_options param.c /^buf_copy_options(bp_from, bp_to)$/
Xbuf_freeall buffer.c /^buf_freeall(buf)$/
Xbuf_modname fileio.c /^buf_modname(buf, fname, ext)$/
Xbuf_write fileio.c /^buf_write(buf, fname, sfname, start, end, append, /
Xbuf_write_all cmdline.c /^buf_write_all(buf)$/
Xbufempty macros.h /^#define bufempty() (curbuf->b_ml.ml_flags & ML_EMP/
Xbuflist_add buffer.c /^buflist_add(fname)$/
Xbuflist_altlnum buffer.c /^buflist_altlnum()$/
Xbuflist_findlnum buffer.c /^buflist_findlnum(buf)$/
Xbuflist_findname buffer.c /^buflist_findname(fname)$/
Xbuflist_findnr buffer.c /^buflist_findnr(nr)$/
Xbuflist_getfile buffer.c /^buflist_getfile(n, lnum, setpm)$/
Xbuflist_getlnum buffer.c /^buflist_getlnum()$/
Xbuflist_list buffer.c /^buflist_list()$/
Xbuflist_name_nr buffer.c /^buflist_name_nr(fnum, fname, lnum)$/
Xbuflist_new buffer.c /^buflist_new(fname, sfname, lnum, use_curbuf)$/
Xbuflist_nr2name buffer.c /^buflist_nr2name(n)$/
Xbuflist_setlnum buffer.c /^buflist_setlnum(buf, lnum)$/
Xbzero unix.c /^# define bzero(a, b) memset((a), 0, (b))$/
Xcall_shell amiga.c /^call_shell(cmd, filter, cooked)$/
Xcatch_cbrk msdos.c /^catch_cbrk()$/
Xcatch_cint msdos.c /^catch_cint(bp, di, si, ds, es, dx, cx, bx, ax)$/
Xcbrk_handler msdos.c /^cbrk_handler()$/
Xccheck_abbr cmdline.c /^ccheck_abbr(c)$/
Xchange_drive msdos.c /^change_drive(drive)$/
Xchange_warning misccmds.c /^change_warning()$/
Xcharsize charset.c /^charsize(c)$/
Xchartabsize charset.c /^chartabsize(c, col)$/
Xcheck_abbr getchar.c /^check_abbr(c, ptr, col, mincol)$/
Xcheck_changed cmdline.c /^check_changed(buf, checkaw, mult_win)$/
Xcheck_changed_any cmdline.c /^check_changed_any(checkaw)$/
Xcheck_cursor screen.c /^check_cursor()$/
Xcheck_fname cmdline.c /^check_fname()$/
Xcheck_more cmdline.c /^check_more(message)$/
Xcheck_readonly cmdline.c /^check_readonly()$/
Xcheck_status misccmds.c /^check_status(buf)$/
Xcheck_termcode term.c /^check_termcode(buf)$/
Xcheck_win amiga.c /^check_win(argc, argv)$/
Xcheck_winsize term.c /^check_winsize()$/
Xcheckclearop normal.c /^checkclearop()$/
Xcheckclearopq normal.c /^checkclearopq()$/
Xchecknextcomm cmdline.c /^checknextcomm(arg)$/
Xcheckpcmark mark.c /^checkpcmark()$/
Xchk_mline fileio.c /^chk_mline(lnum)$/
Xclear_termparam param.c /^clear_termparam()$/
Xclearopbeep normal.c /^clearopbeep()$/
Xclose_buffer buffer.c /^close_buffer(buf, free_buf, remove)$/
Xclose_others window.c /^close_others(message)$/
Xclose_window window.c /^close_window(free_buf)$/
Xclrallmarks mark.c /^clrallmarks(buf)$/
Xclreol winnt.c /^clreol()$/
Xclrscr winnt.c /^clrscr()$/
Xcls search.c /^cls()$/
Xcoladvance linefunc.c /^coladvance(wcol)$/
Xcommand_height window.c /^command_height()$/
Xcomp_Botline screen.c /^comp_Botline(wp)$/
Xcomp_Botline_all screen.c /^comp_Botline_all()$/
Xcomp_col param.c /^comp_col()$/
Xcompute_cmdrow cmdline.c /^compute_cmdrow()$/
Xcopy_redo getchar.c /^copy_redo()$/
Xcopy_spaces alloc.c /^copy_spaces(ptr, count)$/
Xcstrchr regexp.c /^cstrchr(s, c)$/
Xcstrncmp regexp.c /^cstrncmp(s1, s2, n)$/
Xcurs_columns screen.c /^curs_columns(scroll)$/
Xcursor_off term.c /^cursor_off()$/
Xcursor_on term.c /^cursor_on()$/
Xcursor_visible winnt.c /^cursor_visible(int visible)$/
Xcursorcmd cmdline.c /^cursorcmd()$/
Xcursupdate screen.c /^cursupdate()$/
Xdec linefunc.c /^dec(lp)$/
Xdec_cursor linefunc.c /^dec_cursor()$/
Xdecl linefunc.c /^decl(lp)$/
Xdel_spaces alloc.c /^del_spaces(ptr)$/
Xdel_typestr getchar.c /^del_typestr(len)$/
Xdelay winnt.c /^delay(x)$/
Xdelchar misccmds.c /^delchar(fixpos)$/
Xdelline winnt.c /^delline(int count)$/
Xdellines misccmds.c /^dellines(nlines, dowindow, undo)$/
Xdelmode screen.c /^delmode()$/
Xdirname archie.c /^dirname(buf, len)$/
Xdis_msg ops.c /^dis_msg(p, skip_esc)$/
Xdo_Copy regsub.c /^do_Copy(d, c)$/
Xdo_Lower regsub.c /^do_Lower(d, c)$/
Xdo_Upper regsub.c /^do_Upper(d, c)$/
Xdo_align cmdcmds.c /^do_align(start, end, width, type)$/
Xdo_arg_all buffer.c /^do_arg_all()$/
Xdo_buffer buffer.c /^do_buffer(action, start, dir, count, forceit)$/
Xdo_buffer_all buffer.c /^do_buffer_all(all)$/
Xdo_copy cmdcmds.c /^do_copy(line1, line2, n)$/
Xdo_lower regsub.c /^do_lower(d, c)$/
Xdo_mlines fileio.c /^do_mlines()$/
Xdo_move cmdcmds.c /^do_move(line1, line2, n)$/
Xdo_upper regsub.c /^do_upper(d, c)$/
Xdo_window window.c /^do_window(nchar, Prenum)$/
Xdoaddsub ops.c /^doaddsub(command, Prenum1)$/
Xdoarglist cmdline.c /^doarglist(str)$/
Xdobang cmdcmds.c /^dobang(addr_count, line1, line2, forceit, arg)$/
Xdochange ops.c /^dochange()$/
Xdocmdline cmdline.c /^docmdline(cmdline)$/
Xdodelete ops.c /^dodelete()$/
Xdodigraph digraph.c /^dodigraph(c)$/
Xdodis ops.c /^dodis()$/
Xdodojoin ops.c /^dodojoin(count, insert_space, redraw)$/
Xdoecmd cmdline.c /^doecmd(fname, sfname, command, hide, newlnum)$/
Xdoexecbuf ops.c /^doexecbuf(c)$/
Xdofilter cmdcmds.c /^dofilter(line1, line2, buff, do_in, do_out)$/
Xdoformat ops.c /^doformat()$/
Xdoglob csearch.c /^doglob(type, lp, up, cmd)$/
Xdojoin ops.c /^dojoin(insert_space, redraw)$/
Xdojumps mark.c /^dojumps()$/
Xdomake cmdline.c /^domake(arg)$/
Xdomap getchar.c /^domap(maptype, keys, mode)$/
Xdomarks mark.c /^domarks()$/
Xdoput ops.c /^doput(dir, count, fix_indent)$/
Xdorecord ops.c /^dorecord(c)$/
Xdos_packet amiga.c /^dos_packet(pid, action, arg)$/
Xdosearch search.c /^dosearch(dirc, str, reverse, count, echo, message)/
Xdoset param.c /^doset(arg)$/
Xdoshell cmdcmds.c /^doshell(cmd)$/
Xdoshift ops.c /^doshift(op, curs_top, amount)$/
Xdosource cmdline.c /^dosource(fname)$/
Xdosub csearch.c /^dosub(lp, up, cmd, nextcommand, use_old)$/
Xdotag tag.c /^dotag(tag, type, count)$/
Xdotags tag.c /^dotags()$/
Xdotilde ops.c /^dotilde()$/
Xdowrite cmdline.c /^dowrite(fname, append)$/
Xdoyank ops.c /^doyank(deleting)$/
Xecheck_abbr edit.c /^echeck_abbr(c)$/
Xedit edit.c /^edit(count)$/
Xemsg message.c /^emsg(s)$/
Xemsg2 message.c /^emsg2(s, a1)$/
Xend_word search.c /^end_word(count, type, stop)$/
Xenter_buffer buffer.c /^enter_buffer(buf)$/
Xequal macros.h /^#define equal(a, b) (((a).lnum == (b).lnum) && ((a/
Xexpand_env misccmds.c /^expand_env(src, dst, dstlen)$/
Xexpandpath msdos.c /^expandpath(fl, path, fonly, donly, notf)$/
Xfile_name_at_cursor window.c /^file_name_at_cursor()$/
Xfileinfo buffer.c /^fileinfo(fullname)$/
Xfilemess fileio.c /^filemess(name, s)$/
Xfill_inbuf archie.c /^fill_inbuf()$/
Xfindfunc search.c /^findfunc(dir, what, count)$/
Xfindpar search.c /^findpar(dir, count, what, both)$/
Xfindparam param.c /^findparam(arg)$/
Xfindsent search.c /^findsent(dir, count)$/
Xfindswapname memline.c /^findswapname(buf, second_try)$/
Xfindtag tag.c /^findtag(tag)$/
Xfix_fname buffer.c /^fix_fname(fname)$/
Xflush_buffers getchar.c /^flush_buffers(typeahead)$/
Xflushbuf term.c /^flushbuf()$/
Xfm_getname mark.c /^fm_getname(fmark)$/
Xfname_case amiga.c /^fname_case(name)$/
Xfname_expand buffer.c /^fname_expand(fname, sfname)$/
Xfnamecmp vim.h /^# define fnamecmp(x, y) stricmp((char *)(x), (char/
Xfree vim.h /^# define free(x) nofreeNULL(x)$/
Xfree_buff getchar.c /^free_buff(buf)$/
Xfree_yank ops.c /^free_yank(n)$/
Xfree_yank_all ops.c /^free_yank_all()$/
Xfreefiles amiga.c /^freefiles()$/
Xfstatfs memfile.c /^# define fstatfs(fd, buf, len, nul) fstat((fd), (b/
Xfullpathcmp misccmds.c /^fullpathcmp(s1, s2)$/
Xfwd_word search.c /^fwd_word(count, type, eol)$/
Xgchar misccmds.c /^gchar(pos)$/
Xgchar_cursor misccmds.c /^gchar_cursor()$/
Xget_address cmdline.c /^get_address(ptr)$/
Xget_bufcont getchar.c /^get_bufcont(buffer, dozero)$/
Xget_fib amiga.c /^get_fib(fname)$/
Xget_indent misccmds.c /^get_indent()$/
Xget_inserted getchar.c /^get_inserted()$/
Xget_last_insert edit.c /^get_last_insert()$/
Xget_literal edit.c /^get_literal(nextc)$/
Xget_recorded getchar.c /^get_recorded()$/
Xget_varp param.c /^get_varp(p)$/
Xget_x11_icon unix.c /^get_x11_icon()$/
Xget_x11_title unix.c /^get_x11_title()$/
Xget_x11_windis unix.c /^get_x11_windis()$/
Xget_yank_buffer ops.c /^get_yank_buffer(writing)$/
Xgetargcmd cmdline.c /^getargcmd(argp)$/
Xgetchr regexp.c /^getchr()$/
Xgetcmdline cmdline.c /^getcmdline(firstc, buff)$/
Xgetdigits misccmds.c /^getdigits(pp)$/
Xgetdigraph digraph.c /^getdigraph(char1, char2, meta)$/
Xgetent termlib.c /^getent(tbuf, term, termcap, buflen)$/
Xgetfile cmdline.c /^getfile(fname, sfname, setpm, lnum)$/
Xgetlinecol term.c /^getlinecol()$/
Xgetmark mark.c /^getmark(c, changefile)$/
Xgetout main.c /^getout(r)$/
Xgetperm amiga.c /^getperm(name)$/
Xgettail misccmds.c /^gettail(fname)$/
Xgetvcol screen.c /^getvcol(wp, pos, type)$/
Xgotchars getchar.c /^gotchars(s, len)$/
Xgotocmdend cmdline.c /^gotocmdend()$/
Xgotocmdline cmdline.c /^gotocmdline(clr, firstc)$/
Xgotoxy winnt.c /^gotoxy(x, y)$/
Xhandler_routine winnt.c /^BOOL WINAPI handler_routine(DWORD dwCtrlType)$/
Xhas_wildcard amiga.c /^has_wildcard(p)$/
Xhave_wildcard archie.c /^have_wildcard(num, file)$/
Xhelp help.c /^help()$/
Xhome_replace misccmds.c /^home_replace(src, dst, dstlen)$/
Xinc linefunc.c /^inc(lp)$/
Xinc_cursor linefunc.c /^inc_cursor()$/
Xinchar term.c /^inchar(buf, maxlen, time)$/
Xincl linefunc.c /^incl(lp)$/
Xinindent misccmds.c /^inindent()$/
Xinit_typestr getchar.c /^init_typestr()$/
Xinit_yank ops.c /^init_yank()$/
Xinitchr regexp.c /^initchr(str)$/
Xinmacro search.c /^inmacro(opt, s)$/
Xins_typestr getchar.c /^ins_typestr(str, noremap)$/
Xinschar misccmds.c /^inschar(c)$/
Xinsertbuf ops.c /^insertbuf(c)$/
Xinsertchar edit.c /^insertchar(c)$/
Xinsfile amiga.c /^insfile(name, isdir)$/
Xinsline winnt.c /^insline(int count)$/
Xinsstr misccmds.c /^insstr(s)$/
XisFullName amiga.c /^isFullName(fname)$/
Xis_yank_buffer ops.c /^is_yank_buffer(c, write)$/
Xisdir amiga.c /^isdir(name)$/
Xisidchar charset.c /^isidchar(c)$/
Xiskeypad winnt.c /^#define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEY/
Xismult regexp.c /^ismult(c)$/
Xispathsep misccmds.c /^ispathsep(c)$/
Xisspace vim.h /^# define isspace(x) (((x) >= 9 && (x) <= 13) || (/
Xistermparam param.c /^istermparam(p)$/
Xiswhite vim.h /^#define iswhite(x) ((x) == ' ' || (x) == '\\t')$/
Xkbhit winnt.c /^int kbhit()$/
Xlalloc alloc.c /^lalloc(size, message)$/
Xlast_status window.c /^last_status()$/
Xlineempty macros.h /^#define lineempty(p) (*ml_get(p) == NUL)$/
Xlistdigraphs digraph.c /^listdigraphs()$/
Xlock2name amiga.c /^lock2name(lock, buf, len)$/
Xlt macros.h /^#define lt(a, b) (((a).lnum != (b).lnum) \\$/
Xltoreq macros.h /^#define ltoreq(a, b) (((a).lnum != (b).lnum) \\$/
Xmake_windows window.c /^make_windows(count)$/
Xmakemap getchar.c /^makemap(fd)$/
Xmakeset param.c /^makeset(fd)$/
Xmakeswapname memline.c /^makeswapname(buf, second_try)$/
Xmaketitle buffer.c /^maketitle()$/
Xmark_adjust mark.c /^mark_adjust(line1, line2, inc)$/
Xmch_avail_mem amiga.c /^mch_avail_mem(special)$/
Xmch_char_avail amiga.c /^mch_char_avail()$/
Xmch_get_winsize amiga.c /^mch_get_winsize()$/
Xmch_restore_title amiga.c /^mch_restore_title(which)$/
Xmch_screenmode amiga.c /^mch_screenmode(arg)$/
Xmch_set_winsize amiga.c /^mch_set_winsize()$/
Xmch_settitle amiga.c /^mch_settitle(title, icon)$/
Xmch_settmode amiga.c /^mch_settmode(raw)$/
Xmch_suspend amiga.c /^mch_suspend()$/
Xmch_windexit amiga.c /^mch_windexit(r)$/
Xmch_windinit amiga.c /^mch_windinit()$/
Xmch_write amiga.c /^mch_write(p, len)$/
Xmemmove alloc.c /^memmove(desti, source, len)$/
Xmemset unix.h /^# define memset(ptr, c, size) bsdmemset((ptr), (c)/
Xmf_alloc_bhdr memfile.c /^mf_alloc_bhdr(mfp, page_count)$/
Xmf_close memfile.c /^mf_close(mfp, delete)$/
Xmf_do_open memfile.c /^mf_do_open(mfp, fname, new)$/
Xmf_find_hash memfile.c /^mf_find_hash(mfp, nr)$/
Xmf_free memfile.c /^mf_free(mfp, hp)$/
Xmf_free_bhdr memfile.c /^mf_free_bhdr(hp)$/
Xmf_fullname memfile.c /^mf_fullname(mfp)$/
Xmf_get memfile.c /^mf_get(mfp, nr, page_count)$/
Xmf_ins_free memfile.c /^mf_ins_free(mfp, hp)$/
Xmf_ins_hash memfile.c /^mf_ins_hash(mfp, hp)$/
Xmf_ins_used memfile.c /^mf_ins_used(mfp, hp)$/
Xmf_need_trans memfile.c /^mf_need_trans(mfp)$/
Xmf_new memfile.c /^mf_new(mfp, negative, page_count)$/
Xmf_open memfile.c /^mf_open(fname, new, fail_nofile)$/
Xmf_open_file memfile.c /^mf_open_file(mfp, fname)$/
Xmf_put memfile.c /^mf_put(mfp, hp, dirty, infile)$/
Xmf_read memfile.c /^mf_read(mfp, hp)$/
Xmf_release memfile.c /^mf_release(mfp, page_count)$/
Xmf_release_all memfile.c /^mf_release_all()$/
Xmf_rem_free memfile.c /^mf_rem_free(mfp)$/
Xmf_rem_hash memfile.c /^mf_rem_hash(mfp, hp)$/
Xmf_rem_used memfile.c /^mf_rem_used(mfp, hp)$/
Xmf_statistics memfile.c /^mf_statistics()$/
Xmf_sync memfile.c /^mf_sync(mfp, all, check_char)$/
Xmf_trans_add memfile.c /^mf_trans_add(mfp, hp)$/
Xmf_trans_del memfile.c /^mf_trans_del(mfp, old)$/
Xmf_write memfile.c /^mf_write(mfp, hp)$/
Xmktemp cmdcmds.c /^# define mktemp(a) tmpnam(a)$/
Xml_add_stack memline.c /^ml_add_stack(buf)$/
Xml_append memline.c /^ml_append(lnum, line, len, newfile)$/
Xml_append_int memline.c /^ml_append_int(buf, lnum, line, len, newfile)$/
Xml_clearmarked memline.c /^ml_clearmarked()$/
Xml_close memline.c /^ml_close(buf)$/
Xml_close_all memline.c /^ml_close_all()$/
Xml_delete memline.c /^ml_delete(lnum)$/
Xml_delete_int memline.c /^ml_delete_int(buf, lnum)$/
Xml_find_line memline.c /^ml_find_line(buf, lnum, action)$/
Xml_firstmarked memline.c /^ml_firstmarked()$/
Xml_flush_line memline.c /^ml_flush_line(buf)$/
Xml_get memline.c /^ml_get(lnum)$/
Xml_get_buf memline.c /^ml_get_buf(buf, lnum, will_change)$/
Xml_get_cursor memline.c /^ml_get_cursor()$/
Xml_get_pos memline.c /^ml_get_pos(pos)$/
Xml_has_mark memline.c /^ml_has_mark(lnum)$/
Xml_line_alloced memline.c /^ml_line_alloced()$/
Xml_lineadd memline.c /^ml_lineadd(buf, count)$/
Xml_new_data memline.c /^ml_new_data(mfp, negative, page_count)$/
Xml_new_ptr memline.c /^ml_new_ptr(mfp)$/
Xml_open memline.c /^ml_open()$/
Xml_open_files memline.c /^ml_open_files()$/
Xml_preserve memline.c /^ml_preserve(buf, message)$/
Xml_recover memline.c /^ml_recover()$/
Xml_replace memline.c /^ml_replace(lnum, line, copy)$/
Xml_setmarked memline.c /^ml_setmarked(lnum)$/
Xml_sync_all memline.c /^ml_sync_all(check_file)$/
Xml_timestamp memline.c /^ml_timestamp(buf)$/
Xmodname fileio.c /^modname(fname, ext)$/
Xmovemark mark.c /^movemark(count)$/
Xmsg message.c /^msg(s)$/
Xmsg_ceol message.c /^msg_ceol()$/
Xmsg_check message.c /^msg_check()$/
Xmsg_check_screen message.c /^msg_check_screen()$/
Xmsg_end message.c /^msg_end()$/
Xmsg_outchar message.c /^msg_outchar(c)$/
Xmsg_outnum message.c /^msg_outnum(n)$/
Xmsg_outstr message.c /^msg_outstr(s)$/
Xmsg_outtrans message.c /^msg_outtrans(str, len)$/
Xmsg_pos message.c /^msg_pos(row, col)$/
Xmsg_prt_line message.c /^msg_prt_line(s)$/
Xmsg_start message.c /^msg_start()$/
Xmsgmore misccmds.c /^msgmore(n)$/
Xmyregcomp search.c /^myregcomp(pat, sub_cmd, which_pat)$/
Xnextent termlib.c /^nextent(tbuf, termcap, buflen) \/* Read 1 e/
Xnextwild cmdline.c /^nextwild(buff, type)$/
XnofreeNULL alloc.c /^nofreeNULL(x)$/
Xnormal normal.c /^normal()$/
Xnormvideo winnt.c /^normvideo()$/
Xonedown edit.c /^onedown(n)$/
Xoneleft edit.c /^oneleft()$/
Xonepage edit.c /^onepage(dir, count)$/
Xoneright edit.c /^oneright()$/
Xoneup edit.c /^oneup(n)$/
Xopen_buffer buffer.c /^open_buffer()$/
Xopenscript getchar.c /^openscript(name)$/
Xotherfile buffer.c /^otherfile(fname)$/
Xoutchar term.c /^outchar(c)$/
Xoutnum term.c /^outnum(n)$/
Xoutstr term.c /^outstr(s)$/
Xoutstrn term.c /^outstrn(s)$/
Xparam_expand param.c /^param_expand(i, dofree)$/
Xparamchanged param.c /^paramchanged(arg)$/
Xparse_builtin_tcap term.c /^parse_builtin_tcap(tc, s)$/
Xpchar macros.h /^#define pchar(lp, c) (*(ml_get_buf(curbuf, (lp).ln/
Xpchar_cursor misccmds.c /^pchar_cursor(c)$/
Xpeekchr regexp.c /^peekchr()$/
Xperr winnt.c /^void perr(PCHAR szFileName, int line, P/
Xplines misccmds.c /^plines(p)$/
Xplines_m misccmds.c /^plines_m(first, last)$/
Xplines_m_win misccmds.c /^plines_m_win(wp, first, last)$/
Xplines_win misccmds.c /^plines_win(wp, p)$/
Xplural misccmds.c /^plural(n)$/
Xpremsg normal.c /^premsg(c1, c2)$/
Xprep_redo normal.c /^prep_redo(num, cmd, c, nchar)$/
Xprintdigraph digraph.c /^printdigraph(p)$/
Xpstrcmp msdos.c /^pstrcmp(a, b)$/
Xputch winnt.c /^putch(char c)$/
Xputcmdline cmdline.c /^putcmdline(c, buff)$/
Xputdigraph digraph.c /^putdigraph(str)$/
Xputescstr getchar.c /^putescstr(fd, str, set)$/
Xqf_free quickfix.c /^qf_free()$/
Xqf_init quickfix.c /^qf_init()$/
Xqf_jump quickfix.c /^qf_jump(dir, errornr)$/
Xqf_list quickfix.c /^qf_list()$/
Xqf_mark_adjust quickfix.c /^qf_mark_adjust(line1, line2, inc)$/
Xqf_types quickfix.c /^qf_types(c, nr)$/
Xread_redo getchar.c /^read_redo(init)$/
Xread_stuff getchar.c /^read_stuff(advance)$/
Xreadfile fileio.c /^readfile(fname, sfname, from, newfile, skip_lnum, /
Xredrawcmd cmdline.c /^redrawcmd()$/
Xredrawcmdline cmdline.c /^redrawcmdline()$/
Xredrawhelp help.c /^redrawhelp()$/
Xreg regexp.c /^reg(paren, flagp)$/
Xregatom regexp.c /^regatom(flagp)$/
Xregbranch regexp.c /^regbranch(flagp)$/
Xregc regexp.c /^regc(b)$/
Xregcomp regexp.c /^regcomp(exp)$/
Xregdump regexp.c /^regdump(r)$/
Xregexec regexp.c /^regexec(prog, string, at_bol)$/
Xreginsert regexp.c /^reginsert(op, opnd)$/
Xregmatch regexp.c /^regmatch(prog)$/
Xregnext regexp.c /^regnext(p)$/
Xregnode regexp.c /^regnode(op)$/
Xregoptail regexp.c /^regoptail(p, val)$/
Xregpiece regexp.c /^regpiece(flagp)$/
Xregprop regexp.c /^regprop(op)$/
Xregrepeat regexp.c /^regrepeat(p)$/
Xregsub regsub.c /^regsub(prog, source, dest, copy, magic)$/
Xregtail regexp.c /^regtail(p, val)$/
Xregtilde regsub.c /^regtilde(source, magic)$/
Xregtry regexp.c /^regtry(prog, string)$/
Xremove unix.c /^remove(buf)$/
Xrename unix.c /^rename(src, dest)$/
Xresettitle archie.c /^resettitle()$/
XresizeConBufAndWindow winnt.c /^void resizeConBufAndWindow(HANDLE hCons/
Xscreen_char screen.c /^screen_char(p, row, col)$/
Xscreen_del_lines screen.c /^screen_del_lines(off, row, nlines, end)$/
Xscreen_fill screen.c /^screen_fill(start_row, end_row, start_col, end_col/
Xscreen_ins_lines screen.c /^screen_ins_lines(off, row, nlines, end)$/
Xscreen_msg screen.c /^screen_msg(msg, row, col)$/
Xscreen_new_rows window.c /^screen_new_rows()$/
Xscreen_outchar screen.c /^screen_outchar(c, row, col)$/
Xscreen_start screen.c /^screen_start()$/
Xscreen_valid screen.c /^screen_valid()$/
Xscreenalloc screen.c /^screenalloc(clear)$/
Xscreenclear screen.c /^screenclear()$/
Xscreenclear2 screen.c /^screenclear2()$/
Xscroll winnt.c /^scroll()$/
Xscroll_region_reset term.c /^scroll_region_reset()$/
Xscroll_region_set term.c /^scroll_region_set(wp)$/
Xscrolldown screen.c /^scrolldown(nlines)$/
Xscrollup screen.c /^scrollup(nlines)$/
Xsearchc search.c /^searchc(c, dir, type, count)$/
Xsearchit search.c /^searchit(pos, dir, str, count, end, message)$/
Xset_Changed misccmds.c /^set_Changed()$/
Xset_context_in_set_cmd param.c /^set_context_in_set_cmd(arg)$/
Xset_expand_context cmdline.c /^set_expand_context(firstc, buff)$/
Xset_highlight screen.c /^set_highlight(context)$/
Xset_indent misccmds.c /^set_indent(size, delete)$/
Xset_init param.c /^set_init()$/
Xset_keymap amiga.c /^set_keymap(name)$/
Xset_one_cmd_context cmdline.c /^set_one_cmd_context(firstc, buff)$/
Xset_redo_ins getchar.c /^set_redo_ins()$/
Xset_term term.c /^set_term(term)$/
Xset_window msdos.c /^set_window()$/
Xset_winsize term.c /^set_winsize(width, height, mustset)$/
Xset_x11_icon unix.c /^set_x11_icon(icon)$/
Xset_x11_title unix.c /^set_x11_title(title)$/
Xsetaltfname buffer.c /^setaltfname(fname, sfname, lnum)$/
Xsetcursor term.c /^setcursor()$/
Xsetfname buffer.c /^setfname(fname, sfname, message)$/
Xsetmark mark.c /^setmark(c)$/
Xsetpcmark mark.c /^setpcmark()$/
Xsetperm amiga.c /^setperm(name, perm)$/
Xsettitle archie.c /^settitle(str)$/
Xsettmode term.c /^settmode(raw)$/
Xshift_line ops.c /^shift_line(left, round, amount)$/
Xshowmap getchar.c /^showmap(mp)$/
Xshowmatch search.c /^showmatch(initc)$/
Xshowmatches cmdline.c /^showmatches(buff)$/
Xshowmode screen.c /^showmode()$/
Xshowonep param.c /^showonep(p)$/
Xshowparams param.c /^showparams(all)$/
Xshowruler screen.c /^showruler(always)$/
Xsig_winch unix.c /^sig_winch()$/
Xskip_chars search.c /^skip_chars(class, dir)$/
Xskip_regexp regexp.c /^skip_regexp(p, dirc)$/
Xskipchr regexp.c /^skipchr()$/
Xskipspace misccmds.c /^skipspace(pp)$/
Xskiptodigit misccmds.c /^skiptodigit(pp)$/
Xskiptospace misccmds.c /^skiptospace(pp)$/
Xsleep amiga.c /^sleep(n)$/
Xsmsg message.c /^smsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)$/
Xsortcmp amiga.c /^sortcmp(a, b)$/
XstartPS search.c /^startPS(lnum, para, both)$/
Xstart_arrow edit.c /^start_arrow()$/
Xstart_highlight screen.c /^start_highlight()$/
Xstart_redo getchar.c /^start_redo(count)$/
Xstart_redo_ins getchar.c /^start_redo_ins()$/
Xstart_stuff getchar.c /^start_stuff()$/
Xstartinsert ops.c /^startinsert(initstr, startln, count)$/
Xstarttermcap term.c /^starttermcap()$/
Xstatus_redraw_all screen.c /^status_redraw_all()$/
Xstop_arrow edit.c /^stop_arrow()$/
Xstop_highlight screen.c /^stop_highlight()$/
Xstop_insert edit.c /^stop_insert()$/
Xstop_redo_ins getchar.c /^stop_redo_ins()$/
Xstoptermcap term.c /^stoptermcap()$/
Xstrchr unix.h /^# define strchr(ptr, c) index((ptr), (c))$/
Xstrcspn regexp.c /^strcspn(s1, s2)$/
Xstrlowcpy msdos.c /^strlowcpy(d, s)$/
Xstrnfcpy regsub.c /^strnfcpy(f, d, s, n)$/
Xstrnsave alloc.c /^strnsave(string, len)$/
Xstrrchr unix.h /^# define strrchr(ptr, c) rindex((ptr), (c))$/
Xstrsave alloc.c /^strsave(string)$/
Xstrsize charset.c /^strsize(s)$/
XstuffReadbuff getchar.c /^stuffReadbuff(s)$/
Xstuff_empty getchar.c /^stuff_empty()$/
Xstuff_inserted edit.c /^stuff_inserted(c, count, no_esc)$/
Xstuff_yank ops.c /^stuff_yank(bufname, p)$/
XstuffcharReadbuff getchar.c /^stuffcharReadbuff(c)$/
XstuffnumReadbuff getchar.c /^stuffnumReadbuff(n)$/
Xswapchar ops.c /^swapchar(pos)$/
Xtermcapinit term.c /^termcapinit(term)$/
Xtextattr winnt.c /^textattr(int attr)$/
Xtgetch winnt.c /^int tgetch()$/
Xtgetent termlib.c /^tgetent(tbuf, term)$/
Xtgetflag termlib.c /^tgetflag(id)$/
Xtgetnum termlib.c /^tgetnum(id)$/
Xtgetstr termlib.c /^tgetstr(id, buf)$/
Xtgoto term.c /^tgoto(cm, x, y)$/
Xtinit termlib.c /^tinit(name)$/
Xtltoa term.c /^tltoa(i)$/
Xtputs termlib.c /^tputs(cp, affcnt, outc)$/
Xtranschar charset.c /^transchar(c)$/
Xttest term.c /^ttest(pairs)$/
Xu_alloc_line undo.c /^u_alloc_line(size)$/
Xu_blockalloc undo.c /^u_blockalloc(size)$/
Xu_blockfree undo.c /^u_blockfree(buf)$/
Xu_clearall undo.c /^u_clearall(buf)$/
Xu_clearline undo.c /^u_clearline()$/
Xu_free_line undo.c /^u_free_line(ptr)$/
Xu_freeentry undo.c /^u_freeentry(uep, n)$/
Xu_freelist undo.c /^u_freelist(uhp)$/
Xu_getbot undo.c /^u_getbot()$/
Xu_inssub undo.c /^u_inssub(lnum)$/
Xu_redo undo.c /^u_redo(count)$/
Xu_save undo.c /^u_save(top, bot)$/
Xu_save_cursor undo.c /^u_save_cursor()$/
Xu_save_line undo.c /^u_save_line(lnum)$/
Xu_savecommon undo.c /^u_savecommon(top, bot, newbot)$/
Xu_savedel undo.c /^u_savedel(lnum, nlines)$/
Xu_saveline undo.c /^u_saveline(lnum)$/
Xu_savesub undo.c /^u_savesub(lnum)$/
Xu_sync undo.c /^u_sync()$/
Xu_unchanged undo.c /^u_unchanged(buf)$/
Xu_undo undo.c /^u_undo(count)$/
Xu_undo_end undo.c /^u_undo_end()$/
Xu_undoline undo.c /^u_undoline()$/
Xu_undoredo undo.c /^u_undoredo()$/
Xungetchr regexp.c /^ungetchr()$/
Xunregc regexp.c /^unregc()$/
Xunset_Changed misccmds.c /^unset_Changed(buf)$/
XupdateScreen screen.c /^updateScreen(type)$/
Xupdateline screen.c /^updateline()$/
Xupdatescript getchar.c /^updatescript(c)$/
Xusage main.c /^usage(n)$/
Xvbell winnt.c /^vbell()$/
Xvgetc getchar.c /^vgetc()$/
Xvgetorpeek getchar.c /^vgetorpeek(advance)$/
Xvim_chdir msdos.c /^vim_chdir(path)$/
Xvim_delay amiga.c /^vim_delay()$/
Xvim_dirname amiga.c /^vim_dirname(buf, len)$/
Xvim_fgets fileio.c /^vim_fgets(buf, size, fp, lnum)$/
Xvim_remove msdos.c /^vim_remove(name)$/
Xvim_strncpy cmdline.c /^vim_strncpy(to, from, len)$/
Xvim_strnicmp alloc.c /^vim_strnicmp(s1, s2, len)$/
Xvimgetenv amiga.c /^vimgetenv(var)$/
Xvpeekc getchar.c /^vpeekc()$/
Xwait_return message.c /^wait_return(redraw)$/
Xwin_alloc window.c /^win_alloc(after)$/
Xwin_alloc_lsize window.c /^win_alloc_lsize(wp)$/
Xwin_append window.c /^win_append(after, wp)$/
Xwin_comp_pos window.c /^win_comp_pos()$/
Xwin_comp_scroll window.c /^win_comp_scroll(wp)$/
Xwin_copy_options param.c /^win_copy_options(wp_from, wp_to)$/
Xwin_del_lines screen.c /^win_del_lines(wp, row, nlines, invalid, mayclear)$/
Xwin_enter window.c /^win_enter(wp, undo_sync)$/
Xwin_equal window.c /^win_equal(next_curwin, redraw)$/
Xwin_exchange window.c /^win_exchange(Prenum)$/
Xwin_free window.c /^win_free(wp)$/
Xwin_free_lsize window.c /^win_free_lsize(wp)$/
Xwin_init window.c /^win_init(wp)$/
Xwin_ins_lines screen.c /^win_ins_lines(wp, row, nlines, invalid, mayclear)$/
Xwin_line screen.c /^win_line(wp, lnum, startrow, endrow)$/
Xwin_redr_ruler screen.c /^win_redr_ruler(wp, always)$/
Xwin_redr_status screen.c /^win_redr_status(wp)$/
Xwin_remove window.c /^win_remove(wp)$/
Xwin_resize_off amiga.c /^win_resize_off()$/
Xwin_resize_on amiga.c /^win_resize_on()$/
Xwin_rest_invalid screen.c /^win_rest_invalid(wp)$/
Xwin_rotate window.c /^win_rotate(upwards, count)$/
Xwin_setheight window.c /^win_setheight(height)$/
Xwin_split window.c /^win_split(new_height, redraw)$/
Xwin_update screen.c /^win_update(wp)$/
Xwindgoto term.c /^windgoto(row, col)$/
Xwrite_buf fileio.c /^write_buf(fd, buf, len)$/
END_OF_FILE
if test 29029 -ne `wc -c <'vim/src/tags'`; then
echo shar: \"'vim/src/tags'\" unpacked with wrong size!
fi
# end of 'vim/src/tags'
fi
echo shar: End of archive 14 \(of 26\).
cp /dev/null ark14isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:02:42 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 34
Archive-name: vim/part15

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/fileio.c vim/src/getchar.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:08 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 15 (of 26)."'
if test -f 'vim/src/fileio.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/fileio.c'\"
else
echo shar: Extracting \"'vim/src/fileio.c'\" \(31526 characters\)
sed "s/^X//" >'vim/src/fileio.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * fileio.c: read from and write to a file
X */
X
X/*
X * special feature of this version: NUL characters in the file are
X * replaced by newline characters in memory. This allows us to edit
X * binary files!


X */
X
X#ifdef MSDOS
X# include <io.h>

X#endif


X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"

X#include "fcntl.h"
X
X#ifdef LATTICE
X# include <proto/dos.h> /* for Lock() and UnLock() */
X#endif
X
X#define BUFSIZE 8192 /* size of normal write buffer */
X#define SBUFSIZE 256 /* size of emergency write buffer */
X
Xstatic int write_buf __ARGS((int, char_u *, int));
Xstatic void do_mlines __ARGS((void));
X
X void
Xfilemess(name, s)
X char_u *name;
X char_u *s;
X{
X /* careful: home_replace calls vimgetenv(), which also uses IObuff! */


X home_replace(name, IObuff + 1, IOSIZE - 1);
X IObuff[0] = '"';

X STRCAT(IObuff, "\" ");
X STRCAT(IObuff, s);
X /*
X * don't use msg(), because it sometimes outputs a newline
X */
X msg_start();
X msg_outstr(IObuff);
X msg_ceol();
X flushbuf();
X}
X
X/*
X * Read lines from file 'fname' into the buffer after line 'from'.
X *
X * 1. We allocate blocks with lalloc, as big as possible.
X * 2. Each block is filled with characters from the file with a single read().
X * 3. The lines are inserted in the buffer with ml_append().
X *
X * (caller must check that fname != NULL)
X *
X * skip_lnum is the number of lines that must be skipped
X * nlines is the number of lines that are appended
X * When not recovering skip_lnum is 0 and nlines MAXLNUM.
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xreadfile(fname, sfname, from, newfile, skip_lnum, nlines)


X char_u *fname;
X char_u *sfname;

X linenr_t from;
X int newfile;
X linenr_t skip_lnum;
X linenr_t nlines;
X{
X#ifdef UNIX
X int fd = -1;
X#else
X int fd;
X#endif
X register char_u c;
X register linenr_t lnum = from;
X register char_u *ptr = NULL; /* pointer into read buffer */
X register char_u *buffer = NULL; /* read buffer */
X char_u *new_buffer = NULL; /* init to shut up gcc */
X char_u *line_start = NULL; /* init to shut up gcc */
X colnr_t len;
X register long size;
X register char_u *p;
X long filesize = 0;
X int split = 0; /* number of split lines */
X#define UNKNOWN 0x0fffffff /* file size is unknown */
X linenr_t linecnt = curbuf->b_ml.ml_line_count;
X int incomplete = FALSE; /* was the last line incomplete? */
X int error = FALSE; /* errors encountered */
X long linerest = 0; /* remaining characters in line */
X int firstpart = TRUE; /* reading first part */
X#ifdef UNIX
X int perm;
X#endif
X int textmode = curbuf->b_p_tx; /* accept CR-LF for line break */
X struct stat st;
X int readonly;
X
X /*
X * If there is no file name yet, use the one for the read file.
X * b_notedited is set to reflect this.
X */
X if (curbuf->b_filename == NULL)
X {
X if (setfname(fname, sfname, FALSE) == OK)


X curbuf->b_notedited = TRUE;
X }

X


X if (sfname == NULL)

X sfname = fname;
X /*
X * Use the short filename whenever possible.
X * Avoids problems with networks and when directory names are changed.
X */
X if (!did_cd)
X fname = sfname;
X
X if (bufempty()) /* special case: buffer has no lines */
X linecnt = 0;


X
X#ifdef UNIX
X /*

X * On Unix it is possible to read a directory, so we have to
X * check for it before the open().
X */
X perm = getperm(fname);
X# ifdef _POSIX_SOURCE
X if (perm >= 0 && !S_ISREG(perm)) /* not a regular file */
X# else
X if (perm >= 0 && (perm & S_IFMT) != S_IFREG) /* not a regular file */
X# endif
X {
X# ifdef _POSIX_SOURCE
X if (S_ISDIR(perm))
X# else
X if ((perm & S_IFMT) == S_IFDIR)
X# endif
X filemess(fname, (char_u *)"is a directory");
X else
X filemess(fname, (char_u *)"is not a file");
X return FAIL;
X }
X#endif
X
X if (newfile && !readonlymode) /* default: set file not readonly */
X curbuf->b_p_ro = FALSE;
X
X if (newfile && stat((char *)fname, &st) != -1) /* remember time of file */
X curbuf->b_mtime = st.st_mtime;
X else
X curbuf->b_mtime = 0;
X
X/*
X * for UNIX: check readonly with perm and access()
X * for MSDOS and Amiga: check readonly by trying to open the file for writing
X */
X readonly = FALSE;
X#ifdef UNIX
X if (!(perm & 0222) || access((char *)fname, 2))
X readonly = TRUE;
X fd = open((char *)fname, O_RDONLY);
X#else
X if (!newfile || readonlymode || (fd = open((char *)fname, O_RDWR)) < 0)
X {
X readonly = TRUE;
X fd = open((char *)fname, O_RDONLY); /* try to open ro */
X }
X#endif
X
X if (fd < 0) /* cannot open at all */
X {
X#ifdef MSDOS
X /*
X * The screen may be messed up by the "insert disk
X * in drive b: and hit return" message
X */
X screenclear();
X#endif
X
X#ifndef UNIX
X /*
X * On MSDOS and Amiga we can't open a directory, check here.
X */


X if (isdir(fname) == TRUE)

X filemess(fname, (char_u *)"is a directory");
X else
X#endif
X if (newfile)
X#ifdef UNIX
X if (perm < 0)
X#endif
X filemess(fname, (char_u *)"[New File]");
X#ifdef UNIX
X else
X filemess(fname, (char_u *)"[Permission Denied]");
X#endif
X
X return FAIL;
X }
X if (newfile && readonly) /* set file readonly */
X curbuf->b_p_ro = TRUE;
X
X if (newfile)
X curbuf->b_p_eol = TRUE;
X
X ++no_wait_return; /* don't wait for return yet */
X if (!recoverymode)
X filemess(fname, (char_u *)""); /* show that we are busy */
X
X while (!error && !got_int)
X {
X /*
X * We allocate as much space for the file as we can get, plus
X * space for the old line plus room for one terminating NUL.
X * The amount is limited by the fact that read() only can read
X * upto max_unsigned characters (and other things).
X */
X#if defined(AMIGA) || defined(MSDOS)
X if (sizeof(int) <= 2 && linerest >= 0x7ff0)
X {
X ++split;
X *ptr = NL; /* split line by inserting a NL */
X size = 1;
X }
X else
X#endif
X {
X#if !(defined(AMIGA) || defined(MSDOS))
X if (sizeof(int) > 2)
X size = 0x10000L; /* read 64K at a time */
X else
X#endif
X size = 0x7ff0L - linerest; /* limit buffer to 32K */
X
X for ( ; size >= 10; size >>= 1)
X {
X if ((new_buffer = lalloc((long_u)(size + linerest + 1), FALSE)) != NULL)
X break;
X }
X if (new_buffer == NULL)
X {
X emsg(e_outofmem);
X error = TRUE;
X break;
X }
X if (linerest) /* copy characters from the previous buffer */
X memmove((char *)new_buffer, (char *)ptr - linerest, linerest);
X free(buffer);
X buffer = new_buffer;
X ptr = buffer + linerest;
X line_start = buffer;
X
X if ((size = read(fd, (char *)ptr, (size_t)size)) <= 0)
X {
X if (size < 0) /* read error */
X error = TRUE;
X break;
X }
X filesize += size; /* count the number of characters */
X
X /*
X * when reading the first part of a file: guess EOL type
X */
X if (firstpart && p_ta)
X {
X for (p = ptr; p < ptr + size; ++p)
X if (*p == NL)
X {
X if (p > ptr && p[-1] == CR) /* found CR-NL */
X textmode = TRUE;
X else /* found a single NL */
X textmode = FALSE;
X /* if editing a new file: may set p_tx */
X if (newfile && curbuf->b_p_tx != textmode)
X {
X curbuf->b_p_tx = textmode;
X paramchanged((char_u *)"tx");
X }
X break;
X }
X }
X }
X
X /*
X * This loop is executed once for every character read.


X * Keep it fast!
X */

X --ptr;
X while (++ptr, --size >= 0)
X {
X if ((c = *ptr) != NUL && c != NL) /* catch most common case */
X continue;
X if (c == NUL)
X *ptr = NL; /* NULs are replaced by newlines! */
X else
X {
X if (skip_lnum == 0)
X {
X *ptr = NUL; /* end of line */
X len = ptr - line_start + 1;
X if (textmode && ptr[-1] == CR) /* remove CR */
X {
X ptr[-1] = NUL;
X --len;
X }
X if (ml_append(lnum, line_start, len, newfile) == FAIL)
X {
X error = TRUE;
X break;
X }
X ++lnum;
X if (--nlines == 0)
X {
X error = TRUE; /* break loop */
X line_start = ptr; /* nothing left to write */
X break;
X }
X }
X else
X --skip_lnum;
X line_start = ptr + 1;
X }
X }
X linerest = ptr - line_start;
X firstpart = FALSE;
X breakcheck();
X }
X
X if (error && nlines == 0) /* not an error, max. number of lines reached */
X error = FALSE;
X
X if (!error && !got_int && linerest != 0
X#ifdef MSDOS
X /*
X * in MSDOS textmode ignore a trailing CTRL-Z
X */
X && !(!curbuf->b_p_bin && *line_start == Ctrl('Z') && ptr == line_start + 1)
X#endif
X )
X {
X /*
X * If we get EOF in the middle of a line, note the fact and
X * complete the line ourselves.
X */
X incomplete = TRUE;
X if (newfile && curbuf->b_p_bin) /* remember for when writing */
X curbuf->b_p_eol = FALSE;
X *ptr = NUL;
X if (ml_append(lnum, line_start, (colnr_t)(ptr - line_start + 1), newfile) == FAIL)
X error = TRUE;
X else
X ++lnum;
X }
X if (lnum != from && !newfile) /* added at least one line */
X CHANGED;
X
X close(fd);
X free(buffer);
X
X --no_wait_return; /* may wait for return now */
X if (recoverymode) /* in recovery mode return here */
X {
X if (error)
X return FAIL;


X return OK;
X }
X

X#ifdef MSDOS /* the screen may be messed up by the "insert disk
X in drive b: and hit return" message */
X screenclear();
X#endif
X
X linecnt = curbuf->b_ml.ml_line_count - linecnt;
X if (!newfile)
X mark_adjust(from + 1, MAXLNUM, (long)linecnt);
X
X if (got_int)
X {
X filemess(fname, e_interr);
X return OK; /* an interrupt isn't really an error */
X }
X
X /* careful: home_replace calls vimgetenv(), which also uses IObuff! */
X home_replace(fname, IObuff + 1, IOSIZE - 1);
X IObuff[0] = '"';


X sprintf((char *)IObuff + STRLEN(IObuff),

X "\" %s%s%s%s%s%ld line%s, %ld character%s",


X curbuf->b_p_ro ? "[readonly] " : "",

X incomplete ? "[Incomplete last line] " : "",
X split ? "[long lines split] " : "",
X error ? "[READ ERRORS] " : "",
X#ifdef MSDOS
X textmode ? "" : "[notextmode] ",
X#else
X textmode ? "[textmode] " : "",
X#endif
X (long)linecnt, plural((long)linecnt),
X filesize, plural(filesize));
X msg(IObuff);
X
X if (error && newfile) /* with errors we should not write the file */
X {


X curbuf->b_p_ro = TRUE;

X paramchanged((char_u *)"ro");
X }
X
X u_clearline(); /* cannot use "U" command after adding lines */
X
X if (newfile) /* edit a new file: read mode from lines */
X do_mlines();
X if (from < curbuf->b_ml.ml_line_count)
X {
X curwin->w_cursor.lnum = from + 1; /* put cursor at first new line */


X curwin->w_cursor.col = 0;
X }

X
X return OK;
X}
X
X/*

X * writeit - write to file 'fname' lines 'start' through 'end'
X *
X * We do our own buffering here because fwrite() is so slow.
X *
X * If forceit is true, we don't care for errors when attempting backups (jw).
X * In case of an error everything possible is done to restore the original file.
X * But when forceit is TRUE, we risk loosing it.
X * When reset_changed is TRUE and start == 1 and end ==
X * curbuf->b_ml.ml_line_count, reset curbuf->b_changed.
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xbuf_write(buf, fname, sfname, start, end, append, forceit, reset_changed)


X BUF *buf;
X char_u *fname;

X char_u *sfname;
X linenr_t start, end;
X int append;
X int forceit;
X int reset_changed;
X{
X int fd;
X char_u *backup = NULL;
X char_u *ffname;
X register char_u *s;
X register char_u *ptr;
X register char_u c;
X register int len;
X register linenr_t lnum;
X long nchars;
X char_u *errmsg = NULL;
X char_u *buffer;
X char_u smallbuf[SBUFSIZE];
X int bufsize;
X long perm = -1; /* file permissions */
X int retval = OK;
X int newfile = FALSE; /* TRUE if file does not exist yet */
X#ifdef UNIX
X struct stat old;
X int made_writable = FALSE; /* 'w' bit has been set */
X#endif
X#ifdef AMIGA
X BPTR flock;
X#endif
X /* writing everything */
X int whole = (start == 1 && end == buf->b_ml.ml_line_count);
X
X if (fname == NULL || *fname == NUL) /* safety check */
X return FAIL;
X
X /*
X * If there is no file name yet, use the one for the written file.
X * b_notedited is set to reflect this (in case the write fails).
X */
X if (reset_changed && whole && buf == curbuf && curbuf->b_filename == NULL)
X {
X if (setfname(fname, sfname, FALSE) == OK)


X curbuf->b_notedited = TRUE;
X }

X


X if (sfname == NULL)

X sfname = fname;
X /*
X * Use the short filename whenever possible.
X * Avoids problems with networks and when directory names are changed.
X */
X ffname = fname; /* remember full fname */
X if (!did_cd)
X fname = sfname;
X
X /*
X * Disallow writing from .exrc and .vimrc in current directory for
X * security reasons.


X */
X if (secure)
X {
X secure = 2;

X emsg(e_curdir);


X return FAIL;
X }
X

X if (exiting)
X settmode(0); /* when exiting allow typahead now */
X
X ++no_wait_return; /* don't wait for return yet */
X filemess(fname, (char_u *)""); /* show that we are busy */
X
X buffer = alloc(BUFSIZE);
X if (buffer == NULL) /* can't allocate big buffer, use small one */
X {
X buffer = smallbuf;
X bufsize = SBUFSIZE;
X }
X else
X bufsize = BUFSIZE;
X
X#if defined(UNIX) && !defined(ARCHIE)
X /* get information about original file (if there is one) */
X old.st_dev = old.st_ino = 0;
X if (stat((char *)fname, &old))
X newfile = TRUE;
X else
X {
X#ifdef _POSIX_SOURCE
X if (!S_ISREG(old.st_mode)) /* not a file */
X#else
X if ((old.st_mode & S_IFMT) != S_IFREG) /* not a file */
X#endif
X {
X#ifdef _POSIX_SOURCE
X if (S_ISDIR(old.st_mode))
X#else
X if ((old.st_mode & S_IFMT) == S_IFDIR)
X#endif
X errmsg = (char_u *)"is a directory";
X else
X errmsg = (char_u *)"is not a file";
X goto fail;
X }
X perm = old.st_mode;
X }
X/*
X * If we are not appending, the file exists, and the 'writebackup', 'backup'
X * or 'patchmode' option is set, try to make a backup copy of the file.
X */
X if (!append && perm >= 0 && (p_wb || p_bk || (p_pm != NULL && *p_pm != NUL)) &&
X (fd = open((char *)fname, O_RDONLY)) >= 0)
X {
X int bfd, buflen;
X char_u copybuf[BUFSIZE + 1], *wp;
X int some_error = FALSE;
X struct stat new;
X
X new.st_dev = new.st_ino = 0;
X
X /*
X * Unix semantics has it, that we may have a writable file,
X * that cannot be recreated with a simple open(..., O_CREAT, ) e.g:
X * - the directory is not writable,
X * - the file may be a symbolic link,
X * - the file may belong to another user/group, etc.
X *
X * For these reasons, the existing writable file must be truncated and
X * reused. Creation of a backup COPY will be attempted.
X */
X if (*p_bdir != '>') /* try to put .bak in current dir */
X {
X if ((backup = modname(fname, ".bak")) == NULL)
X {
X some_error = TRUE; /* out of memory */
X goto nobackup;
X }
X if (!stat((char *)backup, &new) &&
X new.st_dev == old.st_dev && new.st_ino == old.st_ino)
X {
X /*
X * may happen when modname gave the same file back.
X * E.g. silly link, or filename-length reached.
X * If we don't check here, we either ruin the file when
X * copying or erase it after writing. jw.
X */
X free(backup);
X backup = NULL; /* there is no backup file to delete */
X if (*p_bdir == NUL)
X {
X errmsg = (char_u *)"Invalid backup file (use ! to override)";
X goto nobackup;
X }
X }
X else
X remove((char *)backup); /* remove old backup, if present */
X }
X if (backup == NULL || (bfd = open((char *)backup, O_WRONLY | O_CREAT, 0666)) < 0)
X {
X /*
X * 'backupdir' starts with '>' or no write/create permission
X * in current dirr: try again in p_bdir directory.
X */
X free(backup);
X wp = gettail(fname);
X sprintf((char *)copybuf, "%s/%s", *p_bdir == '>' ? p_bdir + 1 : p_bdir, wp);
X if ((backup = buf_modname(buf, copybuf, (char_u *)".bak")) == NULL)
X {
X some_error = TRUE; /* out of memory */
X goto nobackup;
X }
X if (!stat((char *)backup, &new) &&
X new.st_dev == old.st_dev && new.st_ino == old.st_ino)
X {
X errmsg = (char_u *)"Invalid backup file (use ! to override)";
X free(backup);
X backup = NULL; /* there is no backup file to delete */
X goto nobackup;
X }
X remove((char *)backup);
X if ((bfd = open((char *)backup, O_WRONLY | O_CREAT, 0666)) < 0)
X {
X free(backup);
X backup = NULL; /* there is no backup file to delete */
X errmsg = (char_u *)"Can't make backup file (use ! to override)";
X goto nobackup;
X }
X }
X /* set file protection same as original file, but strip s-bit */
X (void)setperm(backup, perm & 0777);
X
X /* copy the file. */
X while ((buflen = read(fd, (char *)copybuf, BUFSIZE)) > 0)
X {
X if (write_buf(bfd, copybuf, buflen) == FAIL)
X {
X errmsg = (char_u *)"Can't write to backup file (use ! to override)";
X goto writeerr;
X }
X }
Xwriteerr:
X close(bfd);
X if (buflen < 0)
X errmsg = (char_u *)"Can't read file for backup (use ! to override)";
Xnobackup:
X close(fd);
X /* ignore errors when forceit is TRUE */
X if ((some_error || errmsg) && !forceit)


X {
X retval = FAIL;

X goto fail;


X }
X errmsg = NULL;
X }

X /* if forceit and the file was read-only: make it writable */
X if (forceit && (old.st_uid == getuid()) && perm >= 0 && !(perm & 0200))
X {
X perm |= 0200;
X (void)setperm(fname, perm);
X made_writable = TRUE;
X /* if we are writing to the current file, readonly makes no sense */
X if (fname == buf->b_filename || fname == buf->b_sfilename)
X buf->b_p_ro = FALSE;
X }
X#else /* end of UNIX, start of the rest */
X
X/*
X * If we are not appending, the file exists, and the 'writebackup' or
X * 'backup' option is set, make a backup.
X * Do not make any backup, if "writebackup" and "backup" are
X * both switched off. This helps when editing large files on
X * almost-full disks. (jw)
X */
X perm = getperm(fname);
X if (perm < 0)
X newfile = TRUE;
X else if (isdir(fname) == TRUE)
X {
X errmsg = (char_u *)"is a directory";
X goto fail;
X }
X if (!append && perm >= 0 && (p_wb || p_bk || (p_pm != NULL && *p_pm != NUL)))
X {
X /*
X * Form the backup file name - change path/fo.o.h to path/fo.o.h.bak
X */
X backup = buf_modname(buf, fname, (char_u *)".bak");
X if (backup == NULL)
X {
X if (!forceit)
X goto fail;
X }
X else
X {
X /*
X * Delete any existing backup and move the current version to the backup.
X * For safety, we don't remove the backup until the write has finished
X * successfully. And if the 'backup' option is set, leave it around.
X */
X#ifdef AMIGA
X /*
X * With MSDOS-compatible filesystems (crossdos, messydos) it is
X * possible that the name of the backup file is the same as the
X * original file. To avoid the chance of accidently deleting the
X * original file (horror!) we lock it during the remove.
X * This should not happen with ":w", because startscript() should
X * detect this problem and set buf->b_shortname, causing modname to
X * return a correct ".bak" filename. This problem does exist with
X * ":w filename", but then the original file will be somewhere else
X * so the backup isn't really important. If autoscripting is off
X * the rename may fail.
X */
X flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
X#endif
X remove((char *)backup);
X#ifdef AMIGA
X if (flock)
X UnLock(flock);
X#endif
X len = rename((char *)fname, (char *)backup);
X if (len != 0)
X {
X if (forceit)
X {
X free(backup); /* don't do the rename below */
X backup = NULL;
X }
X else
X {
X errmsg = (char_u *)"Can't make backup file (use ! to override)";


X goto fail;
X }
X }
X }
X }

X#endif /* UNIX */
X
X /*
X * If the original file is being overwritten, there is a small chance that
X * we crash in the middle of writing. Therefore the file is preserved now.
X * This makes all block numbers positive so that recovery does not need
X * the original file.
X * Don't do this if there is a backup file and we are exiting.
X */
X if (reset_changed && !newfile && !otherfile(ffname) && !(exiting && backup != NULL))
X ml_preserve(buf, FALSE);
X
X /*
X * We may try to open the file twice: If we can't write to the
X * file and forceit is TRUE we delete the existing file and try to create
X * a new one. If this still fails we may have lost the original file!
X * (this may happen when the user reached his quotum for number of files).
X * Appending will fail if the file does not exist and forceit is FALSE.
X */
X while ((fd = open((char *)fname, O_WRONLY | (append ?
X (forceit ? (O_APPEND | O_CREAT) : O_APPEND) :
X (O_CREAT | O_TRUNC)), 0666)) < 0)
X {
X /*
X * A forced write will try to create a new file if the old one is
X * still readonly. This may also happen when the directory is
X * read-only. In that case the remove() will fail.
X */
X if (!errmsg)
X {
X errmsg = (char_u *)"Can't open file for writing";
X if (forceit)
X {
X#ifdef UNIX
X /* we write to the file, thus it should be marked
X writable after all */
X perm |= 0200;
X made_writable = TRUE;
X if (old.st_uid != getuid() || old.st_gid != getgid())
X perm &= 0777;
X#endif /* UNIX */
X if (!append) /* don't remove when appending */
X remove((char *)fname);
X continue;
X }
X }
X/*
X * If we failed to open the file, we don't need a backup. Throw it away.
X * If we moved or removed the original file try to put the backup in its place.
X */
X if (backup != NULL)
X {
X#ifdef UNIX
X struct stat st;
X
X /*
X * There is a small chance that we removed the original, try
X * to move the copy in its place.
X * This won't work if the backup is in another file system!
X * In that case we leave the copy around.
X */
X if (stat((char *)fname, &st) < 0) /* file does not exist */
X rename((char *)backup, (char *)fname); /* put the copy in its place */
X if (stat((char *)fname, &st) >= 0) /* original file does exist */
X remove((char *)backup); /* throw away the copy */
X#else
X rename((char *)backup, (char *)fname); /* try to put the original file back */
X#endif
X }
X goto fail;


X }
X errmsg = NULL;
X

X if (end > buf->b_ml.ml_line_count)
X end = buf->b_ml.ml_line_count;
X len = 0;
X s = buffer;
X nchars = 0;
X for (lnum = start; lnum <= end; ++lnum)
X {
X /*
X * The next while loop is done once for each character written.


X * Keep it fast!

X */
X ptr = ml_get_buf(buf, lnum, FALSE) - 1;
X while ((c = *++ptr) != NUL)
X {
X if (c == NL)
X *s = NUL; /* replace newlines with NULs */
X else
X *s = c;
X ++s;
X if (++len != bufsize)
X continue;
X if (write_buf(fd, buffer, bufsize) == FAIL)
X {
X end = 0; /* write error: break loop */
X break;
X }
X nchars += bufsize;
X s = buffer;
X len = 0;
X }
X /* write failed or last line has no EOL: stop here */
X if (end == 0 || (buf->b_p_bin && lnum == buf->b_ml.ml_line_count && !buf->b_p_eol))
X break;
X if (buf->b_p_tx) /* write CR-NL */
X {
X *s = CR;
X ++s;
X if (++len == bufsize)
X {
X if (write_buf(fd, buffer, bufsize) == FAIL)
X {
X end = 0; /* write error: break loop */
X break;
X }
X nchars += bufsize;
X s = buffer;
X len = 0;
X }
X }
X *s = NL;
X ++s;
X if (++len == bufsize && end)
X {
X if (write_buf(fd, buffer, bufsize) == FAIL)
X {
X end = 0; /* write error: break loop */
X break;
X }
X nchars += bufsize;
X s = buffer;
X len = 0;
X }
X }
X if (len && end)
X {
X if (write_buf(fd, buffer, len) == FAIL)
X end = 0; /* write error */
X nchars += len;
X }
X
X if (close(fd) != 0)
X {
X errmsg = (char_u *)"Close failed";
X goto fail;
X }
X#ifdef UNIX
X if (made_writable)
X perm &= ~0200; /* reset 'w' bit for security reasons */
X#endif
X if (perm >= 0)
X (void)setperm(fname, perm); /* set permissions of new file same as old file */
X
X if (end == 0)
X {
X errmsg = (char_u *)"write error (file system full?)";


X goto fail;
X }
X

X#ifdef MSDOS /* the screen may be messed up by the "insert disk
X in drive b: and hit return" message */
X if (!exiting)
X screenclear();
X#endif
X
X lnum -= start; /* compute number of written lines */
X --no_wait_return; /* may wait for return now */
X
X /* careful: home_replace calls vimgetenv(), which also uses IObuff! */
X home_replace(fname, IObuff + 1, IOSIZE - 1);
X IObuff[0] = '"';


X sprintf((char *)IObuff + STRLEN(IObuff),

X "\"%s%s %ld line%s, %ld character%s",
X newfile ? " [New File]" : " ",
X#ifdef MSDOS
X buf->b_p_tx ? "" : "[notextmode]",
X#else
X buf->b_p_tx ? "[textmode]" : "",
X#endif
X (long)lnum, plural((long)lnum),
X nchars, plural(nchars));
X msg(IObuff);
X
X if (reset_changed && whole) /* when written everything */
X {
X UNCHANGED(buf);
X u_unchanged(buf);
X /*
X * If written to the current file, update the timestamp of the swap file
X * and reset the 'notedited' flag.
X */
X if (!exiting && buf->b_filename != NULL &&
X fnamecmp(ffname, buf->b_filename) == 0)
X {
X ml_timestamp(buf);
X buf->b_notedited = FALSE;
X }
X }
X
X /*
X * If we kept a backup until now, and we are in patch mode, then we make
X * the backup file our 'original' file.
X */
X if (p_pm && *p_pm)
X {
X char *org = (char *)modname(fname, p_pm);
X
X if (backup != NULL)
X {
X struct stat st;
X
X /*
X * If the original file does not exist yet
X * the current backup file becomes the original file
X */
X if (org == NULL)
X EMSG("patchmode: can't save original file");
X else if (stat(org, &st) < 0)
X {
X rename((char *)backup, org);
X free(backup); /* don't delete the file */
X backup = NULL;
X }
X }
X /*
X * If there is no backup file, remember that a (new) file was
X * created.
X */
X else
X {
X int fd;
X
X if (org == NULL || (fd = open(org, O_CREAT, 0666)) < 0)
X EMSG("patchmode: can't touch empty original file");
X else
X close(fd);
X }
X if (org != NULL)
X {
X setperm((char_u *)org, getperm(fname) & 0777);
X free(org);
X }
X }
X
X /*
X * Remove the backup unless 'backup' option is set
X */
X if (!p_bk && backup != NULL && remove((char *)backup) != 0)
X EMSG("Can't delete backup file");
X
X goto nofail;
X
Xfail:
X --no_wait_return; /* may wait for return now */
X#ifdef MSDOS /* the screen may be messed up by the "insert disk
X in drive b: and hit return" message */
X screenclear();
X#endif
Xnofail:
X
X free(backup);
X free(buffer);
X
X if (errmsg != NULL)
X {
X filemess(fname, errmsg);


X retval = FAIL;
X }

X return retval;
X}
X
X/*
X * write_buf: call write() to write a buffer
X *
X * return FAIL for failure, OK otherwise
X */
X static int
Xwrite_buf(fd, buf, len)
X int fd;
X char_u *buf;
X int len;
X{
X int wlen;
X
X while (len)
X {
X wlen = write(fd, (char *)buf, (size_t)len);
X if (wlen <= 0) /* error! */
X return FAIL;
X len -= wlen;
X buf += wlen;


X }
X return OK;
X}
X
X/*

X * do_mlines() - process mode lines for the current file
X *
X * Returns immediately if the "ml" parameter isn't set.
X */
Xstatic void chk_mline __ARGS((linenr_t));
X
X static void
Xdo_mlines()
X{
X linenr_t lnum;
X int nmlines;
X
X if (!curbuf->b_p_ml || (nmlines = (int)p_mls) == 0)
X return;
X
X for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count && lnum <= nmlines; ++lnum)
X chk_mline(lnum);
X
X for (lnum = curbuf->b_ml.ml_line_count; lnum > 0 && lnum > nmlines &&
X lnum > curbuf->b_ml.ml_line_count - nmlines; --lnum)
X chk_mline(lnum);
X}
X
X/*
X * chk_mline() - check a single line for a mode string


X */
X static void

Xchk_mline(lnum)
X linenr_t lnum;
X{
X register char_u *s;
X register char_u *e;
X char_u *cs; /* local copy of any modeline found */
X int prev;
X int end;
X
X prev = ' ';
X for (s = ml_get(lnum); *s != NUL; ++s)
X {
X if (isspace(prev) && (STRNCMP(s, "vi:", (size_t)3) == 0 || STRNCMP(s, "ex:", (size_t)3) == 0 || STRNCMP(s, "vim:", (size_t)4) == 0))
X {
X do
X ++s;
X while (s[-1] != ':');
X s = cs = strsave(s);
X if (cs == NULL)
X break;
X end = FALSE;
X while (end == FALSE)
X {
X while (*s == ' ' || *s == TAB)
X ++s;
X if (*s == NUL)
X break;
X for (e = s; (*e != ':' || *(e - 1) == '\\') && *e != NUL; ++e)
X ;
X if (*e == NUL)
X end = TRUE;
X *e = NUL;
X if (STRNCMP(s, "set ", (size_t)4) == 0) /* "vi:set opt opt opt: foo" */
X {
X (void)doset(s + 4);
X break;
X }
X if (doset(s) == FAIL) /* stop if error found */
X break;
X s = e + 1;
X }
X free(cs);
X break;
X }
X prev = *s;
X }
X}
X
X/*
X * add extention to filename - change path/fo.o.h to path/fo.o.h.ext or
X * fo_o_h.ext for MSDOS or when dotfname option reset.
X *
X * Assumed that fname is a valid name found in the filesystem we assure that
X * the return value is a different name and ends in ".ext".
X * "ext" MUST start with a "." and MUST be at most 4 characters long.
X * Space for the returned name is allocated, must be freed later.
X */
X
X char_u *
Xmodname(fname, ext)
X char_u *fname, *ext;
X{
X return buf_modname(curbuf, fname, ext);


X}
X
X char_u *

Xbuf_modname(buf, fname, ext)
X BUF *buf;
X char_u *fname, *ext;
X{
X char_u *retval;
X register char_u *s;
X register char_u *ptr;
X register int fnamelen, extlen;
X char_u currentdir[512];
X
X extlen = STRLEN(ext);
X
X /*
X * if there is no filename we must get the name of the current directory
X * (we need the full path in case :cd is used)
X */
X if (fname == NULL || *fname == NUL)
X {
X if (vim_dirname(currentdir, 510) == FAIL || (fnamelen = STRLEN(currentdir)) == 0)
X return NULL;
X if (!ispathsep(currentdir[fnamelen - 1]))
X {
X currentdir[fnamelen++] = PATHSEP;
X currentdir[fnamelen] = NUL;
X }
X }
X else
X fnamelen = STRLEN(fname);
X retval = alloc((unsigned) (fnamelen + extlen + 1));
X if (retval != NULL)
X {


X if (fname == NULL || *fname == NUL)

X STRCPY(retval, currentdir);
X else
X STRCPY(retval, fname);
X /*
X * search backwards until we hit a '/', '\' or ':' replacing all '.' by '_'
X * for MSDOS or when dotfname option reset.
X * Then truncate what is after the '/', '\' or ':' to 8 characters for MSDOS
X * and 26 characters for AMIGA and UNIX.
X */
X for (ptr = retval + fnamelen; ptr >= retval; ptr--)
X {
X#ifndef MSDOS
X if (buf->b_p_sn || buf->b_shortname)
X#endif
X if (*ptr == '.') /* replace '.' by '_' */
X *ptr = '_';
X if (ispathsep(*ptr))
X break;
X }
X ptr++;
X
X /* the filename has at most BASENAMELEN characters. */
X if (STRLEN(ptr) > (unsigned)BASENAMELEN)
X ptr[BASENAMELEN] = '\0';
X#ifndef MSDOS
X if ((buf->b_p_sn || buf->b_shortname) && STRLEN(ptr) > (unsigned)8)
X ptr[8] = '\0';
X#endif
X s = ptr + STRLEN(ptr);
X
X /*
X * Append the extention.
X * ext must start with '.' and cannot exceed 3 more characters.
X */
X STRCPY(s, ext);
X#ifdef MSDOS
X if (fname == NULL || *fname == NUL) /* can't have just the extension */
X *s = '_';
X#endif
X if (fname != NULL && STRCMP(fname, retval) == 0)
X {
X /* after modification still the same name? */
X /* we search for a character that can be replaced by '_' */
X while (--s >= ptr)
X {
X if (*s != '_')
X {
X *s = '_';
X break;
X }
X }
X if (s < ptr)
X {
X /* fname was "________.<ext>" how tricky! */
X *ptr = 'v';
X }


X }
X }
X return retval;
X}
X

X#ifdef WEBB_COMPLETE
X/* vim_fgets();
X *
X * Like fgets(), but if the file line is too long, it is truncated and the
X * rest of the line is thrown away. Returns TRUE or FALSE for end-of-file or
X * not. The integer pointed to by lnum is incremented. Note: do not pass
X * IObuff as the buffer since this is used to read and discard the extra part
X * of any long lines.
X */
X int
Xvim_fgets(buf, size, fp, lnum)
X char_u *buf;
X int size;
X FILE *fp;
X int *lnum;
X{
X char *eof;
X
X buf[size - 2] = NUL;
X eof = fgets((char *)buf, size, fp);
X if (buf[size - 2] != NUL && buf[size - 2] != '\n')
X {
X buf[size - 1] = NUL; /* Truncate the line */
X
X /* Now throw away the rest of the line: */
X do
X {
X IObuff[IOSIZE - 2] = NUL;
X eof = fgets((char *)IObuff, IOSIZE, fp);
X } while (IObuff[IOSIZE - 2] != NUL && IObuff[IOSIZE - 2] != '\n');
X return FALSE;
X }
X ++*lnum;
X return (eof == NULL);


X}
X#endif /* WEBB_COMPLETE */
END_OF_FILE

if test 31526 -ne `wc -c <'vim/src/fileio.c'`; then
echo shar: \"'vim/src/fileio.c'\" unpacked with wrong size!
fi
# end of 'vim/src/fileio.c'
fi
if test -f 'vim/src/getchar.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/getchar.c'\"
else
echo shar: Extracting \"'vim/src/getchar.c'\" \(33517 characters\)
sed "s/^X//" >'vim/src/getchar.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * getchar.c
X *
X * functions related with getting a character from the user/mapping/redo/...
X *
X * manipulations with redo buffer and stuff buffer
X * mappings and abbreviations


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

X/*
X * structure used to store one block of the stuff/redo/macro buffers
X */
Xstruct bufblock
X{
X struct bufblock *b_next; /* pointer to next bufblock */
X char_u b_str[1]; /* contents (actually longer) */
X};
X
X#define MINIMAL_SIZE 20 /* minimal size for b_str */
X
X/*
X * header used for the stuff buffer and the redo buffer
X */
Xstruct buffheader
X{
X struct bufblock bh_first; /* first (dummy) block of list */
X struct bufblock *bh_curr; /* bufblock for appending */
X int bh_index; /* index for reading */
X int bh_space; /* space in bh_curr for appending */
X};
X
Xstatic struct buffheader stuffbuff = {{NULL, {NUL}}, NULL, 0, 0};
Xstatic struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
Xstatic struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
X
X /*
X * when block_redo is TRUE redo buffer will not be changed
X * used by edit() to repeat insertions and 'V' command for redoing
X */
Xstatic int block_redo = FALSE;
X
X/*
X * structure used for mapping
X */
Xstruct mapblock
X{
X struct mapblock *m_next; /* next mapblock */
X char_u *m_keys; /* mapped from */
X int m_keylen; /* strlen(m_keys) */
X char_u *m_str; /* mapped to */
X int m_mode; /* valid mode */
X int m_noremap; /* if non-zero no re-mapping for m_str */
X};
X
Xstatic struct mapblock maplist = {NULL, NULL, 0, NULL, 0, 0};
X /* first dummy entry in maplist */
X
X/*
X * variables used by vgetorpeek() and flush_buffers()
X *
X * typestr contains all characters that are not consumed yet.
X * The part in front may contain the result of mappings, abbreviations and
X * @a commands. The lenght of this part is typemaplen.
X * After it are characters that come from the terminal.
X * no_abbr_cnt is the number of characters in typestr that should not be
X * considered for abbreviations.
X * Some parts of typestr may not be mapped. These parts are remembered in
X * the noremaplist.
X */
X#define MAXMAPLEN 50 /* maximum length of key sequence to be mapped */
X /* must be able to hold an Amiga resize report */
Xstatic char_u *typestr = NULL; /* NUL-terminated buffer for typeahead characters */
Xstatic char_u typebuf[MAXMAPLEN + 3]; /* initial typestr */
X
Xstatic int typemaplen = 0; /* number of mapped characters in typestr */
Xstatic int no_abbr_cnt = 0; /* number of chars without abbrev. in typestr */
X
X/*
X * parts int typestr that should not be mapped are remembered with a list
X * of noremap structs. Noremaplist is the first.
X */
Xstruct noremap
X{
X int nr_off; /* offset to not remappable chars */
X int nr_len; /* number of not remappable chars */
X struct noremap *nr_next; /* next entry in the list */
X};
X
Xstatic struct noremap noremaplist = {0, 0, NULL};
X
Xstatic void free_buff __ARGS((struct buffheader *));
Xstatic char_u *get_bufcont __ARGS((struct buffheader *, int));
Xstatic void add_buff __ARGS((struct buffheader *, char_u *));
Xstatic void add_num_buff __ARGS((struct buffheader *, long));
Xstatic void add_char_buff __ARGS((struct buffheader *, int));
Xstatic int read_stuff __ARGS((int));
Xstatic void start_stuff __ARGS((void));
Xstatic int read_redo __ARGS((int));
Xstatic void init_typestr __ARGS((void));
Xstatic void gotchars __ARGS((char_u *, int));
Xstatic int vgetorpeek __ARGS((int));
Xstatic void showmap __ARGS((struct mapblock *));
X
X/*
X * free and clear a buffer


X */
X static void

Xfree_buff(buf)
X struct buffheader *buf;
X{
X register struct bufblock *p, *np;
X
X for (p = buf->bh_first.b_next; p != NULL; p = np)
X {
X np = p->b_next;
X free(p);
X }
X buf->bh_first.b_next = NULL;
X}
X
X/*
X * return the contents of a buffer as a single string


X */
X static char_u *

Xget_bufcont(buffer, dozero)
X struct buffheader *buffer;
X int dozero; /* count == zero is not an error */
X{
X long_u count = 0;
X char_u *p = NULL;
X struct bufblock *bp;
X
X/* compute the total length of the string */
X for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
X count += STRLEN(bp->b_str);
X
X if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
X {
X *p = NUL;
X for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
X strcat((char *)p, (char *)bp->b_str);
X }
X return (p);
X}
X
X/*
X * return the contents of the record buffer as a single string
X * and clear the record buffer


X */
X char_u *

Xget_recorded()


X{
X char_u *p;
X

X p = get_bufcont(&recordbuff, TRUE);
X free_buff(&recordbuff);
X return (p);
X}
X
X/*
X * return the contents of the redo buffer as a single string


X */
X char_u *

Xget_inserted()
X{
X return(get_bufcont(&redobuff, FALSE));
X}
X
X/*
X * add string "s" after the current block of buffer "buf"


X */
X static void

Xadd_buff(buf, s)
X register struct buffheader *buf;
X char_u *s;
X{
X struct bufblock *p;
X long_u n;
X long_u len;
X
X if ((n = STRLEN(s)) == 0) /* don't add empty strings */
X return;
X
X if (buf->bh_first.b_next == NULL) /* first add to list */
X {
X buf->bh_space = 0;
X buf->bh_curr = &(buf->bh_first);
X }
X else if (buf->bh_curr == NULL) /* buffer has already been read */
X {
X EMSG("Add to read buffer");
X return;
X }
X else if (buf->bh_index != 0)
X STRCPY(buf->bh_first.b_next->b_str, buf->bh_first.b_next->b_str + buf->bh_index);
X buf->bh_index = 0;
X
X if (buf->bh_space >= n)
X {
X strcat((char *)buf->bh_curr->b_str, (char *)s);
X buf->bh_space -= n;
X }
X else
X {
X if (n < MINIMAL_SIZE)
X len = MINIMAL_SIZE;
X else
X len = n;
X p = (struct bufblock *)lalloc((long_u)(sizeof(struct bufblock) + len), TRUE);


X if (p == NULL)

X return; /* no space, just forget it */
X buf->bh_space = len - n;
X STRCPY(p->b_str, s);
X
X p->b_next = buf->bh_curr->b_next;
X buf->bh_curr->b_next = p;
X buf->bh_curr = p;


X }
X return;
X}
X

X static void
Xadd_num_buff(buf, n)
X struct buffheader *buf;
X long n;
X{
X char_u number[32];
X
X sprintf((char *)number, "%ld", n);
X add_buff(buf, number);


X}
X
X static void

Xadd_char_buff(buf, c)
X struct buffheader *buf;
X int c;
X{
X char_u temp[2];
X
X temp[0] = c;


X temp[1] = NUL;

X add_buff(buf, temp);
X}
X
X/*
X * get one character from the stuff buffer
X * If advance == TRUE go to the next char.


X */
X static int

Xread_stuff(advance)
X int advance;


X{
X register char_u c;

X register struct bufblock *curr;
X
X
X if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */
X return NUL;
X
X curr = stuffbuff.bh_first.b_next;
X c = curr->b_str[stuffbuff.bh_index];
X
X if (advance)
X {
X if (curr->b_str[++stuffbuff.bh_index] == NUL)
X {
X stuffbuff.bh_first.b_next = curr->b_next;
X free(curr);
X stuffbuff.bh_index = 0;
X }
X }
X return c;
X}
X
X/*
X * prepare stuff buffer for reading (if it contains something)


X */
X static void

Xstart_stuff()
X{
X if (stuffbuff.bh_first.b_next != NULL)
X {
X stuffbuff.bh_curr = &(stuffbuff.bh_first);
X stuffbuff.bh_space = 0;
X }
X}
X
X/*
X * check if the stuff buffer is empty
X */
X int
Xstuff_empty()
X{
X return (stuffbuff.bh_first.b_next == NULL);
X}
X
X/*
X * Remove the contents of the stuff buffer and the mapped characters in the
X * typeahead buffer (used in case of an error). If 'typeahead' is true,
X * flush all typeahead characters (used when interrupted by a CTRL-C).
X */
X void
Xflush_buffers(typeahead)
X int typeahead;
X{
X struct noremap *p;
X
X init_typestr();
X
X start_stuff();
X while (read_stuff(TRUE) != NUL)
X ;
X
X if (typeahead) /* remove all typeahead */
X {
X /*
X * We have to get all characters, because we may delete the first
X * part of an escape sequence.
X * In an xterm we get one char at a time and we have to get them all.
X */
X while (inchar(typestr, MAXMAPLEN, 10))
X ;
X *typestr = NUL;
X }
X else /* remove mapped characters only */
X STRCPY(typestr, typestr + typemaplen);
X typemaplen = 0;
X no_abbr_cnt = 0;
X noremaplist.nr_len = 0;
X noremaplist.nr_off = 0;
X while (noremaplist.nr_next)
X {
X p = noremaplist.nr_next->nr_next;
X free(noremaplist.nr_next);
X noremaplist.nr_next = p;
X }
X}
X
X void
XResetRedobuff()
X{
X if (!block_redo)
X free_buff(&redobuff);
X}
X
X void
XAppendToRedobuff(s)
X char_u *s;
X{
X if (!block_redo)
X add_buff(&redobuff, s);
X}
X
X void
XAppendCharToRedobuff(c)
X int c;
X{
X if (!block_redo)
X add_char_buff(&redobuff, c);
X}
X
X void
XAppendNumberToRedobuff(n)
X long n;
X{
X if (!block_redo)
X add_num_buff(&redobuff, n);
X}
X
X void
XstuffReadbuff(s)
X char_u *s;
X{
X add_buff(&stuffbuff, s);
X}
X
X void
XstuffcharReadbuff(c)
X int c;
X{
X add_char_buff(&stuffbuff, c);
X}
X
X void
XstuffnumReadbuff(n)
X long n;
X{
X add_num_buff(&stuffbuff, n);
X}
X
X/*
X * Read a character from the redo buffer.
X * The redo buffer is left as it is.
X * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK otherwise
X */
X static int
Xread_redo(init)
X int init;
X{
X static struct bufblock *bp;
X static char_u *p;
X int c;
X
X if (init)
X {
X if ((bp = redobuff.bh_first.b_next) == NULL)
X return FAIL;
X p = bp->b_str;
X return OK;
X }
X if ((c = *p) != NUL)
X {
X if (*++p == NUL && bp->b_next != NULL)
X {
X bp = bp->b_next;
X p = bp->b_str;
X }
X }
X return c;
X}
X
X/*
X * copy the rest of the redo buffer into the stuff buffer (could be done faster)
X */
X void
Xcopy_redo()
X{


X register int c;
X

X while ((c = read_redo(FALSE)) != NUL)
X stuffcharReadbuff(c);
X}
X
Xextern int redo_Visual_busy; /* this is in normal.c */
X
X/*
X * Stuff the redo buffer into the stuffbuff.
X * Insert the redo count into the command.
X * return FAIL for failure, OK otherwise
X */
X int
Xstart_redo(count)
X long count;
X{
X register int c;
X
X if (read_redo(TRUE) == FAIL) /* init the pointers; return if nothing to redo */
X return FAIL;
X
X c = read_redo(FALSE);
X
X/* copy the buffer name, if present */
X if (c == '"')
X {
X add_buff(&stuffbuff, (char_u *)"\"");
X c = read_redo(FALSE);
X
X/* if a numbered buffer is used, increment the number */
X if (c >= '1' && c < '9')
X ++c;
X add_char_buff(&stuffbuff, c);
X c = read_redo(FALSE);
X }
X
X if (c == 'v') /* redo Visual */
X {


X VIsual = curwin->w_cursor;

X redo_Visual_busy = TRUE;
X c = read_redo(FALSE);
X }
X
X/* try to enter the count (in place of a previous count) */
X if (count)
X {
X while (isdigit(c)) /* skip "old" count */
X c = read_redo(FALSE);
X add_num_buff(&stuffbuff, count);
X }
X
X/* copy from the redo buffer into the stuff buffer */
X add_char_buff(&stuffbuff, c);
X copy_redo();


X return OK;
X}
X
X/*

X * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
X * the redo buffer into the stuffbuff.
X * return FAIL for failure, OK otherwise
X */
X int
Xstart_redo_ins()
X{
X register int c;
X
X if (read_redo(TRUE) == FAIL)
X return FAIL;
X start_stuff();
X
X/* skip the count and the command character */
X while ((c = read_redo(FALSE)) != NUL)


X {
X c = TO_UPPER(c);

X if (strchr("AIRO", c) != NULL)
X {
X if (c == 'O')
X stuffReadbuff(NL_STR);


X break;
X }
X }
X

X/* copy the typed text from the redo buffer into the stuff buffer */
X copy_redo();
X block_redo = TRUE;


X return OK;
X}
X

X void
Xset_redo_ins()
X{
X block_redo = TRUE;
X}
X
X void
Xstop_redo_ins()
X{
X block_redo = FALSE;
X}
X
X/*
X * Initialize typestr to point to typebuf.
X * Alloc() cannot be used here: In out-of-memory situations it would
X * be impossible to type anything.


X */
X static void

Xinit_typestr()
X{
X if (typestr == NULL)
X {
X typestr = typebuf;
X typebuf[0] = NUL;
X }
X}
X
X/*
X * insert a string in front of the typeahead buffer (for '@' command and vgetorpeek)
X * return FAIL for failure, OK otherwise
X */
X int
Xins_typestr(str, noremap)
X char_u *str;
X int noremap;
X{
X register char_u *s;
X register int newlen;
X register int addlen;
X
X init_typestr();
X
X /*
X * In typestr there must always be room for MAXMAPLEN + 3 characters
X */
X addlen = STRLEN(str);
X newlen = STRLEN(typestr) + addlen + MAXMAPLEN + 3;
X if (newlen < 0) /* string is getting too long */
X {
X emsg(e_toocompl); /* also calls flush_buffers */
X setcursor();
X return FAIL;
X }
X s = alloc(newlen);
X if (s == NULL) /* out of memory */
X return FAIL;
X
X STRCPY(s, str);
X STRCAT(s, typestr);
X if (typestr != typebuf)
X free(typestr);
X typestr = s;
X typemaplen += addlen; /* the inserted string is not typed */
X if (no_abbr_cnt) /* and not used for abbreviations */
X no_abbr_cnt += addlen;
X if (noremap)
X {
X if (noremaplist.nr_off == 0)
X noremaplist.nr_len += addlen;
X else
X {
X struct noremap *p;
X
X p = (struct noremap *)alloc((int)sizeof(struct noremap));


X if (p != NULL)

X {
X p->nr_next = noremaplist.nr_next;
X p->nr_off = noremaplist.nr_off;
X p->nr_len = noremaplist.nr_len;
X noremaplist.nr_next = p;
X noremaplist.nr_len = addlen;
X noremaplist.nr_off = 0;
X }
X }
X }
X else if (noremaplist.nr_len)
X noremaplist.nr_off += addlen;


X return OK;
X}
X
X/*

X * remove "len" characters from the front of typestr
X */
X void
Xdel_typestr(len)
X int len;
X{
X struct noremap *p;
X
X STRCPY(typestr, typestr + len);
X /* remove chars from the buffer */
X if ((typemaplen -= len) < 0) /* adjust typemaplen */
X typemaplen = 0;
X if ((no_abbr_cnt -= len) < 0) /* adjust no_abbr_cnt */
X no_abbr_cnt = 0;
X
X while (len) /* adjust noremaplist */
X {
X if (noremaplist.nr_off >= len)
X {
X noremaplist.nr_off -= len;
X break;
X }
X len -= noremaplist.nr_off;
X noremaplist.nr_off = 0;
X if (noremaplist.nr_len > len)
X {
X noremaplist.nr_len -= len;
X break;
X }
X len -= noremaplist.nr_len;
X p = noremaplist.nr_next;


X if (p == NULL)

X {
X noremaplist.nr_len = 0;
X break;
X }
X noremaplist.nr_next = p->nr_next;
X noremaplist.nr_len = p->nr_len;
X noremaplist.nr_off = p->nr_off;


X free(p);
X }
X}
X

Xextern int arrow_used; /* this is in edit.c */
X
X/*
X * Write typed characters to script file.
X * If recording is on put the character in the recordbuffer.


X */
X static void

Xgotchars(s, len)
X char_u *s;
X int len;
X{
X while (len--)
X {
X updatescript(*s & 255);
X
X if (Recording)
X add_char_buff(&recordbuff, (*s & 255));
X ++s;
X }
X
X /* do not sync in insert mode, unless cursor key has been used */
X if (!(State & (INSERT + CMDLINE)) || arrow_used)
X u_sync();
X}
X
X/*
X * open new script file for ":so!" command
X * return OK on success, FAIL on error
X */
X int
Xopenscript(name)
X char_u *name;
X{
X int oldcurscript;
X
X if (curscript + 1 == NSCRIPT)
X {
X emsg(e_nesting);
X return FAIL;
X }
X else
X {
X if (scriptin[curscript] != NULL) /* already reading script */
X ++curscript;
X if ((scriptin[curscript] = fopen((char *)name, READBIN)) == NULL)
X {
X emsg2(e_notopen, name);
X if (curscript)
X --curscript;
X return FAIL;
X }
X /*
X * With command ":g/pat/so! file" we have to execute the
X * commands from the file now.
X */
X if (global_busy)
X {
X State = NORMAL;
X oldcurscript = curscript;
X do
X {
X normal();
X vpeekc(); /* check for end of file */
X }
X while (scriptin[oldcurscript]);


X State = CMDLINE;
X }

X }
X return OK;
X}
X
X/*

X * updatescipt() is called when a character can be written into the script file
X * or when we have waited some time for a character (c == 0)
X *
X * All the changed memfiles are synced if c == 0 or when the number of typed
X * characters reaches 'updatecount'.
X */
X void
Xupdatescript(c)
X int c;
X{
X static int count = 0;
X
X if (c && scriptout)
X putc(c, scriptout);
X if (c == 0 || ++count >= p_uc)
X {
X ml_sync_all(c == 0);


X count = 0;
X }

X}
X
X#define NEEDMORET 9999 /* value for incomplete mapping or key-code */
X
X/*
X * get a character: 1. from the stuffbuffer
X * 2. from the typeahead buffer
X * 3. from the user
X *
X * KeyTyped is set to TRUE in the case the user typed the key.
X * vgetc() (advance is TRUE): really get the character.
X * vpeekc() (advance is FALSE): just look whether there is a character available.
X */
X int
Xvgetc()
X{
X return (vgetorpeek(TRUE));
X}
X
X int
Xvpeekc()
X{
X return (vgetorpeek(FALSE));


X}
X
X static int

Xvgetorpeek(advance)
X int advance;
X{
X register int c;
X int n = 0; /* init for GCC */
X int len;
X#ifdef AMIGA
X char_u *s;
X#endif
X register struct mapblock *mp;
X int timedout = FALSE; /* waited for more than 1 second
X for mapping to complete */
X int mapdepth = 0; /* check for recursive mapping */
X int mode_deleted = FALSE; /* set when mode has been deleted */
X
X init_typestr();
X start_stuff();
X if (typemaplen == 0)
X Exec_reg = FALSE;
X do
X {
X c = read_stuff(advance);
X if (c != NUL && !got_int)
X KeyTyped = FALSE;
X else
X {
X /*
X * Loop until we either find a matching mapped key, or we
X * are sure that it is not a mapped key.
X * If a mapped key sequence is found we go back to the start to
X * try re-mapping.
X */


X
X for (;;)
X {

X len = STRLEN(typestr);
X breakcheck(); /* check for CTRL-C */
X if (got_int)
X {
X c = inchar(typestr, MAXMAPLEN, 0); /* flush all input */
X /*
X * If inchar returns TRUE (script file was active) or we are
X * inside a mapping, get out of insert mode.
X * Otherwise we behave like having gotten a CTRL-C.
X * As a result typing CTRL-C in insert mode will
X * really insert a CTRL-C.
X */
X if ((c || typemaplen) && (State & (INSERT + CMDLINE)))
X c = ESC;
X else
X c = Ctrl('C');
X flush_buffers(TRUE); /* flush all typeahead */
X break;
X }
X else if (len > 0) /* see if we have a mapped key sequence */
X {
X /*
X * walk through the maplist until we find an
X * entry that matches.
X *
X * Don't look for mappings if:
X * - timed out
X * - typestr[0] should not be remapped
X * - in insert or cmdline mode and 'paste' option set
X * - waiting for "hit return to continue" and CR or SPACE typed
X */
X mp = NULL;
X if (!timedout && (typemaplen == 0 || (p_remap &&
X (noremaplist.nr_len == 0 || noremaplist.nr_off != 0)))
X && !((State & (INSERT + CMDLINE)) && p_paste)
X && !(State == HITRETURN && (typestr[0] == CR || typestr[0] == ' ')))
X {
X for (mp = maplist.m_next; mp; mp = mp->m_next)
X {
X if ((mp->m_mode & ABBREV) || !(mp->m_mode & State))
X continue;
X n = mp->m_keylen;
X if (noremaplist.nr_off != 0 && n > noremaplist.nr_off)
X continue;
X if (!STRNCMP(mp->m_keys, typestr, (size_t)(n > len ? len : n)))
X break;
X }
X }
X if (mp == NULL) /* no match found */
X {
X /*
X * check if we have a terminal code, when
X * mapping is allowed,
X * keys have not been mapped,
X * and not an ESC sequence, not in insert mode or
X * p_ek is on,
X * and when not timed out,
X */
X if (State != NOMAPPING &&
X /* typemaplen == 0 && */ /* allow mapped keys anyway */
X (typestr[0] != ESC || p_ek || !(State & INSERT)) &&
X !timedout)
X n = check_termcode(typestr);
X else
X n = 0;
X if (n == 0) /* no matching terminal code */
X {
X#ifdef AMIGA /* check for window bounds report */
X if (typemaplen == 0 && (typestr[0] & 0xff) == CSI)
X {
X for (s = typestr + 1; isdigit(*s) || *s == ';' || *s == ' '; ++s)
X ;
X if (*s == 'r' || *s == '|') /* found one */
X {
X STRCPY(typestr, s + 1);
X set_winsize(0, 0, FALSE); /* get size and redraw screen */
X continue;
X }
X if (*s == NUL) /* need more characters */
X n = -1;
X }
X if (n != -1) /* got a single character */
X#endif
X {
X c = typestr[0] & 255;
X if (typemaplen)
X KeyTyped = FALSE;
X else
X {
X KeyTyped = TRUE;
X if (advance) /* write char to script file(s) */
X gotchars(typestr, 1);
X }
X if (advance) /* remove chars from typestr */
X del_typestr(1);
X break; /* got character, break for loop */
X }
X }
X if (n > 0) /* full matching terminal code */
X continue; /* try mapping again */
X
X /* partial match: get some more characters */
X n = NEEDMORET;
X }
X if (n <= len) /* complete match */
X {
X if (n > typemaplen) /* write chars to script file(s) */
X gotchars(typestr + typemaplen, n - typemaplen);
X
X del_typestr(n); /* remove the mapped keys */
X
X /*
X * Put the replacement string in front of mapstr.
X * The depth check catches ":map x y" and ":map y x".
X */
X if (++mapdepth == 1000)
X {
X EMSG("recursive mapping");


X if (State == CMDLINE)
X redrawcmdline();
X else
X setcursor();

X flush_buffers(FALSE);
X mapdepth = 0; /* for next one */
X c = -1;
X break;
X }
X if (ins_typestr(mp->m_str, mp->m_noremap) == FAIL)
X {
X c = -1;
X break;
X }
X continue;
X }
X }
X /*
X * special case: if we get an <ESC> in insert mode and there are
X * no more characters at once, we pretend to go out of insert mode.
X * This prevents the one second delay after typing an <ESC>.
X * If we get something after all, we may have to redisplay the
X * mode. That the cursor is in the wrong place does not matter.
X */
X c = 0;
X if (advance && len == 1 && typestr[0] == ESC && typemaplen == 0 && (State & INSERT) && (p_timeout || (n == NEEDMORET && p_ttimeout)) && (c = inchar(typestr + len, 2, 0)) == 0)
X {
X if (p_smd)
X {
X delmode();
X mode_deleted = TRUE;
X }
X if (curwin->w_cursor.col != 0) /* move cursor one left if possible */
X {
X if (curwin->w_col)
X {
X if (did_ai)
X {
X if (curwin->w_p_nu)
X curwin->w_col = 8;
X else
X curwin->w_col = 0;
X }
X else
X --curwin->w_col;
X }
X else if (curwin->w_p_wrap && curwin->w_row)
X {
X --curwin->w_row;
X curwin->w_col = Columns - 1;
X }
X }
X setcursor();
X flushbuf();
X }
X len += c;
X
X if (len >= typemaplen + MAXMAPLEN) /* buffer full, don't map */
X {
X timedout = TRUE;
X continue;
X }
X c = inchar(typestr + len, typemaplen + MAXMAPLEN - len, !advance ? 0 : ((len == 0 || !(p_timeout || (p_ttimeout && n == NEEDMORET))) ? -1 : (int)p_tm));
X if (c <= NUL) /* no character available */
X {
X if (!advance)
X break;
X if (len) /* timed out */
X {
X timedout = TRUE;
X continue;
X }
X }
X } /* for (;;) */
X } /* if (!character from stuffbuf) */
X
X /* if advance is FALSE don't loop on NULs */
X } while (c < 0 || (advance && c == NUL));
X
X /*
X * The "INSERT" message is taken care of here:
X * if we return an ESC the message is deleted
X * if we don't return an ESC but deleted the message before, redisplay it
X */
X if (p_smd && (State & INSERT))
X {
X if (c == ESC && !mode_deleted)
X delmode();
X else if (c != ESC && mode_deleted)
X showmode();
X }
X
X return c;
X}
X
X/*
X * map[!] : show all key mappings
X * map[!] {lhs} : show key mapping for {lhs}
X * map[!] {lhs} {rhs} : set key mapping for {lhs} to {rhs}
X * noremap[!] {lhs} {rhs} : same, but no remapping for {rhs}
X * unmap[!] {lhs} : remove key mapping for {lhs}
X * abbr : show all abbreviations
X * abbr {lhs} : show abbreviations for {lhs}
X * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs}
X * noreabbr {lhs} {rhs} : same, but no remapping for {rhs}
X * unabbr {lhs} : remove abbreviation for {lhs}
X *
X * maptype == 1 for unmap command, 2 for noremap command.
X *
X * keys is pointer to any arguments.
X *
X * for :map mode is NORMAL
X * for :map! mode is INSERT + CMDLINE
X * for :cmap mode is CMDLINE
X * for :imap mode is INSERT
X * for :abbr mode is INSERT + CMDLINE + ABBREV
X * for :iabbr mode is INSERT + ABBREV
X * for :cabbr mode is CMDLINE + ABBREV
X *
X * Return 0 for success
X * 1 for invalid arguments
X * 2 for no match
X * 3 for ambiguety
X * 4 for out of mem
X */
X int
Xdomap(maptype, keys, mode)
X int maptype;
X char_u *keys;
X int mode;
X{
X struct mapblock *mp, *mprev;
X char_u *arg;
X char_u *p;
X int n = 0; /* init for GCC */
X int len = 0; /* init for GCC */
X char_u *newstr;
X int hasarg;
X int haskey;
X int did_it = FALSE;
X int abbrev = 0;
X int round;
X
X if (mode & ABBREV) /* not a mapping but an abbreviation */
X {
X abbrev = ABBREV;
X mode &= ~ABBREV;
X }
X/*
X * find end of keys and remove CTRL-Vs in it
X * with :unmap white space is included in the keys, no argument possible
X */
X p = keys;
X while (*p && (maptype == 1 || !iswhite(*p)))
X {
X if (*p == Ctrl('V') && p[1] != NUL)
X STRCPY(p, p + 1); /* remove CTRL-V */
X ++p;
X }
X if (*p != NUL)
X *p++ = NUL;
X skipspace(&p);
X arg = p;
X hasarg = (*arg != NUL);
X haskey = (*keys != NUL);
X
X /* check for :unmap without argument */
X if (maptype == 1 && !haskey)
X return 1;
X
X/*
X * remove CTRL-Vs from argument
X */
X while (*p)
X {
X if (*p == Ctrl('V') && p[1] != NUL)
X STRCPY(p, p + 1); /* remove CTRL-V */
X ++p;
X }
X
X/*
X * check arguments and translate function keys
X */
X if (haskey)
X {
X if (*keys == '#' && isdigit(*(keys + 1))) /* function key */
X {
X if (*++keys == '0')
X *keys = K_F10;
X else
X *keys += K_F1 - '1';
X }
X len = STRLEN(keys);
X if (len > MAXMAPLEN) /* maximum lenght of MAXMAPLEN chars */
X return 1;
X
X /*
X * abbreviation must end in id-char
X * rest must be all id-char or all non-id-char
X */
X if (abbrev)
X {
X if (!isidchar(*(keys + len - 1))) /* does not end in id char */
X return 1;
X for (n = 0; n < len - 2; ++n)
X if (isidchar(*(keys + n)) != isidchar(*(keys + len - 2)))
X return 1;
X }
X }
X
X if (haskey && hasarg && abbrev) /* if we will add an abbreviation */
X no_abbr = FALSE; /* reset flag that indicates there are
X no abbreviations */
X
X if (!haskey || (maptype != 1 && !hasarg))
X msg_start();
X/*
X * Find an entry in the maplist that matches.
X * For :unmap we may loop two times: once to try to unmap an entry with a
X * matching 'from' part, a second time, if the first fails, to unmap an
X * entry with a matching 'to' part. This was done to allow ":ab foo bar" to be
X * unmapped by typing ":unab foo", where "foo" will be replaced by "bar" because
X * of the abbreviation.
X */
X for (round = 0; (round == 0 || maptype == 1) && round <= 1 && !did_it && !got_int; ++round)
X {
X for (mp = maplist.m_next, mprev = &maplist; mp && !got_int; mprev = mp, mp = mp->m_next)
X {
X /* skip entries with wrong mode */
X if (!(mp->m_mode & mode) || (mp->m_mode & ABBREV) != abbrev)
X continue;
X if (!haskey) /* show all entries */
X {
X showmap(mp);
X did_it = TRUE;
X }
X else /* do we have a match? */
X {
X if (round) /* second round: try 'to' string for unmap */
X {
X n = STRLEN(mp->m_str);
X p = mp->m_str;
X }
X else
X {
X n = mp->m_keylen;
X p = mp->m_keys;
X }
X if (!STRNCMP(p, keys, (size_t)(n < len ? n : len)))
X {
X if (maptype == 1) /* delete entry */
X {
X if (n != len) /* not a full match */
X continue;
X /*
X * We reset the indicated mode bits. If nothing is left the
X * entry is deleted below.
X */
X mp->m_mode &= (~mode | ABBREV);
X did_it = TRUE; /* remember that we did something */
X }
X else if (!hasarg) /* show matching entry */
X {
X showmap(mp);
X did_it = TRUE;
X }
X else if (n != len) /* new entry is ambigious */
X {
X if (abbrev) /* for abbreviations that's ok */
X continue;
X return 3;
X }
X else
X {
X mp->m_mode &= (~mode | ABBREV); /* remove mode bits */
X if (!(mp->m_mode & ~ABBREV) && !did_it) /* reuse existing entry */
X {
X newstr = strsave(arg);
X if (newstr == NULL)
X return 4; /* no mem */
X free(mp->m_str);
X mp->m_str = newstr;
X mp->m_noremap = maptype;
X mp->m_mode = mode + abbrev;
X did_it = TRUE;
X }
X }
X if (!(mp->m_mode & ~ABBREV)) /* entry can be deleted */
X {
X free(mp->m_keys);
X free(mp->m_str);


X mprev->m_next = mp->m_next;

X free(mp);
X mp = mprev; /* continue with next entry */


X }
X }
X }
X }
X }

X
X if (maptype == 1) /* delete entry */
X {
X if (did_it)
X return 0; /* removed OK */
X else
X return 2; /* no match */
X }
X
X if (!haskey || !hasarg) /* print entries */
X {
X if (did_it)
X msg_end();
X else if (abbrev)
X MSG("No abbreviation found");
X else
X MSG("No mapping found");
X return 0; /* listing finished */
X }
X
X if (did_it) /* have added the new entry already */
X return 0;
X/*
X * get here when we have to add a new entry
X */
X /* allocate a new entry for the maplist */
X mp = (struct mapblock *)alloc((unsigned)sizeof(struct mapblock));


X if (mp == NULL)

X return 4; /* no mem */
X mp->m_keys = strsave(keys);
X mp->m_str = strsave(arg);
X if (mp->m_keys == NULL || mp->m_str == NULL)
X {
X free(mp->m_keys);
X free(mp->m_str);
X free(mp);
X return 4; /* no mem */
X }
X mp->m_keylen = STRLEN(mp->m_keys);
X mp->m_noremap = maptype;
X mp->m_mode = mode + abbrev;
X
X /* add the new entry in front of the maplist */
X mp->m_next = maplist.m_next;
X maplist.m_next = mp;
X
X return 0; /* added OK */


X}
X
X static void

Xshowmap(mp)
X struct mapblock *mp;


X{
X int len;
X

X msg_pos(-1, 0); /* always start in column 0 */
X if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
X msg_outstr((char_u *)"! ");
X else if (mp->m_mode & INSERT)
X msg_outstr((char_u *)"i ");
X else if (mp->m_mode & CMDLINE)
X msg_outstr((char_u *)"c ");
X len = msg_outtrans(mp->m_keys, -1); /* get length of what we have written */
X do
X {
X msg_outchar(' '); /* padd with blanks */
X ++len;
X } while (len < 12);
X if (mp->m_noremap)
X msg_outchar('*');
X else
X msg_outchar(' ');
X msg_outtrans(mp->m_str, -1);
X msg_outchar('\n');
X flushbuf(); /* show one line at a time */
X}
X
X/*
X * Check for an abbreviation.
X * Cursor is at ptr[col]. When inserting, mincol is where insert started.
X * "c" is the character typed before check_abbr was called.
X *
X * Historic vi practice: The last character of an abbreviation must be an id
X * character ([a-zA-Z0-9_]). The characters in front of it must be all id
X * characters or all non-id characters. This allows for abbr. "#i" to "#include".
X *
X * return TRUE if there is an abbreviation, FALSE if not
X */
X int
Xcheck_abbr(c, ptr, col, mincol)
X int c;
X char_u *ptr;
X int col;
X int mincol;
X{
X int len;
X int j;
X char_u tb[3];
X struct mapblock *mp;
X int is_id = TRUE;
X
X if (no_abbr_cnt) /* abbrev. are not recursive */
X return FALSE;
X
X if (col == 0 || !isidchar(ptr[col - 1])) /* cannot be an abbr. */
X return FALSE;
X
X if (col > 1)
X is_id = isidchar(ptr[col - 2]);
X for (len = col - 1; len > 0 && !isspace(ptr[len - 1]) &&
X is_id == isidchar(ptr[len - 1]); --len)
X ;
X
X if (len < mincol)
X len = mincol;
X if (len < col) /* there is a word in front of the cursor */
X {
X ptr += len;
X len = col - len;
X for (mp = maplist.m_next; mp; mp = mp->m_next)
X {
X /* find entries with right mode and keys */
X if ((mp->m_mode & ABBREV) == ABBREV &&
X (mp->m_mode & State) &&
X mp->m_keylen == len &&
X !STRNCMP(mp->m_keys, ptr, (size_t)len))
X break;
X }
X if (mp) /* found a match */
X {
X j = 0;
X if (c < 0x100 && (c < ' ' || c > '~'))
X tb[j++] = Ctrl('V'); /* special char needs CTRL-V */
X tb[j++] = c;
X tb[j] = NUL;
X (void)ins_typestr(tb, TRUE); /* insert the last typed char */
X (void)ins_typestr(mp->m_str, mp->m_noremap); /* insert the to string */
X no_abbr_cnt += STRLEN(mp->m_str) + j; /* no abbrev. for these chars */
X while (len--)
X (void)ins_typestr((char_u *)"\b", TRUE); /* delete the from string */


X return TRUE;
X }
X }

X return FALSE;
X}
X
X/*
X * Write map commands for the current mappings to an .exrc file.


X * Return FAIL on error, OK otherwise.
X */
X int

Xmakemap(fd)
X FILE *fd;
X{
X struct mapblock *mp;
X char_u c1;
X char_u *p;
X
X for (mp = maplist.m_next; mp; mp = mp->m_next)
X {
X c1 = NUL;
X p = (char_u *)"map";
X switch (mp->m_mode)
X {
X case NORMAL:
X break;
X case CMDLINE + INSERT:
X p = (char_u *)"map!";
X break;
X case CMDLINE:
X c1 = 'c';
X break;
X case INSERT:
X c1 = 'i';
X break;
X case INSERT + CMDLINE + ABBREV:
X p = (char_u *)"abbr";
X break;
X case CMDLINE + ABBREV:
X c1 = 'c';
X p = (char_u *)"abbr";
X break;
X case INSERT + ABBREV:
X c1 = 'i';
X p = (char_u *)"abbr";
X break;
X default:
X EMSG("makemap: Illegal mode");
X return FAIL;
X }
X if (c1 && putc(c1, fd) < 0)
X return FAIL;
X if (mp->m_noremap && fprintf(fd, "nore") < 0)
X return FAIL;
X if (fprintf(fd, (char *)p) < 0)
X return FAIL;
X
X if ( putc(' ', fd) < 0 || putescstr(fd, mp->m_keys, FALSE) == FAIL ||
X putc(' ', fd) < 0 || putescstr(fd, mp->m_str, FALSE) == FAIL ||
X#ifdef MSDOS
X putc('\r', fd) < 0 ||
X#endif
X putc('\n', fd) < 0)


X return FAIL;
X }
X return OK;
X}
X
X/*

X * write escape string to file
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xputescstr(fd, str, set)
X FILE *fd;
X char_u *str;
X int set; /* TRUE for makeset, FALSE for makemap */
X{
X for ( ; *str; ++str)
X {
X /*
X * some characters have to be escaped with CTRL-V to
X * prevent them from misinterpreted in DoOneCmd().
X * A space has to be escaped with a backslash to
X * prevent it to be misinterpreted in doset().
X */
X if (*str < ' ' || *str > '~' || (*str == ' ' && !set))
X {
X if (putc(Ctrl('V'), fd) < 0)
X return FAIL;
X }
X else if ((set && *str == ' ') || *str == '|')
X {
X if (putc('\\', fd) < 0)
X return FAIL;
X }
X if (putc(*str, fd) < 0)


X return FAIL;
X }
X return OK;
X}

END_OF_FILE
if test 33517 -ne `wc -c <'vim/src/getchar.c'`; then
echo shar: \"'vim/src/getchar.c'\" unpacked with wrong size!
fi
# end of 'vim/src/getchar.c'
fi
echo shar: End of archive 15 \(of 26\).
cp /dev/null ark15isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:02:52 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 35
Archive-name: vim/part16

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/readme3.0 vim/src/winnt.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:09 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 16 (of 26)."'
if test -f 'vim/readme3.0' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/readme3.0'\"
else
echo shar: Extracting \"'vim/readme3.0'\" \(34259 characters\)
sed "s/^X//" >'vim/readme3.0' <<'END_OF_FILE'
XThis file contains an overview of changes from Vim version 2.0 to 3.0
X
XThe changes new in version 2.x are marked with (2.x).
XSome changes from Robert Webb are marked with (Webb 2.5).
X
XBig improvements
X================
X
XAdded multiple windows and multiple buffers! See doc/windows.doc for an
Xoverview of the new and changed commands.
X
XAdded hidden buffers. 'hidden' option can be set to create a hidden buffer
Xinstead of abandoning a buffer. Added ":bnext", ":bprev", ":bNext" and
X"brewind" commands to go to other buffer. Added ":buffers" command to show all
Xbuffers. Added ":bmod" command: go to next modified buffer. Added ":bdelete"
Xcommand: delete buffer from list. (2.4)
X
XAdded a lot of commands to manipulate buffers:
X- Added commands to open a window for all arguments, all active buffers, all
X buffers: ":all", ":sall", ":unhide", ":sunhide", ":ball", ":sball". (2.5)
X- Added ":bunload" command: Unload buffer from memory. The ":bdelete" command
X does the same plus deletes the buffer from the buffer list. (2.5)
X- Arguments from command line are always put in buffer list. (2.5)
X- Added ":sbuffer", ":sbnext", ":sbNext", ":sbprevious", ":sbmodified",
X ":sbrewind", ":sblast": split window and go to specified buffer. (2.5)
X- Added ":wNext" and ":wprevious": write file and go back in argument list.
X (2.5)
X- Added ":wqall" and ":xall", write all change buffers and exit. (2.5)
X
X
XWhen all changes have been undone the buffer is not considered to be changed.
XVim can then be exit with ":q" instead of ":q!".
X
XAdded simple "more" facility to listings. Can be switched on/off with the
X'more' option.
X
XAdded Webb's code for command line completion, with "#ifdef WEBB_COMPLETE".
X(Webb 2.5)
X
X
XChanges incompatible with previous versions
X===========================================
X
XCommand lines starting with '#' are no longer considered to be comments. '#'
Xis a synonym for :number.
X
XEmbedded newline characters in command lines are considered to be the end of a
Xcommand line. To use newline characters in a command, precede it with CTRL-V
X(you have to type CTRL-V two times to get one).
X
XThe ":files" command is now the same as the ":buffers" command. The file list
Xand the buffer list have been integrated into one list. The buffer number and
Xthe file number are equal and will not change during an editing session. (2.5)
X
X":buffer" does not accept a file name but a buffer number. Use ":set hid" and
X":e file". (2.5)
X
XMade 'laststatus' a numeric option. It says when to use a status line for last
Xwindow: 0 is never, 1 if more than one window, 2 is always. (2.5)
X
XReplaced CTRL-P in insert mode by CTRL-B (for Backwards). CTRL-P can now be
Xused for keyword completion. (2.5)
X
XThe search pattern for the :tag command does not replace the search pattern
Xthat is remembered for the next search command. (Webb 2.5)
X
XUse CTRL-X instead of CTRL-S (subtract). Do not switch off xon/xoff in unix.c.
XFixes problems with CTRL-S on some terminals. (2.4)
X
XUsing >> will not shift lines that start with '#' when 'si' is set. (Webb 2.5)
X
X"\?" in expressions (match exactly one time) replaced by "\=", makes "?\?\?"
Xwork.
X
XThe commands "*" and "#" only search for whole words, using "\<ident\>". (Webb
X2.5)
X
XWhen doing a ":ta" command after CTRL-T, the tag stack is truncated, rather
Xthan keeping old tags at the top. Now repeating CTRL-T will get you back to
Xthe first ":ta" and stop there. (Webb 2.5)
X
XMade argument list global, not local to each window. ":quit" works when there
Xare more files to edit, except when there is only one window. (2.4)
X
XThe ".vim" file is not used for recovery with the "-r" argument. Use
X"Vim -s file.vim file" instead.
X
XFirst page of swap file has changed, cannot recover files from older versions.
XThe swap file can now be recognized by its start: "b0VIM 3.0", where 3.0 is
Xthe version number. (3.0)
X
X
XNew commands and functionality
X==============================
X
XAdded insert-mode keyword completion commands CTRL-P and CTRL-N inside #ifdef
XWEBB_KEYWORD_COMPL. (Webb 2.5)
X
XUpdated error messages for keyword completion in insert mode. (2.7)
X
XAdded "]f" command: Edit file whose name is under the cursor. Added CTRL-W
XCTRL-F and CTRL-W f: split window and edit file whose name is
Xunder the cursor. (Webb 2.5)
X
XChanged "]f" into "gf". Mnemonic: goto file. (2.7)
X
XPut "]f" and "[f" back in, they do the same as "gf". For people that have the
X'g' key remapped. (2.9)
X
XAdded CTRL-W CTRL-R, CTRL-W r, CTRL-W R: rotate windows upwards/downwards
X(2.5)
X
XAdded CTRL-W CTRL-X and CTRL-W x: exchange current window with next one. (Webb
X2.5)
X
XAdded window title for xterm.
X
XAdded termcap options 't_so' (standout) and 't_se' (standout end). Use 't_so'
Xand 't_se' if inversion is not possible and for highlighting directories.
XAt some places standout mode is used instead of inversion. (Webb 2.5)
X
XDo wait_return() message and the message used when asked for 'y' or 'n' is now
Xin standout mode. (Webb 2.5)
X
XAdded termcap option 't_ms' (save to move cursor in reverse mode). Makes
Xinversion work on some terminals.
X
XAdded ":mode" command. Under Amiga and Unix this only re-sets the screen
Xsize. With MSDOS it is possible to switch screen mode.
X
XNow also "%<", "#31<", alternate file name without extension.
X
XAdded ':' register. Contains last command line. "@:" repeats last command
Xline.
X
XAdded ":exit" as synonym for ":xit". More logical, isn't it?
X
XAdded ":swapname". Show swap file name for current buffer.
X
X":args" can have arguments for redefining the argument list, just like
X":next". (2.5)
X
XWhen the command for the tag is a search and it fails, try searching for the
Xtag itself with pattern "^tag(" and "^[#a-zA-Z_].*tag(". (Webb 2.5)
X
X"%" will now go to matching comment delimiters (/ *, * /) and find matches for
Xthe preprocessing lines #ifdef, #else, #elif and #endif. (Webb 2.5)
X
XUsing '%' on #if/#else/#endif makes the movement linewise. (2.7)
X
X"[p", "[P", "]p" and "]P" work like "p" and "P" but adjust the indent of the
Xputted lines to match the context. (Webb 2.5)
X
XChanged put indented: "[p" and "]p" is "]p" (put forward), "[P" and "]P" is
X"[p" (put backward). (2.7)
X
X"[(" and "[{" may be used to go to the (count'th) last unclosed ( or {.
X"])" and "]}" may be used to jump to the (count'th) next unopen) or }. Can be
Xused to jump to the start/end of the innermost c-code block (Webb 2.5)
X
XAdded count to ":", "count:" translates into ":.,.+(count - 1)". (Webb 2.5)
X
XAdded ":sleep" command. (2.4)
X
X"g" is to be used for a new series of commands. First one: "gs" sleeps for a
Xmoment (Mnemonic: Go to Sleep). Give count for that many seconds. Can be
Xinterrupted with CTRL-C. (2.5)
X
XAdded ":last" and ":slast", go to last argument. (2.5)
XAdded ":argument [N]" and ":sargument [N]", go to Nth argument. (2.5)
XAdded ":blast" and ":sblast", go to last buffer. (2.5)
X
XAdded "-o[N]" command line argument: Open N windows on startup. (2.5)
X
XAdded ":only", CTRL-W CTRL-O, CTRL-O o: Close all but current window. (2.5)
X
XAdded default digraph: <space> <char> is meta-char. (2.4)
X
XDigraphs with CTRL-H do not make meta characters. Use CTRL-K <space>
X<char>. Fixes problem with abbreviations when 'digraph' set. (2.5)
X
XDon't allow digraphs with ESC. Hitting ESC in digraph exits insert mode. (2.5)
X
XAdded ":snext", ":sNext", ":sprev" and ":srewind" commands, split window and
Xgo to next/previous file in argument list. (2.4)
X
XAdded CTRL-W CTRL-P and CTRL-W p, jump to previous window. (2.4)
X
XAdded "zz", "zt" and "zb", same as "z.", "zCR" and "z-" but without moving the
Xcursor to the start of the line. (2.4)
X
X":bdelete" and ":bunload" accept a range of buffers and a list of buffer
Xnumbers. (2.7)
X
X
XImprovements
X============
X
XCursor up/down in insert mode keep the same column. Also for "CTRL-O j" and
Xthe like.
X
XAdded column number to :file.
X
XImproved listing of ":set" command. The columns are now sorted top to bottom.
XLong string options are listed at the end (idea comes from nvi).
X
XRenamed directory "macros" to "tools". Moved doc/vim132 to tools/vim132.
X
X"ref" program added for "K" command (in the tools directory. Does simple
Xspelling check.
X
XVim arguments "-c command" and "+command" are now options that can be given
Xanywhere on the command line before the file names. Makes it possible to do
X"Vim "+set ic" -t FuncTion".
X
XImproved Usage message.
X
XAdded check for negative line numbers in colon commands.
X
XRemoved 'n' offset to search patterns. Avoiding pcmark set is now down with
Xtag_busy flag.
X
XImproved error messages for file access.
X
X":args" does not call wait_return() when message is short.
X
XWhen doing :paste twice the option values are saved only once.
X
XAccept '\n' to separate Ex commands, just like '|'.
X
XWith search also accept 'b' for begin, like 's' for start.
XWhen 'e' used the operator is inclusive.
X
XVisual shift accepts a count for number of indents.
X
XNo "hit return to continue" while filtering and only once when reading/writing
Xfiles.
X
XFor Amiga and MSDOS lines longer than 32000 characters are split when reading.
XUsed to give problems (out of memory errors).
X
XWhen ':' entered after "hit return to continue" don't redraw the screen.
X
XIn regexp: made '$' in front of '\|' also end-of-line.
X
XAdded "+command" argument to ":next", ":prev", ":rewind" and ":Next".
X
XGive better error message when "/" did not found pattern and 'wrapscan' off.
X
XAdded message "search hit BOTTOM, continuing at TOP" when search wraps. Don't
Xdisplay this message when 'terse' option is on.
X
XMade ":&" work like ":s//~/".
X
XConsider mapped characters for terminal codes, makes "map <key-code1>
X<key-code2>" work.
X
XRemember two search patterns: One for substitute and one for the rest. This is
Xhow vi works. ":global" command sets both patterns.
X
XError messages during global command are listed below each other. (2.4)
X
XDon't redisplay the "INSERT" message when getting out of insert mode.
X
XWith escape in insert mode and auto-indent the cursor is put in the correct
Xcolumn right away instead of after one second.
X
XAdded "Permission denied" message to readfile().
X
XAdded preserve command. Writes all text into the swap file.
X
XNamed marks are saved for undo, restored for redo.
X
XReduced terminal I/O by using screen_char() instead of outchar() for messages.
X
XAdded count to quickfix commands :cn and :cp. :cl and :cf can be interrupted
Xby CTRL-C.
X
XFor MSDOS ignore CTRL-Z at end of file in textmode.
X
XNo mapping for CR when waiting for "hit return to continue".
X
XUse 'ignorecase' option when searching for tag in tag file.
X
XWhen count given for undo or redo, redraw screen only once.
X
XClear message on command line when scrolling, otherwise it will stay there
Xuntil the screen is cleared. (2.5)
X
XMarks are remembered for buffers that are unloaded. (2.5)
X
XImplemented scroll regions, using "CS" termcap entry. Also works for pc
Xconsole. Does not work for Amiga. (2.5)
X
XMade searches starting with "\<" quite a bit faster, by using regmust in
Xregexp.c. (2.5)
X
XDon't output an extra line when reading a file and screen has been scrolled up
X(e.g. after CTRL-D). (2.5)
X
XAfter "dG" "''" still works (when previous context mark is deleted, use
Xprevious one). (2.5)
X
XA count can be given after an ex command for all commands that do not use a
Xline number or range, e.g. ":sleep 2" is the same as :2sleep". Do not accept a
Xcount where a file name is expected, because file names can be numbers. For
Xexample ":next 4". (2.5)
X
X"~/" is expanded to $HOME, wherever an environment variable is allowed. (2.5)
X
XWhen the start of a filename matches $HOME, it is replaced with "~/" for the
Xwindow title, status line, message from ":read", ":write", CTRL-G, ":file",
X":marks" and ":jumps". Also for string options shown with ":set" that can be a
Xfile name. (2.5)
X
XPrevious context mark for each window instead of for each buffer. (Webb 2.5)
X
XSet previous context mark only if line number changed. (Webb 2.5)
X
XMade tagstack local to each window. (Webb 2.5)
X
XIn the status line of a modified buffer "[+]" is shown. (Webb 2.5)
X
XRemember cursor position in tag stack for :tag command without argument. (Webb
X2.5)
X
XWhen backwards range given for ":" command, ask for confirmation to swap it
Xand continue. (Webb 2.5)
X
XAfter CTRL-T set curswant, so we stay in that column when moving up/down.
X(Webb 2.5)
X
XWith :s/../../c show ruler when waiting for reply. (Webb 2.5)
X
XGive file name message for commands ":bnext", ":bmod" and the like. (2.5)
X
XMade index in argument list local to each window. (2.5)
X
XShow visual selection only in current window. (2.5)
X
XWhen a window is split, redraw both windows with cursor in middle. (2.4)
X
XIncluded code to save the xterm title. Need to define USE_X11, because
Xspecific include file and library are needed. (2.4)
X
XMade "search hit BOT.." messages redisplay after screen redraw. (2.4)
X
XDon't do textwidth formatting when in replace mode and replacing an existing
Xcharacter. (2.4)
X
XPrint message about the file when starting to edit an existing buffer. Fixes
Xnot giving a message when doing ":n" to file being edited in other window.
X(2.4)
X
XWhen lines are deleted/inserted, adjust topline and cursor position of other
Xwindows on same buffer to stay in the same place (if possible). (2.4)
X
XIf CTRL-W CTRL-] is done on a tag that does not exist, the window is not
Xsplit. (2.4)
X
XMoved column number in CTRL-G to the end and adjusted the number. (2.4)
X
XAdded "-- more --" message to listing of mappings. (2.4)
X
XAccept 'q' with "-- more --" message. Interrupts current listing. (2.4)
X
XWhen end of Visual area is on an empty line, minlc is FALSE, makes
X"d}P" and "v}dP" do the same. (2.4)
X
XWhen the commands '*' and '#' do not find an identifier after the cursor, a
Xsearch is done for a non-identifier string. (2.5)
X
XMade the ":buffers" listing nicer by putting the "line" string in column 40.
X(2.7)
X
XUpdated error messages for keyword completion. (2.8)
X
XIf 'winheight' set spread extra lines over other windows. (2.8)
X
XWhen 'updatecount' changed from zero to non-zero, create swap file for all
Xloaded buffers. (2.8)
X
XWhen command line completion found more than one match, beep. (3.0)
X
XChanged "still more files to edit" into "6 more files to edit". (2.9)
X
XWhen :bdel is used with a range and errors occur, still delete the other
Xbuffers. (3.0)
X
XAdded version string to .swp file. (3.0)
X
XIn MSDOS version: After calling a shell, check screen size. Now it is possible
Xto set the screen size with a command like ":!setmode xxx". (3.0)
X
XDon't try to open an X11 display if WINDOWID is not set, makes startup a bit
Xquicker sometimes. (3.0)
X
X
XNew and changed options
X=======================
X
XDefault 'updatetime' is 10000, 10sec. Default 'updatecount' is 1000. This
Xfeels more comfortable. But if you keep on typing, more will be lost when
Xcrashing.
X
XChanged default for 'updatecount' to 200 (1000 was too much). Default for
X'updatetime' is now four seconds (more than three seconds means that your
Xattention is drawn away). (2.7)
X
XAdded 'cmdheight' option ('ch'), number of lines for command line. Set it to 2
Xor 3 if you are annoyed by "hit return to continue" questions for long
Xmessages.
X
XAdded 'winheight' option ('wh'), number of lines for active window. Set it to
X999 to make the current window always fill the screen.
X
XMade 'winheight' option a "minimal window height" option, only set height if
Xcurrent height is smaller. (2.4)
X
XAdded 'laststatus' option ('ls'). When set to 2 last window always has a
Xstatus line. When set to 1 (which is the default) the last window only has a
Xstatus line if there are two or more windows. When set to 0 there is never a
Xstatus line. The screen looks nicer with a status line if you have several
Xwindows, but takes another screen line.
X
XAdded optional '>' to 'directory' and 'backupdir' option, e.g. ">/tmp". When
Xused, 'directory' option is always used for swap file. When not used
X'directory' is only used when swap file cannot be created in current
Xdirectory. The default is that the swap file will be in the current directory
Xwhen possible, in 'directory' otherwise. 'directory' defaults to "/tmp" for
Xunix, "t:" for Amiga and "c:\tmp" for MSDOS. The 'backupdir' option works in
Xthe same way, but is currently only available for Unix.
X
XAdded 'nobuf' option ('nb'). When set one character is send to the terminal
Xat a time (does not work for MSDOS). For debugging purposes.
X
XAdded 'shellpipe' option ('sp'). String to use for the make command to store
Xthe error messages. For Amiga and MSDOS it defaults to ">". For Unix it
Xdefaults to "| tee". For "csh", "tcsh" and "zsh" it is changed into "|& tee".
XFor "sh", "ksh" and "bash" it is changed into "2>&1| tee". Fixes problem with
X:make when not using csh.
X
XAdded 'maxmem' option ('mm'), maximal Kbyte to use for one buffer.
X
XAdded 'smarttab' option ('sta'). When set a TAB in front of a line inserts
X'shiftwidth' positions, 'tabstop' in other places. When not set a TAB always


Xinserts 'tabstop' positions, 'shiftwidth' is only used for ">>" and the like.
X

XAdded 'maxmemtot' option ('mmt'), maximal Kbyte to use for all buffers.
X
XAdded 'ttyfast' option ('tf'). When set the terminal is assumed to be fast,
Xscrolling windows is done by redrawing. When not set windows are scrolled with
Xinsert/delete line commands, causing the windows below it to jump up and down
Xif threre is no support for a scrolling region.
X
XAdded 'equalalways' option: When windows split or closed, always do CTRL-W =.
X(2.5)
X
XAdded 'splitbelow': When set new window from split is below current one. (2.5)
X
XAdded 'tagrelative' option (default ON!). When using tag file in other
Xdirectory, file names are relative to the directory where the tag file is.
X(Webb 2.5)
X
XWhen setting 'winheight' adjust current window straight away. Check for
Xnegative value. (Webb 2.5)
X
XAdded 'gdefault' option: make /g default for :s command (default off). (2.4)
X
XAdded 'title' option (default on). When off, window title is not set. (2.4)
X
XAdded NOTITLE compile time option for Vera: When defined the title option is
Xdefault off. (2.7)
X
XAdded 'icon' option (default off): when set xterm icon is set to file name.
X(2.4)
X
XAdded 'invertweird' option, for terminals that have a weird inversion method.
XMakes the start/end invert code outputted before every character. (2.4)
X
XChanged 'invertweird' to 'weirdinvert', because an option starting with 'inv'
Xis illegal. ":set invertweird" gives an error message. (2.7)
X
XAdded 'endofline' 'eol' option. If not set and in binary mode, last line will
Xnot get an end of line when writing. (2.4)
X
XAdded 'bswrap' option: Backspace (CTRL-H) and space wrap to previous/next line
Xin command mode. Default is ON! Should have been added long ago! (2.4)
X
XWhen 'bswrap' option set, left/right cursor keys in insert mode also wrap to
Xprevious/next line. (2.7)
X
XChanged toggle 'bswrap' option to number 'whichwrap' option: Add numbers to
Xallow specific keys to wrap to next/previous line: 1 for backspace, 2 for
Xspace, 4 for 'h' and 'l', 8 for cursor left/right, 16 for cursor left/right in
Xinsert mode. (2.7)
X
XAdded 'patchmode' option. Oldest version of a file is kept. (2.4)
X
XAdded 't_csc' termcap option: when set (to anything) the cursor positioning is
Xdone relative to the start of the scrolling region. Otherwise it is relative
Xto the start of the screen. Unfortunately there is no termcap entry for this.
XWe are just guessing its value. Currently only MSDOS pcterm is know to need
Xthis set. This fixes doing 'o' not getting the new line in the right place for
XMSDOS. (2.7)
X
XAdded 'highlight' ('hl') option: Can set highlighting mode for various
Xoccasions. 'i' for invert, 'b' for bold, 's' for standout; 'v' = visual mode,
X'd' = directories in CTRL-D listing, 'e' = error messages, 's' = status lines,
X'h' = help file headers, 'r' = return to continue message. They have to be
Xgiven in pairs, separated with a comma. For example:
X":set hl=ds,vb,ei,si,hb,ri". Invert is used for occasions that are not
Xincluded. Default is "ds,es,hs,rs,vi,si". (2.6)
X
XChanged the default highlight mode for directories to bold. (2.7)
X
XAdded 'n' to 'highlight' option: no highlighting. (2.7)
X
XAdded 'bold' termcap option as t_tb. (2.6)
X
X
XVi compatibility fixes
X======================
X
X":>", ":<" and ":yank" leave cursor on the last line.
X
XAbbreviations recognized like vi, fixes abbreviation of "#i" to "#include".
X
X"d]]" also stops at '{'.
X
X']' and '[' are not linewise.
X
X"z." and "z-" move cursor to start of line. "zz" does the same as "z.".
X
X":>>" shifts two indents, ":>>>" three, etc.
X
XWhen no file name yet and giving a ":read fname" command, use that file name.
X(2.4) When no file name yet and giving a ":write fname" command, use that file
Xname. (2.5)
X
X":3,3join" does nothing, fixes "g/^$/.,/./-j" to delete only multiple empty
Xlines. (2.5)
X
X":wnext" does not go to next file in argument list if write fails. (2.5)
X
XCTRL-W CURSOR-UP and CTRL-W CURSOR-DOWN do the same as CTRL-W k and CTRL-W j.
X(2.5)
X
X'smartindent' is improved: When '}' is typed as the first char on a line,
Xit is moved to line up with the line containing the matching '{' (rather than
Xjust moving back one shift-width no matter what). If '#' is the first
Xcharacter typed on a line, then the line is moved all the way to the left.
X(Webb 2.5)
X
XWhen 'smartindent' set, '#' removes all indent. Now the existing indent is
Xremembered for the next line (like with ^ CTRL-D). (2.7)
X
XWhen ESC is used to cancel a command, don't beep. (Webb 2.5)
X
XWhen 'autoindent' set and inserting a CR, delete white space after the cursor.
X(Webb 2.5)
X
XDon't set curswant when 'h' or 'l' fails. (Webb 2.5)
X
XWith "70|" command set curswant to 70, also when line is shorter. (Webb 2.5)
X
XFixed "cc" to delete the text linewise, but keep the indent when 'ai' is set.
X(2.5)
X
X"dTx" and "dFx" do not include cursor position.
X
X":r" without a file name specified reads current file.
X
X"ce" when on the end of a word changes until the end of the next word
X(but "cw" not).
X
XAfter "dd" put cursor on first non-blank in line.
X
XAbbreviations are never recursive, makes ":ab f f-o" work.
X
X'#' is not the start of an ex comment but an abbreviation for ":number".
X
XPut redo for "p" and "P" back in. It is not completely compatible, because vi
Xdoesn't always redo putting less then a line (but that is considered to be a
Xbug in vi). (2.5)
X
XAdjusted comp_col() for when 'laststatus' is set. Reduces need for "hit return
Xto continue". (2.5)
X
XWith ":global" command, don't display "n more lines" messages until the end.
X(2.5)
X
XDon't reset yank buffer with "." command. Makes dwu"a. work. (2.4)
X
XDon't check for abbreviation when a (non-id) character is entered with CTRL-V.
X(2.4)
X
XWith change command put deleted text in "1, even with text within one line.
X(2.4)
X
XWhen deleting and a register is specified, also yank into buffer "1. (2.4)
X
X":3|" prints line 3 instead of jumping to it. (2.4)
X
XSeparated 'wrapmargin' and 'textwidth'. Both can be used, if textwidth is set
Xit overrides 'wrapmargin'. (2.8)
X
X
XBug fixes
X=========
X
XFixed problem in memmove for __sgi.
X
XFixed ":cd" not working for unix.
X
XMade incrementing hex numbers with CTRL-A work on systems that don't accept 0x
Xin scanf for "%x".
X
XReset p_ro in readfile() when starting to edit a new file.
X
Xinchar() also calls flushbuf when waiting for a second, fixes screen not
Xupdated while waiting for a mapping to be completed.
X
XFixed ":/pat/s/x/X/"; 's' was seen as option to search command.
X
XFixed search patterns where delimiter is inside of a range, e.g. "/[/]".
X
XFixed ignoring 'ignorecase' option for "/[a-z]". Fixed mixing upper/lower case
Xwhen 'ignorecase' option not set (just slowed down the searching).
X
XUse iswhite() instead of isspace() for "^" and set_indent().
X
XAllow pipe in ":r !cmd" and ":w !cmd".
XAdjusted check for '|' in ":e +cmd".
X
XFixed insertchar() lookahead for digraph not working when using mapped
Xcharacters.
X
XFixed :unab and :unmap for rhs with spaces.
X
XFixed not accepting ambiguous abbreviations.
X
XAdded check for valid abbreviations.
X
XFixed crash for AmigaDOS 1.3 when giving more than one file on the command
Xline.
X
XUpdated isidchar for meta chars.
X
XAdded setting of Changed flag to :move and :copy.
X
XNumber after search pattern (e.g. "/pattern/3") is line offset.
X
X"cc<ESC>" when 'ai' is set, deletes the indent.
X
XFixed ":s/1/1^M/gc" on "111" and ":s/O/oO/gc" looping.
X
XFixed trailing "\" in substitute string (produced garbage).
X
XFixed yanking control characters (like "^B") with block visual mode.
X
XFixed cursor left of line with "i<ESC>" when 'number' set.
X
XMSDOS: isdir() adjusted for trailing backslash, fixes CTRL-D listing.
X
XMSDOS: Fixed call to lalloc() in addfile() in msdos.c, could only do 32 files.
X
XMSDOS: Fixed setting archive bit in setperm() in msdos.c.
X
XMSDOS: Do not eat backslashes in ":next" command.
X
XFixed bug in makescriptname: alloc 1 byte extra.
X
XFixed bug in doaddsub(): Line truncated 30 chars after number.
X
XFixed CTRL-O in insert mode moving cursor when it is after end of line.
X
XVertical movement in insert mode can put cursor one char after the line.
X
XFixed not inverting 0xa0 in visual mode when scrolling. This caused gaps in
Xthe inverted region.
X
XFixed hangup for "?$" command.
X
XFixed keyword macros: ^B must be ^R.
X
X":set all" and ":set termcap" do not look for other arguments.
X
X{count}% puts cursor on first non-blank.
X
XWhen ":ta" to tag in same file, start search in line 1. Fixes problem when
X'wrapscan' is not set.
X
XFixed setting of pcmark for "(" and ")".
X
XFixed setting pcmark with :e command.
X
XFixed a crash on Unix when terminal type unknown. (2.5)
X
XFixed 'showmatch', the cursor was off. (2.5)
X
XSolved crash when 'lines' was set in .exrc. (2.5)
X
XFixed memory leak for mf_xfname. (2.5)
X
XFixed a problem in the Unix part for making backup files. Strange that this
Xdid not cause the compiler to complain. (2.5)
X
XFilename expansion is now done into NameBuff instead of IObuff. Fixes bugs
Xwhere file name was scrambled or Vim crashed some time after ":next file".
X(2.5)
X
XFixed deleting the file message when 't_tp' was set in .vimrc. (2.5)
X
XFixed cursor positioning problem when :s/../../gc made line go past end of
Xscreen. (Webb 2.5)
X
XDon't nag about swap file not existing when preserving, except for
X":preserve". (2.5)
X
XFixed loosing changes without warning when 'hidden' option set and re-editing
Xthe same file with a command like ":rewind". (2.5)
X
XClear commandline with ":buffers" command. (2.5)
X
XFixed ":1buf" to go to first buffer instead of second one. (2.5)
X
XFixed default for ":sleep" to be 1 instead of current line number. (2.5)
X
XWhen the 'hidden' option is set don't give error message for changed file on
Xseveral commands (:ta). (2.5)
X
XUpdate timestamp in swap file when the file has been written. (2.5)
X
XFixed a problem not updating the time stamp in the swap file when writing
Xanother but the current buffer. (2.7)
X
XFixed bug: not-edited file could be written with ":w". (2.5)
X
XFixed invering Visual part when 'nowrap' set and start is left of window.
X(2.4)
X
XFixed problem with join: Deleted leading spaces in the 2nd line when it
Xshouldn't. (2.4)
X
XMSDOS: Trailing CTRL-V in sourced ex file now handled correctly. (2.4)
X
XImproved check for readonly files, now "466" is not readonly for others. (2.4)
X
XFixed not inverting one char with "1v" when cursor cannot be made invisible.
X(2.4)
X
XStop Visual mode before exiting a window. (2.4)
X
XChanged "short_u" to "unsigned" in data block. Fixes problem with lines longer
Xthan 64K characters on Unix. Disadvantage: Need 2 bytes extra for each line.
X(2.4)
X
XFixed plines_win() and chartabsize() for lines that are almost 32768
Xcharacters. (2.4)
X
XReplace MAX_INT by INT_MAX, fixes problem with "$" not getting very far. (2.4)
X
XStatus lines also redrawn after ":set". Needed when 'ruler' option was
Xchanged. (2.4)
X
XFixed fname freed twice in mf_open(). Fixes crash/hang when editing a file in
Xa readonly directory. (2.4)
X
XUpdate mf_neg_count in mf_free, fixes "line count wrong in block 1" errors.
X(2.4)
X
XFixed bug when in replace mode and beyond the end of the line. (2.4)
X
XFixed a problem for 'r' with a count. Could corrupt the text in the buffer!
X(2.4)
X
XScroll options adjusted after CTRL-W =. (2.4)
X
XIf a tag is found, but the associated file does not exist, do not start
Xediting an empty file. (2.4)
X
Xsc_col and ru_col cannot become negative anymore, fixes crash with ":win 1".
X(2.4)
X
XCheck_winsize makes Rows at least 2. (2.4)
X
X'o' and 'O' commands did not update marks for the line just below the new
Xline. (2.4)
X
XFixed truncated displaying of string options. (2.4)
X
XFixed chmod for help file in makefile.unix. (2.4)
X
XHighlighting of directories for CTRL-D on command line no longer highlights
Xsome spaces. (2.4)
X
XMoved #endif in param.c from below to above p_wh, fixes problem when
XCOMPATIBLE is defined. (2.4)
X
XDon't reset msg_scrolled in UpdateScreen() when redrawing is disabled. (2.4)
X
XFixed cursor positioning error when cursor is on first char of non-empty
Xcmdline. (2.4)
X
XFixed problem with redraw when filename completion fails under unix. (2.4)
X
XNo "hit return to continue" while editing a command line
X(e.g. when filename completion fails). (2.4)
X
XFixed bug: Errors while reading file caused big problems. (2.4)
X
XDon't try to preserve if there is no swap file. (2.4)
X
XDont' complain about .swp file existing without a file name. (2.4)
X
XFixed endless loop for CTRL-R a in insert mode while register a contained
XCTRL-R a. Can now be interrupted with CTRL-C. (2.6)
X
XFixed ":n *" in MSDOS not finding file names with dot. (2.7)
X
XFixed cursor not moved to the right column when scrolling with CTRL-E and
XCTRL-Y. (2.7)
X
XFixed bug when using CTRL-A to increment a decimal number after incrementing
Xan upper case hexadecimal number. (2.7)
X
XOnly reset the 'notedited' flag when writing to the current file name, not
Xwhen writing to another file. (2.7)
X
XFixed screen redraw when window resized, was sometimes done only after
Xcharacter typed. (2.7)
X
XCorrected the order of the options to be alfabetical. (2.7)
X
XFixed using CTRL-D on the command line when there are no matches at all. (2.7)
X
XFixed beeping always when doing CTRL-A on command line. (2.7)
X
XFixed the line number for the alternate file being used for the next command.
Xe.g. ":w #", ":e file" when # is file. (2.7)
X
XMoved the fileinfo() in doecmd() to after the place where the cursor is set.
XFixes reporting the wrong cursor position when entering a hidden buffer. (2.7)
X
XFixed compilation problem in unix.c when compiling without WEBB_COMPLETE.
X(2.7)
X
XWhen going to previous line with backspace, set curswant. (2.7)
X
XFixed status line showing "[No File] [+] [+]": two plusses. (2.7)
X
XThe 'changed' flag was not reset for other buffers with :wall. (2.7)
X
XSolved bug in 'r': The change was not written to the swap file, which made the
Xchange to be lost sometimes. (2.6)
X
XDon't ask for swapping the command line range when in global command. (2.6)
X
XFixed :bdelete, it did't work. :bdelete and :bunload cannot remove a buffer
Xwith an open window, unless it is only the current window. (2.6)
X
XFixed .swp files not deleted when starting to edit a file when the current
Xbuffer is empty and has no name. This also fixes the problem which happens
Xwhen starting vim without a file name and the starting to edit a file that
Xdoes not exist. (2.6)
X
XWhen error encountered while loading files for "-o" option or ":all", continue
Xloading the other files. (2.8)
X
XIf cursor is in column 0, always reset horizontal scrolling. Makes tabs
Xcompletely visible. (2.8)
X
XFixed problem in mf_release_all, empty used list not detected properly. (2.8)
X
XFixed crash with command ":@:", repeat last command line. (2.8)
X
XFixed cursor in wrong column when matched string from search was just one line
Xbelow the window. (2.8)
X
X":m+1" on the last line in the file silently deleted that line. (3.0)
X
XFixed command line completion of ":s<TAB>". (3.0)
X
XThe ":srewind" command did not work. (3.0)
X
XThe ":k" command did not work. (3.0)
X
XWhen making windows for ":all" or "-o" argument, ignore 'splitbelow' option.
X(3.0)
X
XFixed a problem when recovering with a swap file that has a page size
Xdifferent from the default page size. (3.0)
X
XThe ":bdelete" command did not delete the last buffer. (3.0)
X
XWhen using a range with ":bdelete" that included the current buffer, all the
Xbuffers after it would get loaded before being deleted (3.0)
X
XFixed <SPACE>, wrapping to first char of next line, not setting the wanted
Xcolumn, causing the next 'k' to go to the wrong column. Same for <BACKSPACE>
Xon the first column, sticking in the last column. (3.0)
X
X
XInternals
X=========
X
XRenamed u_char to char_u, u_short to short_u. Avoids problems with systems
Xwhere these are already defined.
X
XReplaced almost all char by char_u, solves some problems with characters above
X127.
X
XRemoved ptr2nr(). This means that line numbers are adjusted when
Xinserting/deleting lines. Marks remember line number instead of pointer; undo
Xuses line count to compute ue_bot.
X
XMoved all objects files into "obj" directory.
X
XAdded "window.c" for multiple window code.
X
XAdded "memfile.c" and "memline.c" for swap file code.
X
XMoved what was remaining of "storage.c" to "undo.c", deleted "storage.c".
X
XDeleted autoscript file stuff.
X
XRenamed "buffers.c" to "getchar.c".
X
XCreated "buffer.c". Deleted "script.c".
X
XMoved a few functions from "cmdline.c" to "cmdcmds.c" to reduce the size of
X"cmdline.c".
X
XIntegrated file list into buffer list. ":buffers" and ":files" do the same.
XMoved functions from "filelist.c" to "buffer.c", deleted "filelist.c". (2.5)
X
XRemove mch_start_listing() and mch_stop_listing(), replaced by "--more--".
X(2.5)
X
X
XPortability
X===========
X
XA few patches, the file "winnt.c" and "makefile.nt" for windows NT. (2.4)
X
XAdded support for Archimedes. It probably doesn't work, because "archie.h" was
Xmissing, and the patches are for Vim version 2.0. Included them anyway, so
Xpeople can make patches to make it working. (2.9)
X
XAdded a few changes for USL in unix.c.
X
XMade makefile for unix more easy to change for a specific system.
X
XIncluded small patches for gcc on HPUX 9. (2.4)
X
XSet the SIGWINCH signal, when receiving that signal, for all systems. (Webb
X2.5)
X
XChanged Visual into VIsual, because it is also used by X11. (2.4)
X
XAdded some changes for USL and picky gcc. (2.4)
X
XIncluded patches for SCO 3.2. (2.4)
X
XRemoved the use of the 'obj' directory from makefile.unix. Some versions of
Xmake and cc were having problems with it. (2.7)
END_OF_FILE
if test 34259 -ne `wc -c <'vim/readme3.0'`; then
echo shar: \"'vim/readme3.0'\" unpacked with wrong size!
fi
# end of 'vim/readme3.0'
fi
if test -f 'vim/src/winnt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/winnt.c'\"
else
echo shar: Extracting \"'vim/src/winnt.c'\" \(31469 characters\)
sed "s/^X//" >'vim/src/winnt.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved

X *
X */
X
X/*
X * winnt.c
X *
X * Windows NT system-dependent routines.
X * A reasonable approximation of the amiga dependent code.
X * Portions lifted from SDK samples, from the MSDOS dependent code,
X * and from NetHack 3.1.3.
X *
X * rog...@wonderware.com
X */
X
X#include <io.h>
X#include "vim.h"
X#include "globals.h"
X#include "param.h"
X#include "proto.h"
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include <stdlib.h>
X#include <windows.h>
X#include <wincon.h>
X
Xstatic int WaitForChar __ARGS((int));
Xstatic int cbrk_handler __ARGS(());
X
X/* Win32 Console handles for input and output */
XHANDLE hConIn;
XHANDLE hConOut;
X
X/* Win32 Screen buffer,coordinate,console I/O information */
XCONSOLE_SCREEN_BUFFER_INFO csbi;
XCOORD ntcoord;
XINPUT_RECORD ir;
X
X/* The attribute of the screen when the editor was started */
XWORD DefaultAttribute;
X
Xtypedef struct filelist {
X char **file;
X int nfiles;
X int maxfiles;
X} FileList;
X
Xstatic void addfile __ARGS((FileList *, char *, int));
Xstatic int pstrcmp(); /* __ARGS((char **, char **)); BCC does not
X * like this */
Xstatic void strlowcpy __ARGS((char *, char *));
Xstatic int expandpath __ARGS((FileList *, char *, int, int, int));
X
Xstatic int cbrk_pressed = FALSE; /* set by ctrl-break interrupt */
Xstatic int ctrlc_pressed = FALSE; /* set when ctrl-C or ctrl-break
X * detected */
X
Xvoid vim_delay()
X{
X delay(500);
X}
X
X/*
X * this version of remove is not scared by a readonly (backup) file
X */
Xint vim_remove(name)
X char *name;
X{
X setperm(name, _S_IWRITE); /* default permissions */
X return unlink(name);
X}
X
X/*
X * mch_write(): write the output buffer to the screen
X */
Xvoid mch_write(s, len)
X char *s;
X int len;
X{
X char *p;
X int row,
X col;
X
X s[len] = '\0';
X if (term_console) /* translate ESC | sequences into bios calls */
X while (len--) {
X
X /* optimization: use one single WriteConsole for runs of text,
X rather than calling putch() multiple times. It ain't curses,
X but it helps. */
X
X DWORD prefix = strcspn(s, "\n\r\a\033");
X
X if (prefix) {
X DWORD nwritten;
X
X if (WriteConsole(hConOut, s, prefix, &nwritten, 0)) {
X
X len -= (nwritten - 1);
X s += nwritten;


X }
X continue;
X }
X

X if (s[0] == '\n') {
X if (ntcoord.Y == (Rows - 1)) {
X gotoxy(1, ntcoord.Y + 1);
X scroll();
X } else {
X gotoxy(1, ntcoord.Y + 2);
X }
X s++;
X continue;
X } else if (s[0] == '\r') {
X gotoxy(1, ntcoord.Y + 1);
X s++;
X continue;
X } else if (s[0] == '\a') {
X vbell();
X s++;
X continue;
X } else if (s[0] == ESC && len > 1 && s[1] == '|') {
X switch (s[2]) {
X
X case 'v':
X cursor_visible(0);
X goto got3;
X
X case 'V':
X cursor_visible(1);
X goto got3;
X
X case 'J':
X clrscr();
X goto got3;
X
X case 'K':
X clreol();
X goto got3;
X
X case 'L':
X insline(1);
X goto got3;
X
X case 'M':
X delline(1);
X got3: s += 3;
X len -= 2;
X continue;
X
X case '0':


X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':

X p = s + 2;
X row = getdigits(&p); /* no check for length! */
X if (p > s + len)
X break;
X if (*p == ';') {
X ++p;
X col = getdigits(&p); /* no check for length! */
X if (p > s + len)
X break;
X if (*p == 'H') {
X gotoxy(col, row);
X len -= p - s;
X s = p + 1;
X continue;
X }
X } else if (*p == 'm') {


X if (row == 0)

X normvideo();
X else
X textattr(row);
X len -= p - s;
X s = p + 1;
X continue;
X } else if (*p == 'L') {
X insline(row);
X len -= p - s;
X s = p + 1;
X continue;
X } else if (*p == 'M') {
X delline(row);
X len -= p - s;
X s = p + 1;


X continue;
X }
X }
X }

X putch(*s++);
X }
X else
X write(1, s, (unsigned) len);
X}
X/*
X * Keyboard translation tables.
X * (Adopted from the MSDOS port)
X */
X
X#define KEYPADLO 0x47
X#define KEYPADHI 0x53
X
X#define PADKEYS (KEYPADHI - KEYPADLO + 1)
X#define iskeypad(x) (KEYPADLO <= (x) && (x) <= KEYPADHI)
X
X/*
X * Wait until console input is available
X */
X
Xstatic int WaitForChar(msec)
X int msec;
X{
X int count;
X int ch;
X int scan;
X int shiftstate;
X int altseq;
X int retval = 0;
X
X if (WaitForSingleObject(hConIn, msec) == WAIT_OBJECT_0) {
X count = 0;
X PeekConsoleInput(hConIn, &ir, 1, &count);
X if (count > 0) {
X ch = ir.Event.KeyEvent.uChar.AsciiChar;
X scan = ir.Event.KeyEvent.wVirtualScanCode;
X shiftstate = ir.Event.KeyEvent.dwControlKeyState;
X if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) &&
X (ch || (iskeypad(scan)))) {
X retval = 1; /* Found what we sought */
X }
X } else { /* There are no events in console event queue */
X retval = 0;
X }
X }
X return retval;
X}
X
Xstatic int pending = 0;
X
Xint tgetch()
X{
X int valid = 0;
X int metaflags = 0;
X int count;
X unsigned short int scan;
X unsigned char ch;
X unsigned long shiftstate;
X const struct pad *kpad;
X char keymess[100];
X
X if (pending)
X {
X ch = pending;
X pending = 0;
X }
X else
X {
X
X valid = 0;
X while (!valid) {
X ReadConsoleInput(hConIn, &ir, 1, &count);
X if (ir.EventType == WINDOW_BUFFER_SIZE_EVENT) {
X set_winsize(Rows, Columns, FALSE);
X }
X else
X {
X if ((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown)
X {
X ch = ir.Event.KeyEvent.uChar.AsciiChar;
X scan = ir.Event.KeyEvent.wVirtualScanCode;
X if (ch || (iskeypad(scan)))
X valid = 1;
X }
X }
X }
X if (!ch)
X {
X pending = scan;
X ch = 0;
X }
X }
X return ch;
X}
X
X
Xint kbhit()
X{
X int done = 0; /* true = "stop searching" */
X int retval; /* true = "we had a match" */
X int count;
X unsigned short int scan;
X unsigned char ch;
X unsigned long shiftstate;
X
X if (pending)
X return 1;
X
X done = 0;
X retval = 0;
X while (!done) {
X count = 0;
X PeekConsoleInput(hConIn, &ir, 1, &count);
X if (count > 0) {
X ch = ir.Event.KeyEvent.uChar.AsciiChar;
X scan = ir.Event.KeyEvent.wVirtualScanCode;
X shiftstate = ir.Event.KeyEvent.dwControlKeyState;
X if (((ir.EventType == KEY_EVENT) && ir.Event.KeyEvent.bKeyDown) &&
X (ch || (iskeypad(scan)) )) {
X done = 1; /* Stop looking */
X retval = 1; /* Found what we sought */
X } else /* Discard it, its an insignificant event */
X ReadConsoleInput(hConIn, &ir, 1, &count);
X } else { /* There are no events in console event queue */
X done = 1; /* Stop looking */
X retval = 0;
X }
X }
X return retval;
X}
X
X
X/*


X * GetChars(): low level input funcion.
X * Get a characters from the keyboard.
X * If time == 0 do not wait for characters.
X * If time == n wait a short time for characters.
X * If time == -1 wait forever for characters.
X */

Xint GetChars(buf, maxlen, time)
X char *buf;


X int maxlen;
X int time;

X{


X int len = 0;

X int c;
X
X if (time >= 0) {
X if (time == 0) /* don't know if time == 0 is allowed */
X time = 1;
X if (WaitForChar(time) == 0) /* no character available */
X return 0;


X } else { /* time == -1 */

X /* If there is no character available within 2 seconds (default)
X * write the autoscript file to disk */
X if (WaitForChar((int) p_ut) == 0)
X updatescript(0);
X }
X
X/*
X * Try to read as many characters as there are.
X * Works for the controlling tty only.
X */
X --maxlen; /* may get two chars at once */
X /* we will get at least one key. Get more if they are available After a
X * ctrl-break we have to read a 0 (!) from the buffer. bioskey(1) will
X * return 0 if no key is available and when a ctrl-break was typed. When
X * ctrl-break is hit, this does not always implies a key hit. */
X cbrk_pressed = FALSE;
X while ((len == 0 || kbhit()) && len < maxlen) {
X switch (c = tgetch()) {
X case 0:
X *buf++ = K_NUL;


X break;
X case 3:

X cbrk_pressed = TRUE;
X /* FALLTHROUGH */
X default:


X *buf++ = c;
X }

X len++;
X }
X return len;
X}
X
X/*
X * We have no job control, fake it by starting a new shell.
X */
Xvoid mch_suspend()


X{
X outstr("new shell started\n");

X call_shell(NULL, 0, TRUE);
X}
X
Xextern int _fmode;
Xchar OrigTitle[256];
X/*
X */
Xvoid mch_windinit()
X{
X CONSOLE_SCREEN_BUFFER_INFO csbi;
X
X _fmode = O_BINARY; /* we do our own CR-LF translation */
X flushbuf();
X
X /* Obtain handles for the standard Console I/O devices */
X hConIn = CreateFile("CONIN$",
X GENERIC_READ | GENERIC_WRITE,
X FILE_SHARE_READ | FILE_SHARE_WRITE,
X NULL, OPEN_EXISTING, 0, NULL);
X
X hConOut = CreateFile("CONOUT$",
X GENERIC_READ | GENERIC_WRITE,
X FILE_SHARE_READ | FILE_SHARE_WRITE,
X NULL, OPEN_EXISTING, 0, NULL);
X
X GetConsoleTitle(OrigTitle, sizeof(OrigTitle));
X
X /* get current attributes and fill out CHAR_INFO structure for fill char */
X GetConsoleScreenBufferInfo(hConOut, &csbi);
X DefaultAttribute = csbi.wAttributes;


X
X mch_get_winsize();
X}
X

Xvoid check_win(argc, argv)


X int argc;
X char **argv;
X{
X if (!isatty(0) || !isatty(1)) {

X fprintf(stderr, "VIM: no controlling terminal\n");
X exit(2);
X }

X /* In some cases with DOS 6.0 on a NEC notebook there is a 12 seconds
X * delay when starting up that can be avoided by the next two lines.
X * Don't ask me why! This could be fixed by removing setver.sys from
X * config.sys. Forget it. gotoxy(1,1); cputs(" "); */
X}
X
X/*


X * fname_case(): Set the case of the filename, if it already exists.

X * msdos filesystem is far to primitive for that. do nothing.
X */
Xvoid fname_case(name)
X char *name;
X{
X}
X
X
X/*
X * mch_settitle(): set titlebar of our window
X * Can the icon also be set?
X */
Xvoid mch_settitle(title, icon)
X char *title;
X char *icon;
X{
X if (title != NULL)
X SetConsoleTitle(title);
X}
X
X/*
X * Restore the window/icon title.
X * which is one of:
X * 1 Just restore title
X * 2 Just restore icon (which we don't have)
X * 3 Restore title and icon (which we don't have)
X */
X void
Xmch_restore_title(which)
X int which;
X{
X mch_settitle((which & 1) ? OrigTitle : NULL, NULL);
X}
X
X/*


X * Get name of current directory into buffer 'buf' of length 'len' bytes.
X * Return non-zero for success.
X */

Xint vim_dirname(buf, len)
X char *buf;
X int len;
X{
X return (_getcwd(buf, len) != NULL);
X}
X
X/*


X * get absolute filename into buffer 'buf' of length 'len' bytes
X */

Xint FullName(fname, buf, len)
X char *fname,
X *buf;
X int len;
X{
X if (fname == NULL) /* always fail */
X return FAIL;
X
X if (_fullpath(buf, fname, len) == NULL) {
X strncpy(buf, fname, len); /* failed, use the relative path name */
X return FAIL;
X }


X return OK;
X}
X
X/*

X * return TRUE is fname is an absolute path name
X */
X int
XisFullName(fname)
X char_u *fname;
X{
X return (STRCHR(fname, ':') != NULL);
X}
X
X/*


X * get file permissions for 'name'

X * -1 : error
X * else FA_attributes defined in dos.h
X */
Xlong getperm(name)
X char *name;
X{
X int r;
X struct stat sb;
X
X r = _stat(name, &sb); /* get file mode */
X
X if (r)
X return r;
X else
X return sb.st_mode;
X}
X
X/*


X * set file permission for 'name' to 'perm'
X */

Xint setperm(name, perm)
X char *name;
X long perm;
X{
X return _chmod(name, (int) perm);
X}
X
X/*


X * check if "name" is a directory
X */

Xint isdir(name)
X char *name;
X{
X int f;
X
X f = getperm(name);
X if (f == -1)
X return -1; /* file does not exist at all */
X if ((f & _S_IFDIR) == 0)
X return FAIL; /* not a directory */


X return OK;
X}
X
X/*

X * Careful: mch_windexit() may be called before mch_windinit()!
X */
Xvoid mch_windexit(r)


X int r;
X{
X settmode(0);
X stoptermcap();
X flushbuf();

X ml_close_all(); /* remove all memfiles */
X mch_restore_title(3);
X exit(r);
X}
X
X/*
X * function for ctrl-break interrupt
X */
XBOOL WINAPI handler_routine(DWORD dwCtrlType)
X{
X cbrk_pressed = TRUE;
X ctrlc_pressed = TRUE;
X}
X
X/*
X * set the tty in (raw) ? "raw" : "cooked" mode


X *
X */
X

Xvoid mch_settmode(raw)
X int raw;
X{
X long cmodein;
X long cmodeout;
X long mask;
X
X GetConsoleMode(hConIn, &cmodein);
X GetConsoleMode(hConOut, &cmodeout);
X
X if (raw) {
X if (term_console)
X outstr(T_TP); /* set colors */
X
X cmodein &= ~(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
X ENABLE_ECHO_INPUT);
X cmodein |= ENABLE_WINDOW_INPUT;
X
X SetConsoleMode(hConIn, cmodein);
X
X cmodeout &= ~(ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
X SetConsoleMode(hConOut, cmodeout);
X SetConsoleCtrlHandler(handler_routine, TRUE);
X } else {
X
X if (term_console)
X normvideo(); /* restore screen colors */
X
X cmodein |= (ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT |
X ENABLE_ECHO_INPUT);
X cmodein &= ~(ENABLE_WINDOW_INPUT);
X
X SetConsoleMode(hConIn, cmodein);
X
X cmodeout |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
X
X SetConsoleMode(hConOut, cmodeout);
X
X SetConsoleCtrlHandler(handler_routine, FALSE);
X }
X}
X
Xint mch_get_winsize()
X{
X int i;
X/*
X * Use the console mode API
X */
X if (GetConsoleScreenBufferInfo(hConOut, &csbi)) {
X Rows = csbi.dwSize.Y;
X Columns = csbi.dwSize.X;
X DefaultAttribute = csbi.wAttributes;
X } else {
X Rows = 25;


X Columns = 80;
X }

X
X if (Columns < 5 || Columns > MAX_COLUMNS ||
X Rows < 2 || Rows > MAX_COLUMNS) {
X /* these values are overwritten by termcap size or default */
X Columns = 80;
X Rows = 25;
X return OK;
X }
X /* Rows_max = Rows; /* remember physical max height */
X
X check_winsize();
X /*script_winsize();*/


X
X return OK;
X}
X

X/*********************************************************************
X* FUNCTION: perr(PCHAR szFileName, int line, PCHAR szApiName, *
X* DWORD dwError) *
X* *
X* PURPOSE: report API errors. Allocate a new console buffer, display *
X* error number and error text, restore previous console *
X* buffer *
X* *
X* INPUT: current source file name, current line number, name of the *
X* API that failed, and the error number *
X* *
X* RETURNS: none *
X*********************************************************************/
X
X/* maximum size of the buffer to be returned from FormatMessage */
X#define MAX_MSG_BUF_SIZE 512
X
Xvoid perr(PCHAR szFileName, int line, PCHAR szApiName, DWORD dwError)
X{
X CHAR szTemp[1024];
X DWORD cMsgLen;
X CHAR *msgBuf; /* buffer for message text from system */
X int iButtonPressed; /* receives button pressed in the
X * error box */
X
X /* format our error message */
X sprintf(szTemp, "%s: Error %d from %s on line %d:\n", szFileName,
X dwError, szApiName, line);
X /* get the text description for that error number from the system */
X cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
X FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError,
X MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) & msgBuf, MAX_MSG_BUF_SIZE,
X NULL);
X if (!cMsgLen)
X sprintf(szTemp + strlen(szTemp), "Unable to obtain error message text! \n"
X "%s: Error %d from %s on line %d", __FILE__,
X GetLastError(), "FormatMessage", __LINE__);
X else
X strcat(szTemp, msgBuf);
X strcat(szTemp, "\n\nContinue execution?");
X MessageBeep(MB_ICONEXCLAMATION);
X iButtonPressed = MessageBox(NULL, szTemp, "Console API Error",
X MB_ICONEXCLAMATION | MB_YESNO | MB_SETFOREGROUND);
X /* free the message buffer returned to us by the system */
X if (cMsgLen)
X LocalFree((HLOCAL) msgBuf);
X if (iButtonPressed == IDNO)
X exit(1);
X return;
X}
X#define PERR(bSuccess, api) {if (!(bSuccess)) perr(__FILE__, __LINE__, \
X api, GetLastError());}
X
X
Xvoid resizeConBufAndWindow(HANDLE hConsole, SHORT xSize, SHORT ySize)
X{
X CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */
X BOOL bSuccess;
X SMALL_RECT srWindowRect; /* hold the new console size */
X COORD coordScreen;
X
X bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
X PERR(bSuccess, "GetConsoleScreenBufferInfo");
X /* get the largest size we can size the console window to */
X coordScreen = GetLargestConsoleWindowSize(hConsole);
X PERR(coordScreen.X | coordScreen.Y, "GetLargestConsoleWindowSize");
X /* define the new console window size and scroll position */
X srWindowRect.Right = (SHORT) (min(xSize, coordScreen.X) - 1);
X srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1);
X srWindowRect.Left = srWindowRect.Top = (SHORT) 0;
X /* define the new console buffer size */
X coordScreen.X = xSize;
X coordScreen.Y = ySize;
X /* if the current buffer is larger than what we want, resize the */
X /* console window first, then the buffer */
X if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize) {
X bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
X PERR(bSuccess, "SetConsoleWindowInfo");
X bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
X PERR(bSuccess, "SetConsoleScreenBufferSize");
X }
X /* if the current buffer is smaller than what we want, resize the */
X /* buffer first, then the console window */
X if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize) {
X bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen);
X PERR(bSuccess, "SetConsoleScreenBufferSize");
X bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect);
X PERR(bSuccess, "SetConsoleWindowInfo");
X }
X /* if the current buffer *is* the size we want, don't do anything! */
X return;
X}
X
Xvoid mch_set_winsize()
X{
X resizeConBufAndWindow(hConOut, Columns, Rows);
X}
X
Xint call_shell(cmd, filter, cooked)
X char *cmd;
X int filter; /* if != 0: called by dofilter() */


X int cooked;
X{
X int x;

X char newcmd[200];
X
X flushbuf();
X
X if (cooked)
X settmode(0); /* set to cooked mode */
X


X if (cmd == NULL)
X x = system(p_sh);

X else { /* we use "command" to start the shell, slow
X * but easy */
X sprintf(newcmd, "%s /c %s", p_sh, cmd);


X x = system(newcmd);
X }

X outchar('\n');


X if (cooked)
X settmode(1); /* set to raw mode */

X
X#ifdef WEBB_COMPLETE
X if (x && !expand_interactively)
X#else
X if (x)
X#endif


X {
X smsg("%d returned", x);

X outchar('\n');
X }

X resettitle();


X return x;
X}
X

X#define FL_CHUNK 32
X
Xstatic void addfile(fl, f, isdir)
X FileList *fl;
X char *f;
X int isdir;
X{
X char *p;
X
X if (!fl->file) {
X fl->file = (char **) alloc(sizeof(char *) * FL_CHUNK);
X if (!fl->file)
X return;
X fl->nfiles = 0;
X fl->maxfiles = FL_CHUNK;
X }
X if (fl->nfiles >= fl->maxfiles) {
X char **t;
X int i;
X
X t = (char **) lalloc(sizeof(char *) * (fl->maxfiles + FL_CHUNK), TRUE);
X if (!t)
X return;
X for (i = fl->nfiles - 1; i >= 0; i--)
X t[i] = fl->file[i];
X free(fl->file);
X fl->file = t;
X fl->maxfiles += FL_CHUNK;
X }
X p = alloc((unsigned) (strlen(f) + 1 + isdir));
X if (p) {
X strcpy(p, f);
X if (isdir)
X strcat(p, "/");
X }
X fl->file[fl->nfiles++] = p;
X}
X
Xstatic int pstrcmp(a, b)
X char **a,
X **b;
X{
X return (strcmp(*a, *b));
X}
X
Xint has_wildcard(s)
X char *s;
X{
X if (s)
X for (; *s; ++s)
X if (*s == '?' || *s == '*')
X return 1;


X return 0;
X}
X

Xstatic void strlowcpy(d, s)
X char *d,
X *s;
X{
X while (*s)
X *d++ = tolower(*s++);
X *d = '\0';
X}
X
Xstatic int expandpath(fl, path, fonly, donly, notf)
X FileList *fl;
X char *path;
X int fonly,
X donly,
X notf;
X{
X char buf[MAX_PATH];
X char *p,
X *s,
X *e;
X int lastn,
X c = 1,
X r;
X WIN32_FIND_DATA fb;
X HANDLE hFind;
X
X lastn = fl->nfiles;
X
X/*
X * Find the first part in the path name that contains a wildcard.
X * Copy it into buf, including the preceding characters.
X */
X p = buf;
X s = NULL;
X e = NULL;
X while (*path) {
X if (*path == '\\' || *path == ':' || *path == '/') {
X if (e)
X break;
X else
X s = p;
X }
X if (*path == '*' || *path == '?')
X e = p;
X *p++ = *path++;
X }
X e = p;
X if (s)
X s++;
X else
X s = buf;
X
X /* now we have one wildcard component between s and e */
X *e = '\0';
X r = 0;
X /* If we are expanding wildcards we try both files and directories */
X if ((hFind = FindFirstFile(buf, &fb)) == INVALID_HANDLE_VALUE) {
X /* not found */
X strcpy(e, path);
X if (notf)
X addfile(fl, buf, FALSE);
X return 1; /* unexpanded or empty */
X }
X while (c) {
X strlowcpy(s, fb.cFileName);
X if (*s != '.' || (s[1] != '\0' && (s[1] != '.' || s[2] != '\0'))) {
X strcat(buf, path);
X if (!has_wildcard(path))
X addfile(fl, buf, (isdir(buf) > 0));
X else
X r |= expandpath(fl, buf, fonly, donly, notf);
X }
X c = FindNextFile(hFind, &fb);
X }
X qsort(fl->file + lastn, fl->nfiles - lastn, sizeof(char *), pstrcmp);
X FindClose(hFind);
X return r;
X}
X
X/*
X * MSDOS rebuilt of Scott Ballantynes ExpandWildCard for amiga/arp.
X * jw
X */
X
Xint ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)


X int num_pat;
X char **pat;
X int *num_file;
X char ***file;

X int files_only,
X list_notfound;
X{
X int i,
X r = 0;
X FileList f;
X
X f.file = NULL;
X f.nfiles = 0;


X for (i = 0; i < num_pat; i++) {

X if (!has_wildcard(pat[i]))
X addfile(&f, pat[i], files_only ? FALSE : (isdir(pat[i]) > 0));
X else
X r |= expandpath(&f, pat[i], files_only, 0, list_notfound);
X }
X if (r == 0) {
X *num_file = f.nfiles;
X *file = f.file;
X } else {
X *num_file = 0;
X *file = NULL;
X }
X return (r ? FAIL : OK);
X}
X
Xvoid FreeWild(num, file)


X int num;
X char **file;
X{

X if (file == NULL || num <= 0)
X return;


X while (num--)
X free(file[num]);
X free(file);

X}
X
X/*
X * The normal chdir() does not change the default drive.
X * This one does.
X */
X#undef chdir
Xint vim_chdir(path)
X char *path;
X{
X if (path[0] == NUL) /* just checking... */
X return FAIL;
X if (path[1] == ':') { /* has a drive name */
X if (_chdrive(toupper(path[0]) - 'A' + 1))
X return -1; /* invalid drive name */
X path += 2;
X }
X if (*path == NUL) /* drive name only */
X return OK;
X return _chdir(path); /* let the normal chdir() do the rest */
X}
X
Xclrscr()
X{
X int count;
X
X ntcoord.X = 0;
X ntcoord.Y = 0;
X FillConsoleOutputCharacter(hConOut, ' ', Columns * Rows,
X ntcoord, &count);
X FillConsoleOutputAttribute(hConOut, DefaultAttribute, Rows * Columns,
X ntcoord, &count);
X}
X
Xclreol()
X{
X int count;
X FillConsoleOutputCharacter(hConOut, ' ',
X Columns - ntcoord.X,
X ntcoord, &count);
X FillConsoleOutputAttribute(hConOut, DefaultAttribute,
X Columns - ntcoord.X,
X ntcoord, &count);
X}
X
Xinsline(int count)
X{
X SMALL_RECT source,
X clip;
X COORD dest;
X CHAR_INFO fill;
X
X dest.X = 0;
X dest.Y = ntcoord.Y + count;
X
X source.Left = 0;
X source.Top = ntcoord.Y;
X source.Right = Columns;
X source.Bottom = Rows - 1;
X
X fill.Char.AsciiChar = ' ';
X fill.Attributes = DefaultAttribute;
X
X ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
X &fill);
X}
X
Xdelline(int count)
X{
X SMALL_RECT source,
X clip;
X COORD dest;
X CHAR_INFO fill;
X
X dest.X = 0;
X dest.Y = ntcoord.Y;
X
X source.Left = 0;
X source.Top = ntcoord.Y + count;
X source.Right = Columns;
X source.Bottom = Rows - 1;
X
X /* get current attributes and fill out CHAR_INFO structure for fill char */
X fill.Char.AsciiChar = ' ';
X fill.Attributes = DefaultAttribute;
X
X ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
X &fill);
X}
X
X
Xscroll()
X{
X SMALL_RECT source,
X clip;
X COORD dest;
X CHAR_INFO fill;
X
X dest.X = 0;
X dest.Y = 0;
X
X source.Left = 0;
X source.Top = 1;
X source.Right = Columns;
X source.Bottom = Rows - 1;
X
X /* get current attributes and fill out CHAR_INFO structure for fill char */
X fill.Char.AsciiChar = ' ';
X fill.Attributes = DefaultAttribute;
X
X ScrollConsoleScreenBuffer(hConOut, &source, (PSMALL_RECT) 0, dest,
X &fill);
X}
X
Xgotoxy(x, y)
X register int x,
X y;
X{
X ntcoord.X = x - 1;
X ntcoord.Y = y - 1;
X SetConsoleCursorPosition(hConOut, ntcoord);
X}
X
Xnormvideo()
X{
X int count;
X WORD attr = DefaultAttribute;
X
X SetConsoleTextAttribute(hConOut, attr);
X}
X
Xtextattr(int attr)
X{
X int count;
X WORD attrw = attr;
X
X SetConsoleTextAttribute(hConOut, attr);
X}
X
Xputch(char c)
X{
X int count;
X
X WriteConsole(hConOut, &c, 1, &count, 0);
X ntcoord.X += count;
X}
X
Xdelay(x)
X{
X Sleep(x);
X}
X
Xsleep(x)
X{
X Sleep(x * 1000);
X}
X
Xvbell()
X{
X COORD origin = {0, 0};
X WORD flash = ~DefaultAttribute & 0xff;
X WORD off = DefaultAttribute;
X
X int count;
X LPWORD oldattrs = alloc(Rows * Columns * sizeof(WORD));
X
X ReadConsoleOutputAttribute(hConOut, oldattrs, Rows * Columns, origin,
X &count);
X FillConsoleOutputAttribute(hConOut, flash, Rows * Columns, origin,
X &count);
X WriteConsoleOutputAttribute(hConOut, oldattrs, Rows * Columns, origin,
X &count);
X free(oldattrs);
X}
X
Xcursor_visible(int visible)
X{
X CONSOLE_CURSOR_INFO cci;
X
X cci.bVisible = visible ? TRUE : FALSE;
X cci.dwSize = 100; /* 100 percent cursor */
X SetConsoleCursorInfo(hConOut, &cci);
X}
X
Xvoid set_window(void)
X{
X}
X
X/*
X * check for an "interrupt signal": CTRL-break or CTRL-C
X */
Xvoid breakcheck()
X{
X if (ctrlc_pressed) {
X ctrlc_pressed = FALSE;
X got_int = TRUE;
X }
X}
X
X long
Xmch_avail_mem(special)
X int special;
X{
X return 0x7fffffff; /* virual memory eh */
X}
X
X/*
X * return non-zero if a character is available
X */
X int
Xmch_char_avail()
X{
X return WaitForChar(0);
X}
X
X/*
X * set screen mode, always fails.
X */
X int
Xmch_screenmode(arg)
X char_u *arg;
X{
X EMSG("Screen mode setting not supported");
X return FAIL;
X}
END_OF_FILE
if test 31469 -ne `wc -c <'vim/src/winnt.c'`; then
echo shar: \"'vim/src/winnt.c'\" unpacked with wrong size!
fi
# end of 'vim/src/winnt.c'
fi
echo shar: End of archive 16 \(of 26\).
cp /dev/null ark16isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:00 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 36
Archive-name: vim/part17

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/macros/center.UU vim/src/amiga.c vim/src/edit.c


# Wrapped by kent@sparky on Mon Aug 15 21:44:09 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 17 (of 26)."'
if test -f 'vim/macros/center.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/center.UU'\"
else
echo shar: Extracting \"'vim/macros/center.UU'\" \(270 characters\)
sed "s/^X//" >'vim/macros/center.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/center
XM(E1H:7,@;6%C<F\@8V5N=&5R<R!A(&QI;F4@:6X@86X@.# @8VAA<F%C=&5R
XM('-P86-E+@HB0V%R969U;#H@;&EN97,@;&]N9V5R('1H86X@.# @8VAA<F%C
XM=&5R<R!W:6QL(&)E('1R=6YC871E9 IM87 @.V-E(#IS+UY;( E=*B\O#21M
XB83@Q82 ;.#$6?$1@86QL9# Z<R\@("\@+V<-)' -:R1X"EY;
X
Xend
END_OF_FILE
if test 270 -ne `wc -c <'vim/macros/center.UU'`; then
echo shar: \"'vim/macros/center.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/center'\" \(169 characters\)
cat vim/macros/center.UU | uudecode
if test 169 -ne `wc -c <'vim/macros/center'`; then
echo shar: \"'vim/macros/center'\" uudecoded with wrong size!
else
rm vim/macros/center.UU
fi
fi
# end of 'vim/macros/center.UU'
fi
if test -f 'vim/src/amiga.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/amiga.c'\"
else
echo shar: Extracting \"'vim/src/amiga.c'\" \(32474 characters\)
sed "s/^X//" >'vim/src/amiga.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *

X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.

X */
X
X/*
X * amiga.c
X *
X * Amiga system-dependent routines.
X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X
X#include <fcntl.h>
X
X#undef TRUE /* will be redefined by exec/types.h */
X#undef FALSE
X
X#ifndef LATTICE
X# include <exec/types.h>
X# include <exec/exec.h>
X# include <libraries/dos.h>
X# include <libraries/dosextens.h>
X# include <intuition/intuition.h>
X#else
X# include <proto/dos.h>
X# include <libraries/dosextens.h>
X# include <proto/intuition.h>
X# include <proto/exec.h>
X#endif
X
X#include <exec/memory.h>
X
X#ifndef NO_ARP
X#include <libraries/arpbase.h> /* for arp.library */
X#endif
X#include <dos/dostags.h> /* for 2.0 functions */
X#include <dos/dosasl.h>
X
X#if defined(LATTICE) && !defined(SASC) && !defined(NO_ARP)
X# include <libraries/arp_pragmas.h>
X#endif
X
X/*
X * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
X */
X#undef TRUE
X#define TRUE (1)
X#undef FALSE
X#define FALSE (0)
X
X#ifndef AZTEC_C
Xstatic long dos_packet __ARGS((struct MsgPort *, long, long));
X#endif
Xstatic int lock2name __ARGS((BPTR lock, char_u *buf, long len));
Xstatic struct FileInfoBlock *get_fib __ARGS((char_u *));
Xstatic int sortcmp __ARGS((char **a, char **b));
X
Xstatic BPTR raw_in = (BPTR)NULL;
Xstatic BPTR raw_out = (BPTR)NULL;
Xstatic int close_win = FALSE; /* set if Vim opened the window */
X
Xstruct IntuitionBase *IntuitionBase = NULL;
X#ifndef NO_ARP
Xstruct ArpBase *ArpBase = NULL;
X#endif
X
Xstatic struct Window *wb_window;
Xstatic char_u *oldwindowtitle = NULL;
X
X#ifndef NO_ARP
Xint dos2 = FALSE; /* Amiga DOS 2.0x or higher */
X#endif
Xint size_set = FALSE; /* set to TRUE if window size was set */
X
X void
Xwin_resize_on()
X{
X OUTSTRN("\033[12{");
X}
X
X void
Xwin_resize_off()
X{
X OUTSTRN("\033[12}");
X}
X
X void
Xmch_write(p, len)
X char_u *p;
X int len;
X{
X Write(raw_out, (char *)p, (long)len);


X}
X
X/*
X * GetChars(): low level input funcion.
X * Get a characters from the keyboard.
X * If time == 0 do not wait for characters.
X * If time == n wait a short time for characters.
X * If time == -1 wait forever for characters.
X *

X * Return number of characters read.


X */
X int
XGetChars(buf, maxlen, time)

X char_u *buf;
X int maxlen;
X int time; /* milli seconds */
X{
X int len;
X long utime;


X
X if (time >= 0)

X {


X if (time == 0)

X utime = 100L; /* time = 0 causes problems in DOS 1.2 */
X else
X utime = time * 1000L; /* convert from milli to micro secs */
X if (WaitForChar(raw_in, utime) == 0) /* no character available */


X return 0;
X }
X else /* time == -1 */

X {
X /*
X * If there is no character available within 2 seconds (default)


X * write the autoscript file to disk

X */
X if (WaitForChar(raw_in, p_ut * 1000L) == 0)
X updatescript(0);
X }
X
X for (;;) /* repeat until we got a character */
X {
X len = Read(raw_in, (char *)buf, (long)maxlen);
X if (len > 0)


X return len;
X }
X}

X
X/*
X * return non-zero if a character is available
X */
X int
Xmch_char_avail()
X{

X return (WaitForChar(raw_in, 100L) != 0);
X}
X
X void
Xsleep(n)
X int n;
X{
X#ifndef LATTICE /* SAS declares void Delay(UNLONG) */
X void Delay __ARGS((long));
X#endif


X
X if (n > 0)

X Delay((long)(50L * n));


X}
X
X long
Xmch_avail_mem(special)
X int special;
X{

X return (long)AvailMem(special ? (long)MEMF_CHIP : (long)MEMF_ANY);


X}
X
X void
Xvim_delay()
X{

X Delay(25L);


X}
X
X/*
X * We have no job control, fake it by starting a new shell.
X */
Xvoid

Xmch_suspend()
X{
X OUTSTR("new shell started\n");
X (void)call_shell(NULL, 0, TRUE);
X}
X
X#define DOS_LIBRARY ((UBYTE *) "dos.library")


X
X void
Xmch_windinit()
X{

X static char intlibname[] = "intuition.library";
X
X#ifdef AZTEC_C
X Enable_Abort = 0; /* disallow vim to be aborted */
X#endif
X Columns = 80;
X Rows = 24;
X
X /*
X * Set input and output channels, unless we have opened our own window
X */
X if (raw_in == (BPTR)NULL)
X {
X raw_in = Input();
X raw_out = Output();
X }
X
X flushbuf();
X
X wb_window = NULL;
X if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)intlibname, 0L)) == NULL)
X {
X fprintf(stderr, "cannot open %s!?\n", intlibname);
X mch_windexit(3);
X }
X (void)mch_get_winsize();
X}
X
X#include <workbench/startup.h>


X
X/*
X * Check_win checks whether we have an interactive window.

X * If not, a new window is opened with the newcli command.
X * If we would open a window ourselves, the :sh and :! commands would not
X * work properly (Why? probably because we are then running in a background CLI).
X * This also is the best way to assure proper working in a next Workbench release.
X *
X * For the -e option (quickfix mode) and -x we open our own window and disable :sh.
X * Otherwise the compiler would never know when editing is finished.
X */
X#define BUF2SIZE 320 /* lenght of buffer for argument with complete path */
X
X void
Xcheck_win(argc, argv)


X int argc;
X char **argv;
X{

X int i;
X BPTR nilfh, fh;
X char_u buf1[20];
X char_u buf2[BUF2SIZE];
X static char_u *(constrings[3]) = {(char_u *)"con:0/0/662/210/",
X (char_u *)"con:0/0/640/200/",
X (char_u *)"con:0/0/320/200/"};
X static char_u winerr[] = "VIM: Can't open window!\n";
X struct WBArg *argp;
X int ac;
X char *av;
X char_u *device = NULL;
X int exitval = 4;
X struct Library *DosBase;
X int usewin = FALSE;
X
X/*
X * check if we are running under DOS 2.0x or higher
X */
X if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
X {
X CloseLibrary(DosBase);
X#ifndef NO_ARP
X dos2 = TRUE;
X#endif
X }
X else /* without arp functions we NEED 2.0 */
X {
X#ifdef NO_ARP
X fprintf(stderr, "Need Amigados version 2.04 or later\n");
X exit(3);
X#else
X /* need arp functions for dos 1.x */
X if (!(ArpBase = (struct ArpBase *) OpenLibrary((UBYTE *)ArpName, ArpVersion)))
X {
X fprintf(stderr, "Need %s version %ld\n", ArpName, ArpVersion);
X exit(3);
X }
X#endif
X }
X
X/*
X * scan argv[] for the '-e', '-x' and '-d' arguments
X */
X for (i = 1; i < argc; ++i)
X if (argv[i][0] == '-')
X {
X switch (argv[i][1])
X {
X case 'e':
X case 'x':
X usewin = TRUE;
X break;
X
X case 'd':
X if (i < argc - 1)
X device = (char_u *)argv[i + 1];
X break;
X }
X }
X
X/*
X * If we were not started from workbench, do not have a '-d' argument and
X * we have been started with an interactive window, use that window.
X */
X if (argc != 0 && device == NULL &&
X IsInteractive(Input()) && IsInteractive(Output()))
X return;
X
X/*
X * If we are in quickfix mode, we open our own window. We can't use the
X * newcli trick below, because the compiler would not know when we are finished.
X * We do the same with the '-x' option, for mail, rn, etc.
X */
X if (usewin)
X {
X /*
X * Try to open a window. First try the specified device.
X * Then try a 24 line 80 column window.
X * If that fails, try two smaller ones.
X */
X for (i = -1; i < 3; ++i)
X {


X if (i >= 0)

X device = constrings[i];
X if (device && (raw_in = Open((UBYTE *)device, (long)MODE_NEWFILE)) != (BPTR)NULL)
X break;
X }
X if (raw_in == (BPTR)NULL) /* all three failed */
X {
X fprintf(stderr, (char *)winerr);
X goto exit;
X }
X raw_out = raw_in;
X close_win = TRUE;
X return;
X }
X
X if ((nilfh = Open((UBYTE *)"NIL:", (long)MODE_NEWFILE)) == (BPTR)NULL)
X {
X fprintf(stderr, "Cannot open NIL:\n");
X goto exit;
X }
X
X /*
X * make a unique name for the temp file (which we will not delete!)
X */
X sprintf((char *)buf1, "t:nc%ld", (char *)buf1); /* nobody else is using our stack */
X if ((fh = Open((UBYTE *)buf1, (long)MODE_NEWFILE)) == (BPTR)NULL)
X {
X fprintf(stderr, "Cannot create %s\n", (char *)buf1);
X goto exit;
X }
X /*
X * Write the command into the file, put quotes around the arguments that
X * have a space in them.
X */
X if (argc == 0) /* run from workbench */
X ac = ((struct WBStartup *)argv)->sm_NumArgs;
X else
X ac = argc;
X for (i = 0; i < ac; ++i)
X {
X if (argc == 0)
X {
X *buf2 = NUL;
X argp = &(((struct WBStartup *)argv)->sm_ArgList[i]);
X if (argp->wa_Lock)
X (void)lock2name(argp->wa_Lock, buf2, (long)(BUF2SIZE - 1));
X#ifndef NO_ARP
X if (dos2) /* use 2.0 function */
X#endif
X AddPart((UBYTE *)buf2, (UBYTE *)argp->wa_Name, (long)(BUF2SIZE - 1));
X#ifndef NO_ARP
X else /* use arp function */
X TackOn((char *)buf2, argp->wa_Name);
X#endif
X av = (char *)buf2;
X }
X else
X av = argv[i];
X
X if (av[0] == '-' && av[1] == 'd') /* skip '-d' option */
X {
X ++i;
X continue;
X }
X if (strchr(av, ' '))
X Write(fh, "\"", 1L);
X Write(fh, av, (long)strlen(av));
X if (strchr(av, ' '))
X Write(fh, "\"", 1L);
X Write(fh, " ", 1L);
X }
X Write(fh, "\nendcli\n", 8L);
X Close(fh);
X
X/*
X * Try to open a new cli in a window. If '-d' argument was given try to open
X * the specified device. Then try a 24 line 80 column window.
X * If that fails, try two smaller ones.
X */
X for (i = -1; i < 3; ++i)
X {


X if (i >= 0)

X device = constrings[i];
X else if (device == NULL)
X continue;
X sprintf((char *)buf2, "newcli <nil: >nil: %s from %s", (char *)device, (char *)buf1);
X#ifndef NO_ARP
X if (dos2)
X {
X#endif
X if (!SystemTags((UBYTE *)buf2, SYS_UserShell, TRUE, TAG_DONE))
X break;
X#ifndef NO_ARP
X }
X else
X {
X if (Execute((UBYTE *)buf2, nilfh, nilfh))
X break;
X }
X#endif
X }
X if (i == 3) /* all three failed */
X {
X DeleteFile((UBYTE *)buf1);
X fprintf(stderr, (char *)winerr);
X goto exit;
X }
X exitval = 0; /* The Execute succeeded: exit this program */
X
Xexit:
X#ifndef NO_ARP
X if (ArpBase)
X CloseLibrary((struct Library *) ArpBase);
X#endif
X exit(exitval);


X}
X
X/*
X * fname_case(): Set the case of the filename, if it already exists.

X * This will cause the filename to remain exactly the same.
X */
X void
Xfname_case(name)
X char_u *name;
X{
X register struct FileInfoBlock *fib;
X register size_t len;
X
X fib = get_fib(name);
X if (fib != NULL)
X {
X len = STRLEN(name);
X if (len == strlen(fib->fib_FileName)) /* safety check */
X memmove((char *)name, fib->fib_FileName, len);
X free(fib);
X }
X}
X
X/*
X * Get the FileInfoBlock for file "fname"
X * The returned structure has to be free()d.
X * Returns NULL on error.
X */
X static struct FileInfoBlock *
Xget_fib(fname)
X char_u *fname;
X{
X register BPTR flock;
X register struct FileInfoBlock *fib;
X
X if (fname == NULL) /* safety check */
X return NULL;
X fib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
X if (fib != NULL)
X {


X flock = Lock((UBYTE *)fname, (long)ACCESS_READ);

X if (flock == (BPTR)NULL || !Examine(flock, fib))
X {
X free(fib); /* in case of an error the memory is freed here */
X fib = NULL;
X }
X if (flock)
X UnLock(flock);
X }
X return fib;
X}
X
X/*
X * set the title of our window
X * icon name is not set
X */
X void
Xmch_settitle(title, icon)
X char_u *title;
X char_u *icon;
X{
X if (wb_window != NULL && title != NULL)
X SetWindowTitles(wb_window, (UBYTE *)title, (UBYTE *)-1L);


X}
X
X/*
X * Restore the window/icon title.
X * which is one of:
X * 1 Just restore title
X * 2 Just restore icon (which we don't have)
X * 3 Restore title and icon (which we don't have)
X */
X void
Xmch_restore_title(which)
X int which;
X{

X mch_settitle((which & 1) ? oldwindowtitle : NULL, NULL);


X}
X
X/*
X * Get name of current directory into buffer 'buf' of length 'len' bytes.

X * Return OK for success, FAIL for failure.
X */
X int
Xvim_dirname(buf, len)
X char_u *buf;
X int len;
X{
X return FullName((char_u *)"", buf, len);


X}
X
X/*
X * get absolute filename into buffer 'buf' of length 'len' bytes

X *
X * return FAIL for failure, OK otherwise
X */
X int

XFullName(fname, buf, len)
X char_u *fname, *buf;
X int len;
X{
X BPTR l;
X int retval = FAIL;
X int i;
X
X *buf = NUL;


X if (fname == NULL) /* always fail */
X return FAIL;
X

X if ((l = Lock((UBYTE *)fname, (long)ACCESS_READ)) != (BPTR)0)/* lock the file */
X {
X retval = lock2name(l, buf, (long)len);
X UnLock(l);
X }
X else if (!isFullName(fname)) /* not a full path yet */
X {
X /*
X * if cannot lock the file, try to lock the current directory and then
X * concatenate the file name
X */
X if ((l = Lock((UBYTE *)"", (long)ACCESS_READ)) != (BPTR)NULL) /* lock current dir */
X {
X retval = lock2name(l, buf, (long)len);
X UnLock(l);
X if (retval == OK)
X {
X i = STRLEN(buf);
X if (i < len - 1 && (i == 0 || buf[i - 1] != ':'))
X buf[i++] = '/';
X STRNCPY(buf + i, fname, (size_t)(len - i)); /* concatenate the fname */
X }
X }
X }
X if (retval == FAIL || *buf == 0 || *buf == ':')
X STRCPY(buf, fname); /* something failed; use the filename */


X return retval;
X}
X

X/*
X * return TRUE is fname is an absolute path name
X */
X int
XisFullName(fname)
X char_u *fname;
X{
X return (STRCHR(fname, ':') != NULL);
X}
X
X/*

X * Get the full filename from a lock. Use 2.0 function if possible, because
X * the arp function has more restrictions on the path length.


X *
X * return FAIL for failure, OK otherwise
X */
X static int

Xlock2name(lock, buf, len)
X BPTR lock;
X char_u *buf;
X long len;
X{
X#ifndef NO_ARP
X if (dos2) /* use 2.0 function */
X#endif
X return ((int)NameFromLock(lock, (UBYTE *)buf, len) ? OK : FAIL);
X#ifndef NO_ARP
X else /* use arp function */
X return ((int)PathName(lock, (char *)buf, (long)(len/32)) ? OK : FAIL);
X#endif


X}
X
X/*
X * get file permissions for 'name'

X */
X long
Xgetperm(name)
X char_u *name;
X{
X struct FileInfoBlock *fib;
X long retval = -1;
X
X fib = get_fib(name);
X if (fib != NULL)
X {
X retval = fib->fib_Protection;
X free(fib);


X }
X return retval;
X}
X

X/*
X * set file permission for 'name' to 'perm'

X *
X * return FAIL for failure, OK otherwise
X */
X int

Xsetperm(name, perm)
X char_u *name;
X long perm;
X{
X perm &= ~FIBF_ARCHIVE; /* reset archived bit */
X return (SetProtection((UBYTE *)name, (long)perm) ? OK : FAIL);
X}
X
X/*
X * return FALSE if "name" is not a directory
X * return TRUE if "name" is a directory.
X * return -1 for error.


X */
X int
Xisdir(name)

X char_u *name;
X{
X struct FileInfoBlock *fib;
X int retval = -1;
X
X fib = get_fib(name);
X if (fib != NULL)
X {
X retval = ((fib->fib_DirEntryType >= 0) ? TRUE : FALSE);
X free(fib);


X }
X return retval;
X}
X

X/*
X * Careful: mch_windexit() may be called before mch_windinit()!
X */
X void

Xmch_windexit(r)
X int r;
X{
X if (raw_in) /* put terminal in 'normal' mode */


X {
X settmode(0);
X stoptermcap();
X }

X if (raw_out)
X {
X if (term_console)
X {
X win_resize_off(); /* window resize events de-activated */
X if (size_set)
X OUTSTR("\233t\233u"); /* reset window size (CSI t CSI u) */


X }
X flushbuf();
X }
X

X mch_restore_title(3); /* restore window title */
X


X ml_close_all(); /* remove all memfiles */
X

X#ifndef NO_ARP
X if (ArpBase)
X CloseLibrary((struct Library *) ArpBase);
X#endif
X if (close_win)
X Close(raw_in);
X if (r)
X printf("Vim exiting with %d\n", r); /* somehow this makes :cq work!? */


X exit(r);
X}
X
X/*

X * This is a routine for setting a given stream to raw or cooked mode on the
X * Amiga . This is useful when you are using Lattice C to produce programs
X * that want to read single characters with the "getch()" or "fgetc" call.
X *
X * Written : 18-Jun-87 By Chuck McManis.
X */
X
X#define MP(xx) ((struct MsgPort *)((struct FileHandle *) (BADDR(xx)))->fh_Type)
X
X/*
X * Function mch_settmode() - Convert the specified file pointer to 'raw' or 'cooked'
X * mode. This only works on TTY's.
X *
X * Raw: keeps DOS from translating keys for you, also (BIG WIN) it means
X * getch() will return immediately rather than wait for a return. You
X * lose editing features though.
X *
X * Cooked: This function returns the designate file pointer to it's normal,
X * wait for a <CR> mode. This is exactly like raw() except that
X * it sends a 0 to the console to make it back into a CON: from a RAW:
X */
X void
Xmch_settmode(raw)
X int raw;
X{
X if (dos_packet(MP(raw_in), (long)ACTION_SCREEN_MODE, raw ? -1L : 0L) == 0)
X fprintf(stderr, "cannot change console mode ?!\n");


X}
X
X/*
X * set screen mode, always fails.
X */
X int
Xmch_screenmode(arg)
X char_u *arg;
X{
X EMSG("Screen mode setting not supported");
X return FAIL;
X}

X
X/*
X * Code for this routine came from the following :
X *
X * ConPackets.c - C. Scheppner, A. Finkel, P. Lindsay CBM
X * DOS packet example
X * Requires 1.2
X *
X * Found on Fish Disk 56.
X *
X * Heavely modified by mool.
X */
X
X#include <devices/conunit.h>
X
X/*
X * try to get the real window size


X * return FAIL for failure, OK otherwise
X */
X int

Xmch_get_winsize()
X{
X struct ConUnit *conUnit;
X char id_a[sizeof(struct InfoData) + 3];
X struct InfoData *id;
X
X if (!term_console) /* not an amiga window */
X return FAIL;
X
X /* insure longword alignment */
X id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
X
X /*
X * Should make console aware of real window size, not the one we set.
X * Unfortunately, under DOS 2.0x this redraws the window and it
X * is rarely needed, so we skip it now, unless we changed the size.
X */
X if (size_set)
X OUTSTR("\233t\233u"); /* CSI t CSI u */
X flushbuf();
X
X if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0 ||
X (wb_window = (struct Window *)id->id_VolumeNode) == NULL)
X {
X /* it's not an amiga window, maybe aux device */
X /* terminal type should be set */
X term_console = FALSE;
X return FAIL;
X }
X if (oldwindowtitle == NULL)
X oldwindowtitle = (char_u *)wb_window->Title;
X if (id->id_InUse == (BPTR)NULL)
X {
X fprintf(stderr, "mch_get_winsize: not a console??\n");
X return FAIL;
X }
X conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
X
X /* get window size */
X Rows = conUnit->cu_YMax + 1;
X Columns = conUnit->cu_XMax + 1;
X if (Rows < 0 || Rows > 200) /* cannot be an amiga window */
X {
X Columns = 80;
X Rows = 24;
X term_console = FALSE;
X return FAIL;
X }
X check_winsize();


X
X return OK;
X}
X
X/*

X * try to set the real window size
X */
X void
Xmch_set_winsize()
X{
X if (term_console)
X {
X size_set = TRUE;
X outchar(CSI);
X outnum((long)Rows);
X outchar('t');
X outchar(CSI);
X outnum((long)Columns);
X outchar('u');


X flushbuf();
X }
X}
X

X#ifdef SETKEYMAP
X/*
X * load and activate a new keymap for our CLI - DOES NOT WORK -
X * The problem is that after the setting of the keymap the input blocks
X * But the new keymap works allright in another window.
X * Tried but no improvement:
X * - remembering the length, data and command fields in request->io_xxx
X * - settmode(0) first, settmode(1) afterwards
X * - putting the keymap directly in conunit structure
X */
X
X#include <devices/keymap.h>
X
X void
Xset_keymap(name)
X char_u *name;
X{
X char id_a[sizeof(struct InfoData) + 3];
X struct InfoData *id;
X static struct KeyMap *old;
X static BPTR segment = (BPTR)NULL;
X struct IOStdReq *request;
X int c;
X
X if (!term_console)
X return;
X
X /* insure longword alignment */
X id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
X
X if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0)
X {
X EMSG("dos_packet failed");
X return;
X }
X if (id->id_InUse == (BPTR)NULL)
X {
X EMSG("not a console??");
X return;
X }
X request = (struct IOStdReq *) id->id_InUse;
X
X if (segment != (BPTR)NULL) /* restore old keymap */
X {
X request->io_Command = CD_SETKEYMAP;
X request->io_Length = sizeof(struct KeyMap);
X request->io_Data = (APTR)old;
X DoIO((struct IORequest *)request);
X if (request->io_Error)
X EMSG("Cannot reset keymap");
X else /* no error, free the allocated memory */
X {
X UnLoadSeg(segment);
X FreeMem(old, sizeof(struct KeyMap));
X segment = (BPTR)NULL;
X }
X }
X if (name != NULL)
X {
X segment = LoadSeg(name);
X if (segment == (BPTR)NULL)
X {
X EMSG("Cannot open keymap file");
X return;
X }
X old = (struct KeyMap *)AllocMem(sizeof(struct KeyMap), MEMF_PUBLIC);


X if (old == NULL)

X {
X EMSG(e_outofmem);
X UnLoadSeg(segment);
X segment = (BPTR)NULL;
X }
X else
X {
X request->io_Command = CD_ASKKEYMAP;
X request->io_Length = sizeof(struct KeyMap);
X request->io_Data = (APTR)old;
X DoIO((struct IORequest *)request);
X if (request->io_Error)
X {
X EMSG("Cannot get old keymap");
X UnLoadSeg(segment);
X segment = (BPTR)NULL;
X FreeMem(old, sizeof(struct KeyMap));
X }
X else
X {
X request->io_Command = CD_SETKEYMAP;
X request->io_Length = sizeof(struct KeyMap);
X request->io_Data = (APTR)((segment << 2) + 18);
X DoIO((struct IORequest *)request);
X if (request->io_Error)
X EMSG("Cannot set keymap");
X
X /* test for blocking */
X request->io_Command = CMD_READ;
X request->io_Length = 1;
X request->io_Data = (APTR)&c;
X DoIO((struct IORequest *)request); /* BLOCK HERE! */
X if (request->io_Error)
X EMSG("Cannot set keymap");


X }
X }
X }
X}
X#endif

X
X#ifndef AZTEC_C
X/*
X * Sendpacket.c
X *
X * An invaluable addition to your Amiga.lib file. This code sends a packet to
X * the given message port. This makes working around DOS lots easier.
X *
X * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
X * however that you may wish to add it to Amiga.Lib, to do so, compile it and
X * say 'oml lib:amiga.lib -r sendpacket.o'
X */
X
X/* #include <proto/exec.h> */
X/* #include <proto/dos.h> */
X#include <exec/memory.h>
X
X/*
X * Function - dos_packet written by Phil Lindsay, Carolyn Scheppner, and Andy
X * Finkel. This function will send a packet of the given type to the Message
X * Port supplied.
X */
X
X static long
Xdos_packet(pid, action, arg)
X struct MsgPort *pid; /* process indentifier ... (handlers message port) */
X long action, /* packet type ... (what you want handler to do) */
X arg; /* single argument */
X{
X# ifndef NO_ARP
X struct MsgPort *replyport;
X struct StandardPacket *packet;
X long res1;
X


X if (dos2)
X# endif

X return DoPkt(pid, action, arg, 0L, 0L, 0L, 0L); /* use 2.0 function */
X# ifndef NO_ARP
X
X replyport = (struct MsgPort *) CreatePort(NULL, 0); /* use arp function */
X if (!replyport)
X return (0);
X
X /* Allocate space for a packet, make it public and clear it */
X packet = (struct StandardPacket *)
X AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
X if (!packet) {
X DeletePort(replyport);
X return (0);
X }
X packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
X packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
X packet->sp_Pkt.dp_Port = replyport;
X packet->sp_Pkt.dp_Type = action;
X packet->sp_Pkt.dp_Arg1 = arg;
X
X PutMsg(pid, (struct Message *)packet); /* send packet */
X
X WaitPort(replyport);
X GetMsg(replyport);
X
X res1 = packet->sp_Pkt.dp_Res1;
X
X FreeMem(packet, (long) sizeof(struct StandardPacket));
X DeletePort(replyport);
X
X return (res1);
X# endif
X}
X#endif
X
X/*
X * call shell, return FAIL for failure, OK otherwise
X */
X int
Xcall_shell(cmd, filter, cooked)
X char_u *cmd;


X int filter; /* if != 0: called by dofilter() */
X int cooked;
X{

X BPTR mydir;
X int x;
X#ifndef LATTICE
X int use_execute;
X char_u *shellcmd = NULL;
X char_u *shellarg;
X#endif


X int retval = OK;
X

X if (close_win)
X {
X /* if Vim opened a window: Executing a shell may cause crashes */
X EMSG("Cannot execute shell with -e or -x option");
X return FAIL;
X }
X
X if (term_console)
X win_resize_off(); /* window resize events de-activated */
X flushbuf();
X


X if (cooked)
X settmode(0); /* set to cooked mode */

X mydir = Lock((UBYTE *)"", (long)ACCESS_READ); /* remember current directory */
X
X#ifdef LATTICE /* not tested very much */


X if (cmd == NULL)

X {


X# ifndef NO_ARP
X if (dos2)
X# endif

X x = SystemTags(p_sh, SYS_UserShell, TRUE, TAG_DONE);
X# ifndef NO_ARP
X else
X x = Execute(p_sh, raw_in, raw_out);
X# endif
X }
X else
X {


X# ifndef NO_ARP
X if (dos2)
X# endif

X x = SystemTags((char *)cmd, SYS_UserShell, TRUE, TAG_DONE);
X# ifndef NO_ARP
X else
X x = Execute((char *)cmd, 0L, raw_out);
X# endif
X }
X# ifdef NO_ARP
X if (x < 0)
X# else
X if ((dos2 && x < 0) || (!dos2 && !x))
X# endif
X {
X outstr((char_u *)"Cannot execute ");


X if (cmd == NULL)

X {
X outstr((char_u *)"shell ");
X outstr(p_sh);
X }
X else
X outstr(cmd);
X outchar('\n');
X retval = FAIL;
X }
X# ifdef NO_ARP
X else if (x)
X# else
X else if (!dos2 || x)
X# endif
X {
X if (x = IoErr())
X {
X#ifdef WEBB_COMPLETE
X if (!expand_interactively)
X#endif


X {
X outchar('\n');

X outnum(x);
X outstr((char_u *)" returned\n");


X }
X retval = FAIL;
X }

X }
X#else /* !LATTICE */
X if (p_st >= 4 || (p_st >= 2 && !filter))
X use_execute = 1;
X else
X use_execute = 0;
X if (!use_execute)
X {
X /*
X * separate shell name from argument
X */
X shellcmd = strsave(p_sh);
X if (shellcmd == NULL) /* out of memory, use Execute */
X use_execute = 1;
X else
X {
X shellarg = shellcmd;
X skiptospace(&shellarg); /* find start of arguments */
X if (*shellarg != NUL)
X {
X *shellarg++ = NUL;
X skipspace(&shellarg);
X }
X }
X }
X if (cmd == NULL)
X {
X if (use_execute)
X {


X# ifndef NO_ARP
X if (dos2)
X# endif

X x = SystemTags((UBYTE *)p_sh, SYS_UserShell, TRUE, TAG_DONE);
X# ifndef NO_ARP
X else
X x = !Execute((UBYTE *)p_sh, raw_in, raw_out);
X# endif
X }
X else
X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, NULL);
X }
X else if (use_execute)
X {


X# ifndef NO_ARP
X if (dos2)
X# endif

X x = SystemTags((UBYTE *)cmd, SYS_UserShell, TRUE, TAG_DONE);
X# ifndef NO_ARP
X else
X x = !Execute((UBYTE *)cmd, 0L, raw_out);
X# endif
X }
X else if (p_st & 1)
X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, (char *)cmd, NULL);
X else
X x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, "-c", (char *)cmd, NULL);
X# ifdef NO_ARP
X if (x < 0)
X# else
X if ((dos2 && x < 0) || (!dos2 && x))
X# endif
X {
X outstr((char_u *)"Cannot execute ");
X if (use_execute)


X {
X if (cmd == NULL)

X outstr(p_sh);
X else
X outstr(cmd);
X }
X else
X {
X outstr((char_u *)"shell ");
X outstr(shellcmd);


X }
X outchar('\n');

X retval = FAIL;
X }
X else
X {
X if (use_execute)
X {
X# ifdef NO_ARP
X if (x)
X# else
X if (!dos2 || x)
X# endif
X x = IoErr();
X }
X else
X x = wait();
X if (x)
X {
X#ifdef WEBB_COMPLETE
X if (!expand_interactively)
X#endif


X {
X outchar('\n');

X outnum((long)x);
X outstrn((char_u *)" returned\n");


X }
X retval = FAIL;
X }

X }
X free(shellcmd);
X#endif /* !LATTICE */
X
X if (mydir = CurrentDir(mydir)) /* make sure we stay in the same directory */
X UnLock(mydir);


X if (cooked)
X settmode(1); /* set to raw mode */

X resettitle();
X if (term_console)
X win_resize_on(); /* window resize events activated */


X return retval;
X}
X

X/*
X * check for an "interrupt signal"

X * We only react to a CTRL-C, but also clear the other break signals to avoid trouble
X * with lattice-c programs.
X */
X void
Xbreakcheck()
X{
X if (SetSignal(0L, (long)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) & SIGBREAKF_CTRL_C)


X got_int = TRUE;
X}
X

X/* this routine causes manx to use this Chk_Abort() rather than it's own */
X/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
X/* is zero). Since we want to check for our own ^C's */
X
X#ifdef _DCC
X#define Chk_Abort chkabort
X#endif
X
X long
XChk_Abort()
X{
X return(0L);
X}
X
X/*
X * ExpandWildCard() - this code does wild-card pattern matching using the arp
X * routines. This is based on WildDemo2.c (found in arp1.1
X * distribution). That code's copyright follows :
X *-------------------------------------------------------------------------
X * WildDemo2.c - Search filesystem for patterns, and separate into directories
X * and files, sorting each separately using DA lists.
X *
X * -+=SDB=+-
X *
X * Copyright (c) 1987, Scott Ballantyne
X * Use and abuse as you please.


X *
X * num_pat is number of input patterns
X * pat is array of pointers to input patterns
X * num_file is pointer to number of matched file names

X * file is pointer to array of pointers to matched file names
X * if file_only is TRUE we match only files, no dirs
X * if list_notfound is TRUE we include not-found entries (probably locked)
X * return OK for success, FAIL for error (you may loose some memory)
X *-------------------------------------------------------------------------
X */
X
X/* #include <arpfunctions.h> */
Xextern void *malloc __ARGS((size_t)), *calloc __ARGS((size_t, size_t));
Xstatic int insfile __ARGS((char_u *, int));
Xstatic void freefiles __ARGS((void));
X
X#define ANCHOR_BUF_SIZE (512)
X#define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE)
X
X/*
X * we use this structure to built a list of file names
X */
Xstruct onefile
X{
X struct onefile *next;
X char_u name[1]; /* really longer */
X} *namelist = NULL;
X
X/*
X * insert one file into the list of file names


X * return FAIL for failure

X * return OK for success


X */
X static int

Xinsfile(name, isdir)
X char_u *name;
X int isdir;
X{
X struct onefile *new;
X
X new = (struct onefile *)alloc((unsigned)(sizeof(struct onefile) + STRLEN(name) + isdir));
X if (new == NULL)
X return FAIL;
X STRCPY(&(new->name[0]), name);
X if (isdir)
X STRCAT(&(new->name[0]), "/");
X new->next = namelist;
X namelist = new;


X return OK;
X}
X
X/*

X * free a whole list of file names


X */
X static void

Xfreefiles()
X{
X struct onefile *p;
X
X while (namelist)
X {
X p = namelist->next;
X free(namelist);
X namelist = p;
X }
X}
X
X static int
Xsortcmp(a, b)
X char **a, **b;
X{
X return strcmp(*a, *b);
X}
X
X int
XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
X int num_pat;
X char_u **pat;
X int *num_file;


X char_u ***file;
X int files_only;
X int list_notfound;

X{
X int i;
X struct AnchorPath *Anchor;
X int domatchend = FALSE;
X LONG Result;
X struct onefile *p;


X char_u *errmsg = NULL;

X char_u *starbuf, *sp, *dp;
X int foundone;
X
X *num_file = 0;
X *file = (char_u **)"";
X
X /* Get our AnchorBase */
X Anchor = (struct AnchorPath *) calloc((size_t)1, (size_t)ANCHOR_SIZE);
X if (!Anchor)
X goto OUT_OF_MEMORY;
X Anchor->ap_StrLen = ANCHOR_BUF_SIZE; /* ap_Length not supported anymore */
X#ifdef APF_DODOT
X Anchor->ap_Flags = APF_DODOT | APF_DOWILD; /* allow '.' for current dir */
X#else
X Anchor->ap_Flags = APF_DoDot | APF_DoWild; /* allow '.' for current dir */
X#endif
X


X for (i = 0; i < num_pat; i++)

X {
X#ifndef NO_ARP
X if (dos2)
X {
X#endif
X /* hack to replace '*' by '#?' */
X starbuf = alloc((unsigned)(2 * STRLEN(pat[i]) + 1)); /* maximum required */
X if (starbuf == NULL)
X goto OUT_OF_MEMORY;
X for (sp = pat[i], dp = starbuf; *sp; ++sp)
X {
X if (*sp == '*')
X {
X *dp++ = '#';
X *dp++ = '?';
X }
X else
X *dp++ = *sp;
X }
X *dp = NUL;
X Result = MatchFirst((UBYTE *)starbuf, Anchor);
X free(starbuf);
X#ifndef NO_ARP
X }
X else
X Result = FindFirst((char *)pat[i], Anchor);
X#endif
X domatchend = TRUE;
X foundone = FALSE;
X while (Result == 0)
X {
X if (!files_only || Anchor->ap_Info.fib_DirEntryType < 0)
X {
X (*num_file)++;
X if (insfile((char_u *)Anchor->ap_Buf, Anchor->ap_Info.fib_DirEntryType >= 0) == FAIL)
X {
XOUT_OF_MEMORY:
X errmsg = (char_u *)"Out of memory";
X goto Return;
X }
X foundone = TRUE;
X }
X#ifndef NO_ARP
X if (dos2)
X#endif
X Result = MatchNext(Anchor);
X#ifndef NO_ARP
X else
X Result = FindNext(Anchor);
X#endif
X }
X if (Result == ERROR_BUFFER_OVERFLOW)
X {
X errmsg = (char_u *)"ANCHOR_BUF_SIZE too small.";
X goto Return;
X }
X if (!foundone)
X {
X if (list_notfound) /* put object with error in list */
X {
X (*num_file)++;
X if (insfile(pat[i], FALSE) == FAIL)
X goto OUT_OF_MEMORY;
X }
X else if (Result != ERROR_OBJECT_NOT_FOUND && Result != ERROR_NO_MORE_ENTRIES)
X {
X errmsg = (char_u *)"I/O ERROR";
X goto Return;
X }
X }
X#ifndef NO_ARP
X if (dos2)
X#endif
X MatchEnd(Anchor);
X#ifndef NO_ARP
X else
X FreeAnchorChain(Anchor);
X#endif
X domatchend = FALSE;
X }
X
X p = namelist;
X if (p)
X {
X *file = (char_u **) malloc(sizeof(char_u *) * (*num_file));


X if (*file == NULL)

X goto OUT_OF_MEMORY;
X for (i = *num_file - 1; p; p = p->next, --i)
X {
X (*file)[i] = (char_u *) malloc(STRLEN(p->name) + 1);
X if ((*file)[i] == NULL)
X goto OUT_OF_MEMORY;
X STRCPY((*file)[i], p->name);
X }
X qsort((void *)*file, (size_t)*num_file, sizeof(char_u *), sortcmp);
X }
XReturn:
X if (domatchend)
X {
X#ifndef NO_ARP
X if (dos2)
X#endif
X MatchEnd(Anchor);
X#ifndef NO_ARP
X else
X FreeAnchorChain(Anchor);
X#endif
X }
X if (Anchor)
X free(Anchor);
X freefiles();
X if (errmsg)
X {
X emsg(errmsg);
X *num_file = 0;


X return FAIL;
X }
X return OK;
X}
X

X void
XFreeWild(num, file)
X int num;
X char_u **file;
X{
X if (file == NULL || num == 0)


X return;
X while (num--)
X free(file[num]);
X free(file);
X}
X

X int
Xhas_wildcard(p)
X char_u *p;
X{
X for ( ; *p; ++p)
X if (strchr("*?[(~#", *p) != NULL)


X return TRUE;
X return FALSE;

X}
X
X/*
X * With 2.0 support for reading local environment variables
X * Careful: uses IObuff!


X */
X
X char_u *

Xvimgetenv(var)
X char_u *var;


X{
X int len;
X

X#ifndef NO_ARP
X if (!dos2)
X return (char_u *)getenv((char *)var);
X#endif
X
X len = GetVar((UBYTE *)var, (UBYTE *)IObuff, (long)(IOSIZE - 1), (long)0);
X
X if (len == -1)
X return NULL;
X else
X return IObuff;
X}
END_OF_FILE
if test 32474 -ne `wc -c <'vim/src/amiga.c'`; then
echo shar: \"'vim/src/amiga.c'\" unpacked with wrong size!
fi
# end of 'vim/src/amiga.c'
fi
if test -f 'vim/src/edit.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/edit.c'\"
else
echo shar: Extracting \"'vim/src/edit.c'\" \(31932 characters\)
sed "s/^X//" >'vim/src/edit.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *

X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.

X */
X
X/*
X * edit.c: functions for insert mode
X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X#include "ops.h" /* for operator */
X
Xextern char_u *get_inserted();
Xstatic void start_arrow __ARGS((void));
Xstatic void stop_arrow __ARGS((void));
Xstatic void stop_insert __ARGS((void));
Xstatic int echeck_abbr __ARGS((int));
X
Xint arrow_used; /* Normally FALSE, set to TRUE after hitting
X * cursor key in insert mode. Used by vgetorpeek()
X * to decide when to call u_sync() */
Xint restart_edit = 0; /* call edit when next command finished */
Xstatic char_u *last_insert = NULL;
X /* the text of the previous insert */
Xstatic int last_insert_skip;
X /* number of chars in front of the previous insert */
Xstatic int new_insert_skip;
X /* number of chars in front of the current insert */
X
X void
Xedit(count)
X long count;
X{
X int c;
X int cc;
X char_u *ptr;
X char_u *saved_line = NULL; /* saved line for replace mode */
X linenr_t saved_lnum = 0; /* lnum of saved line */
X int saved_char = NUL; /* char replaced by NL */
X linenr_t lnum;
X int temp = 0;
X int mode;


X int nextc = 0;

X int lastc = 0;
X colnr_t mincol;
X static linenr_t o_lnum = 0;
X static int o_eol = FALSE;
X#ifdef WEBB_KEYWORD_COMPL
X FPOS complete_pos;
X FPOS first_match;
X char_u *complete_pat = NULL;
X char_u *completion_str = NULL;
X char_u *last_completion_str = NULL;
X char_u *tmp_ptr;
X int previous_c = 0;
X int complete_col = 0; /* init for gcc */
X int complete_direction;
X int complete_any_word = 0; /* true -> ^N/^P hit with no prefix
X * init for gcc */
X int done;
X int found_error = FALSE;
X char_u backup_char = 0; /* init for gcc */
X
X c = NUL;
X#endif /* WEBB_KEYWORD_COMPL */
X
X if (restart_edit)
X {
X arrow_used = TRUE;
X restart_edit = 0;
X /*
X * If the cursor was after the end-of-line before the CTRL-O
X * and it is now at the end-of-line, put it after the end-of-line
X * (this is not correct in very rare cases).
X */
X if (o_eol && curwin->w_cursor.lnum == o_lnum &&
X *((ptr = ml_get(curwin->w_cursor.lnum)) + curwin->w_cursor.col) != NUL &&
X *(ptr + curwin->w_cursor.col + 1) == NUL)
X ++curwin->w_cursor.col;
X }
X else
X {
X arrow_used = FALSE;
X o_eol = FALSE;
X }
X
X#ifdef DIGRAPHS
X dodigraph(-1); /* clear digraphs */
X#endif
X
X/*
X * Get the current length of the redo buffer, those characters have to be
X * skipped if we want to get to the inserted characters.
X */
X
X ptr = get_inserted();
X new_insert_skip = STRLEN(ptr);
X free(ptr);
X
X old_indent = 0;


X
X for (;;)
X {

X if (arrow_used) /* don't repeat insert when arrow key used */


X count = 0;
X

X if (!arrow_used)
X curwin->w_set_curswant = TRUE; /* set curwin->w_curswant for next K_DARROW or K_UARROW */
X cursupdate(); /* Figure out where the cursor is based on curwin->w_cursor. */
X showruler(0);
X setcursor();
X#ifdef WEBB_KEYWORD_COMPL
X previous_c = c;
X#endif /* WEBB_KEYWORD_COMPL */


X if (nextc) /* character remaining from CTRL-V */
X {
X c = nextc;

X nextc = 0;
X }
X else
X {


X c = vgetc();
X if (c == Ctrl('C'))
X got_int = FALSE;
X }

X#ifdef WEBB_KEYWORD_COMPL
X if (previous_c == Ctrl('N') || previous_c == Ctrl('P'))
X {
X /* Show error message from attempted keyword completion (probably
X * 'Pattern not found') until another key is hit, then go back to
X * showing what mode we are in.
X */
X showmode();
X if (c != Ctrl('N') && c != Ctrl('P'))
X {
X /* Get here when we have finished typing a sequence of ^N and
X * ^P. Free up memory that was used, and make sure we can redo
X * the insert.
X */
X if (completion_str != NULL)
X AppendToRedobuff(completion_str);
X free(complete_pat);
X free(completion_str);
X free(last_completion_str);
X complete_pat = completion_str = last_completion_str = NULL;
X }
X }
X#endif /* WEBB_KEYWORD_COMPL */
X if (c != Ctrl('D')) /* remember to detect ^^D and 0^D */


X lastc = c;
X

X/*
X * In replace mode a backspace puts the original text back.
X * We save the current line to be able to do that.
X * If characters are appended to the line, they will be deleted.
X * If we start a new line (with CR) the saved line will be empty, thus
X * the characters will be deleted.
X * If we backspace over the new line, that line will be saved.
X */
X if (State == REPLACE && saved_lnum != curwin->w_cursor.lnum)
X {
X free(saved_line);
X saved_line = strsave(ml_get(curwin->w_cursor.lnum));
X saved_lnum = curwin->w_cursor.lnum;
X }


X
X#ifdef DIGRAPHS
X c = dodigraph(c);

X#endif /* DIGRAPHS */
X
X if (c == Ctrl('V'))
X {
X screen_start();
X screen_outchar('^', curwin->w_row, curwin->w_col);
X AppendToRedobuff((char_u *)"\026"); /* CTRL-V */
X cursupdate();
X setcursor();
X
X c = get_literal(&nextc);
X
X insertchar(c);
X continue;
X }
X switch (c) /* handle character in insert mode */
X {
X case Ctrl('O'): /* execute one command */
X if (echeck_abbr(Ctrl('O') + 0x100))
X break;
X count = 0;


X if (State == INSERT)

X restart_edit = 'I';
X else
X restart_edit = 'R';
X o_lnum = curwin->w_cursor.lnum;
X o_eol = (gchar_cursor() == NUL);
X goto doESCkey;
X
X case ESC: /* an escape ends input mode */
X if (echeck_abbr(ESC + 0x100))


X break;
X /*FALLTHROUGH*/
X

X case Ctrl('C'):
XdoESCkey:
X if (!arrow_used)
X {
X AppendToRedobuff(ESC_STR);
X
X if (--count > 0) /* repeat what was typed */
X {
X (void)start_redo_ins();
X continue;
X }
X stop_insert();
X }
X if (!restart_edit)


X curwin->w_set_curswant = TRUE;

X
X /*
X * The cursor should end up on the last inserted character.
X */
X if (curwin->w_cursor.col != 0 && (!restart_edit || gchar_cursor() == NUL) && !p_ri)
X dec_cursor();
X if (extraspace) /* did reverse replace in column 0 */
X {
X (void)delchar(FALSE);
X updateline();
X extraspace = FALSE;


X }
X State = NORMAL;

X /* inchar() may have deleted the "INSERT" message */
X if (Recording)
X showmode();
X else if (p_smd)
X MSG("");
X free(saved_line);
X old_indent = 0;
X return;
X
X /*
X * Insert the previously inserted text.
X * Last_insert actually is a copy of the redo buffer, so we
X * first have to remove the command.
X * For ^@ the trailing ESC will end the insert.
X */
X case K_ZERO:


X case Ctrl('A'):

X stuff_inserted(NUL, 1L, (c == Ctrl('A')));
X break;
X
X /*
X * insert the contents of a register
X */
X case Ctrl('R'):
X if (insertbuf(vgetc()) == FAIL)
X beep();
X break;
X
X case Ctrl('B'): /* toggle reverse insert mode */
X p_ri = !p_ri;
X showmode();
X break;
X
X /*
X * If the cursor is on an indent, ^T/^D insert/delete one
X * shiftwidth. Otherwise ^T/^D behave like a TAB/backspace.
X * This isn't completely compatible with
X * vi, but the difference isn't very noticeable and now you can
X * mix ^D/backspace and ^T/TAB without thinking about which one
X * must be used.
X */
X case Ctrl('T'): /* make indent one shiftwidth greater */
X case Ctrl('D'): /* make indent one shiftwidth smaller */
X stop_arrow();
X AppendCharToRedobuff(c);
X if ((lastc == '0' || lastc == '^') && curwin->w_cursor.col)
X {
X --curwin->w_cursor.col;
X (void)delchar(FALSE); /* delete the '^' or '0' */
X if (lastc == '^')
X old_indent = get_indent(); /* remember current indent */
X
X /* determine offset from first non-blank */
X temp = curwin->w_cursor.col;
X beginline(TRUE);
X temp -= curwin->w_cursor.col;
X set_indent(0, TRUE); /* remove all indent */
X }
X else
X {
Xins_indent:
X /* determine offset from first non-blank */
X temp = curwin->w_cursor.col;
X beginline(TRUE);
X temp -= curwin->w_cursor.col;
X
X shift_line(c == Ctrl('D'), TRUE, 1);
X
X /* try to put cursor on same character */
X temp += curwin->w_cursor.col;
X }


X if (temp <= 0)

X curwin->w_cursor.col = 0;

X else
X curwin->w_cursor.col = temp;
X did_ai = FALSE;
X did_si = FALSE;
X can_si = FALSE;
X goto redraw;


X
X case BS:
X case DEL:

Xnextbs:
X mode = 0;
Xdodel:
X /* can't delete anything in an empty file */
X /* can't backup past first character in buffer */
X /* can't backup past starting point unless 'backspace' > 1 */
X /* can backup to a previous line if 'backspace' == 0 */
X if (bufempty() || (!p_ri &&
X ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col <= 0) ||
X (p_bs < 2 && (arrow_used ||
X (curwin->w_cursor.lnum == Insstart.lnum &&
X curwin->w_cursor.col <= Insstart.col) ||
X (curwin->w_cursor.col <= 0 && p_bs == 0))))))
X {
X beep();
X goto redraw;
X }
X
X stop_arrow();
X if (p_ri)
X inc_cursor();
X if (curwin->w_cursor.col <= 0) /* delete newline! */
X {
X lnum = Insstart.lnum;
X if (curwin->w_cursor.lnum == Insstart.lnum || p_ri)
X {
X if (!u_save((linenr_t)(curwin->w_cursor.lnum - 2), (linenr_t)(curwin->w_cursor.lnum + 1)))
X goto redraw;
X --Insstart.lnum;
X Insstart.col = 0;
X /* this is in xvim, why?
X if (curbuf->b_p_ai)
X for (ptr = ml_get(Insstart.lnum);
X iswhite(*ptr++); Insstart.col++)
X ; */
X }
X /* in replace mode, in the line we started replacing, we
X only move the cursor */
X if (State != REPLACE || curwin->w_cursor.lnum > lnum)
X {
X temp = gchar_cursor(); /* remember current char */
X --curwin->w_cursor.lnum;
X (void)dojoin(FALSE, TRUE);
X if (temp == NUL && gchar_cursor() != NUL)
X ++curwin->w_cursor.col;
X if (saved_char) /* restore what NL replaced */
X {
X State = NORMAL; /* no replace for this char */
X inschar(saved_char); /* but no showmatch */
X State = REPLACE;
X saved_char = NUL;
X if (!p_ri)
X dec_cursor();
X }
X else if (p_ri) /* in reverse mode */
X saved_lnum = 0; /* save this line again */
X }
X else
X dec_cursor();
X did_ai = FALSE;
X }
X else
X {
X if (p_ri && State != REPLACE)
X dec_cursor();
X mincol = 0;
X if (mode == 3 && !p_ri && curbuf->b_p_ai) /* keep indent */
X {
X temp = curwin->w_cursor.col;
X beginline(TRUE);
X if (curwin->w_cursor.col < temp)
X mincol = curwin->w_cursor.col;
X curwin->w_cursor.col = temp;
X }
X
X /* delete upto starting point, start of line or previous word */
X do
X {
X if (!p_ri)
X dec_cursor();
X
X /* start of word? */
X if (mode == 1 && !isspace(gchar_cursor()))
X {
X mode = 2;
X temp = isidchar(gchar_cursor());
X }
X /* end of word? */
X else if (mode == 2 && (isspace(cc = gchar_cursor()) || isidchar(cc) != temp))
X {
X if (!p_ri)
X inc_cursor();
X else if (State == REPLACE)
X dec_cursor();
X break;
X }
X if (State == REPLACE)
X {
X if (saved_line)
X {
X if (extraspace)
X {
X if ((int)STRLEN(ml_get(curwin->w_cursor.lnum)) - 1 > (int)STRLEN(saved_line))
X (void)delchar(FALSE);
X else
X {
X dec_cursor();
X (void)delchar(FALSE);
X extraspace = FALSE;
X pchar_cursor(*saved_line);
X }
X }
X else if (curwin->w_cursor.col < STRLEN(saved_line))
X pchar_cursor(saved_line[curwin->w_cursor.col]);
X else if (!p_ri)
X (void)delchar(FALSE);
X }
X }
X else /* State != REPLACE */
X {
X (void)delchar(FALSE);
X if (p_ri && gchar_cursor() == NUL)
X break;
X }
X if (mode == 0) /* just a single backspace */
X break;
X if (p_ri && State == REPLACE && inc_cursor())
X break;
X } while (p_ri || (curwin->w_cursor.col > mincol && (curwin->w_cursor.lnum != Insstart.lnum ||
X curwin->w_cursor.col != Insstart.col)));
X if (extraspace)
X dec_cursor();
X }
X did_si = FALSE;
X can_si = FALSE;
X if (curwin->w_cursor.col <= 1)
X did_ai = FALSE;
X /*
X * It's a little strange to put backspaces into the redo
X * buffer, but it makes auto-indent a lot easier to deal
X * with.
X */
X AppendCharToRedobuff(c);
X if (vpeekc() == BS)


X {
X c = vgetc();

X goto nextbs; /* speedup multiple backspaces */
X }
Xredraw:
X cursupdate();
X updateline();
X break;
X
X case Ctrl('W'): /* delete word before cursor */
X mode = 1;
X goto dodel;
X
X case Ctrl('U'): /* delete inserted text in current line */
X mode = 3;
X goto dodel;
X
X case K_LARROW:
X if (oneleft() == OK)
X {
X start_arrow();
X }
X /* if 'whichwrap' set for cursor in insert mode may go
X * to previous line */
X else if ((p_ww & 16) && curwin->w_cursor.lnum > 1)
X {
X start_arrow();


X --(curwin->w_cursor.lnum);
X coladvance(MAXCOL);

X curwin->w_curswant = MAXCOL; /* so we stay at the end */
X }
X else
X beep();
X break;
X
X case K_SLARROW:
X if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0)
X {
X bck_word(1L, 0);
X start_arrow();
X }
X else
X beep();
X break;
X
X case K_RARROW:
X if (gchar_cursor() != NUL)
X {


X curwin->w_set_curswant = TRUE;

X start_arrow();
X ++curwin->w_cursor.col;
X }
X /* if 'whichwrap' set for cursor in insert mode may go
X * to next line */
X else if ((p_ww & 16) && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
X {
X curwin->w_set_curswant = TRUE;
X start_arrow();
X ++curwin->w_cursor.lnum;
X curwin->w_cursor.col = 0;
X }
X else
X beep();
X break;
X
X case K_SRARROW:
X if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count || gchar_cursor() != NUL)
X {
X fwd_word(1L, 0, 0);
X start_arrow();
X }
X else
X beep();
X break;
X
X case K_UARROW:
X if (oneup(1L))
X start_arrow();
X else
X beep();
X break;
X
X case K_SUARROW:
X if (onepage(BACKWARD, 1L))
X start_arrow();
X else
X beep();
X break;
X
X case K_DARROW:
X if (onedown(1L))
X start_arrow();
X else
X beep();
X break;
X
X case K_SDARROW:
X if (onepage(FORWARD, 1L))
X start_arrow();
X else
X beep();
X break;
X
X case TAB:
X if (echeck_abbr(TAB + 0x100))
X break;
X if ((!curbuf->b_p_et && !(p_sta && inindent())) || (p_ri && State == REPLACE))
X goto normalchar;
X
X AppendToRedobuff((char_u *)"\t");
X
X if (!curbuf->b_p_et) /* insert smart tab */
X goto ins_indent;
X
X /* p_te set: expand a tab into spaces */
X stop_arrow();
X did_ai = FALSE;
X did_si = FALSE;
X can_si = FALSE;
X if (p_sta && inindent())
X temp = (int)curbuf->b_p_sw;
X else
X temp = (int)curbuf->b_p_ts;
X temp -= curwin->w_cursor.col % temp;
X inschar(' '); /* delete one char in replace mode */
X while (--temp)
X insstr((char_u *)" "); /* insstr does not delete chars */
X goto redraw;
X
X case CR:
X case NL:
X if (echeck_abbr(c + 0x100))
X break;
X stop_arrow();
X if (State == REPLACE)
X {
X saved_char = gchar_cursor();
X (void)delchar(FALSE);
X }
X /*
X * When 'autoindent' set delete white space after the cursor.
X * Vi does this, although it probably does it implicitly due
X * to the way it does auto-indent -- webb.
X */
X if (curbuf->b_p_ai || curbuf->b_p_si)
X while ((c = gchar_cursor()) == ' ' || c == TAB)
X (void)delchar(FALSE);
X
X AppendToRedobuff(NL_STR);
X if (!Opencmd(FORWARD, TRUE, State == INSERT))
X goto doESCkey; /* out of memory */
X if (p_ri)
X {
X dec_cursor();
X if (State == REPLACE && curwin->w_cursor.col > 0)
X dec_cursor();
X }


X break;
X
X#ifdef DIGRAPHS
X case Ctrl('K'):

X screen_start();
X screen_outchar('?', curwin->w_row, curwin->w_col);
X setcursor();
X c = vgetc();
X if (c != ESC)
X {


X if (charsize(c) == 1)

X {
X screen_start();
X screen_outchar(c, curwin->w_row, curwin->w_col);
X }
X setcursor();
X cc = vgetc();
X if (cc != ESC)
X {
X AppendToRedobuff((char_u *)"\026"); /* CTRL-V */


X c = getdigraph(c, cc, TRUE);

X goto normalchar;
X }
X }
X updateline();
X goto doESCkey;


X#endif /* DIGRAPHS */
X

X#ifdef WEBB_KEYWORD_COMPL
X case Ctrl('P'): /* Do previous pattern completion */
X case Ctrl('N'): /* Do next pattern completion */
X if (c == Ctrl('P'))
X complete_direction = BACKWARD;
X else
X complete_direction = FORWARD;
X if (previous_c != Ctrl('N') && previous_c != Ctrl('P'))
X {
X /* First time we hit ^N or ^P (in a row, I mean) */
X complete_pos = curwin->w_cursor;
X ptr = ml_get(complete_pos.lnum);
X complete_col = complete_pos.col;
X temp = complete_col - 1;
X if (temp < 0 || !isidchar(ptr[temp]))
X {
X complete_pat = strsave((char_u *)"\\<[a-zA-Z_]");
X complete_any_word = TRUE;
X }
X else
X {
X while (temp >= 0 && isidchar(ptr[temp]))
X temp--;
X temp++;
X complete_pat = alloc(curwin->w_cursor.col - temp + 3);
X if (complete_pat != NULL)
X sprintf((char *)complete_pat, "\\<%.*s",
X (int)(curwin->w_cursor.col - temp), ptr + temp);
X complete_any_word = FALSE;
X }
X last_completion_str = strsave((char_u *)" ");
X }
X else
X {
X /* This is not the first ^N or ^P we have hit in a row */
X while (curwin->w_cursor.col != complete_col)
X {
X curwin->w_cursor.col--;
X delchar(FALSE);
X }
X if (completion_str != NULL)
X {
X free(last_completion_str);
X last_completion_str = strsave(completion_str);
X }
X }
X if (complete_pat == NULL || last_completion_str == NULL)
X {
X found_error = TRUE;
X break;
X }
X if (!complete_any_word)


X {
X ptr = ml_get(curwin->w_cursor.lnum);

X backup_char = ptr[complete_col - 1];
X ptr[complete_col - 1] = ' ';
X }
X done = FALSE;
X found_error = FALSE;
X first_match.lnum = 0;
X keep_old_search_pattern = TRUE;
X while (!done)
X {
X if (complete_direction == BACKWARD)
X {
X ptr = ml_get(complete_pos.lnum);
X while (isidchar(ptr[complete_pos.col]))
X complete_pos.col--;
X complete_pos.col++;
X }
X if (!searchit(&complete_pos, complete_direction,
X complete_pat, 1L, TRUE, TRUE))
X {
X found_error = TRUE;
X break;
X }
X if (complete_any_word)
X ptr = ml_get_pos(&complete_pos);
X else
X ptr = ml_get_pos(&complete_pos) + 1;
X tmp_ptr = ptr;
X temp = 1;
X while (*tmp_ptr != NUL && isidchar(*tmp_ptr++))
X temp++;
X free (completion_str);
X tmp_ptr = completion_str = alloc(temp);
X if (completion_str == NULL)
X {
X found_error = TRUE;
X break;
X }
X while (*ptr != NUL && isidchar(*ptr))
X *(tmp_ptr++) = *(ptr++);
X *tmp_ptr = NUL;
X if (completion_str[0] != NUL &&
X STRCMP(completion_str, last_completion_str) != 0)
X done = TRUE;
X else if (first_match.lnum == 0)
X {
X first_match.lnum = complete_pos.lnum;
X first_match.col = complete_pos.col;
X }
X else if (complete_pos.lnum == first_match.lnum
X && complete_pos.col == first_match.col)
X {
X if (completion_str[0] == NUL)
X EMSG("Exact match only");
X else
X EMSG("No other matches");
X done = TRUE;
X }
X }
X if (!found_error)
X insstr(completion_str);
X if (!complete_any_word)


X {
X ptr = ml_get(curwin->w_cursor.lnum);

X ptr[complete_col - 1] = backup_char;
X }
X keep_old_search_pattern = FALSE;
X updateline();
X break;
X#endif /* WEBB_KEYWORD_COMPL */
X
X case Ctrl('Y'): /* copy from previous line */
X lnum = curwin->w_cursor.lnum - 1;
X goto copychar;
X
X case Ctrl('E'): /* copy from next line */
X lnum = curwin->w_cursor.lnum + 1;
Xcopychar:


X if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)

X {
X beep();
X break;
X }
X
X /* try to advance to the cursor column */
X temp = 0;
X ptr = ml_get(lnum);
X while (temp < curwin->w_virtcol && *ptr)
X temp += chartabsize(*ptr++, (long)temp);
X
X if (temp > curwin->w_virtcol)
X --ptr;
X if ((c = *ptr) == NUL)
X {
X beep();
X break;
X }
X
X /*FALLTHROUGH*/
X default:
Xnormalchar:
X /*
X * do some very smart indenting when entering '{' or '}' or '#'
X */
X if (curwin->w_cursor.col > 0 && ((can_si && c == '}') || (did_si && c == '{')))
X {
X FPOS *pos, old_pos;
X int i;
X
X /* for '}' set indent equal to matching '{' */
X if (c == '}' && (pos = showmatch('{')) != NULL)


X {
X old_pos = curwin->w_cursor;

X curwin->w_cursor = *pos;

X i = get_indent();


X curwin->w_cursor = old_pos;

X set_indent(i, TRUE);
X }
X else
X shift_line(TRUE, TRUE, 1);
X }
X /* set indent of '#' always to 0 */
X if (curwin->w_cursor.col > 0 && can_si && c == '#')
X {
X /* remember current indent for next line */
X old_indent = get_indent();
X set_indent(0, TRUE);
X }
X
X if (isidchar(c) || !echeck_abbr(c))
X insertchar(c);
X break;


X }
X }
X}
X
X/*

X * Next character is interpreted literally.
X * A one, two or three digit decimal number is interpreted as its byte value.
X * If one or two digits are entered, *nextc is set to the next character.
X */
X int
Xget_literal(nextc)
X int *nextc;
X{
X int cc;
X int nc;
X int oldstate;
X int i;
X
X oldstate = State;
X State = NOMAPPING; /* next characters not mapped */


X
X if (got_int)
X {

X *nextc = NUL;
X return Ctrl('C');
X }
X cc = 0;
X for (i = 0; i < 3; ++i)
X {
X nc = vgetc();
X if (!isdigit(nc))
X break;
X cc = cc * 10 + nc - '0';
X nc = 0;
X }
X if (i == 0) /* no number entered */
X {
X cc = nc;
X nc = 0;
X if (cc == K_ZERO) /* NUL is stored as NL */
X cc = '\n';
X }
X else if (cc == 0) /* NUL is stored as NL */
X cc = '\n';


X
X State = oldstate;

X *nextc = nc;
X got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */
X return cc;
X}
X
X/*
X * Special characters in this context are those that need processing other
X * than the simple insertion that can be performed here. This includes ESC
X * which terminates the insert, and CR/NL which need special processing to
X * open up a new line. This routine tries to optimize insertions performed by
X * the "redo", "undo" or "put" commands, so it needs to know when it should
X * stop and defer processing to the "normal" mechanism.
X */
X#define ISSPECIAL(c) ((c) < ' ' || (c) >= DEL)
X
X void
Xinsertchar(c)
X unsigned c;
X{
X int haveto_redraw = FALSE;
X int textwidth;
X
X stop_arrow();
X
X /*
X * find out textwidth to be used:
X * if 'textwidth' option is set, use it
X * else if 'wrapmargin' option is set, use Columns - 'wrapmargin'
X * if invalid value, us 0.
X */
X textwidth = curbuf->b_p_tw;
X if (textwidth == 0 && curbuf->b_p_wm)
X textwidth = Columns - curbuf->b_p_wm;
X if (textwidth < 0)
X textwidth = 0;
X
X /*
X * If the cursor is past 'textwidth' and we are inserting a non-space,
X * try to break the line in two or more pieces. If c == NUL then we have
X * been called to do formatting only. If textwidth == 0 it does nothing.
X * Don't do this if an existing character is being replaced.
X */
X if (c == NUL || !(isspace(c) || (State == REPLACE && *ml_get_cursor() != NUL)))
X {
X while (textwidth && curwin->w_virtcol >= textwidth)
X {
X int startcol; /* Cursor column at entry */
X int wantcol; /* column at textwidth border */
X int foundcol; /* column for start of word */
X
X if ((startcol = curwin->w_cursor.col) == 0)
X break;
X coladvance(textwidth); /* find column of textwidth border */
X wantcol = curwin->w_cursor.col;
X
X curwin->w_cursor.col = startcol - 1;
X foundcol = 0;
X while (curwin->w_cursor.col > 0) /* find position to break at */
X {
X if (isspace(gchar_cursor()))
X {
X while (curwin->w_cursor.col > 0 && isspace(gchar_cursor()))
X --curwin->w_cursor.col;
X if (curwin->w_cursor.col == 0) /* only spaces in front of text */
X break;
X foundcol = curwin->w_cursor.col + 1;
X if (curwin->w_cursor.col < wantcol)
X break;
X }
X --curwin->w_cursor.col;
X }
X
X if (foundcol == 0) /* no spaces, cannot break line */
X {
X curwin->w_cursor.col = startcol;
X break;
X }
X curwin->w_cursor.col = foundcol; /* put cursor after pos. to break line */
X startcol -= foundcol;
X Opencmd(FORWARD, FALSE, FALSE);
X while (isspace(gchar_cursor()) && startcol) /* delete blanks */
X {
X (void)delchar(FALSE);
X --startcol; /* adjust cursor pos. */
X }
X curwin->w_cursor.col += startcol;


X curs_columns(FALSE); /* update curwin->w_virtcol */

X haveto_redraw = TRUE;
X }
X if (c == NUL) /* formatting only */
X return;
X if (haveto_redraw)
X {
X /*
X * If the cursor ended up just below the screen we scroll up here
X * to avoid a redraw of the whole screen in the most common cases.
X */
X if (curwin->w_cursor.lnum == curwin->w_botline && !curwin->w_empty_rows)
X win_del_lines(curwin, 0, 1, TRUE, TRUE);


X updateScreen(CURSUPD);
X }
X }
X

X did_ai = FALSE;
X did_si = FALSE;
X can_si = FALSE;
X
X /*
X * If there's any pending input, grab up to MAX_COLUMNS at once.
X * This speeds up normal text input considerably.
X */
X if (vpeekc() != NUL && State != REPLACE && !p_ri)
X {
X char_u p[MAX_COLUMNS + 1];
X int i;
X
X p[0] = c;
X i = 1;
X while ((c = vpeekc()) != NUL && !ISSPECIAL(c) && i < MAX_COLUMNS &&
X (textwidth == 0 || (curwin->w_virtcol += charsize(p[i - 1])) < textwidth) &&
X !(!no_abbr && !isidchar(c) && isidchar(p[i - 1])))
X p[i++] = vgetc();
X#ifdef DIGRAPHS
X dodigraph(-1); /* clear digraphs */
X dodigraph(p[i-1]); /* may be the start of a digraph */
X#endif
X p[i] = '\0';
X insstr(p);
X AppendToRedobuff(p);
X }
X else
X {
X inschar(c);
X AppendCharToRedobuff(c);
X }
X
X /*
X * TODO: If the cursor has shifted past the end of the screen, should
X * adjust the screen display. Avoids extra redraw.
X */
X
X updateline();
X}
X
X/*
X * start_arrow() is called when an arrow key is used in insert mode.
X * It resembles hitting the <ESC> key.


X */
X static void

Xstart_arrow()
X{
X if (!arrow_used) /* something has been inserted */
X {
X AppendToRedobuff(ESC_STR);
X arrow_used = TRUE; /* this means we stopped the current insert */
X stop_insert();
X }
X}
X
X/*
X * stop_arrow() is called before a change is made in insert mode.
X * If an arrow key has been used, start a new insertion.


X */
X static void

Xstop_arrow()
X{
X if (arrow_used)
X {
X u_save_cursor(); /* errors are ignored! */
X Insstart = curwin->w_cursor; /* new insertion starts here */
X ResetRedobuff();
X AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */
X arrow_used = FALSE;
X }
X}
X
X/*
X * do a few things to stop inserting


X */
X static void

Xstop_insert()
X{
X stop_redo_ins();
X
X /*
X * save the inserted text for later redo with ^@
X */
X free(last_insert);
X last_insert = get_inserted();
X last_insert_skip = new_insert_skip;
X
X /*
X * If we just did an auto-indent, truncate the line, and put
X * the cursor back.
X */
X if (did_ai && !arrow_used)
X {
X ml_replace(curwin->w_cursor.lnum, (char_u *)"", TRUE);


X curwin->w_cursor.col = 0;

X if (curwin->w_p_list) /* the deletion is only seen in list mode */
X updateline();
X }
X did_ai = FALSE;
X did_si = FALSE;
X can_si = FALSE;
X}
X
X/*
X * move cursor to start of line
X * if flag == TRUE move to first non-white
X */
X void
Xbeginline(flag)
X int flag;
X{


X curwin->w_cursor.col = 0;

X if (flag)
X {


X register char_u *ptr;
X

X for (ptr = ml_get(curwin->w_cursor.lnum); iswhite(*ptr); ++ptr)
X ++curwin->w_cursor.col;
X }
X curwin->w_set_curswant = TRUE;
X}
X
X/*
X * oneright oneleft onedown oneup
X *
X * Move one char {right,left,down,up}.
X * Return OK when sucessful, FAIL when we hit a line of file boundary.
X */
X
X int
Xoneright()


X{
X char_u *ptr;
X

X ptr = ml_get_cursor();
X if (*ptr++ == NUL || *ptr == NUL)
X return FAIL;


X curwin->w_set_curswant = TRUE;

X ++curwin->w_cursor.col;


X return OK;
X}
X

X int
Xoneleft()
X{
X if (curwin->w_cursor.col == 0)
X return FAIL;


X curwin->w_set_curswant = TRUE;

X --curwin->w_cursor.col;


X return OK;
X}
X

X int
Xoneup(n)
X long n;
X{
X if (n != 0 && curwin->w_cursor.lnum == 1)
X return FAIL;
X if (n >= curwin->w_cursor.lnum)


X curwin->w_cursor.lnum = 1;
X else

X curwin->w_cursor.lnum -= n;
X
X if (operator == NOP)
X cursupdate(); /* make sure curwin->w_topline is valid */
X
X /* try to advance to the column we want to be at */
X coladvance(curwin->w_curswant);


X return OK;
X}
X

X int
Xonedown(n)
X long n;
X{
X if (n != 0 && curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)
X return FAIL;
X curwin->w_cursor.lnum += n;
X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)


X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;

X
X if (operator == NOP)
X cursupdate(); /* make sure curwin->w_topline is valid */
X
X /* try to advance to the column we want to be at */
X coladvance(curwin->w_curswant);


X return OK;
X}
X
X/*

X * move screen 'count' pages up or down and update screen


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xonepage(dir, count)
X int dir;
X long count;
X{
X linenr_t lp;
X long n;
X
X if (curbuf->b_ml.ml_line_count == 1) /* nothing to do */
X return FAIL;
X for ( ; count > 0; --count)
X {
X if (dir == FORWARD ? (curwin->w_topline >= curbuf->b_ml.ml_line_count - 1) : (curwin->w_topline == 1))
X {
X beep();
X return FAIL;
X }


X if (dir == FORWARD)
X {

X if (curwin->w_botline > curbuf->b_ml.ml_line_count) /* at end of file */
X curwin->w_topline = curbuf->b_ml.ml_line_count;
X else if (plines(curwin->w_botline) >= curwin->w_height - 2 || /* next line is big */
X curwin->w_botline - curwin->w_topline <= 3) /* just three lines on screen */
X curwin->w_topline = curwin->w_botline;
X else
X curwin->w_topline = curwin->w_botline - 2;


X curwin->w_cursor.lnum = curwin->w_topline;

X if (count != 1)
X comp_Botline(curwin);
X }
X else /* dir == BACKWARDS */
X {
X lp = curwin->w_topline;
X /*
X * If the first two lines on the screen are not too big, we keep
X * them on the screen.
X */
X if ((n = plines(lp)) > curwin->w_height / 2)
X --lp;
X else if (lp < curbuf->b_ml.ml_line_count && n + plines(lp + 1) < curwin->w_height / 2)
X ++lp;
X curwin->w_cursor.lnum = lp;
X n = 0;
X while (n <= curwin->w_height && lp >= 1)
X {
X n += plines(lp);
X --lp;
X }
X if (n <= curwin->w_height) /* at begin of file */
X curwin->w_topline = 1;
X else if (lp >= curwin->w_topline - 2) /* happens with very long lines */
X {
X --curwin->w_topline;
X comp_Botline(curwin);
X curwin->w_cursor.lnum = curwin->w_botline - 1;
X }
X else
X curwin->w_topline = lp + 2;
X }
X }
X beginline(TRUE);
X updateScreen(VALID);


X return OK;
X}
X

X void
Xstuff_inserted(c, count, no_esc)
X int c;
X long count;
X int no_esc;
X{
X char_u *esc_ptr = NULL;
X char_u *ptr;
X
X if (last_insert == NULL)
X {
X EMSG("No inserted text yet");
X return;
X }
X if (c)
X stuffcharReadbuff(c);
X if (no_esc && (esc_ptr = (char_u *)STRRCHR(last_insert, 27)) != NULL)
X *esc_ptr = NUL; /* remove the ESC */
X
X /* skip the command */
X ptr = last_insert + last_insert_skip;
X
X do
X stuffReadbuff(ptr);


X while (--count > 0);
X

X if (no_esc && esc_ptr)
X *esc_ptr = 27; /* put the ESC back */


X}
X
X char_u *

Xget_last_insert()
X{
X if (last_insert == NULL)
X return NULL;
X return last_insert + last_insert_skip;
X}
X
X/*


X * Check the word in front of the cursor for an abbreviation.
X * Called when the non-id character "c" has been entered.

X * When an abbreviation is recognized it is removed from the text and
X * the replacement string is inserted in typestr, followed by "c".


X */
X static int

Xecheck_abbr(c)
X int c;
X{
X if (p_paste || no_abbr) /* no abbreviations or in paste mode */
X return FALSE;
X
X return check_abbr(c, ml_get(curwin->w_cursor.lnum), curwin->w_cursor.col,
X curwin->w_cursor.lnum == Insstart.lnum ? Insstart.col : 0);
X}
END_OF_FILE
if test 31932 -ne `wc -c <'vim/src/edit.c'`; then
echo shar: \"'vim/src/edit.c'\" unpacked with wrong size!
fi
# end of 'vim/src/edit.c'
fi
echo shar: End of archive 17 \(of 26\).
cp /dev/null ark17isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:07 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 37
Archive-name: vim/part18

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/search.c vim/src/unix.c vim/tools/readme
# vim/uganda.txt
# Wrapped by kent@sparky on Mon Aug 15 21:44:10 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 18 (of 26)."'
if test -f 'vim/src/search.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/search.c'\"
else
echo shar: Extracting \"'vim/src/search.c'\" \(30917 characters\)
sed "s/^X//" >'vim/src/search.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */

X/*
X * search.c: code for normal mode searching commands


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"

X#include "ops.h" /* for mincl */
X
X/* modified Henry Spencer's regular expression routines */
X#include "regexp.h"
X
Xstatic int inmacro __ARGS((char_u *, char_u *));
Xstatic int cls __ARGS((void));
X
Xstatic char_u *top_bot_msg = (char_u *)"search hit TOP, continuing at BOTTOM";
Xstatic char_u *bot_top_msg = (char_u *)"search hit BOTTOM, continuing at TOP";
X
X/*
X * This file contains various searching-related routines. These fall into
X * three groups:
X * 1. string searches (for /, ?, n, and N)
X * 2. character searches within a single line (for f, F, t, T, etc)
X * 3. "other" kinds of searches like the '%' command, and 'word' searches.
X */
X
X/*
X * String searches
X *
X * The string search functions are divided into two levels:
X * lowest: searchit(); called by dosearch() and edit().
X * Highest: dosearch(); changes curwin->w_cursor, called by normal().
X *
X * The last search pattern is remembered for repeating the same search.
X * This pattern is shared between the :g, :s, ? and / commands.
X * This is in myregcomp().
X *
X * The actual string matching is done using a heavily modified version of
X * Henry Spencer's regular expression library.
X */
X
X/*
X * Two search patterns are remembered: One for the :substitute command and
X * one for other searches. last_pattern points to the one that was
X * used the last time.
X */
Xstatic char_u *search_pattern = NULL;
Xstatic char_u *subst_pattern = NULL;
Xstatic char_u *last_pattern = NULL;
X
Xstatic int want_start; /* looking for start of line? */
X
X/*
X * translate search pattern for regcomp()
X *
X * sub_cmd == 0: save pat in search_pattern (normal search command)
X * sub_cmd == 1: save pat in subst_pattern (:substitute command)
X * sub_cmd == 2: save pat in both patterns (:global command)
X * which_pat == 0: use previous search pattern if "pat" is NULL
X * which_pat == 1: use previous sustitute pattern if "pat" is NULL
X * which_pat == 2: use last used pattern if "pat" is NULL
X *
X */
X regexp *
Xmyregcomp(pat, sub_cmd, which_pat)
X char_u *pat;
X int sub_cmd;
X int which_pat;
X{
X regexp *retval;
X
X if (pat == NULL || *pat == NUL) /* use previous search pattern */
X {
X if (which_pat == 0)
X {
X if (search_pattern == NULL)
X {
X emsg(e_noprevre);
X return (regexp *) NULL;
X }
X pat = search_pattern;
X }
X else if (which_pat == 1)
X {
X if (subst_pattern == NULL)
X {
X emsg(e_nopresub);
X return (regexp *) NULL;
X }
X pat = subst_pattern;
X }
X else /* which_pat == 2 */
X {
X if (last_pattern == NULL)
X {
X emsg(e_noprevre);
X return (regexp *) NULL;
X }
X pat = last_pattern;
X }
X }
X
X /*
X * save the currently used pattern in the appropriate place,
X * unless the pattern should not be remembered
X */
X if (!keep_old_search_pattern)
X {
X if (sub_cmd == 0 || sub_cmd == 2) /* search or global command */
X {
X if (search_pattern != pat)
X {
X free(search_pattern);
X search_pattern = strsave(pat);
X last_pattern = search_pattern;
X reg_magic = p_magic; /* Magic sticks with the r.e. */
X }
X }
X if (sub_cmd == 1 || sub_cmd == 2) /* substitute or global command */
X {
X if (subst_pattern != pat)
X {
X free(subst_pattern);
X subst_pattern = strsave(pat);
X last_pattern = subst_pattern;
X reg_magic = p_magic; /* Magic sticks with the r.e. */
X }
X }
X }
X
X want_start = (*pat == '^'); /* looking for start of line? */
X reg_ic = p_ic; /* tell the regexec routine how to search */
X retval = regcomp(pat);


X return retval;
X}
X
X/*

X * lowest level search function.
X * Search for 'count'th occurrence of 'str' in direction 'dir'.
X * Start at position 'pos' and return the found position in 'pos'.


X * Return OK for success, FAIL for failure.
X */
X int

Xsearchit(pos, dir, str, count, end, message)
X FPOS *pos;
X int dir;
X char_u *str;
X long count;
X int end;
X int message;
X{
X int found;
X linenr_t lnum = 0; /* init to shut up gcc */
X linenr_t startlnum;
X regexp *prog;
X register char_u *s;
X char_u *ptr;
X register int i;
X register char_u *match, *matchend;
X int loop;
X
X if ((prog = myregcomp(str, 0, 2)) == NULL)
X {
X if (message)
X emsg(e_invstring);
X return FAIL;
X }
X/*
X * find the string
X */
X found = 1;
X while (count-- && found) /* stop after count matches, or no more matches */
X {
X startlnum = pos->lnum; /* remember start of search for detecting no match */
X found = 0; /* default: not found */
X
X i = pos->col + dir; /* search starts one postition away */
X lnum = pos->lnum;
X
X if (dir == BACKWARD && i < 0)
X --lnum;
X
X for (loop = 0; loop != 2; ++loop) /* do this twice if 'wrapscan' is set */
X {
X for ( ; lnum > 0 && lnum <= curbuf->b_ml.ml_line_count; lnum += dir, i = -1)
X {
X s = ptr = ml_get(lnum);
X if (dir == FORWARD && i > 0) /* first line for forward search */
X {
X if (want_start || STRLEN(s) <= (size_t)i) /* match not possible */
X continue;
X s += i;
X }
X
X if (regexec(prog, s, dir == BACKWARD || i <= 0))
X { /* match somewhere on line */
X match = prog->startp[0];
X matchend = prog->endp[0];
X if (dir == BACKWARD && !want_start)
X {
X /*
X * Now, if there are multiple matches on this line,
X * we have to get the last one. Or the last one before
X * the cursor, if we're on that line.
X */
X while (*match != NUL && regexec(prog, match + 1, (int)FALSE))
X {
X if ((i >= 0) && ((prog->startp[0] - s) > i))
X break;
X match = prog->startp[0];
X matchend = prog->endp[0];
X }
X
X if ((i >= 0) && ((match - s) > i))
X continue;
X }
X
X pos->lnum = lnum;
X if (end)
X pos->col = (int) (matchend - ptr - 1);
X else
X pos->col = (int) (match - ptr);
X found = 1;
X break;
X }
X /* breakcheck is slow, do it only once in 16 lines */


X if ((lnum & 15) == 0)

X breakcheck(); /* stop if ctrl-C typed */
X if (got_int)
X break;
X
X if (loop && lnum == startlnum) /* if second loop stop where started */
X break;
X }
X /* stop the search if wrapscan isn't set, after an interrupt and after a match */
X if (!p_ws || got_int || found)


X break;
X
X /*

X * If 'wrapscan' is set we continue at the other end of the file.
X * If 'terse' is not set, we give a message.
X * This message is also remembered in keep_msg for when the screen
X * is redrawn. The keep_msg is cleared whenever another message is
X * written.
X */
X if (dir == BACKWARD) /* start second loop at the other end */
X {
X lnum = curbuf->b_ml.ml_line_count;
X if (!p_terse && message)
X {
X msg(top_bot_msg);
X keep_msg = top_bot_msg;
X }
X }
X else
X {
X lnum = 1;
X if (!p_terse && message)
X {
X msg(bot_top_msg);
X keep_msg = bot_top_msg;
X }
X }
X }
X if (got_int)
X break;
X }
X
X free(prog);
X
X if (!found) /* did not find it */
X {
X if (got_int)
X emsg(e_interr);
X else if (message)
X {
X if (p_ws)
X emsg(e_patnotf);
X else if (lnum == 0)
X EMSG("search hit TOP without match");
X else
X EMSG("search hit BOTTOM without match");
X }


X return FAIL;
X }
X

X return OK;
X}
X
X/*

X * Highest level string search function.
X * Search for the 'count'th occurence of string 'str' in direction 'dirc'
X * If 'dirc' is 0: use previous dir.
X * If 'str' is 0 or 'str' is empty: use previous string.
X * If 'reverse' is TRUE: go in reverse of previous dir.
X * If 'echo' is TRUE: echo the search command and handle options
X * If 'message' is TRUE: may give error message
X *
X * return 0 for failure, 1 for found, 2 for found and line offset added
X */
X int
Xdosearch(dirc, str, reverse, count, echo, message)
X int dirc;
X char_u *str;
X int reverse;
X long count;
X int echo;
X int message;
X{
X FPOS pos; /* position of the last match */
X char_u *searchstr;
X static int lastsdir = '/'; /* previous search direction */
X static int lastoffline;/* previous/current search has line offset */
X static int lastend; /* previous/current search set cursor at end */
X static long lastoff; /* previous/current line or char offset */
X int old_lastsdir;
X int old_lastoffline;
X int old_lastend;
X long old_lastoff;
X int ret; /* Return value */
X register char_u *p;
X register long c;
X char_u *dircp = NULL;
X
X /*
X * save the values for when keep_old_search_pattern is set
X * (no if around this because gcc wants them initialized)
X */
X old_lastsdir = lastsdir;
X old_lastoffline = lastoffline;
X old_lastend = lastend;
X old_lastoff = lastoff;
X
X if (dirc == 0)
X dirc = lastsdir;
X else
X lastsdir = dirc;
X if (reverse)
X {
X if (dirc == '/')
X dirc = '?';
X else
X dirc = '/';
X }
X searchstr = str;
X /* use previous string */
X if (str == NULL || *str == NUL || *str == dirc)
X {
X if (search_pattern == NULL)
X {
X emsg(e_noprevre);
X ret = 0;
X goto end_dosearch;
X }
X searchstr = (char_u *)""; /* will use search_pattern in myregcomp() */
X }
X if (str != NULL && *str != NUL) /* look for (new) offset */
X {
X /*
X * Find end of regular expression.
X * If there is a matching '/' or '?', toss it.
X */
X p = skip_regexp(str, dirc);
X if (*p == dirc)
X {
X dircp = p; /* remember where we put the NUL */


X *p++ = NUL;
X }

X lastoffline = FALSE;
X lastend = FALSE;
X lastoff = 0;
X /*
X * Check for a line offset or a character offset.
X * for get_address (echo off) we don't check for a character offset,
X * because it is meaningless and the 's' could be a substitute command.
X */
X if (*p == '+' || *p == '-' || isdigit(*p))
X lastoffline = TRUE;
X else if (echo && (*p == 'e' || *p == 's' || *p == 'b'))
X {
X if (*p == 'e') /* end */
X lastend = TRUE;
X ++p;
X }
X if (isdigit(*p) || *p == '+' || *p == '-') /* got an offset */
X {
X if (isdigit(*p) || isdigit(*(p + 1)))
X lastoff = atol((char *)p); /* 'nr' or '+nr' or '-nr' */
X else if (*p == '-') /* single '-' */
X lastoff = -1;
X else /* single '+' */
X lastoff = 1;
X ++p;
X while (isdigit(*p)) /* skip number */
X ++p;
X }
X searchcmdlen = p - str; /* compute lenght of search command
X for get_address() */
X }
X
X if (echo)
X {
X msg_start();
X msg_outchar(dirc);
X msg_outtrans(*searchstr == NUL ? search_pattern : searchstr, -1);
X if (lastoffline || lastend || lastoff)
X {
X msg_outchar(dirc);
X if (lastend)
X msg_outchar('e');
X else if (!lastoffline)
X msg_outchar('s');
X if (lastoff < 0)
X {
X msg_outchar('-');
X msg_outnum((long)-lastoff);
X }
X else if (lastoff > 0 || lastoffline)
X {
X msg_outchar('+');
X msg_outnum((long)lastoff);
X }
X }
X msg_ceol();
X (void)msg_check();
X
X gotocmdline(FALSE, NUL);
X flushbuf();
X }
X
X pos = curwin->w_cursor;
X
X c = searchit(&pos, dirc == '/' ? FORWARD : BACKWARD, searchstr, count, lastend, message);
X if (dircp)
X *dircp = dirc; /* put second '/' or '?' back for normal() */
X if (c == FAIL)
X {
X ret = 0;
X goto end_dosearch;
X }
X if (lastend)
X mincl = TRUE; /* 'e' includes last character */
X
X if (!lastoffline) /* add the character offset to the column */
X {
X if (lastoff > 0) /* offset to the right, check for end of line */
X {
X p = ml_get_pos(&pos) + 1;
X c = lastoff;
X while (c-- && *p++ != NUL)
X ++pos.col;
X }
X else /* offset to the left, check for start of line */
X {
X if ((c = pos.col + lastoff) < 0)
X c = 0;
X pos.col = c;
X }
X }
X
X if (!tag_busy)
X setpcmark();
X curwin->w_cursor = pos;


X curwin->w_set_curswant = TRUE;
X

X if (!lastoffline)
X {
X ret = 1;
X goto end_dosearch;
X }
X
X/*
X * add the offset to the line number.
X */
X c = curwin->w_cursor.lnum + lastoff;
X if (c < 1)


X curwin->w_cursor.lnum = 1;

X else if (c > curbuf->b_ml.ml_line_count)


X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;

X else
X curwin->w_cursor.lnum = c;


X curwin->w_cursor.col = 0;
X

X ret = 2;
X
Xend_dosearch:
X if (keep_old_search_pattern)
X {
X lastsdir = old_lastsdir;
X lastoffline = old_lastoffline;
X lastend = old_lastend;
X lastoff = old_lastoff;
X }
X return ret;
X}
X
X
X/*
X * Character Searches
X */
X
X/*
X * searchc(c, dir, type, count)
X *
X * Search for character 'c', in direction 'dir'. If 'type' is 0, move to the
X * position of the character, otherwise move to just before the char.
X * Repeat this 'count' times.
X */
X int
Xsearchc(c, dir, type, count)
X int c;
X register int dir;
X int type;
X long count;
X{
X static int lastc = NUL; /* last character searched for */
X static int lastcdir; /* last direction of character search */
X static int lastctype; /* last type of search ("find" or "to") */
X register int col;


X char_u *p;
X int len;
X

X if (c != NUL) /* normal search: remember args for repeat */
X {
X lastc = c;
X lastcdir = dir;
X lastctype = type;
X }
X else /* repeat previous search */
X {
X if (lastc == NUL)
X return FALSE;
X if (dir) /* repeat in opposite direction */
X dir = -lastcdir;
X else
X dir = lastcdir;
X }
X
X p = ml_get(curwin->w_cursor.lnum);


X col = curwin->w_cursor.col;

X len = STRLEN(p);
X
X /*
X * On 'to' searches, skip one to start with so we can repeat searches in
X * the same direction and have it work right.
X * REMOVED to get vi compatibility
X * if (lastctype)
X * col += dir;
X */
X
X while (count--)


X {
X for (;;)
X {

X if ((col += dir) < 0 || col >= len)
X return FALSE;
X if (p[col] == lastc)
X break;
X }
X }
X if (lastctype)
X col -= dir;


X curwin->w_cursor.col = col;

X return TRUE;
X}
X
X/*
X * "Other" Searches
X */
X
X/*
X * showmatch - move the cursor to the matching paren or brace
X *
X * Improvement over vi: Braces inside quotes are ignored.
X */
X FPOS *
Xshowmatch(initc)
X int initc;
X{
X static FPOS pos; /* current search position */
X int findc; /* matching brace */
X int c;
X int count = 0; /* cumulative number of braces */
X int idx = 0; /* init for gcc */
X static char_u table[6] = {'(', ')', '[', ']', '{', '}'};
X int inquote = 0; /* non-zero when inside quotes */
X register char_u *linep; /* pointer to current line */
X register char_u *ptr;
X int do_quotes; /* check for quotes in current line */
X int hash_dir = 0; /* Direction searched for # things */
X int comment_dir = 0; /* Direction searched for comments */
X


X pos = curwin->w_cursor;

X linep = ml_get(pos.lnum);
X
X /*
X * if initc given, look in the table for the matching character
X */
X if (initc != NUL)
X {
X for (idx = 0; idx < 6; ++idx)
X if (table[idx] == initc)
X {
X initc = table[idx = idx ^ 1];
X break;
X }
X if (idx == 6) /* invalid initc! */
X return NULL;
X }
X /*
X * no initc given, look under the cursor
X */
X else
X {
X if (linep[0] == '#' && pos.col == 0)
X hash_dir = 1;
X
X /*
X * Are we on a comment?
X */
X if (linep[pos.col] == '/')
X {
X if (linep[pos.col + 1] == '*')
X {
X comment_dir = 1;
X idx = 0;
X }
X else if (pos.col > 0 && linep[pos.col - 1] == '*')
X {
X comment_dir = -1;
X idx = 1;
X }
X }
X if (linep[pos.col] == '*')
X {
X if (linep[pos.col + 1] == '/')
X {
X comment_dir = -1;
X idx = 1;
X }
X else if (pos.col > 0 && linep[pos.col - 1] == '/')
X {
X comment_dir = 1;


X idx = 0;
X }

X }
X
X /*
X * If we are not on a comment or the # at the start of a line, then
X * look for brace anywhere on this line after the cursor.
X */
X if (!hash_dir && !comment_dir)
X {
X /*
X * find the brace under or after the cursor
X */
X linep = ml_get(pos.lnum);

X for (;;)
X {

X initc = linep[pos.col];
X if (initc == NUL)
X break;
X
X for (idx = 0; idx < 6; ++idx)
X if (table[idx] == initc)
X break;
X if (idx != 6)
X break;
X ++pos.col;
X }
X if (idx == 6)
X {
X if (linep[0] == '#')
X hash_dir = 1;
X else
X return NULL;
X }
X }
X if (hash_dir)
X {
X /*
X * Look for matching #if, #else, #elif, or #endif
X */
X mtype = MLINE; /* Linewise for this case only */
X ptr = linep + 1;
X while (*ptr == ' ' || *ptr == TAB)
X ptr++;
X if (STRNCMP(ptr, "if", (size_t)2) == 0 || STRNCMP(ptr, "el", (size_t)2) == 0)
X hash_dir = 1;
X else if (STRNCMP(ptr, "endif", (size_t)5) == 0)
X hash_dir = -1;


X else
X return NULL;

X pos.col = 0;
X while (!got_int)
X {
X if (hash_dir > 0)
X {
X if (pos.lnum == curbuf->b_ml.ml_line_count)
X break;
X }
X else if (pos.lnum == 1)
X break;
X pos.lnum += hash_dir;
X linep = ml_get(pos.lnum);
X if ((pos.lnum & 15) == 0)
X breakcheck();
X if (linep[0] != '#')
X continue;
X ptr = linep + 1;
X while (*ptr == ' ' || *ptr == TAB)
X ptr++;
X if (hash_dir > 0)
X {
X if (STRNCMP(ptr, "if", (size_t)2) == 0)
X count++;
X else if (STRNCMP(ptr, "el", (size_t)2) == 0)
X {
X if (count == 0)
X return &pos;
X }
X else if (STRNCMP(ptr, "endif", (size_t)5) == 0)
X {
X if (count == 0)
X return &pos;
X count--;
X }
X }
X else
X {
X if (STRNCMP(ptr, "if", (size_t)2) == 0)
X {
X if (count == 0)
X return &pos;
X count--;
X }
X else if (STRNCMP(ptr, "endif", (size_t)5) == 0)
X count++;
X }
X }


X return NULL;
X }
X }
X

X findc = table[idx ^ 1]; /* get matching brace */
X idx &= 1;
X
X do_quotes = -1;
X while (!got_int)
X {
X /*
X * Go to the next position, forward or backward. We could use
X * inc() and dec() here, but that is much slower
X */
X if (idx) /* backward search */
X {
X if (pos.col == 0) /* at start of line, go to previous one */
X {
X if (pos.lnum == 1) /* start of file */
X break;
X --pos.lnum;
X linep = ml_get(pos.lnum);
X pos.col = STRLEN(linep); /* put pos.col on trailing NUL */
X do_quotes = -1;
X /* we only do a breakcheck() once for every 16 lines */
X if ((pos.lnum & 15) == 0)
X breakcheck();
X }
X else
X --pos.col;
X }
X else /* forward search */
X {
X if (linep[pos.col] == NUL) /* at end of line, go to next one */
X {
X if (pos.lnum == curbuf->b_ml.ml_line_count) /* end of file */
X break;
X ++pos.lnum;
X linep = ml_get(pos.lnum);
X pos.col = 0;
X do_quotes = -1;
X /* we only do a breakcheck() once for every 16 lines */
X if ((pos.lnum & 15) == 0)
X breakcheck();
X }
X else
X ++pos.col;
X }
X
X if (comment_dir)
X {
X /* Note: comments do not nest, and we ignore quotes in them */
X if (linep[pos.col] != '/' ||
X (comment_dir == 1 && pos.col == 0) ||
X linep[pos.col - comment_dir] != '*')
X continue;
X return &pos;
X }
X
X if (do_quotes == -1) /* count number of quotes in this line */
X {
X /*
X * count the number of quotes in the line, skipping \" and '"'
X */
X for (ptr = linep; *ptr; ++ptr)
X if (*ptr == '"' && (ptr == linep || ptr[-1] != '\\') &&
X (ptr == linep || ptr[-1] != '\'' || ptr[1] != '\''))
X ++do_quotes;
X do_quotes &= 1; /* result is 1 with even number of quotes */
X
X /*
X * If we find an uneven count, check current line and previous
X * one for a '\' at the end.
X */
X if (!do_quotes)
X {
X inquote = FALSE;
X if (ptr[-1] == '\\')
X {
X do_quotes = 1;
X if (idx) /* backward search */
X inquote = TRUE;
X }
X if (pos.lnum > 1)
X {
X ptr = ml_get(pos.lnum - 1);
X if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\\')
X {
X do_quotes = 1;
X if (!idx) /* forward search */
X inquote = TRUE;
X }
X }
X }
X }
X
X /*
X * Things inside quotes are ignored by setting 'inquote'.
X * If we find a quote without a preceding '\' invert 'inquote'.
X * At the end of a line not ending in '\' we reset 'inquote'.
X *
X * In lines with an uneven number of quotes (without preceding '\')
X * we do not know which part to ignore. Therefore we only set
X * inquote if the number of quotes in a line is even,
X * unless this line or the previous one ends in a '\'.
X * Complicated, isn't it?
X */
X switch (c = linep[pos.col])
X {
X case NUL:
X inquote = FALSE;
X break;
X
X case '"':
X /* a quote that is preceded with a backslash is ignored */
X if (do_quotes && (pos.col == 0 || linep[pos.col - 1] != '\\'))
X inquote = !inquote;


X break;
X
X /*

X * Skip things in single quotes: 'x' or '\x'.
X * Be careful for single single quotes, eg jon's.
X * Things like '\233' or '\x3f' are not skipped, there is never a
X * brace in them.
X */
X case '\'':
X if (idx) /* backward search */
X {
X if (pos.col > 1)
X {
X if (linep[pos.col - 2] == '\'')
X pos.col -= 2;
X else if (linep[pos.col - 2] == '\\' && pos.col > 2 && linep[pos.col - 3] == '\'')
X pos.col -= 3;
X }
X }
X else if (linep[pos.col + 1]) /* forward search */
X {
X if (linep[pos.col + 1] == '\\' && linep[pos.col + 2] && linep[pos.col + 3] == '\'')
X pos.col += 3;
X else if (linep[pos.col + 2] == '\'')
X pos.col += 2;
X }
X break;
X
X default:
X if (!inquote) /* only check for match outside of quotes */
X {
X if (c == initc)
X count++;
X else if (c == findc)
X {
X if (count == 0)
X return &pos;
X count--;
X }
X }
X }
X }
X return (FPOS *) NULL; /* never found it */
X}
X
X/*
X * findfunc(dir, what) - Find the next line starting with 'what' in direction 'dir'
X *
X * Return TRUE if a line was found.
X */
X int
Xfindfunc(dir, what, count)
X int dir;
X int what;
X long count;
X{
X linenr_t curr;
X
X curr = curwin->w_cursor.lnum;
X


X for (;;)
X {

X if (dir == FORWARD)
X {

X if (curr++ == curbuf->b_ml.ml_line_count)
X break;
X }
X else
X {
X if (curr-- == 1)
X break;
X }
X
X if (*ml_get(curr) == what)


X {
X if (--count > 0)

X continue;
X setpcmark();
X curwin->w_cursor.lnum = curr;


X curwin->w_cursor.col = 0;

X return TRUE;
X }
X }
X

X return FALSE;
X}
X
X/*

X * findsent(dir, count) - Find the start of the next sentence in direction 'dir'
X * Sentences are supposed to end in ".", "!" or "?" followed by white space or
X * a line break. Also stop at an empty line.
X * Return TRUE if the next sentence was found.
X */
X int
Xfindsent(dir, count)


X int dir;
X long count;
X{

X FPOS pos, tpos;
X register int c;
X int (*func) __PARMS((FPOS *));
X int startlnum;
X int noskip = FALSE; /* do not skip blanks */
X


X pos = curwin->w_cursor;

X if (dir == FORWARD)

X func = incl;
X else
X func = decl;
X
X while (count--)
X {
X /* if on an empty line, skip upto a non-empty line */
X if (gchar(&pos) == NUL)
X {
X do
X if ((*func)(&pos) == -1)
X break;
X while (gchar(&pos) == NUL);


X if (dir == FORWARD)

X goto found;
X }
X /* if on the start of a paragraph or a section and searching
X * forward, go to the next line */
X else if (dir == FORWARD && pos.col == 0 && startPS(pos.lnum, NUL, FALSE))
X {
X if (pos.lnum == curbuf->b_ml.ml_line_count)
X return FALSE;
X ++pos.lnum;
X goto found;


X }
X else if (dir == BACKWARD)

X decl(&pos);
X
X /* go back to the previous non-blank char */
X while ((c = gchar(&pos)) == ' ' || c == '\t' ||
X (dir == BACKWARD && strchr(".!?)]\"'", c) != NULL && c != NUL))
X if (decl(&pos) == -1)
X break;
X
X /* remember the line where the search started */
X startlnum = pos.lnum;
X
X for (;;) /* find end of sentence */
X {
X if ((c = gchar(&pos)) == NUL ||
X (pos.col == 0 && startPS(pos.lnum, NUL, FALSE)))
X {
X if (dir == BACKWARD && pos.lnum != startlnum)
X ++pos.lnum;
X break;
X }
X if (c == '.' || c == '!' || c == '?')
X {
X tpos = pos;
X do
X if ((c = inc(&tpos)) == -1)
X break;
X while (strchr(")}\"'", c = gchar(&tpos)) != NULL && c != NUL);
X if (c == -1 || c == ' ' || c == '\t' || c == NUL)
X {
X pos = tpos;
X if (gchar(&pos) == NUL) /* skip NUL at EOL */
X inc(&pos);
X break;
X }
X }
X if ((*func)(&pos) == -1)
X {
X if (count)
X return FALSE;
X noskip = TRUE;
X break;
X }
X }
Xfound:
X /* skip white space */
X while (!noskip && ((c = gchar(&pos)) == ' ' || c == '\t'))
X if (incl(&pos) == -1)
X break;
X }
X
X setpcmark();
X curwin->w_cursor = pos;
X return TRUE;
X}
X
X/*
X * findpar(dir, count, what) - Find the next paragraph in direction 'dir'
X * Paragraphs are currently supposed to be separated by empty lines.
X * Return TRUE if the next paragraph was found.
X * If 'what' is '{' or '}' we go to the next section.
X * If 'both' is TRUE also stop at '}'.
X */
X int
Xfindpar(dir, count, what, both)
X register int dir;
X long count;
X int what;
X int both;
X{
X register linenr_t curr;
X int did_skip; /* TRUE after separating lines have
X been skipped */
X int first; /* TRUE on first line */
X
X curr = curwin->w_cursor.lnum;
X
X while (count--)
X {
X did_skip = FALSE;
X for (first = TRUE; ; first = FALSE)
X {
X if (*ml_get(curr) != NUL)
X did_skip = TRUE;
X
X if (!first && did_skip && startPS(curr, what, both))
X break;
X
X if ((curr += dir) < 1 || curr > curbuf->b_ml.ml_line_count)
X {
X if (count)
X return FALSE;
X curr -= dir;


X break;
X }
X }
X }

X setpcmark();
X if (both && *ml_get(curr) == '}') /* include line with '}' */
X ++curr;
X curwin->w_cursor.lnum = curr;
X if (curr == curbuf->b_ml.ml_line_count)
X {
X if ((curwin->w_cursor.col = STRLEN(ml_get(curr))) != 0)
X --curwin->w_cursor.col;
X mincl = TRUE;
X }
X else


X curwin->w_cursor.col = 0;

X return TRUE;
X}
X
X/*
X * check if the string 's' is a nroff macro that is in option 'opt'


X */
X static int

Xinmacro(opt, s)
X char_u *opt;


X register char_u *s;
X{

X register char_u *macro;
X
X for (macro = opt; macro[0]; ++macro)
X {
X if (macro[0] == s[0] && (((s[1] == NUL || s[1] == ' ')
X && (macro[1] == NUL || macro[1] == ' ')) || macro[1] == s[1]))
X break;
X ++macro;
X if (macro[0] == NUL)
X break;
X }
X return (macro[0] != NUL);
X}
X
X/*
X * startPS: return TRUE if line 'lnum' is the start of a section or paragraph.
X * If 'para' is '{' or '}' only check for sections.
X * If 'both' is TRUE also stop at '}'
X */
X int
XstartPS(lnum, para, both)
X linenr_t lnum;
X int para;
X int both;


X{
X register char_u *s;
X

X s = ml_get(lnum);
X if (*s == para || *s == '\f' || (both && *s == '}'))
X return TRUE;
X if (*s == '.' && (inmacro(p_sections, s + 1) || (!para && inmacro(p_para, s + 1))))


X return TRUE;
X return FALSE;
X}
X
X/*

X * The following routines do the word searches performed by the 'w', 'W',
X * 'b', 'B', 'e', and 'E' commands.
X */
X
X/*
X * To perform these searches, characters are placed into one of three
X * classes, and transitions between classes determine word boundaries.
X *
X * The classes are:
X *
X * 0 - white space
X * 1 - letters, digits and underscore
X * 2 - everything else
X */
X
Xstatic int stype; /* type of the word motion being performed */
X
X/*
X * cls() - returns the class of character at curwin->w_cursor
X *
X * The 'type' of the current search modifies the classes of characters if a 'W',
X * 'B', or 'E' motion is being done. In this case, chars. from class 2 are
X * reported as class 1 since only white space boundaries are of interest.


X */
X static int

Xcls()


X{
X register int c;
X

X c = gchar_cursor();
X if (c == ' ' || c == '\t' || c == NUL)
X return 0;
X
X if (isidchar(c))
X return 1;
X
X /*
X * If stype is non-zero, report these as class 1.
X */
X return (stype == 0) ? 2 : 1;
X}
X
X
X/*
X * fwd_word(count, type, eol) - move forward one word
X *
X * Returns TRUE if the cursor was already at the end of the file.
X * If eol is TRUE, last word stops at end of line (for operators).
X */
X int
Xfwd_word(count, type, eol)
X long count;
X int type;
X int eol;
X{
X int sclass; /* starting class */
X int i;
X
X stype = type;


X while (--count >= 0)
X {

X sclass = cls();
X
X /*
X * We always move at least one character.
X */
X i = inc_cursor();


X if (i == -1)

X return TRUE;
X if (i == 1 && eol && count == 0) /* started at last char in line */
X return FALSE;
X
X if (sclass != 0)
X while (cls() == sclass)
X {
X i = inc_cursor();
X if (i == -1 || (i == 1 && eol && count == 0))


X return FALSE;
X }
X

X /*
X * go to next non-white
X */
X while (cls() == 0)
X {
X /*
X * We'll stop if we land on a blank line
X */
X if (curwin->w_cursor.col == 0 && *ml_get(curwin->w_cursor.lnum) == NUL)
X break;
X
X i = inc_cursor();
X if (i == -1 || (i == 1 && eol && count == 0))


X return FALSE;
X }
X }
X return FALSE;
X}
X
X/*

X * bck_word(count, type) - move backward 'count' words
X *
X * Returns TRUE if top of the file was reached.
X */
X int
Xbck_word(count, type)
X long count;
X int type;
X{
X int sclass; /* starting class */
X
X stype = type;


X while (--count >= 0)
X {

X sclass = cls();
X
X if (dec_cursor() == -1) /* started at start of file */
X return TRUE;
X
X if (cls() != sclass || sclass == 0)
X {
X /*
X * We were at the start of a word. Go back to the end of the prior
X * word.
X */
X while (cls() == 0) /* skip any white space */
X {
X /*
X * We'll stop if we land on a blank line
X */
X if (curwin->w_cursor.col == 0 && *ml_get(curwin->w_cursor.lnum) == NUL)
X goto finished;
X
X if (dec_cursor() == -1) /* hit start of file, stop here */
X return FALSE;
X }
X sclass = cls();
X }
X
X /*
X * Move backward to start of this word.
X */
X if (skip_chars(sclass, BACKWARD))
X return FALSE;
X
X inc_cursor(); /* overshot - forward one */
Xfinished:
X ;
X }


X return FALSE;
X}
X
X/*

X * end_word(count, type, stop) - move to the end of the word
X *
X * There is an apparent bug in the 'e' motion of the real vi. At least on the
X * System V Release 3 version for the 80386. Unlike 'b' and 'w', the 'e'
X * motion crosses blank lines. When the real vi crosses a blank line in an
X * 'e' motion, the cursor is placed on the FIRST character of the next
X * non-blank line. The 'E' command, however, works correctly. Since this
X * appears to be a bug, I have not duplicated it here.
X *
X * Returns TRUE if end of the file was reached.
X *
X * If stop is TRUE and we are already on the end of a word, move one less.
X */
X int
Xend_word(count, type, stop)
X long count;
X int type;
X int stop;
X{
X int sclass; /* starting class */
X
X stype = type;


X while (--count >= 0)
X {

X sclass = cls();
X if (inc_cursor() == -1)
X return TRUE;
X
X /*
X * If we're in the middle of a word, we just have to move to the end of it.
X */
X if (cls() == sclass && sclass != 0)
X {
X /*
X * Move forward to end of the current word
X */
X if (skip_chars(sclass, FORWARD))
X return TRUE;
X }
X else if (!stop || sclass == 0)
X {
X /*
X * We were at the end of a word. Go to the end of the next word.
X */
X
X if (skip_chars(0, FORWARD)) /* skip any white space */
X return TRUE;
X
X /*
X * Move forward to the end of this word.
X */
X if (skip_chars(cls(), FORWARD))
X return TRUE;
X }
X dec_cursor(); /* overshot - backward one */
X stop = FALSE; /* we move only one word less */
X }


X return FALSE;
X}
X

X int
Xskip_chars(class, dir)
X int class;
X int dir;
X{
X while (cls() == class)
X if ((dir == FORWARD ? inc_cursor() : dec_cursor()) == -1)


X return TRUE;
X return FALSE;
X}

END_OF_FILE
if test 30917 -ne `wc -c <'vim/src/search.c'`; then
echo shar: \"'vim/src/search.c'\" unpacked with wrong size!
fi
# end of 'vim/src/search.c'
fi
if test -f 'vim/src/unix.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/unix.c'\"
else
echo shar: Extracting \"'vim/src/unix.c'\" \(30140 characters\)
sed "s/^X//" >'vim/src/unix.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * unix.c -- BSD and SYSV code
X *


X * A lot of this file was written by Juergen Weigert.

X */
X
X#include "vim.h"
X#include "globals.h"

X#include "param.h"
X#include "proto.h"
X
X#include <fcntl.h>

X#if !defined(pyr) && !defined(NOT_BOTH_TIME)
X# include <time.h> /* on some systems time.h should not be
X included together with sys/time.h */
X#endif
X#include <sys/ioctl.h>
X#ifndef M_XENIX
X# include <sys/types.h>
X#endif
X#include <signal.h>
X
X#ifndef USE_SYSTEM /* use fork/exec to start the shell */
X# include <sys/wait.h>
X# if !defined(SCO) && !defined(SOLARIS) && !defined(hpux) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(_SEQUENT_) && !defined(UNISYS) /* SCO returns pid_t */
Xextern int fork();
X# endif
X# if !defined(linux) && !defined(SOLARIS) && !defined(USL) && !defined(sun) && !(defined(hpux) && defined(__STDC__)) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(USL) && !defined(UNISYS)
Xextern int execvp __ARGS((const char *, const char **));
X# endif
X#endif
X
X#if defined(SYSV_UNIX) || defined(USL)
X# if defined(__sgi) || defined(UTS2) || defined(UTS4) || defined(MIPS) || defined (MIPSEB) || defined(__osf__)
X# include <sys/time.h>
X# endif
X# if defined(M_XENIX) || defined(SCO)
X# include <stropts.h>
X# endif
X# if defined(M_XENIX) || defined(SCO) || defined(UNICOS)
X# include <sys/select.h>
X# define bzero(a, b) memset((a), 0, (b))
X# endif
X# if !defined(M_XENIX) && !defined(UNICOS)
X# include <poll.h>
X# endif
X# if defined(SCO) || defined(ISC)
X# include <sys/stream.h>
X# include <sys/ptem.h>
X# endif
X# if defined(M_UNIX) && !defined(SCO)
X# include <sys/time.h>
X# endif /* M_UNIX */
X# ifdef ISC
X# include <termios.h>
X# endif
X# include <termio.h>
X#else /* SYSV_UNIX */
X# include <sys/time.h>
X# if defined(hpux) || defined(linux)
X# include <termio.h>
X# if defined(hpux) && !defined(SIGWINCH) /* hpux 9.01 has it */
X# define SIGWINCH SIGWINDOW
X# endif
X# else
X# include <sgtty.h>
X# endif /* hpux */
X#endif /* !SYSV_UNIX */
X
X#if (defined(pyr) || defined(NO_FD_ZERO)) && defined(SYSV_UNIX) && defined(FD_ZERO)
X# undef FD_ZERO
X#endif
X
X#if defined(ESIX) || defined(M_UNIX) && !defined(SCO)
X# ifdef SIGWINCH
X# undef SIGWINCH
X# endif
X# ifdef TIOCGWINSZ
X# undef TIOCGWINSZ
X# endif
X#endif
X
X#ifdef USE_X11
X
X# include <X11/Xlib.h>
X# include <X11/Xutil.h>
X
XWindow x11_window = 0;
XDisplay *x11_display = NULL;
X
Xstatic int get_x11_windis __ARGS((void));
X#ifdef BUGGY
Xstatic void set_x11_title __ARGS((char_u *));
Xstatic void set_x11_icon __ARGS((char_u *));
X#endif
X#endif
X
Xstatic void get_x11_title __ARGS((void));
Xstatic void get_x11_icon __ARGS((void));
X
Xstatic int Read __ARGS((char_u *, long));
Xstatic int WaitForChar __ARGS((int));


Xstatic int RealWaitForChar __ARGS((int));
Xstatic void fill_inbuf __ARGS((void));

X#ifdef USL
Xstatic void sig_winch __ARGS((int));
X#else
X# if defined(SIGWINCH) && !defined(linux) && !defined(__alpha) && !defined(mips) && !defined(_SEQUENT_) && !defined(SCO) && !defined(SOLARIS) && !defined(ISC)
Xstatic void sig_winch __ARGS((int, int, struct sigcontext *));
X# endif
X#endif
X
Xstatic int do_resize = FALSE;
Xstatic char_u *oldtitle = NULL;
Xstatic char_u *oldicon = NULL;
Xstatic char_u *extra_shell_arg = NULL;
Xstatic int show_shell_mess = TRUE;


X
X/*
X * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
X */
X#undef TRUE

X#define TRUE 1
X#undef FALSE
X#define FALSE 0


X
X void
Xmch_write(s, len)

X char_u *s;
X int len;
X{
X write(1, (char *)s, len);
X}
X
X/*


X * GetChars(): low level input funcion.
X * Get a characters from the keyboard.

X * If wtime == 0 do not wait for characters.
X * If wtime == n wait a short time for characters.
X * If wtime == -1 wait forever for characters.
X */
X int
XGetChars(buf, maxlen, wtime)


X char_u *buf;
X int maxlen;

X int wtime; /* don't use "time", MIPS cannot handle it */


X{
X int len;
X

X if (wtime >= 0)
X {
X while (WaitForChar(wtime) == 0) /* no character available */
X {
X if (!do_resize) /* return if not interrupted by resize */
X return 0;
X set_winsize(0, 0, FALSE);
X do_resize = FALSE;
X }
X }
X else /* wtime == -1 */
X {
X /*
X * If there is no character available within 'updatetime' seconds
X * flush all the swap files to disk
X * Also done when interrupted by SIGWINCH.
X */
X if (WaitForChar((int)p_ut) == 0)


X updatescript(0);
X }
X
X for (;;) /* repeat until we got a character */
X {

X if (do_resize) /* window changed size */
X {
X set_winsize(0, 0, FALSE);
X do_resize = FALSE;
X }
X /*
X * we want to be interrupted by the winch signal
X */
X WaitForChar(-1);
X if (do_resize) /* interrupted by SIGWINCHsignal */
X continue;
X len = Read(buf, (long)maxlen);


X if (len > 0)
X return len;
X }
X}
X
X/*
X * return non-zero if a character is available
X */
X int
Xmch_char_avail()
X{

X return WaitForChar(0);


X}
X
X long
Xmch_avail_mem(special)
X int special;
X{

X return 0x7fffffff; /* virual memory eh */
X}
X

X#ifndef FD_ZERO
X void
Xvim_delay()
X{
X poll(0, 0, 500);
X}
X#else
X# if (defined(__STDC__) && !defined(hpux)) || defined(ultrix)
Xextern int select __ARGS((int, fd_set *, fd_set *, fd_set *, struct timeval *));
X# endif


X
X void
Xvim_delay()
X{

X struct timeval tv;
X
X tv.tv_sec = 25 / 50;
X tv.tv_usec = (25 % 50) * (1000000/50);
X select(0, 0, 0, 0, &tv);
X}
X#endif
X
X static void
X#if defined(__alpha) || (defined(mips) && !defined(USL))
Xsig_winch()
X#else
X# if defined(_SEQUENT_) || defined(SCO) || defined(ISC)
Xsig_winch(sig, code)
X int sig;
X int code;
X# else
X# if defined(USL)
Xsig_winch(sig)
X int sig;
X# else
Xsig_winch(sig, code, scp)
X int sig;
X int code;
X struct sigcontext *scp;


X# endif
X# endif
X#endif

X{
X#if defined(SIGWINCH)
X /* this is not required on all systems, but it doesn't hurt anybody */
X signal(SIGWINCH, (void (*)())sig_winch);
X#endif
X do_resize = TRUE;
X}
X
X/*
X * If the machine has job control, use it to suspend the program,
X * otherwise fake it by starting a new shell.


X */
X void
Xmch_suspend()
X{

X#ifdef SIGTSTP
X settmode(0);
X kill(0, SIGTSTP); /* send ourselves a STOP signal */
X settmode(1);
X#else


X OUTSTR("new shell started\n");
X (void)call_shell(NULL, 0, TRUE);

X#endif
X}


X
X void
Xmch_windinit()
X{

X Columns = 80;
X Rows = 24;
X

X flushbuf();
X
X (void)mch_get_winsize();
X#if defined(SIGWINCH)
X signal(SIGWINCH, (void (*)())sig_winch);
X#endif
X}
X
X/*


X * Check_win checks whether we have an interactive window.
X * If not, a new window is opened with the newcli command.
X * If we would open a window ourselves, the :sh and :! commands would not
X * work properly (Why? probably because we are then running in a background CLI).
X * This also is the best way to assure proper working in a next Workbench release.
X *

X * For the -e option (quickfix mode) we open our own window and disable :sh.
X * Otherwise we would never know when editing is finished.


X */
X#define BUF2SIZE 320 /* lenght of buffer for argument with complete path */
X
X void
Xcheck_win(argc, argv)
X int argc;
X char **argv;
X{

X if (!isatty(0) || !isatty(1))
X {


X fprintf(stderr, "VIM: no controlling terminal\n");
X exit(2);

X }
X}
X
X/*


X * fname_case(): Set the case of the filename, if it already exists.
X * This will cause the filename to remain exactly the same.
X */
X void
Xfname_case(name)
X char_u *name;
X{
X}

X
X#ifdef USE_X11
X/*
X * try to get x11 window and display


X *
X * return FAIL for failure, OK otherwise
X */
X static int

Xget_x11_windis()
X{
X char *winid;
X
X /*
X * If WINDOWID not set, should try another method to find out
X * what the current window number is. The only code I know for
X * this is very complicated.
X * We assume that zero is invalid for WINDOWID.
X */
X if (x11_window == 0 && (winid = getenv("WINDOWID")) != NULL)
X x11_window = (Window)atol(winid);
X if (x11_window != 0 && x11_display == NULL)
X x11_display = XOpenDisplay(NULL);
X if (x11_window == 0 || x11_display == NULL)
X return FAIL;


X return OK;
X}
X
X/*

X * Determine original x11 Window Title


X */
X static void

Xget_x11_title()
X{
X XTextProperty text_prop;
X
X if (get_x11_windis() == OK)
X {
X /* Get window name if any */
X if (XGetWMName(x11_display, x11_window, &text_prop))
X {
X if (text_prop.value != NULL)
X oldtitle = strsave((char_u *)text_prop.value);
X XFree((void *)text_prop.value);
X }
X }
X if (oldtitle == NULL) /* could not get old title */
X oldtitle = (char_u *)"Thanks for flying Vim";
X}
X
X/*
X * Determine original x11 Window icon
X */
X
X static void
Xget_x11_icon()
X{
X XTextProperty text_prop;
X
X if (get_x11_windis() == OK)
X {
X /* Get icon name if any */
X if (XGetWMIconName(x11_display, x11_window, &text_prop))
X {
X if (text_prop.value != NULL)
X oldicon = strsave((char_u *)text_prop.value);
X XFree((void *)text_prop.value);
X }
X }
X
X /* could not get old icon, use terminal name */
X if (oldicon == NULL)
X {
X if (STRNCMP(term_strings.t_name, "builtin_", 8) == 0)
X oldicon = term_strings.t_name + 8;
X else
X oldicon = term_strings.t_name;
X }
X}
X
X#if BUGGY
X
XThis is not included, because it probably does not work at all.
XOn my FreeBSD/Xfree86 in a shelltool I get all kinds of error messages and
XVim is stopped in an uncontrolled way.
X
X/*
X * Set x11 Window Title
X *
X * get_x11_windis() must be called before this and have returned OK


X */
X static void

Xset_x11_title(title)
X char_u *title;
X{
X XTextProperty text_prop;
X
X /* Get icon name if any */
X text_prop.value = title;
X text_prop.nitems = STRLEN(title);
X XSetWMName(x11_display, x11_window, &text_prop);
X if (XGetWMName(x11_display, x11_window, &text_prop)) /* required? */
X XFree((void *)text_prop.value);
X}
X
X/*
X * Set x11 Window icon
X *
X * get_x11_windis() must be called before this and have returned OK


X */
X static void

Xset_x11_icon(icon)
X char_u *icon;
X{
X XTextProperty text_prop;
X
X /* Get icon name if any */
X text_prop.value = icon;
X text_prop.nitems = STRLEN(icon);
X XSetWMIconName(x11_display, x11_window, &text_prop);
X if (XGetWMIconName(x11_display, x11_window, &text_prop)) /* required? */
X XFree((void *)text_prop.value);
X}
X#endif
X
X#else /* USE_X11 */
X
X static void
Xget_x11_title()
X{
X oldtitle = (char_u *)"Thanks for flying Vim";


X}
X
X static void

Xget_x11_icon()
X{
X if (STRNCMP(term_strings.t_name, "builtin_", 8) == 0)
X oldicon = term_strings.t_name + 8;
X else
X oldicon = term_strings.t_name;
X}
X
X#endif /* USE_X11 */
X
X
X/*
X * set the window title and icon
X * Currently only works for x11.


X */
X void
Xmch_settitle(title, icon)
X char_u *title;
X char_u *icon;
X{

X int type = 0;
X
X if (term_strings.t_name == NULL) /* no terminal name (yet) */
X return;
X
X/*
X * if the window ID and the display is known, we may use X11 calls
X */
X#ifdef USE_X11
X if (get_x11_windis() == OK)
X type = 1;
X#endif
X
X /*
X * note: if terminal is xterm, title is set with escape sequence rather
X * than x11 calls, because the x11 calls don't always work
X */
X if ( STRCMP(term_strings.t_name, "xterm") == 0 ||
X STRCMP(term_strings.t_name, "builtin_xterm") == 0)
X type = 2;
X
X /*
X * Note: getting the old window title for iris-ansi will only
X * currently work if you set WINDOWID by hand, it is not
X * done automatically like an xterm.
X */
X if (STRCMP(term_strings.t_name, "iris-ansi") == 0 ||
X STRCMP(term_strings.t_name, "iris-ansi-net") == 0)
X type = 3;
X
X if (type)


X {
X if (title != NULL)

X {
X if (oldtitle == NULL) /* first call, save title */
X get_x11_title();
X
X switch(type)
X {
X#ifdef USE_X11
X#ifdef BUGGY
X case 1: set_x11_title(title); /* x11 */
X break;
X#endif
X#endif
X case 2: outstrn((char_u *)"\033]2;"); /* xterm */
X outstrn(title);
X outchar(Ctrl('G'));
X flushbuf();
X break;
X
X case 3: outstrn((char_u *)"\033P1.y"); /* iris-ansi */
X outstrn(title);
X outstrn((char_u *)"\234");
X flushbuf();


X break;
X }
X }
X

X if (icon != NULL)
X {
X if (oldicon == NULL) /* first call, save icon */
X get_x11_icon();
X
X switch(type)
X {
X#ifdef USE_X11
X#ifdef BUGGY
X case 1: set_x11_icon(icon); /* x11 */
X break;
X#endif
X#endif
X case 2: outstrn((char_u *)"\033]1;"); /* xterm */
X outstrn(icon);
X outchar(Ctrl('G'));
X flushbuf();
X break;
X
X case 3: outstrn((char_u *)"\033P3.y"); /* iris-ansi */
X outstrn(icon);
X outstrn((char_u *)"\234");
X flushbuf();


X break;
X }
X }
X }
X}

X
X/*
X * Restore the window/icon title.
X * which is one of:
X * 1 Just restore title
X * 2 Just restore icon

X * 3 Restore title and icon

X */
X void
Xmch_restore_title(which)
X int which;
X{

X mch_settitle((which & 1) ? oldtitle : NULL, (which & 2) ? oldicon : NULL);


X}
X
X/*
X * Get name of current directory into buffer 'buf' of length 'len' bytes.
X * Return OK for success, FAIL for failure.
X */
X int
Xvim_dirname(buf, len)
X char_u *buf;
X int len;
X{

X#if defined(SYSV_UNIX) || defined(USL) || defined(hpux) || defined(linux)


X extern int errno;
X extern char *sys_errlist[];
X

X if (getcwd((char *)buf, len) == NULL)
X {
X STRCPY(buf, sys_errlist[errno]);
X return FAIL;
X }
X return OK;
X#else
X return (getwd((char *)buf) != NULL ? OK : FAIL);
X#endif
X}
X
X/*


X * get absolute filename into buffer 'buf' of length 'len' bytes
X *

X * return FAIL for failure, OK for success
X */


X int
XFullName(fname, buf, len)
X char_u *fname, *buf;
X int len;
X{

X int l;
X char_u olddir[MAXPATHL];
X char_u *p;
X int c;


X int retval = OK;
X

X if (fname == NULL) /* always fail */

X {
X *buf = NUL;


X return FAIL;
X }
X

X *buf = 0;
X if (!isFullName(fname)) /* if not an absolute path */
X {
X /*


X * If the file name has a path, change to that directory for a moment,
X * and then do the getwd() (and get back to where we were).
X * This will get the correct path name with "../" things.

X */
X if ((p = STRRCHR(fname, '/')) != NULL)
X {
X#if defined(SYSV_UNIX) || defined(USL) || defined(hpux) || defined(linux)
X if (getcwd((char *)olddir, MAXPATHL) == NULL)
X#else
X if (getwd((char *)olddir) == NULL)
X#endif


X {
X p = NULL; /* can't get current dir: don't chdir */

X retval = FAIL;
X }
X else
X {

X c = *p;
X *p = NUL;
X if (chdir((char *)fname))
X retval = FAIL;


X else
X fname = p + 1;
X *p = c;
X }
X }

X#if defined(SYSV_UNIX) || defined(USL) || defined(hpux) || defined(linux)
X if (getcwd((char *)buf, len) == NULL)
X#else
X if (getwd((char *)buf) == NULL)
X#endif


X {
X retval = FAIL;

X *buf = NUL;
X }

X l = STRLEN(buf);


X if (l && buf[l - 1] != '/')

X STRCAT(buf, "/");
X if (p)
X chdir((char *)olddir);
X }
X STRCAT(buf, fname);


X return retval;
X}
X
X/*
X * return TRUE is fname is an absolute path name
X */
X int
XisFullName(fname)
X char_u *fname;
X{

X return (*fname == '/');
X}
X
X/*


X * get file permissions for 'name'
X */
X long
Xgetperm(name)
X char_u *name;
X{

X struct stat statb;
X

X if (stat((char *)name, &statb))


X return -1;
X return statb.st_mode;

X}
X
X/*
X * set file permission for 'name' to 'perm'
X *
X * return FAIL for failure, OK otherwise
X */
X int
Xsetperm(name, perm)
X char_u *name;

X int perm;
X{
X#ifdef SCO
X return (chmod((char *)name, (mode_t)perm) == 0 ? OK : FAIL);
X#else
X return (chmod((char *)name, perm) == 0 ? OK : FAIL);
X#endif
X}
X
X/*


X * return TRUE if "name" is a directory
X * return FALSE if "name" is not a directory

X * return -1 for error


X */
X int
Xisdir(name)
X char_u *name;
X{

X struct stat statb;
X

X if (stat((char *)name, &statb))
X return -1;
X#ifdef _POSIX_SOURCE
X return (S_ISDIR(statb.st_mode) ? TRUE : FALSE);
X#else
X return ((statb.st_mode & S_IFMT) == S_IFDIR ? TRUE : FALSE);
X#endif
X}
X


X void
Xmch_windexit(r)
X int r;
X{

X settmode(0);
X exiting = TRUE;
X mch_settitle(oldtitle, oldicon); /* restore xterm title */
X stoptermcap();
X flushbuf();


X ml_close_all(); /* remove all memfiles */

X exit(r);
X}
X


X void
Xmch_settmode(raw)
X int raw;
X{

X#if defined(ECHOE) && defined(ICANON) && !defined(__NeXT__)
X /* for "new" tty systems */
X# ifdef CONVEX
X static struct termios told;
X struct termios tnew;
X# else


X static struct termio told;
X struct termio tnew;

X# endif
X#ifdef TIOCLGET
X static unsigned long tty_local;
X#endif
X
X if (raw)
X {
X#ifdef TIOCLGET
X ioctl(0, TIOCLGET, &tty_local);
X#endif
X ioctl(0, TCGETA, &told);
X tnew = told;
X /*
X * ICRNL enables typing ^V^M
X */
X tnew.c_iflag &= ~ICRNL;


X tnew.c_lflag &= ~(ICANON | ECHO | ISIG | ECHOE

X#ifdef IEXTEN
X | IEXTEN /* IEXTEN enables typing ^V on SOLARIS */
X#endif
X );


X tnew.c_cc[VMIN] = 1; /* return after 1 char */
X tnew.c_cc[VTIME] = 0; /* don't wait */
X ioctl(0, TCSETA, &tnew);

X }
X else
X {
X ioctl(0, TCSETA, &told);
X#ifdef TIOCLGET
X ioctl(0, TIOCLSET, &tty_local);
X#endif
X }
X#else
X# ifndef TIOCSETN
X# define TIOCSETN TIOCSETP /* for hpux 9.0 */
X# endif
X /* for "old" tty systems */
X static struct sgttyb ttybold;
X struct sgttyb ttybnew;
X
X if (raw)
X {
X ioctl(0, TIOCGETP, &ttybold);
X ttybnew = ttybold;
X ttybnew.sg_flags &= ~(CRMOD | ECHO);
X ttybnew.sg_flags |= RAW;
X ioctl(0, TIOCSETN, &ttybnew);
X }
X else
X ioctl(0, TIOCSETN, &ttybold);
X#endif
X}
X
X/*


X * set screen mode, always fails.
X */
X int
Xmch_screenmode(arg)
X char_u *arg;
X{
X EMSG("Screen mode setting not supported");
X return FAIL;
X}
X
X/*

X * Try to get the current window size:
X * 1. with an ioctl(), most accurate method
X * 2. from the environment variables LINES and COLUMNS
X * 3. from the termcap
X * 4. keep using the old values

X */
X int
Xmch_get_winsize()
X{

X int old_Rows = Rows;
X int old_Columns = Columns;

X char_u *p;
X
X Columns = 0;
X Rows = 0;
X
X/*


X * 1. try using an ioctl. It is the most accurate method.
X */

X# ifdef TIOCGSIZE
X {
X struct ttysize ts;
X
X if (ioctl(0, TIOCGSIZE, &ts) == 0)
X {
X Columns = ts.ts_cols;
X Rows = ts.ts_lines;
X }
X }
X# else /* TIOCGSIZE */
X# ifdef TIOCGWINSZ


X {
X struct winsize ws;
X
X if (ioctl(0, TIOCGWINSZ, &ws) == 0)
X {
X Columns = ws.ws_col;
X Rows = ws.ws_row;

X }
X }
X# endif /* TIOCGWINSZ */
X# endif /* TIOCGSIZE */
X
X/*


X * 2. get size from environment
X */

X if (Columns == 0 || Rows == 0)
X {
X if ((p = (char_u *)getenv("LINES")))
X Rows = atoi((char *)p);
X if ((p = (char_u *)getenv("COLUMNS")))
X Columns = atoi((char *)p);
X }
X
X#ifdef TERMCAP


X/*
X * 3. try reading the termcap
X */
X if (Columns == 0 || Rows == 0)
X {
X extern void getlinecol();
X
X getlinecol(); /* get "co" and "li" entries from termcap */

X }
X#endif
X
X/*


X * 4. If everything fails, use the old values
X */
X if (Columns <= 0 || Rows <= 0)
X {

X Columns = old_Columns;
X Rows = old_Rows;


X return FAIL;
X }
X

X check_winsize();


X
X/* if size changed: screenalloc will allocate new screen buffers */

X return OK;
X}
X
X void

Xmch_set_winsize()
X{
X /* should try to set the window size to Rows and Columns */
X}
X
X int
Xcall_shell(cmd, dummy, cooked)
X char_u *cmd;


X int dummy;
X int cooked;
X{

X#ifdef USE_SYSTEM /* use system() to start the shell: simple but slow */
X
X int x;
X char_u newcmd[1024];
X
X flushbuf();
X


X if (cooked)
X settmode(0); /* set to cooked mode */
X

X if (cmd == NULL)

X x = system(p_sh);
X else

X {
X sprintf(newcmd, "%s %s -c \"%s\"", p_sh,
X extra_shell_arg == NULL ? "" : extra_shell_arg, cmd);


X x = system(newcmd);
X }

X if (x == 127)
X {

X outstrn((char_u *)"\nCannot execute shell sh\n");
X }
X#ifdef WEBB_COMPLETE
X else if (x && !expand_interactively)
X#else
X else if (x)


X#endif
X {
X outchar('\n');
X outnum((long)x);
X outstrn((char_u *)" returned\n");
X }
X

X if (cooked)
X settmode(1); /* set to raw mode */
X resettitle();

X return (x ? FAIL : OK);
X
X#else /* USE_SYSTEM */ /* first attempt at not using system() */
X
X char_u newcmd[1024];
X int pid;
X int status = -1;
X char **argv = NULL;
X int argc;
X int i;
X char_u *p;
X int inquote;
X
X flushbuf();
X signal(SIGINT, SIG_IGN); /* we don't want to be killed here */


X if (cooked)
X settmode(0); /* set to cooked mode */
X

X /*
X * 1: find number of arguments
X * 2: separate them and built argv[]
X */
X STRCPY(newcmd, p_sh);
X for (i = 0; i < 2; ++i)
X {
X p = newcmd;
X inquote = FALSE;
X argc = 0;


X for (;;)
X {

X if (i == 1)
X argv[argc] = (char *)p;
X ++argc;
X while (*p && (inquote || (*p != ' ' && *p != TAB)))
X {


X if (*p == '"')

X inquote = !inquote;
X ++p;
X }
X if (*p == NUL)
X break;
X if (i == 1)


X *p++ = NUL;
X skipspace(&p);

X }
X if (i == 0)

X {
X argv = (char **)alloc((unsigned)((argc + 4) * sizeof(char *)));
X if (argv == NULL) /* out of memory */
X goto error;
X }
X }
X if (cmd != NULL)
X {
X if (extra_shell_arg != NULL)
X argv[argc++] = (char *)extra_shell_arg;
X argv[argc++] = "-c";
X argv[argc++] = (char *)cmd;
X }
X argv[argc] = NULL;
X
X if ((pid = fork()) == -1) /* maybe we should use vfork() */
X {
X outstrn((char_u *)"\nCannot fork\n");
X }
X else if (pid == 0) /* child */
X {
X signal(SIGINT, SIG_DFL);
X if (!show_shell_mess)
X {
X fclose(stdout);
X fclose(stderr);
X }
X execvp(argv[0], (char **)argv);
X exit(127); /* exec failed, return failure code */
X }
X else /* parent */
X {
X wait(&status);
X status = (status >> 8) & 255;
X if (status)
X {
X#ifdef WEBB_COMPLETE
X if (status == 127)
X {
X outstrn((char_u *)"\nCannot execute shell ");
X outstrn(p_sh);


X outchar('\n');
X }

X else if (!expand_interactively)


X {
X outchar('\n');

X outnum((long)status);


X outstrn((char_u *)" returned\n");
X }

X#else
X outchar('\n');
X if (status == 127)
X {
X outstrn((char_u *)"Cannot execute shell ");
X outstrn(p_sh);
X }
X else
X {
X outnum((long)status);
X outstrn((char_u *)" returned");


X }
X outchar('\n');

X#endif /* WEBB_COMPLETE */
X }
X }

X free(argv);
X
Xerror:


X if (cooked)
X settmode(1); /* set to raw mode */
X resettitle();

X signal(SIGINT, SIG_DFL);
X return (status ? FAIL : OK);
X
X#endif /* USE_SYSTEM */
X}
X
X/*


X * The input characters are buffered to be able to check for a CTRL-C.
X * This should be done with signals, but I don't know how to do that in

X * a portable way for a tty in RAW mode.
X */
X
X#define INBUFLEN 250
Xstatic char_u inbuf[INBUFLEN]; /* internal typeahead buffer */
Xstatic int inbufcount = 0; /* number of chars in inbuf[] */
X
X static int
XRead(buf, maxlen)
X char_u *buf;


X long maxlen;
X{
X if (inbufcount == 0) /* if the buffer is empty, fill it */
X fill_inbuf();
X if (maxlen > inbufcount)
X maxlen = inbufcount;

X memmove((char *)buf, (char *)inbuf, maxlen);


X inbufcount -= maxlen;
X if (inbufcount)

X memmove((char *)inbuf, (char *)inbuf + maxlen, inbufcount);
X return (int)maxlen;
X}
X
X void
Xbreakcheck()
X{
X/*


X * check for CTRL-C typed by reading all available characters
X */
X if (RealWaitForChar(0)) /* if characters available */
X fill_inbuf();

X}
X
X static void

Xfill_inbuf()


X{
X int len;
X

X if (inbufcount >= INBUFLEN) /* buffer full */
X return;

X len = read(0, inbuf + inbufcount, (long)(INBUFLEN - inbufcount));
X if (len <= 0) /* cannot read input??? */
X {
X fprintf(stderr, "Vim: Error reading input, exiting...\n");
X exit(1);


X }
X while (len-- > 0)

X {
X /*


X * if a CTRL-C was typed, remove it from the buffer and set got_int
X */
X if (inbuf[inbufcount] == 3)
X {
X /* remove everything typed before the CTRL-C */

X memmove((char *)inbuf, (char *)inbuf + inbufcount, len + 1);
X inbufcount = 0;


X got_int = TRUE;
X }

X ++inbufcount;
X }
X}
X
X/*

X * Wait "ticks" until a character is available from the keyboard or from inbuf[]
X * ticks = -1 will block forever

X */
X


X static int
XWaitForChar(ticks)
X int ticks;
X{
X if (inbufcount) /* something in inbuf[] */

X return 1;
X return RealWaitForChar(ticks);
X}
X
X/*

X * Wait "ticks" until a character is available from the keyboard
X * ticks = -1 will block forever

X */
X static int

XRealWaitForChar(ticks)
X int ticks;
X{

X#ifndef FD_ZERO
X struct pollfd fds;
X
X fds.fd = 0;
X fds.events = POLLIN;
X return (poll(&fds, 1, ticks));
X#else
X struct timeval tv;
X fd_set fdset;
X
X if (ticks >= 0)
X {
X tv.tv_sec = ticks / 1000;
X tv.tv_usec = (ticks % 1000) * (1000000/1000);
X }
X
X FD_ZERO(&fdset);
X FD_SET(0, &fdset);
X return (select(1, &fdset, NULL, NULL, (ticks >= 0) ? &tv : NULL));
X#endif
X}
X
X#if !defined(__alpha) && !defined(mips) && !defined(SCO) && !defined(remove) && !defined(CONVEX)
X int
Xremove(buf)
X# if defined(linux) || defined(__STDC__) || defined(__NeXT__) || defined(M_UNIX)
X const
X# endif
X char *buf;
X{
X return unlink(buf);
X}
X#endif
X
X/*


X * ExpandWildCard() - this code does wild-card pattern matching using the shell
X *
X * Mool: return 0 for success, 1 for error (you may loose some memory) and
X * put an error message in *file.

X *
X * num_pat is number of input patterns
X * pat is array of pointers to input patterns
X * num_file is pointer to number of matched file names
X * file is pointer to array of pointers to matched file names

X * On Unix we do not check for files only yet
X * list_notfound is ignored
X */
X
Xextern char *mktemp __ARGS((char *));
X#ifndef SEEK_SET
X# define SEEK_SET 0
X#endif
X#ifndef SEEK_END
X# define SEEK_END 2
X#endif

X
X int
XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
X int num_pat;
X char_u **pat;
X int *num_file;
X char_u ***file;
X int files_only;
X int list_notfound;
X{

X char_u tmpname[TMPNAMELEN];
X char_u *command;
X int i;
X int dir;
X size_t len;
X FILE *fd;
X char_u *buffer;
X char_u *p;
X int use_glob = FALSE;
X


X *num_file = 0; /* default: no files found */

X *file = (char_u **)"";
X
X /*

X * If there are no wildcards, just copy the names to allocated memory.

X * Saves a lot of time, because we don't have to start a new shell.
X */
X if (!have_wildcard(num_pat, pat))
X {
X *file = (char_u **)alloc(num_pat * sizeof(char_u *));


X if (*file == NULL)

X {


X *file = (char_u **)"";

X return FAIL;


X }
X for (i = 0; i < num_pat; i++)

X (*file)[i] = strsave(pat[i]);
X *num_file = num_pat;

X return OK;
X }
X
X/*

X * get a name for the temp file
X */
X STRCPY(tmpname, TMPNAME2);
X if (*mktemp((char *)tmpname) == NUL)
X {
X emsg(e_notmp);


X return FAIL;
X }
X
X/*

X * let the shell expand the patterns and write the result into the temp file
X * If we use csh, glob will work better than echo.
X */
X if ((len = STRLEN(p_sh)) >= 3 && STRCMP(p_sh + len - 3, "csh") == 0)
X use_glob = TRUE;
X
X len = TMPNAMELEN + 11;


X for (i = 0; i < num_pat; ++i) /* count the length of the patterns */

X len += STRLEN(pat[i]) + 3;
X command = alloc(len);
X if (command == NULL)
X return FAIL;
X if (use_glob)
X STRCPY(command, "glob >"); /* built the shell command */
X else
X STRCPY(command, "echo >"); /* built the shell command */
X STRCAT(command, tmpname);
X for (i = 0; i < num_pat; ++i)
X {
X#ifdef USE_SYSTEM
X STRCAT(command, " \""); /* need extra quotes because we */
X STRCAT(command, pat[i]); /* start the shell twice */
X STRCAT(command, "\"");
X#else
X STRCAT(command, " ");
X STRCAT(command, pat[i]);
X#endif
X }
X#ifdef WEBB_COMPLETE
X if (expand_interactively)
X show_shell_mess = FALSE;
X#endif /* WEBB_COMPLETE */
X if (use_glob) /* Use csh fast option */
X extra_shell_arg = (char_u *)"-f";


X i = call_shell(command, 0, FALSE); /* execute it */

X extra_shell_arg = NULL;
X show_shell_mess = TRUE;
X free(command);
X if (i == FAIL) /* call_shell failed */
X {
X remove((char *)tmpname);
X#ifdef WEBB_COMPLETE
X /* With interactive completion, the error message is not printed */
X if (!expand_interactively)


X#endif /* WEBB_COMPLETE */
X {

X must_redraw = CLEAR; /* probably messed up screen */

X msg_outchar('\n'); /* clear bottom line quickly */
X cmdline_row = Rows - 1; /* continue on last line */
X }


X return FAIL;
X }
X
X/*

X * read the names from the file into memory
X */
X fd = fopen((char *)tmpname, "r");
X if (fd == NULL)
X {
X emsg2(e_notopen, tmpname);
X return FAIL;
X }


X fseek(fd, 0L, SEEK_END);
X len = ftell(fd); /* get size of temp file */
X fseek(fd, 0L, SEEK_SET);

X buffer = alloc(len + 1);


X if (buffer == NULL)

X {
X remove((char *)tmpname);
X fclose(fd);
X return FAIL;
X }
X i = fread((char *)buffer, 1, len, fd);
X fclose(fd);
X remove((char *)tmpname);


X if (i != len)
X {

X emsg2(e_notread, tmpname);
X free(buffer);


X return FAIL;
X }
X

X if (use_glob) /* file names are separated with NUL */
X {


X buffer[len] = NUL; /* make sure the buffers ends in NUL */

X i = 0;


X for (p = buffer; p < buffer + len; ++p)
X if (*p == NUL) /* count entry */
X ++i;
X if (len)

X ++i; /* count last entry */
X }
X else /* file names are separated with SPACE */
X {
X buffer[len] = '\n'; /* make sure the buffers ends in NL */
X p = buffer;
X for (i = 0; *p != '\n'; ++i) /* count number of entries */
X {
X while (*p != ' ' && *p != '\n') /* skip entry */
X ++p;
X skipspace(&p); /* skip to next entry */
X }
X }
X *num_file = i;
X *file = (char_u **)alloc(sizeof(char_u *) * i);


X if (*file == NULL)

X {
X free(buffer);


X *file = (char_u **)"";

X return FAIL;


X }
X p = buffer;

X for (i = 0; i < *num_file; ++i)
X {
X (*file)[i] = p;
X if (use_glob)
X {


X while (*p && p < buffer + len) /* skip entry */
X ++p;

X ++p; /* skip NUL */
X }
X else
X {
X while (*p != ' ' && *p != '\n') /* skip entry */
X ++p;
X if (*p == '\n') /* last entry */
X *p = NUL;
X else
X {
X *p++ = NUL;
X skipspace(&p); /* skip to next entry */
X }
X }
X }


X for (i = 0; i < *num_file; ++i)
X {

X dir = (isdir((*file)[i]) == TRUE);
X if (dir < 0) /* if file doesn't exist don't add '/' */
X dir = 0;
X p = alloc((unsigned)(STRLEN((*file)[i]) + 1 + dir));
X if (p)
X {
X STRCPY(p, (*file)[i]);
X if (dir)
X STRCAT(p, "/");
X }
X (*file)[i] = p;
X }
X free(buffer);


X return OK;
X}
X
X void
XFreeWild(num, file)
X int num;
X char_u **file;
X{
X if (file == NULL || num == 0)
X return;
X while (num--)
X free(file[num]);
X free(file);
X}
X
X int
Xhas_wildcard(p)
X char_u *p;
X{

X#ifdef __STDC__
X return strpbrk((char *)p, "*?[{`~$") != NULL;
X#else


X for ( ; *p; ++p)

X if (STRCHR("*?[{`~$", *p) != NULL)
X return 1;
X return 0;
X#endif
X}
X
X int
Xhave_wildcard(num, file)


X int num;
X char_u **file;
X{

X register int i;
X


X for (i = 0; i < num; i++)
X if (has_wildcard(file[i]))
X return 1;

X return 0;
X}
X

X#if defined(M_XENIX) || defined(UTS2)
X/*
X * Scaled-down version of rename, which is missing in Xenix.
X * This version can only move regular files and will fail if the
X * destination exists.
X */
X int
Xrename(src, dest)
X char_u *src, *dest;


X{
X struct stat st;
X

X if (stat(dest, &st) >= 0) /* fail if destination exists */
X return -1;
X if (link(src, dest) != 0) /* link file to new name */
X return -1;
X if (unlink(src) == 0) /* delete link to old name */
X return 0;
X return -1;
X}
X#endif /* M_XENIX || UTS2 */
END_OF_FILE
if test 30140 -ne `wc -c <'vim/src/unix.c'`; then
echo shar: \"'vim/src/unix.c'\" unpacked with wrong size!
fi
# end of 'vim/src/unix.c'
fi
if test -f 'vim/tools/readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tools/readme'\"
else
echo shar: Extracting \"'vim/tools/readme'\" \(153 characters\)
sed "s/^X//" >'vim/tools/readme' <<'END_OF_FILE'
XSome tools that can be used with Vim:
X
Xvim132: shell script to edit in 132 column mode on vt100 compatible terminals
Xref: shell script for the K command
END_OF_FILE
if test 153 -ne `wc -c <'vim/tools/readme'`; then
echo shar: \"'vim/tools/readme'\" unpacked with wrong size!
fi
# end of 'vim/tools/readme'
fi
if test -f 'vim/uganda.txt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/uganda.txt'\"
else
echo shar: Extracting \"'vim/uganda.txt'\" \(3139 characters\)
sed "s/^X//" >'vim/uganda.txt' <<'END_OF_FILE'
XVim is public domain. If you are happy with Vim and want to express that,
Xdon't send me money. I don't need it. But I know a place where they do need
Xyour money. Please read on.
X
XSummer 1993 I spent one month in Uganda with a Dutch team. I was very
Ximpressed with what I experienced there. Together with local people we built a
Xnursery school in Kibaale. In only three weeks from nothing to a roofed
Xbuilding!
X
XKibaale is a small town in the south of Uganda. It is an area that is suffering
Xfrom AIDS very badly. About 30% of the adults are infected. Because parents
Xdie, there are many orphans. They need a lot of help. The Kibaale children
Xcentre is working hard to provide the needy with food, medical care and
Xeducation. Food and medical care to keep them healthy now, and education so
Xthat they can take care of themselves in the future. This is the best charity
Xprogram I have ever encountered.
X
XThe key to solving the problems in this area is education. This has been
Xneglected in the past years with president Idi Amin and the following civil
Xwars. Now that the governement is stable again the people have to learn how to
Xtake care of themselves and how to avoid infections. There is also help for
Xpeople who are ill and hungry, but the primary goal is to prevent people from
Xgetting ill and learn them how to grow their own crops.
X
XI was impressed by the progress that is being made there. The work is very
Xwell organized. Every dollar is spent on something useful. Our team brought
Xabout $2000. For that money we were able to built most of a two classroom
Xnursery school. They have further plans to build a primary school and houses
Xfor the teachers. They also need money for books and other teaching materials.
X
XIf you want to support the Kibaale children centre, please send a contribution.
X
XHow do you know that the money will be spent right? First of all you have my
Xpersonal guarantee as the author of Vim. Further the project is co-sponsored
Xand inspected by World Vision, Save the Children Fund and International Child
XCare Fund. I will work for the project as a volunteer from September 1994 to
XAugust 1995.
X
XIf you have any further questions, send me e-mail: mo...@oce.nl.
X
XThe director of the project is:
XSekaran Vellasamy
Xp.o. box 1658
XMasaka, Uganda, East Africa
X
XTransfering money from Holland:
XUse one of my accounts:
XRabobank Venlo, nr. 3765.05.117
XPostbank, nr. 1644503
X
XTransfering money from Europe:
XTo avoid banking costs the best thing is to send me a Eurocheque, written out
Xto "Bram Moolenaar" in Dutch Guilders (fl). But any other method should work.
X
XTransfering money from USA:
XSend me a check that can be cashed in Holland. Any "standard" banking check
Xshould be OK. Please consider adding $10 for banking costs.
X
XMy address: Bram Moolenaar
X Kibaale Donation
X Molenstraat 2
X 2162 HP Lisse
X The Netherlands.
X
XOr you can transfer the money directly to the director of the project:
X
XCitibank, N.A.
Xa/c no. 36059709
XGlobal Clearance Services
X111 Wall Street 16th floor
XNew York 10043
XU.S.A.
XBeneficiary Mr. Sekaran Vellasamy a/c no. 2100, Gold Trust Bank LTD - Kampala
END_OF_FILE
if test 3139 -ne `wc -c <'vim/uganda.txt'`; then
echo shar: \"'vim/uganda.txt'\" unpacked with wrong size!
fi
# end of 'vim/uganda.txt'
fi
echo shar: End of archive 18 \(of 26\).
cp /dev/null ark18isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:16 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 38
Archive-name: vim/part19

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/vim.man.UU vim/src/window.c vim/tutor/tutor


# Wrapped by kent@sparky on Mon Aug 15 21:44:10 1994
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 19 (of 26)."'
if test -f 'vim/doc/vim.man.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/vim.man.UU'\"
else
echo shar: Extracting \"'vim/doc/vim.man.UU'\" \(10854 characters\)
sed "s/^X//" >'vim/doc/vim.man.UU' <<'END_OF_FILE'
Xbegin 644 vim/doc/vim.man
XM"@H*5DE-*#$I(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @("!624TH,2D*"@I."$Y!"$%-"$U%"$4*(" @(" @
XM('9I;2 M(%9I($E-<')O=F5D+"!A('!R;V=R86UM97)S('1E>'0@961I=&]R
XM"@I3"%-9"%E."$Y/"$]0"%!3"%-)"$E3"%,*(" @(" @('8(=FD(:6T(;2!;
XM;W!T:6]N<UT@6V9I;&4@+BY="B @(" @("!V"'9I"&EM"&T@6V]P=&EO;G-=
XM("UT('1A9PH@(" @(" @=@AV:0AI;0AM(%MO<'1I;VYS72 M92!;97)R;W)F
XM:6QE70H*1 A$10A%4PA30PA#4@A220A)4 A05 A420A)3PA/3@A."B @(" @
XM("!6"%9I"&EM"&T@(&ES(&$@=&5X="!E9&ET;W(@=&AA="!I<R!U<'=A<F1S
XM(&-O;7!A=&EB;&4@=&\@=FDN($ET"B @(" @("!C86X@8F4@=7-E9"!T;R!E
XM9&ET(&%N>2!!4T-)22!T97AT+B!)="!I<R!E<W!E8VEA;&QY("!U<V4M"B @
XM(" @("!F=6P@9F]R(&5D:71I;F<@<')O9W)A;7,N"@H@(" @(" @5&AE<F4@
XM(&%R92 @82 @;&]T("!O9B @96YH86YC96UE;G1S(&%B;W9E('9I.B!M=6QT
XM:2!L979E; H@(" @(" @=6YD;RP@;75L=&D@=VEN9&]W<R!A;F0@(&)U9F9E
XM<G,L("!C;VUM86YD("!L:6YE("!E9&ET:6YG+ H@(" @(" @9FEL96YA;64@
XM8V]M<&QE=&EO;BP@;VXM;&EN92!H96QP+"!V:7-U86P@<V5L96-T:6]N+"!E
XM=&,N+@H@(" @(" @4F5A9"!D:69F97)E;F-E+F1O8R @9F]R("!A("!S=6UM
XM87)Y("!O9B @=&AE("!D:69F97)E;F-E<PH@(" @(" @8F5T=V5E;B!V:2!A
XM;F0@5FEM+@H*(" @(" @($UO<W0@(&]F=&5N("!6"%9I"&EM"&T@:7,@<W1A
XM<G1E9"!T;R!E9&ET(&$@<VEN9VQE(&9I;&4@=VET:"!T:&4*(" @(" @(&-O
XM;6UA;F0*"B @(" @(" @(" @('9I;2!F:6QE"@H@(" @(" @36]R92!G96YE
XM<F%L;'D@5DE-(&ES('-T87)T960@=VET:#H*"B @(" @(" @(" @('9I;2!;
XM;W!T:6]N<UT@6V9I;&5L:7-T70H*(" @(" @($EF('1H92!F:6QE;&ES="!I
XM<R!M:7-S:6YG+"!T:&4@961I=&]R('=I;&P@<W1A<G0@=VET:" @86X*(" @
XM(" @(&5M<'1Y("!B=69F97(N("!/=&AE<G=I<V4@97AA8W1L>2!O;F4@;W5T
XM(&]F('1H92!F;VQL;W=I;F<*(" @(" @('1H<F5E(&UA>2!B92!U<V5D('1O
XM("!C:&]O<V4@(&]N92 @;W(@(&UO<F4@(&9I;&5S("!T;R @8F4*(" @(" @
XM(&5D:71E9"X*"B @(" @("!F:6QE("XN(" @("!!(&QI<W0@;V8@9FEL92!N
XM86UE<RX@5&AE(&9I<G-T(&]N92 H86QP:&%B970M"B @(" @(" @(" @(" @
XM(" @("!I8V%L;'DI('=I;&P@8F4@=&AE(&-U<G)E;G0@9FEL92!A;F0@<F5A
XM9"!I;G1O"B @(" @(" @(" @(" @(" @("!T:&4@(&)U9F9E<BX@(%1H92!C
XM=7)S;W(@=VEL;"!B92!P;W-I=&EO;F5D(&]N"B @(" @(" @(" @(" @(" @
XM("!T:&4@9FER<W0@;&EN92!O9B!T:&4@8G5F9F5R+B!9;W4@8V%N("!G970@
XM('1O"B @(" @(" @(" @(" @(" @("!T:&4@;W1H97(@9FEL97,@=VET:"!T
XM:&4@(CIN97AT(B!C;VUM86YD+@H*(" @(" @("UT('MT86=](" @(%1H92 @
XM9FEL92!T;R!E9&ET(&%N9"!T:&4@:6YI=&EA;"!C=7)S;W(@<&]S:2T*(" @
XM(" @(" @(" @(" @(" @('1I;VX@9&5P96YD<R!O;B!A(")T86<B+"!A('-O
XM<G0@;V8@9V]T;R!L86)E;"X*(" @(" @(" @(" @(" @(" @('MT86=](&ES
XM(&QO;VME9"!U<"!I;B!T:&4@=&%G<R!F:6QE+"!T:&4@87-S;RT*(" @(" @
XM(" @(" @(" @(" @(&-I871E9"!F:6QE(&)E8V]M97,@=&AE(&-U<G)E;G0@
XM9FEL92 @86YD("!T:&4*(" @(" @(" @(" @(" @(" @(&%S<V]C:6%T960@
XM8V]M;6%N9"!I<R!E>&5C=71E9"X@36]S=&QY('1H:7,@:7,*(" @(" @(" @
XM(" @(" @(" @('5S960@9F]R($,@<')O9W)A;7,N('MT86=]('1H96X@('-H
XM;W5L9" @8F4@(&$*(" @(" @(" @(" @(" @(" @(&9U;F-T:6]N("!N86UE
XM+B @5&AE("!E9F9E8W0@(&ES('1H870@=&AE(&9I;&4*(" @(" @(" @(" @
XM(" @(" @(&-O;G1A:6YI;F<@=&AA="!F=6YC=&EO;B!B96-O;65S("!T:&4@
XM(&-U<G)E;G0*(" @(" @(" @(" @(" @(" @(&9I;&4@86YD('1H92!C=7)S
XM;W(@:7,@<&]S:71I;VYE9"!O;B!T:&4@<W1A<G0*(" @(" @(" @(" @(" @
XM(" @(&]F('1H92!F=6YC=&EO;B @*'-E92 @<F5F97)E;F-E+F1O8RP@('-E
XM8W1I;VX*(" @(" @(" @(" @(" @(" @(")T86<@<V5A<F-H97,B*2X*"B @
XM(" @(" M92!;97)R;W)F:6QE70H@(" @(" @(" @(" @(" @(" @4W1A<G0@
XM(&EN("!Q=6EC:T9I>"!M;V1E+B!4:&4@9FEL92!;97)R;W)F:6QE70H@(" @
XM(" @(" @(" @(" @(" @:7,@<F5A9"!A;F0@=&AE(&9I<G-T(&5R<F]R(&ES
XM("!D:7-P;&%Y960N("!)9@H*"@H@(" @(" @(" @(" @(" @(" @(" @(" @
XM(#$Y.30@075G=7-T(#$R(" @(" @(" @(" @(" @(" @(" @(" @,0H*"@H*
XM"E9)32@Q*2 @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @5DE-*#$I"@H*(" @(" @(" @(" @(" @(" @(%ME
XM<G)O<F9I;&5=(" @:7,@(&]M:71T960@('1H92 @9FEL92 @;F%M92 @:7,*
XM(" @(" @(" @(" @(" @(" @(&]B=&%I;F5D(&9R;VT@=&AE("=E<G)O<F9I
XM;&4G(&]P=&EO;B H9&5F875L=',*(" @(" @(" @(" @(" @(" @('1O(" B
XM07IT96-#+D5R<B(@(&9O<B @=&AE("!!;6EG82P@(F5R<F]R<R(@;VX*(" @
XM(" @(" @(" @(" @(" @(&]T:&5R('-Y<W1E;7,I+B!&=7)T:&5R(&5R<F]R
XM<R!C86X@(&)E("!J=6UP960*(" @(" @(" @(" @(" @(" @('1O("!W:71H
XM("!T:&4@(CIC;B(@8V]M;6%N9"X@4V5E(')E9F5R96YC92YD;V,*(" @(" @
XM(" @(" @(" @(" @('-E8W1I;VX@-2XU+@H*3PA/4 A05 A420A)3PA/3@A.
XM4PA3"B @(" @("!4:&4@;W!T:6]N<RP@:68@<')E<V5N="P@;75S="!P<F5C
XM961E("!T:&4@(&9I;&5L:7-T+B @5&AE"B @(" @("!O<'1I;VYS(&UA>2!B
XM92!G:79E;B!I;B!A;GD@;W)D97(N"@H@(" @(" @+7(@(" @(" @(" @4F5C
XM;W9E<GD@(&UO9&4N("!4:&4@('-W87 @(&9I;&4@(&ES("!U<V5D("!T;PH@
XM(" @(" @(" @(" @(" @(" @<F5C;W9E<B!A(&-R87-H960@961I=&EN9R @
XM<V5S<VEO;BX@(%1H92 @<W=A< H@(" @(" @(" @(" @(" @(" @9FEL92 @
XM:7,@82!F:6QE('=I=&@@=&AE('-A;64@9FEL92!N86UE(&%S('1H90H@(" @
XM(" @(" @(" @(" @(" @=&5X="!F:6QE('=I=&@@("(N<W=P(B @87!P96YD
XM960N("!3964@(')E9F5R+0H@(" @(" @(" @(" @(" @(" @96YC92YD;V,L
XM(&-H87!T97(@(E)E8V]V97)Y(&%F=&5R(&$@8W)A<V@B+@H*(" @(" @("UV
XM(" @(" @(" @(%9I97<@(&UO9&4N(%1H92 G<F5A9&]N;'DG(&]P=&EO;B!W
XM:6QL(&)E('-E="X*(" @(" @(" @(" @(" @(" @(%EO=2!C86X@<W1I;&P@
XM961I="!T:&4@(&)U9F9E<BP@(&)U=" @=VEL;" @8F4*(" @(" @(" @(" @
XM(" @(" @('!R979E;G1E9" @9G)O;2!A8V-I9&5N=&QY(&]V97)W<FET:6YG
XM(&$@9FEL92X*(" @(" @(" @(" @(" @(" @($EF('EO=2!D;R!W86YT('1O
XM(&]V97)W<FET92 @82 @9FEL92P@(&%D9" @86X*(" @(" @(" @(" @(" @
XM(" @(&5X8VQA;6%T:6]N("!M87)K("!T;R @=&AE("!%>" @8V]M;6%N9"P@
XM87,@:6X*(" @(" @(" @(" @(" @(" @("(Z=R$B+B @5&AE("UV("!O<'1I
XM;VX@(&%L<V\@(&EM<&QI97,@('1H92 @+6X*(" @(" @(" @(" @(" @(" @
XM(&]P=&EO;B H<V5E(&)E;&]W*2X@(%1H92 G<F5A9&]N;'DG(&]P=&EO;B!C
XM86X*(" @(" @(" @(" @(" @(" @(&)E(')E<V5T('=I=&@@(CIS970@;F]R
XM;R(@*'-E92 @<F5F97)E;F-E+F1O8RP*(" @(" @(" @(" @(" @(" @(&]P
XM=&EO;G,@8VAA<'1E<BDN"@H@(" @(" @+6(@(" @(" @(" @0FEN87)Y+B @
XM02 @9F5W(&]P=&EO;G,@=VEL;"!B92!S970@=&AA="!M86ME<PH@(" @(" @
XM(" @(" @(" @(" @:70@<&]S<VEB;&4@=&\@961I=" @82 @8FEN87)Y("!O
XM<B @97AE8W5T86)L90H@(" @(" @(" @(" @(" @(" @9FEL92X*"B @(" @
XM(" K6VYU;5T@(" @("!&;W(@('1H92 @9FER<W0@(&9I;&4@=&AE(&-U<G-O
XM<B!W:6QL(&)E('!O<VDM"B @(" @(" @(" @(" @(" @("!T:6]N960@;VX@
XM;&EN92 B;G5M(BX@268@(FYU;2(@:7,@;6ES<VEN9RP@=&AE"B @(" @(" @
XM(" @(" @(" @("!C=7)S;W(@=VEL;"!B92!P;W-I=&EO;F5D(&]N('1H92!L
XM87-T(&QI;F4N"@H@(" @(" @*R]P870@(" @(" @1F]R("!T:&4@(&9I<G-T
XM("!F:6QE('1H92!C=7)S;W(@=VEL;"!B92!P;W-I+0H@(" @(" @(" @(" @
XM(" @(" @=&EO;F5D(&]N('1H92!F:7)S="!O8V-U<G)E;F-E(&]F(" B<&%T
XM(B @*'-E90H@(" @(" @(" @(" @(" @(" @<F5F97)E;F-E+F1O8RP@('-E
XM8W1I;VX@(G!A='1E<FX@<V5A<F-H97,B(&9O<@H@(" @(" @(" @(" @(" @
XM(" @=&AE(&%V86EL86)L92!S96%R8V@@<&%T=&5R;G,I+@H*(" @(" @("M[
XM8V]M;6%N9'T*"B @(" @(" M8R![8V]M;6%N9'T*(" @(" @(" @(" @(" @
XM(" @('MC;VUM86YD?2!W:6QL(&)E("!E>&5C=71E9" @869T97(@('1H92 @
XM9FER<W0*(" @(" @(" @(" @(" @(" @(&9I;&4@(&AA<R @8F5E;B!R96%D
XM+B![8V]M;6%N9'T@:7,@:6YT97)P<F5T960*(" @(" @(" @(" @(" @(" @
XM(&%S(&%N($5X(&-O;6UA;F0N($EF("!T:&4@('MC;VUM86YD?2 @8V]N=&%I
XM;G,*(" @(" @(" @(" @(" @(" @('-P86-E<R @:70@(&UU<W0@(&)E(&5N
XM8VQO<V5D(&EN(&1O=6)L92!Q=6]T97,*(" @(" @(" @(" @(" @(" @("AT
XM:&ES(&1E<&5N9',@;VX@('1H92 @<VAE;&P@('1H870@(&ES("!U<V5D*2X*
XM(" @(" @(" @(" @(" @(" @($5X86UP;&4Z(%9I;2 B*W-E="!S:2(@;6%I
XM;BYC"@H@(" @(" @+7@@(" @(" @(" @*$%M:6=A("!O;FQY*2 @5FEM("!I
XM<R!N;W0@<F5S=&%R=&5D('1O(&]P96X@80H@(" @(" @(" @(" @(" @(" @
XM;F5W('=I;F1O=RX@5&AI<R!O<'1I;VX@<VAO=6QD("!B92 @=7-E9" @=VAE
XM;@H@(" @(" @(" @(" @(" @(" @5FEM("!I<R @97AE8W5T960@(&)Y(&$@
XM<')O9W)A;2!T:&%T('=I;&P@=V%I= H@(" @(" @(" @(" @(" @(" @9F]R
XM('1H92!E9&ET('-E<W-I;VX@=&\@(&9I;FES:" @*&4N9RX@(&UA:6PI+@H*
XM"@H@(" @(" @(" @(" @(" @(" @(" @(" @(#$Y.30@075G=7-T(#$R(" @
XM(" @(" @(" @(" @(" @(" @(" @,@H*"@H*"E9)32@Q*2 @(" @(" @(" @
XM(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @5DE-
XM*#$I"@H*(" @(" @(" @(" @(" @(" @(%1H92 B.G-H(B!A;F0@(CHA(B!C
XM;VUM86YD<R!W:6QL(&YO="!W;W)K+@H*(" @(" @("UO6TY=(" @(" @($]P
XM96X@($X@('=I;F1O=W,N("!7:&5N($X@:7,@;VUI='1E9"P@;W!E;B!O;F4*
XM(" @(" @(" @(" @(" @(" @('=I;F1O=R!F;W(@96%C:"!F:6QE+@H*(" @
XM(" @("UN(" @(" @(" @($YO('-W87 @9FEL92!W:6QL(&)E('5S960N("!2
XM96-O=F5R>2 @869T97(@(&$*(" @(" @(" @(" @(" @(" @(&-R87-H('=I
XM;&P@8F4@:6UP;W-S:6)L92X@2&%N9'D@:68@>6]U('=A;G0@=&\*(" @(" @
XM(" @(" @(" @(" @(&5D:70@82 @9FEL92 @;VX@(&$@('9E<GD@('-L;W<@
XM(&UE9&EU;2 @*&4N9RX*(" @(" @(" @(" @(" @(" @(&9L;W!P>2DN("!#
XM86X@(&%L<V\@(&)E(&1O;F4@=VET:" B.G-E="!U8STP(BX*(" @(" @(" @
XM(" @(" @(" @($-A;B!B92!U;F1O;F4@=VET:" B.G-E="!U8STR,# B+@H*
XM(" @(" @("US('MS8W)I<'1I;GT*(" @(" @(" @(" @(" @(" @(%1H92!S
XM8W)I<'0@9FEL92![<V-R:7!T:6Y](&ES(')E860N(%1H92 @8VAA<BT*(" @
XM(" @(" @(" @(" @(" @(&%C=&5R<R @:6X@('1H92!F:6QE(&%R92!I;G1E
XM<G!R971E9"!A<R!I9B!Y;W4*(" @(" @(" @(" @(" @(" @(&AA9"!T>7!E
XM9"!T:&5M+B!4:&4@<V%M92!C86X@8F4@9&]N92!W:71H("!T:&4*(" @(" @
XM(" @(" @(" @(" @(&-O;6UA;F0@("(Z<V]U<F-E(2 @>W-C<FEP=&EN?2(N
XM($EF('1H92!E;F0@;V8*(" @(" @(" @(" @(" @(" @('1H92!F:6QE(&ES
XM(')E86-H960@8F5F;W)E('1H92 @961I=&]R("!E>&ET<RP*(" @(" @(" @
XM(" @(" @(" @(&9U<G1H97(@8VAA<F%C=&5R<R!A<F4@<F5A9"!F<F]M('1H
XM92!K97EB;V%R9"X*"B @(" @(" M=R![<V-R:7!T;W5T?0H@(" @(" @(" @
XM(" @(" @(" @06QL('1H92!C:&%R86-T97)S('1H870@>6]U('1Y<&4@87)E
XM("!R96-O<F1E9 H@(" @(" @(" @(" @(" @(" @:6X@('1H92 @9FEL92![
XM<V-R:7!T;W5T?2P@=6YT:6P@>6]U(&5X:70@5DE-+@H@(" @(" @(" @(" @
XM(" @(" @5&AI<R!I<R!U<V5F=6P@:68@>6]U('=A;G0@=&\@8W)E871E(&$@
XM('-C<FEP= H@(" @(" @(" @(" @(" @(" @9FEL92!T;R!B92!U<V5D('=I
XM=&@@(G9I;2 M<R(@;W(@(CIS;W5R8V4A(BX*"B @(" @(" M5"!T97)M:6YA
XM;"!496QL<R @5FEM("!T:&4@(&YA;64@(&]F('1H92!T97)M:6YA;"!Y;W4@
XM87)E"B @(" @(" @(" @(" @(" @("!U<VEN9RX@4VAO=6QD("!B92 @82 @
XM=&5R;6EN86P@(&MN;W=N("!T;R @5FEM"B @(" @(" @(" @(" @(" @(" H
XM8G5I;'1I;BD@;W(@9&5F:6YE9"!I;B!T:&4@=&5R;6-A<"!F:6QE+@H*(" @
XM(" @("UD(&1E=FEC92 @($]P96X@(")D979I8V4B("!F;W(@=7-E(&%S(&$@
XM=&5R;6EN86PN($]N;'D@;VX*(" @(" @(" @(" @(" @(" @('1H92!!;6EG
XM82X@17AA;7!L93H@(BUD(&-O;CHR,"\S,"\V,# O,34P(BX*"E,(4T4(144(
XM12!!"$%,"$Q3"%-/"$\*(" @(" @(%9I;2!D;V-U;65N=&%T:6]N.@H*(" @
XM(" @(')E9F5R96YC92YD;V,Z"B @(" @(" @(" @(" @(" @("!!(&-O;7!L
XM971E(')E9F5R96YC92!O9B!6:6T@*&QO;F<I"@H@(" @(" @=VEN9&]W<RYD
XM;V,Z"B @(" @(" @(" @(" @(" @("!%>'!L86YA=&EO;B!O9B!T:&4@;75L
XM=&D@=VEN9&]W<R @86YD("!B=69F97)S"B @(" @(" @(" @(" @(" @("!C
XM;VUM86YD<R!A;F0@;W!T:6]N<PH*(" @(" @(&EN9&5X.B @(" @($]V97)V
XM:65W("!O9B @86QL("!C;VUM86YD("!C:&%R86-T97)S("AU<V5F=6P*(" @
XM(" @(" @(" @(" @(" @('=H96X@861D:6YG(&YE=R!M87!P:6YG<RD*"B @
XM(" @("!D:69F97)E;F-E+F1O8SH*(" @(" @(" @(" @(" @(" @($]V97)V
XM:65W(&]F('1H92!D:69F97)E;F-E<R!B971W965N('9I(&%N9"!6:6T*"B @
XM(" @("!U;FEX+F1O8SH@("!5;FEX+7-P96-I9FEC(&-O;6UE;G1S"@H@(" @
XM(" @=FEM+FAL<#H@(" @1FEL92!U<V5D(&)Y('1H92!O;BUL:6YE(&AE;' @
XM*'-H;W)T*0H*00A!50A55 A42 A(3PA/4@A2"B @(" @("!-;W-T(&]F(%9)
XM32!W87,@;6%D92!B>2!"<F%M($UO;VQE;F%A<BX*"@H*(" @(" @(" @(" @
XM(" @(" @(" @(" @(" Q.3DT($%U9W5S=" Q,B @(" @(" @(" @(" @(" @
XM(" @(" @(#,*"@H*"@I624TH,2D@(" @(" @(" @(" @(" @(" @(" @(" @
XM(" @(" @(" @(" @(" @(" @(" @(" @(" @(%9)32@Q*0H*"B @(" @("!6
XM24T@(&ES("!B87-E9"!O;B!3=&5V:64L('=O<FME9"!O;B!B>3H@5&EM(%1H
XM;VUP<V]N+"!4;VYY"B @(" @("!!;F1R97=S(&%N9"!'+E(N("A&<F5D*2!7
XM86QT97(*"D((0E4(54<(1U,(4PH@(" @(" @4')O8F%B;'DN"@H*"@H*"@H*
XM"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H@
XM(" @(" @(" @(" @(" @(" @(" @(" @(#$Y.30@075G=7-T(#$R(" @(" @
X6(" @(" @(" @(" @(" @(" @- H*"B @
X
Xend
END_OF_FILE
if test 10854 -ne `wc -c <'vim/doc/vim.man.UU'`; then
echo shar: \"'vim/doc/vim.man.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/doc/vim.man'\" \(7852 characters\)
cat vim/doc/vim.man.UU | uudecode
if test 7852 -ne `wc -c <'vim/doc/vim.man'`; then
echo shar: \"'vim/doc/vim.man'\" uudecoded with wrong size!
else
rm vim/doc/vim.man.UU
fi
fi
# end of 'vim/doc/vim.man.UU'
fi
if test -f 'vim/src/window.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/window.c'\"
else
echo shar: Extracting \"'vim/src/window.c'\" \(25721 characters\)
sed "s/^X//" >'vim/src/window.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic int win_comp_pos __ARGS((void));
Xstatic void win_exchange __ARGS((long));
Xstatic void win_rotate __ARGS((int, int));
Xstatic void win_append __ARGS((WIN *, WIN *));
Xstatic void win_remove __ARGS((WIN *));
X
Xstatic WIN *prevwin = NULL; /* previous window */
X
X/*
X * all CTRL-W window commands are handled here, called from normal().
X */
X void
Xdo_window(nchar, Prenum)
X int nchar;
X long Prenum;
X{
X long Prenum1;
X WIN *wp;
X char_u *ptr;
X


X if (Prenum == 0)

X Prenum1 = 1;
X else


X Prenum1 = Prenum;
X

X switch (nchar)
X {
X/* split current window in two parts */
X case 'S':
X case Ctrl('S'):
X case 's': VIsual.lnum = 0; /* stop Visual mode */
X win_split(Prenum, TRUE);
X break;
X
X/* open new window */


X case Ctrl('N'):

X case 'n': VIsual.lnum = 0; /* stop Visual mode */
X stuffcharReadbuff(':');
X if (Prenum)
X stuffnumReadbuff(Prenum); /* window height */
X stuffReadbuff((char_u *)"new\n"); /* it is cmdline.c */
X break;
X
X/* quit current window */


X case Ctrl('Q'):

X case 'q': VIsual.lnum = 0; /* stop Visual mode */
X stuffReadbuff((char_u *)":quit\n"); /* it is cmdline.c */
X break;
X
X/* close current window */


X case Ctrl('C'):

X case 'c': VIsual.lnum = 0; /* stop Visual mode */
X stuffReadbuff((char_u *)":close\n"); /* it is cmdline.c */
X break;
X
X/* close all but current window */


X case Ctrl('O'):

X case 'o': VIsual.lnum = 0; /* stop Visual mode */
X stuffReadbuff((char_u *)":only\n"); /* it is cmdline.c */
X break;
X
X/* cursor to next window */
X case 'j':
X case K_DARROW:
X case Ctrl('J'):
X VIsual.lnum = 0; /* stop Visual mode */
X for (wp = curwin; wp->w_next != NULL && Prenum1-- > 0;
X wp = wp->w_next)
X ;
X win_enter(wp, TRUE);
X cursupdate();
X break;
X
X/* cursor to next window with wrap around */


X case Ctrl('W'):

X case 'w':
X VIsual.lnum = 0; /* stop Visual mode */
X if (lastwin == firstwin) /* just one window */
X beep();
X else
X {
X if (Prenum) /* go to specified window */
X {
X for (wp = firstwin; --Prenum > 0; )
X {
X if (wp->w_next == NULL)
X break;
X else
X wp = wp->w_next;
X }
X }
X else /* go to next window */
X {
X wp = curwin->w_next;
X if (wp == NULL)
X wp = firstwin; /* wrap around */
X }
X win_enter(wp, TRUE);
X cursupdate();
X }
X break;
X
X/* cursor to window above */


X case 'k':
X case K_UARROW:

X case Ctrl('K'):

X VIsual.lnum = 0; /* stop Visual mode */
X for (wp = curwin; wp->w_prev != NULL && Prenum1-- > 0;
X wp = wp->w_prev)
X ;
X win_enter(wp, TRUE);
X cursupdate();
X break;
X
X/* cursor to last accessed (previous) window */
X case 'p':


X case Ctrl('P'):

X VIsual.lnum = 0; /* stop Visual mode */
X if (prevwin == NULL)


X beep();
X else
X {

X win_enter(prevwin, TRUE);
X cursupdate();
X }
X break;
X
X/* exchange current and next window */
X case 'x':
X case Ctrl('X'):
X win_exchange(Prenum);
X break;
X
X/* rotate windows downwards */


X case Ctrl('R'):

X case 'r': VIsual.lnum = 0; /* stop Visual mode */
X win_rotate(FALSE, (int)Prenum1); /* downwards */
X break;
X
X/* rotate windows upwards */
X case 'R': VIsual.lnum = 0; /* stop Visual mode */
X win_rotate(TRUE, (int)Prenum1); /* upwards */
X break;
X
X/* make all windows the same height */
X case '=': win_equal(NULL, TRUE);
X break;
X
X/* increase current window height */
X case '+': win_setheight(curwin->w_height + (int)Prenum1);
X break;
X
X/* decrease current window height */
X case '-': win_setheight(curwin->w_height - (int)Prenum1);
X break;
X
X/* set current window height */
X case Ctrl('_'):
X case '_': win_setheight(Prenum ? (int)Prenum : 9999);
X break;
X
X/* jump to tag and split window if tag exists */
X case ']':
X case Ctrl(']'):
X VIsual.lnum = 0; /* stop Visual mode */
X postponed_split = TRUE;
X stuffcharReadbuff(Ctrl(']'));
X break;
X
X/* edit file name under cursor in a new window */
X case 'f':


X case Ctrl('F'):

X VIsual.lnum = 0; /* stop Visual mode */
X ptr = file_name_at_cursor();
X if (ptr == NULL)


X beep();
X else
X {

X stuffReadbuff((char_u *) ":split ");
X stuffReadbuff(ptr);


X stuffReadbuff((char_u *) "\n");

X free(ptr);
X }
X break;
X
X default: beep();


X break;
X }
X}
X

X/*
X * split the current window, implements CTRL-W s and :split
X *
X * new_height is the height for the new window, 0 to make half of current height
X * redraw is TRUE when redraw now


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xwin_split(new_height, redraw)
X long new_height;
X int redraw;
X{
X WIN *wp;
X linenr_t lnum;
X int h;
X int i;
X int need_status;
X int do_equal = (p_ea && new_height == 0);
X int needed;
X int available;
X
X /* add a status line when p_ls == 1 and splitting the first window */
X if (lastwin == firstwin && p_ls == 1 && curwin->w_status_height == 0)
X need_status = STATUS_HEIGHT;
X else
X need_status = 0;
X
X/*
X * check if we are able to split the current window and compute its height
X */
X available = curwin->w_height;
X needed = 2 * MIN_ROWS + STATUS_HEIGHT + need_status;
X if (p_ea)
X {
X for (wp = firstwin; wp != NULL; wp = wp->w_next)
X if (wp != curwin)
X {
X available += wp->w_height;
X needed += MIN_ROWS;
X }
X }
X if (available < needed)
X {
X EMSG(e_noroom);
X return FAIL;
X }
X if (need_status)
X {
X curwin->w_status_height = STATUS_HEIGHT;
X curwin->w_height -= STATUS_HEIGHT;
X }
X if (new_height == 0)
X new_height = curwin->w_height / 2;
X
X if (new_height > curwin->w_height - MIN_ROWS - STATUS_HEIGHT)
X new_height = curwin->w_height - MIN_ROWS - STATUS_HEIGHT;
X
X if (new_height < MIN_ROWS)
X new_height = MIN_ROWS;
X
X /* if it doesn't fit in the current window, need win_equal() */
X if (curwin->w_height - new_height - STATUS_HEIGHT < MIN_ROWS)
X do_equal = TRUE;
X/*
X * allocate new window structure and link it in the window list
X */
X if (p_sb) /* new window below current one */
X wp = win_alloc(curwin);
X else
X wp = win_alloc(curwin->w_prev);
X if (wp == NULL)
X return FAIL;
X/*
X * compute the new screen positions
X */
X wp->w_height = new_height;
X win_comp_scroll(wp);
X curwin->w_height -= new_height + STATUS_HEIGHT;
X win_comp_scroll(curwin);
X if (p_sb) /* new window below current one */
X {
X wp->w_winpos = curwin->w_winpos + curwin->w_height + STATUS_HEIGHT;
X wp->w_status_height = curwin->w_status_height;
X curwin->w_status_height = STATUS_HEIGHT;
X }
X else /* new window above current one */
X {
X wp->w_winpos = curwin->w_winpos;
X wp->w_status_height = STATUS_HEIGHT;
X curwin->w_winpos = wp->w_winpos + wp->w_height + STATUS_HEIGHT;
X }
X/*
X * make the contents of the new window the same as the current one
X */
X wp->w_buffer = curbuf;
X curbuf->b_nwindows++;
X wp->w_cursor = curwin->w_cursor;
X wp->w_row = curwin->w_row;
X wp->w_col = curwin->w_col;
X wp->w_virtcol = curwin->w_virtcol;
X wp->w_curswant = curwin->w_curswant;
X wp->w_set_curswant = curwin->w_set_curswant;
X wp->w_empty_rows = curwin->w_empty_rows;
X wp->w_leftcol = curwin->w_leftcol;
X wp->w_pcmark = curwin->w_pcmark;
X wp->w_prev_pcmark = curwin->w_prev_pcmark;
X
X wp->w_arg_idx = curwin->w_arg_idx;
X /*
X * copy tagstack and options from existing window
X */
X for (i = 0; i < curwin->w_tagstacklen; i++)
X {
X wp->w_tagstack[i].fmark = curwin->w_tagstack[i].fmark;
X wp->w_tagstack[i].tagname = strsave(curwin->w_tagstack[i].tagname);
X }
X wp->w_tagstackidx = curwin->w_tagstackidx;
X wp->w_tagstacklen = curwin->w_tagstacklen;
X win_copy_options(curwin, wp);
X/*
X * Both windows need redrawing
X */


X wp->w_redr_type = NOT_VALID;

X wp->w_redr_status = TRUE;

X curwin->w_redr_type = NOT_VALID;
X curwin->w_redr_status = TRUE;
X/*
X * Cursor is put in middle of window in both windows
X */
X if (wp->w_height < curwin->w_height) /* use smallest of two heights */
X h = wp->w_height;
X else
X h = curwin->w_height;
X h >>= 1;
X for (lnum = wp->w_cursor.lnum; lnum > 1; --lnum)
X {
X h -= plines(lnum);
X if (h <= 0)
X break;
X }
X wp->w_topline = lnum;
X curwin->w_topline = lnum;
X/*
X * make the new window the current window and redraw
X */
X if (do_equal)
X win_equal(wp, FALSE);
X win_enter(wp, FALSE);
X if (redraw)
X updateScreen(NOT_VALID);


X return OK;
X}
X
X/*

X * make 'count' windows on the screen
X * return actual number of windows on the screen
X * called when there is just one window, filling the whole screen.
X */
X int
Xmake_windows(count)
X int count;
X{
X int maxcount;
X int todo;
X int p_sb_save;
X
X/*
X * each window needs at least MIN_ROWS lines and a status line
X */
X maxcount = (curwin->w_height + curwin->w_status_height) /
X (MIN_ROWS + STATUS_HEIGHT);
X if (count > maxcount)
X count = maxcount;
X
X /*
X * add status line now, otherwise first window will be too big
X */
X if ((p_ls == 2 || (count > 1 && p_ls == 1)) && curwin->w_status_height == 0)
X {
X curwin->w_status_height = STATUS_HEIGHT;
X curwin->w_height -= STATUS_HEIGHT;
X }
X
X/*
X * set 'splitbelow' off for a moment, don't what that now
X */
X p_sb_save = p_sb;
X p_sb = FALSE;
X /* todo is number of windows left to create */
X for (todo = count - 1; todo > 0; --todo)
X if (win_split((long)(curwin->w_height - (curwin->w_height - todo
X * STATUS_HEIGHT) / (todo + 1) - STATUS_HEIGHT), FALSE) == FAIL)
X break;
X p_sb = p_sb_save;
X
X /* return actual number of windows */
X return (count - todo);
X}
X
X/*
X * Exchange current and next window


X */
X static void

Xwin_exchange(Prenum)
X long Prenum;
X{
X WIN *wp;
X WIN *wp2;
X int temp;
X
X if (lastwin == firstwin) /* just one window */
X {
X beep();
X return;
X }
X
X/*
X * find window to exchange with


X */
X if (Prenum)
X {

X wp = firstwin;
X while (wp != NULL && --Prenum > 0)


X wp = wp->w_next;

X }
X else if (curwin->w_next != NULL) /* Swap with next */
X wp = curwin->w_next;
X else /* Swap last window with previous */
X wp = curwin->w_prev;
X
X if (wp == curwin || wp == NULL)
X return;
X
X/*
X * 1. remove curwin from the list. Remember after which window it was in wp2
X * 2. insert curwin before wp in the list
X * if wp != wp2
X * 3. remove wp from the list
X * 4. insert wp after wp2
X * 5. exchange the status line height
X */
X wp2 = curwin->w_prev;
X win_remove(curwin);
X win_append(wp->w_prev, curwin);
X if (wp != wp2)
X {
X win_remove(wp);
X win_append(wp2, wp);
X }
X temp = curwin->w_status_height;
X curwin->w_status_height = wp->w_status_height;
X wp->w_status_height = temp;
X
X win_comp_pos(); /* recompute window positions */
X
X win_enter(wp, TRUE);
X cursupdate();
X updateScreen(CLEAR);
X}
X
X/*
X * rotate windows: if upwards TRUE the second window becomes the first one
X * if upwards FALSE the first window becomes the second one


X */
X static void

Xwin_rotate(upwards, count)
X int upwards;
X int count;
X{
X WIN *wp;
X int height;
X
X if (firstwin == lastwin) /* nothing to do */
X {
X beep();
X return;


X }
X while (count--)
X {

X if (upwards) /* first window becomes last window */
X {
X wp = firstwin;
X win_remove(wp);
X win_append(lastwin, wp);
X wp = lastwin->w_prev; /* previously last window */
X }
X else /* last window becomes first window */
X {
X wp = lastwin;
X win_remove(lastwin);
X win_append(NULL, wp);
X wp = firstwin; /* previously last window */
X }
X /* exchange status height of old and new last window */
X height = lastwin->w_status_height;
X lastwin->w_status_height = wp->w_status_height;
X wp->w_status_height = height;
X
X /* recompute w_winpos for all windows */
X (void) win_comp_pos();
X }
X
X cursupdate();
X updateScreen(CLEAR);
X}
X
X/*
X * make all windows the same height
X */
X void
Xwin_equal(next_curwin, redraw)
X WIN *next_curwin; /* pointer to current window to be */
X int redraw;
X{
X int total;
X int less;
X int wincount;
X int winpos;
X int temp;
X WIN *wp;
X int new_height;
X
X/*
X * count the number of lines available
X */
X total = 0;
X wincount = 0;


X for (wp = firstwin; wp; wp = wp->w_next)

X {
X total += wp->w_height - MIN_ROWS;
X wincount++;
X }
X
X/*
X * if next_curwin given and 'winheight' set, make next_curwin p_wh lines
X */
X if (next_curwin != NULL && p_wh)
X {
X if (p_wh - MIN_ROWS > total) /* all lines go to current window */
X less = total;
X else
X {
X less = p_wh - MIN_ROWS - total / wincount;
X if (less < 0)
X less = 0;
X }
X }
X else
X less = 0;
X
X
X/*
X * spread the available lines over the windows
X */
X winpos = 0;
X for (wp = firstwin; wp != NULL; wp = wp->w_next)
X {
X if (wp == next_curwin && less)
X {
X less = 0;
X temp = p_wh - MIN_ROWS;
X if (temp > total)
X temp = total;
X }
X else
X temp = (total - less + (wincount >> 1)) / wincount;
X new_height = MIN_ROWS + temp;
X if (wp->w_winpos != winpos || wp->w_height != new_height)
X {


X wp->w_redr_type = NOT_VALID;

X wp->w_redr_status = TRUE;

X }
X wp->w_winpos = winpos;
X wp->w_height = new_height;
X win_comp_scroll(wp);
X total -= temp;
X --wincount;
X winpos += wp->w_height + wp->w_status_height;
X }
X if (redraw)
X {
X cursupdate();
X updateScreen(CLEAR);
X }
X}
X
X/*
X * close current window
X * If "free_buf" is TRUE related buffer may be freed.
X *
X * called by :quit, :close, :xit, :wq and findtag()
X */
X void
Xclose_window(free_buf)
X int free_buf;
X{
X WIN *wp;
X
X if (lastwin == firstwin)
X {
X EMSG("Cannot close last window");
X return;
X }
X
X/*
X * Close the link to the buffer.
X */
X close_buffer(curbuf, free_buf, FALSE);
X
X/*
X * Remove the window.
X */
X if (curwin->w_prev == NULL) /* freed space goes to next window */
X {
X wp = curwin->w_next;
X wp->w_winpos = curwin->w_winpos;
X }
X else /* freed space goes to previous window */
X wp = curwin->w_prev;
X wp->w_height += curwin->w_height + curwin->w_status_height;
X
X win_free(curwin);
X curwin = NULL;
X if (p_ea)
X win_equal(wp, FALSE);
X win_enter(wp, FALSE);
X /*
X * if last window has status line now and we don't want one,
X * remove the status line
X */
X if (lastwin->w_status_height &&
X (p_ls == 0 || (p_ls == 1 && firstwin == lastwin)))
X {
X lastwin->w_height += lastwin->w_status_height;
X lastwin->w_status_height = 0;
X win_comp_scroll(lastwin);
X }
X win_comp_scroll(curwin);
X updateScreen(NOT_VALID);
X}
X
X/*
X * close all windows except current one
X * buffers in the windows become hidden
X *
X * called by :only and do_arg_all();
X */
X void
Xclose_others(message)
X int message;
X{
X WIN *wp;
X WIN *nextwp;
X


X if (lastwin == firstwin)

X {
X if (message)
X EMSG("Already only one window");
X return;
X }
X
X for (wp = firstwin; wp != NULL; wp = nextwp)
X {
X nextwp = wp->w_next;
X if (wp == curwin) /* don't close current window */
X continue;
X /*
X * Close the link to the buffer.
X */
X close_buffer(wp->w_buffer, FALSE, FALSE);
X
X /*
X * Remove the window. All lines go to current window.
X */
X curwin->w_height += wp->w_height + wp->w_status_height;
X
X win_free(wp);
X }
X /*
X * if current window has status line and we don't want one,
X * remove the status line
X */
X if (curwin->w_status_height && p_ls != 2)
X {
X curwin->w_height += curwin->w_status_height;
X curwin->w_status_height = 0;
X }
X curwin->w_winpos = 0; /* put current window at top of the screen */
X win_comp_scroll(curwin);
X if (message)
X updateScreen(NOT_VALID);
X}
X
X/*
X * init the cursor in the window
X *
X * called when a new file is being edited
X */
X void
Xwin_init(wp)
X WIN *wp;
X{


X wp->w_redr_type = NOT_VALID;

X wp->w_cursor.lnum = 1;
X wp->w_curswant = wp->w_cursor.col = 0;
X wp->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */
X wp->w_pcmark.col = 0;
X wp->w_prev_pcmark.lnum = 0;
X wp->w_prev_pcmark.col = 0;
X wp->w_topline = 1;
X wp->w_botline = 2;
X}
X
X/*
X * make window wp the current window
X */
X void
Xwin_enter(wp, undo_sync)
X WIN *wp;
X int undo_sync;
X{
X if (wp == curwin) /* nothing to do */
X return;
X
X /* sync undo before leaving the current buffer */
X if (undo_sync && curbuf != wp->w_buffer)
X u_sync();
X if (curwin != NULL)
X prevwin = curwin; /* remember for CTRL-W p */
X curwin = wp;
X curbuf = wp->w_buffer;
X maketitle();
X /* set window height to desired minimal value */
X if (p_wh && curwin->w_height < p_wh)
X win_setheight((int)p_wh);
X}
X
X/*
X * allocate a window structure and link it in the window list
X */
X WIN *
Xwin_alloc(after)
X WIN *after;
X{
X WIN *new;
X
X/*
X * allocate window structure and linesizes arrays
X */
X new = (WIN *)alloc((unsigned)sizeof(WIN));
X if (new)
X {
X/*
X * most stucture members have to be zero
X */
X memset((char *)new, 0, sizeof(WIN));
X/*
X * link the window in the window list
X */
X win_append(after, new);
X
X win_alloc_lsize(new);
X
X /* position the display and the cursor at the top of the file. */
X new->w_topline = 1;
X new->w_cursor.lnum = 1;
X }
X return new;
X}
X
X/*
X * remove window 'wp' from the window list and free the structure
X */
X void
Xwin_free(wp)
X WIN *wp;
X{
X if (prevwin == wp)
X prevwin = NULL;
X win_free_lsize(wp);
X win_remove(wp);
X free(wp);


X}
X
X static void

Xwin_append(after, wp)
X WIN *after, *wp;
X{
X WIN *before;
X
X if (after == NULL) /* after NULL is in front of the first */
X before = firstwin;
X else
X before = after->w_next;
X
X wp->w_next = before;
X wp->w_prev = after;
X if (after == NULL)
X firstwin = wp;
X else
X after->w_next = wp;
X if (before == NULL)
X lastwin = wp;
X else
X before->w_prev = wp;
X}
X
X/*
X * remove window from the window list


X */
X static void

Xwin_remove(wp)
X WIN *wp;
X{
X if (wp->w_prev)
X wp->w_prev->w_next = wp->w_next;
X else
X firstwin = wp->w_next;
X if (wp->w_next)
X wp->w_next->w_prev = wp->w_prev;
X else
X lastwin = wp->w_prev;
X}
X
X/*
X * allocate lsize arrays for a window


X * return FAIL for failure, OK for success
X */
X int

Xwin_alloc_lsize(wp)
X WIN *wp;
X{


X wp->w_lsize_valid = 0;

X wp->w_lsize_lnum = (linenr_t *) malloc((size_t) (Rows * sizeof(linenr_t)));
X wp->w_lsize = (char_u *)malloc((size_t) Rows);
X if (wp->w_lsize_lnum == NULL || wp->w_lsize == NULL)
X {
X win_free_lsize(wp); /* one of the two may have worked */
X wp->w_lsize_lnum = NULL;
X wp->w_lsize = NULL;


X return FAIL;
X }
X return OK;

X}
X
X/*
X * free lsize arrays for a window
X */
X void
Xwin_free_lsize(wp)
X WIN *wp;
X{
X free(wp->w_lsize_lnum);
X free(wp->w_lsize);
X}
X
X/*
X * call this fuction whenever Rows changes value
X */
X void
Xscreen_new_rows()
X{
X WIN *wp;
X int extra_lines;
X
X if (firstwin == NULL) /* not initialized yet */
X return;
X/*
X * the number of extra lines is the difference between the position where
X * the command line should be and where it is now
X */
X compute_cmdrow();
X extra_lines = Rows - p_ch - cmdline_row;
X if (extra_lines < 0) /* reduce windows height */
X {
X for (wp = lastwin; wp; wp = wp->w_prev)
X {
X if (wp->w_height - MIN_ROWS < -extra_lines)
X {
X extra_lines += wp->w_height - MIN_ROWS;
X wp->w_height = MIN_ROWS;
X win_comp_scroll(wp);
X }
X else
X {
X wp->w_height += extra_lines;
X win_comp_scroll(wp);
X break;
X }
X }
X (void)win_comp_pos(); /* compute w_winpos */
X }
X else if (extra_lines > 0) /* increase height of last window */
X {
X lastwin->w_height += extra_lines;
X win_comp_scroll(lastwin);
X }
X
X compute_cmdrow();
X}
X
X/*
X * update the w_winpos field for all windows
X * returns the row just after the last window


X */
X static int

Xwin_comp_pos()
X{
X WIN *wp;
X int row;


X
X row = 0;

X for (wp = firstwin; wp != NULL; wp = wp->w_next)
X {
X if (wp->w_winpos != row) /* if position changes, redraw */
X {
X wp->w_winpos = row;


X wp->w_redr_type = NOT_VALID;

X wp->w_redr_status = TRUE;

X }
X row += wp->w_height + wp->w_status_height;
X }
X return row;
X}
X
X/*
X * set current window height
X */
X void
Xwin_setheight(height)
X int height;
X{
X WIN *wp;
X int room; /* total number of lines available */
X int take; /* number of lines taken from other windows */
X int room_cmdline; /* lines available from cmdline */
X int row;
X
X if (height < MIN_ROWS) /* need at least some lines */
X height = MIN_ROWS;
X/*
X * compute the room we have from all the windows
X */
X room = MIN_ROWS; /* count the MIN_ROWS for the current window */
X for (wp = firstwin; wp != NULL; wp = wp->w_next)
X room += wp->w_height - MIN_ROWS;
X/*
X * compute the room available from the command line
X */
X room_cmdline = Rows - p_ch - cmdline_row;
X/*
X * limit new height to the room available
X */
X if (height > room + room_cmdline) /* can't make it that large */
X height = room + room_cmdline; /* use all available room */
X/*
X * compute the number of lines we will take from the windows (can be negative)
X */
X take = height - curwin->w_height;
X if (take == 0) /* no change, nothing to do */
X return;
X
X if (take > 0)
X {
X take -= room_cmdline; /* use lines from cmdline first */
X if (take < 0)
X take = 0;
X }
X/*
X * set the current window to the new height
X */
X curwin->w_height = height;
X win_comp_scroll(curwin);
X/*
X * take lines from the windows below the current window
X */
X for (wp = curwin->w_next; wp != NULL && take != 0; wp = wp->w_next)
X {
X if (wp->w_height - take < MIN_ROWS)
X {
X take -= wp->w_height - MIN_ROWS;
X wp->w_height = MIN_ROWS;
X }
X else
X {
X wp->w_height -= take;
X take = 0;
X }
X win_comp_scroll(wp); /* recompute p_scroll */
X wp->w_redr_type = NOT_VALID; /* need to redraw this window */
X wp->w_redr_status = TRUE;
X }
X/*
X * take lines from the windows above the current window
X */
X for (wp = curwin->w_prev; wp != NULL && take != 0; wp = wp->w_prev)
X {
X if (wp->w_height - take < MIN_ROWS)
X {
X take -= wp->w_height - MIN_ROWS;
X wp->w_height = MIN_ROWS;
X }
X else
X {
X wp->w_height -= take;
X take = 0;
X }
X win_comp_scroll(wp); /* recompute p_scroll */
X wp->w_redr_type = NOT_VALID; /* need to redraw this window */
X wp->w_redr_status = TRUE;
X }
X
X/* recompute the window positions */
X row = win_comp_pos();
X
X/*
X * If there is extra space created between the last window and the command line,
X * clear it.
X */
X screen_fill(row, cmdline_row, 0, (int)Columns, ' ', ' ');
X cmdline_row = row;
X


X updateScreen(NOT_VALID);
X}
X
X void

Xwin_comp_scroll(wp)
X WIN *wp;
X{
X wp->w_p_scroll = (wp->w_height >> 1);
X if (wp->w_p_scroll == 0)
X wp->w_p_scroll = 1;
X}
X
X/*
X * command_height: called whenever p_ch has been changed
X */
X void
Xcommand_height()
X{
X int current;
X
X current = Rows - cmdline_row;
X if (current > p_ch) /* p_ch got smaller */
X lastwin->w_height += current - p_ch;
X else /* p_ch got bigger */
X {
X if (lastwin->w_height - (p_ch - current) < MIN_ROWS)
X {
X emsg(e_noroom);
X p_ch = lastwin->w_height - MIN_ROWS + current;
X }
X lastwin->w_height -= p_ch - current;
X /* clear the lines added to cmdline */
X screen_fill((int)(Rows - p_ch), (int)Rows, 0, (int)Columns, ' ', ' ');
X }
X win_comp_scroll(lastwin);
X cmdline_row = Rows - p_ch;
X lastwin->w_redr_type = NOT_VALID;
X lastwin->w_redr_status = TRUE;
X redraw_cmdline = TRUE;
X}
X
X void
Xlast_status()
X{
X if (lastwin->w_status_height)
X {
X /* remove status line */
X if (p_ls == 0 || (p_ls == 1 && firstwin == lastwin))
X {
X lastwin->w_status_height = 0;
X lastwin->w_height++;
X win_comp_scroll(lastwin);
X lastwin->w_redr_status = TRUE;
X }
X }
X else
X {
X /* add status line */
X if (p_ls == 2 || (p_ls == 1 && firstwin != lastwin))
X {
X if (lastwin->w_height <= MIN_ROWS) /* can't do it */
X emsg(e_noroom);
X else
X {
X lastwin->w_status_height = 1;
X lastwin->w_height--;
X win_comp_scroll(lastwin);
X lastwin->w_redr_status = TRUE;


X }
X }
X }
X}
X
X/*

X * file_name_at_cursor()
X *
X * Return the name of the file under (or to the right of) the cursor. The
X * p_path variable is searched if the file name does not start with '/'.
X * The string returned has been alloc'ed and should be freed by the caller.
X * NULL is returned if the file name or file is not found.


X */
X char_u *

Xfile_name_at_cursor()
X{
X char_u *ptr;
X char_u *dir;
X char_u *file_name;
X char_u save_char;
X int col;
X int len;
X
X /* characters in a file name besides alfa-num */
X#ifdef UNIX
X char_u *file_chars = (char_u *)"/.-_+,~$";
X#endif
X#ifdef AMIGA
X char_u *file_chars = (char_u *)"/.-_+,$:";
X#endif
X#ifdef MSDOS
X char_u *file_chars = (char_u *)"/.-_+,$\\:";
X#endif
X
X ptr = ml_get(curwin->w_cursor.lnum);


X col = curwin->w_cursor.col;
X

X /* search forward for what could be the start of a file name */
X while (!isalnum((char) ptr[col]) && STRCHR(file_chars, ptr[col]) == NULL)
X ++col;
X if (ptr[col] == NUL) /* nothing found */
X return NULL;
X
X /* search backward for char that cannot be in a file name */
X while (col >= 0 &&
X (isalnum((char) ptr[col]) || STRCHR(file_chars, ptr[col]) != NULL))
X --col;
X ptr += col + 1;
X col = 0;
X
X /* search forward for a char that cannot be in a file name */


X while (ptr[col] != NUL

X && (isalnum((char) ptr[col]) || STRCHR(file_chars, ptr[col]) != NULL))
X ++col;
X
X /* copy file name into NameBuff, expanding environment variables */
X save_char = ptr[col];
X ptr[col] = NUL;
X expand_env(ptr, NameBuff, MAXPATHL);
X ptr[col] = save_char;
X
X if (isFullName(NameBuff)) /* absolute path */
X {
X if ((file_name = strsave(NameBuff)) == NULL)
X return NULL;
X if (getperm(file_name) >= 0)
X return file_name;
X }
X else /* relative path, use 'path' option */
X {
X if ((file_name = alloc((int)(STRLEN(p_path) + STRLEN(NameBuff) + 2))) == NULL)
X return NULL;
X dir = p_path;


X for (;;)
X {

X skipspace(&dir);
X for (len = 0; dir[len] != NUL && dir[len] != ' '; len++)
X ;
X if (len == 0)
X break;
X if (len == 1 && dir[0] == '.') /* current dir */
X STRCPY(file_name, NameBuff);
X else
X {
X STRNCPY(file_name, dir, (size_t)len);
X#ifdef AMIGA /* Amiga doesn't like c:/file */
X if (file_name[len - 1] != ':')
X#endif
X file_name[len] = '/';
X STRCPY(file_name + len + 1, NameBuff);
X }
X if (getperm(file_name) >= 0)
X return file_name;
X dir += len;
X }
X }
X free(file_name); /* file doesn't exist */
X return NULL;
X}
END_OF_FILE
if test 25721 -ne `wc -c <'vim/src/window.c'`; then
echo shar: \"'vim/src/window.c'\" unpacked with wrong size!
fi
# end of 'vim/src/window.c'
fi
if test -f 'vim/tutor/tutor' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tutor/tutor'\"
else
echo shar: Extracting \"'vim/tutor/tutor'\" \(28799 characters\)
sed "s/^X//" >'vim/tutor/tutor' <<'END_OF_FILE'
X*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
X* W e l c o m e t o V I T u t o r - V e r s i o n 1 . 2 *
X*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
X **************
X * Lesson 1.0 *
X **************
X
X Vim is a very powerful editor that has many commands, too many to
X explain in a tutor such as this. This tutor is designed to describe
X enough of the commands that you will be able to easily use Vim as
X an all-purpose editor.
X
X The approximate time required to complete the tutor is 25-30 minutes,
X depending upon how much time is spent with experimentation.
X
X It is important to remember that this tutor is set up to teach by
X use. That means that the student needs to execute the commands to
X learn them properly.
X
X Now, make sure that your Shift-Lock key is NOT depressed and press
X the j key enough times to move the cursor so that Lesson 1.1
X completely fills the screen.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 1.1 *
X **************
X =====>>>>> MOVING THE CURSOR <<<<<=====
X
X ** To move the cursor, press the h,j,k,l keys as indicated. **
X ^
X k
X < h l >
X j
X v
X 1. Move the cursor around the screen until you are comfortable.
X
X 2. Hold down the down key (j) until it repeats.
X---> Now you know how to move to the next lesson.
X
X 3. Using the down key, move to Lesson 1.2.
X
XNote: If you are ever unsure about something you typed, press <ESC> to place
X you in Command Mode. Then retype the command you wanted.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 1.2 *
X **************
X =====>>>>> ENTERING AND EXITING VIM <<<<<=====
X
X !! NOTE: Before executing any of the steps below, read this entire lesson!!
X
X 1. Press the <ESC> key (to make sure you are in Command Mode).
X
X 2. Type :q! <RETURN>.
X
X---> This exits the editor WITHOUT saving any changes you have made.
X If you want to save the changes and exit type :wq <RETURN>
X
X 3. When you see the shell prompt (%) type: vim tutor <RETURN>.
X
X---> 'vim' means enter the vim editor, 'tutor' is the file you wish to edit.
X
X 4. If you have these steps memorized and are confident, execute steps
X 1 through 3 to exit and re-enter the editor. Then cursor down to
X Lesson 1.3.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 1.3 *
X **************
X =====>>>>> TEXT EDITING - DELETION <<<<<=====
X
X** While in Command Mode press x to delete the character under the cursor. **
X
X 1. Move the cursor to the line below marked --->.
X
X 2. To fix the errors, move the cursor until it is on top of the
X character to be deleted.
X
X 3. Press the x key to delete the unwanted character.
X
X 4. Repeat steps 2 through 4 until the sentence is correct.
X
X---> The ccow jumpedd ovverr thhe mooon.
X
X 5. Now that the line is correct, go on to Lesson 1.4.
X
XNOTE: As you go through this tutor, do not try to memorize, learn by usage.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 1.4 *
X **************
X =====>>>>> TEXT EDITING - INSERTION <<<<<=====
X
X ** While in Command Mode press i to insert text. **
X
X 1. Move the cursor to the first line below marked --->.
X
X 2. To make the first line the same as the second, move the cursor on top
X of the first character AFTER where the text is to be inserted.
X
X 3. Press i and type in the necessary additions.
X
X 4. As each error is fixed press <ESC> to return to Command Mode.
X Repeat steps 2 through 4 to correct the sentence.
X
X---> There is text misng this .
X---> There is some text missing from this line.
X
X 5. When you are comfortable inserting text move to the summary below.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 1 SUMMARY *
X ********************
X
X 1. The cursor is moved using either the arrow keys or the h,j,k,l keys.
X h (left) j (down) k (up) l (right)
X
X 2. To enter Vim (from the % prompt) type: % vim FILENAME <RETURN>
X
X 3. To exit Vim type: <ESC> :q! <RETURN>
X OR type: <ESC> :wq <RETURN> to save the changes.
X
X 4. To delete a character under the cursor in Command Mode type: x
X
X 5. To insert text at the cursor while in Command Mode type:
X i type in text <ESC>
X
XNOTE: Pressing <ESC> will place you in Command Mode or will cancel
X an unwanted and partially completed command.
X
XNow continue with Lesson 2.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 2.1 *
X **************
X =====>>>>> DELETION COMMANDS <<<<<=====
X
X ** Type dw to delete to the end of a word. **
X
X 1. Press <ESC> to make sure you are in Command Mode.
X
X 2. Move the cursor to the line below marked --->.
X
X 3. Move the cursor to the beginning of a word that needs to be deleted.
X
X 4. Type dw to make the word disappear.
X
X NOTE: The letters dw will appear on the last line of the screen as you type
X them. If you typed something wrong, press <ESC> and start over.
X
X---> There are a some words fun that don't belong paper in this sentence.
X
X 5. Repeat steps 3 and 4 until the sentence is correct and go to Lesson 2.2.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 2.2 *
X **************
X =====>>>>> MORE DELETION COMMANDS <<<<<=====
X
X ** Type d$ to delete to the end of the line. **
X
X 1. Press <ESC> to make sure you are in Command Mode.
X
X 2. Move the cursor to the line below marked --->.
X
X 3. Move the cursor to the end of the correct line (AFTER the first . ).
X
X 4. Type d$ to delete to the end of the line.
X
X---> Somebody typed the end of this line twice. end of this line twice.
X
X
X 5. Move on to Lesson 2.3 to understand what is happening.
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 2.3 *
X **************
X =====>>>>> ON COMMANDS AND OBJECTS <<<<<=====
X
X The format for the d delete command is as follows:
X
X [number] d object OR d [number] object
X Where:
X number - is how many times to execute the command (optional, default=1).
X d - is the command to delete.
X object - is what the command will operate on (listed below).
X
X A short list of objects:
X w - from the cursor to the end of the word, including the space.
X e - from the cursor to the end of the word, NOT including the space.
X $ - from the cursor to the end of the line.
X
XNOTE: For the adventurous, pressing just the object while in Command Mode
X without a command will move the cursor as specified in the object list.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 2.4 *
X **************
X =====>>>>> AN EXCEPTION TO 'COMMAND-OBJECT' <<<<<=====
X
X ** Type dd to delete a whole line. **
X
X Due to the frequency of whole line deletion, the designers of Vim decided
X it would be easier to simply type two d's in a row to delete a line.
X
X 1. Move the cursor to the second line in the phrase below.
X
X 2. Type dd to delete the line.
X
X 3. Now move to the fourth line.
X
X 4. Type 2dd (remember number-command-object) to delete the two lines.
X
X 1) Roses are red,
X 2) Mud is fun,
X 3) Violets are blue,
X 4) I have a car,
X 5) Clocks tell time,
X 6) Sugar is sweet
X 7) And so are you.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 2.5 *
X **************
X =====>>>>> THE UNDO COMMAND <<<<<=====
X
X ** Press u to undo the last commands, U to fix a whole line. **
X
X 1. Move the cursor to the line below marked ---> and place it on the
X first error.
X 2. Type x to delete the first unwanted character.
X 3. Now type u to undo the last command executed.
X 4. This time fix all the errors on the line using the x command.
X 5. Now type a capital U to return the line to its original state.
X 6. Now type u a few times to undo the U and preceding commands.
X 7. Now type CTRL-R (keeping CTRL key pressed while hitting R) a few times
X to redo the commands (undo the undo's).
X
X---> Fiix the errors oon thhis line and reeplace them witth undo.
X
X 8. These are very useful commands. Now move on to the Lesson 2 Summary.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 2 SUMMARY *
X ********************
X
X 1. To delete from the cursor to the end of a word type: dw
X
X 2. To delete from the cursor to the end of a line type: d$
X
X 3. To delete a whole line type: dd
X
X 4. The format for a command in command mode is:
X
X [number] command object OR command [number] object
X where:
X number - is how many times to repeat the command
X command - is what to do, such as d for delete
X object - is what the command should act upon, such as w (word),
X $ (to the end of line), etc.
X
X 5. To undo previous actions, type: u (lowercase u)
X To undo all the changes on a line type: U (capital U)
X To undo the undo's type: CTRL-R
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 3.1 *
X **************
X =====>>>>> THE PUT COMMAND <<<<<=====
X
X ** Type p to put the last deletion after the cursor. **
X
X 1. Move the cursor to the first line in the set below.
X
X 2. Type dd to delete the line and store it in Vim's buffer.
X
X 3. Move the cursor to the line ABOVE where the deleted line should go.
X
X 4. While in Command Mode, type p to replace the line.
X
X 5. Repeat steps 2 through 4 to put all the lines in correct order.
X
X d) Can you learn too?
X b) Violets are blue,
X c) Intelligence is learned,
X a) Roses are red,
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 3.2 *
X **************
X =====>>>>> THE REPLACE COMMAND <<<<<=====
X
X ** Type r and a character to replace the character under the cursor. **
X
X 1. Move the cursor to the first line below marked --->.
X
X 2. Move the cursor so that it is on top of the first error.
X
X 3. Type r and then the character which should replace the error.
X
X 4. Repeat steps 2 and 3 until the first line is correct.
X
X---> Whan this lime was tuoed in, someone presswd some wrojg keys!
X---> When this line was typed in, someone pressed some wrong keys!
X
X 5. Now move on to Lesson 3.2.
X
XNOTE: Remember that you should be learning by use, not memorization.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 3.3 *
X **************
X =====>>>>> THE CHANGE COMMAND <<<<<=====
X
X ** To change part or all of a word, type cw . **
X
X 1. Move the cursor to the first line below marked --->.
X
X 2. Place the cursor on the u in lubw.
X
X 3. Type cw and the correct word (in this case, type 'ine'.)
X
X 4. Press <ESC> and move to the next error (the first character to be changed.)
X
X 5. Repeat steps 3 and 4 until the first sentence is the same as the second.
X
X---> This lubw has a few wptfd that mrrf changing usf the change command.
X---> This line has a few words that need changing using the change command.
X
XNotice that cw not only replaces the word, but also places you in insert.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 3.4 *
X **************
X =====>>>>> MORE CHANGES USING c <<<<<=====
X
X ** The change command is used with the same objects as delete. **
X
X 1. The change command works in the same way as delete. The format is:
X
X [number] c object OR c [number] object
X
X 2. The objects are also the same, such as w (word), $ (end of line), etc.
X
X 3. Move to the first line below marked --->.
X
X 4. Move the cursor to the first error.
X
X 5. Type c$ to make the rest of the line like the second and press <ESC>.
X
X---> The end of this line needs some help to make it like the second.
X---> The end of this line needs to be corrected using the c$ command.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 3 SUMMARY *
X ********************
X
X 1. To replace text that has already been deleted, type p . This Puts the
X deleted text AFTER the cursor (if a line was deleted it will go on the
X line below the cursor).
X
X 2. To replace the character under the cursor, type r and then the
X character which will replace the original.
X
X 3. The change command allows you to change the specified object from the
X cursor to the end of the object. eg. Type cw to change from the
X cursor to the end of the word, c$ to change to the end of a line.
X
X 4. The format for change is:
X
X [number] c object OR c [number] object
X
XNow go on to the next lesson.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 4.1 *
X **************
X =====>>>>> LOCATION AND FILE STATUS <<<<<=====
X
X ** Type CTRL-g to show your location in the file and the file status.
X Type SHIFT-G to move to a line in the file. **
X
X Note: Read this entire lesson before executing any of the steps!!
X
X 1. Hold down the Ctrl key and press g . A status line will appear at the
X bottom of the page with the filename and the line you are on. Remember
X the line number for Step 3.
X
X 2. Press shift-G to move you to the bottom of the file.
X
X 3. Type in the number of the line you were on and then shift-G. This will
X return you to the line you were on when you first pressed Ctrl-g.
X (When you type in the numbers, they will NOT be displayed on the screen.)
X
X 4. If you feel confident to do this, execute steps 1 through 3.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 4.2 *
X **************
X =====>>>>> THE SEARCH COMMAND <<<<<=====
X
X ** Type / followed by a phrase to search for the phrase. **
X
X 1. In command mode type the / character. Notice that it and the cursor
X appear at the bottom of the screen as with the : command.
X
X 2. Now type 'errroor' <RETURN>. This is the word you want to search for.
X
X 3. To search for the same phrase again, simply type n .
X To search for the same phrase in the opposite direction, type Shift-N .
X
X 4. If you want to search for a phrase in the backwards direction, use the
X command ? instead of /.
X
X---> When the search reaches the end of the file it will continue at the start.
X
X "errroor" is not the way to spell error; errroor is an error.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 4.3 *
X **************
X =====>>>>> MATCHING PARENTHESES SEARCH <<<<<=====
X
X ** Type % to find a matching ),], or } . **
X
X 1. Place the cursor on any (, [, or { in the line below marked --->.
X
X 2. Now type the % character.
X
X 3. The cursor should be on the matching parenthesis or bracket.
X
X 4. Type % to move the cursor back to the first bracket (by matching).
X
X---> This ( is a test line with ('s, ['s ] and {'s } in it. ))
X
XNote: This is very useful in debugging a program with unmatched parentheses!
X
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 4.4 *
X **************
X =====>>>>> A WAY TO CHANGE ERRORS <<<<<=====
X
X ** Type :s/old/new/g to substitute 'new' for 'old'. **
X
X 1. Move the cursor to the line below marked --->.
X
X 2. Type :s/thee/the <RETURN> . Note that this command only changes the
X first occurrence on the line.
X
X 3. Now type :s/thee/the/g meaning substitute globally on the line.
X This changes all occurrences on the line.
X
X---> thee best time to see thee flowers is in thee spring.
X
X 4. To change every occurrence of a character string between two lines,
X type :#,#s/old/new/g where #,# are the numbers of the two lines.
X Type :%s/old/new/g to change every occurrence in the whole file.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 4 SUMMARY *
X ********************
X
X 1. Ctrl-g displays your location in the file and the file status.
X Shift-G moves to the end of the file. A line number followed
X by Shift-G moves to that line number.
X
X 2. Typing / followed by a phrase searches FORWARD for the phrase.
X Typing ? followed by a phrase searches BACKWARD for the phrase.
X After a search type n to find the next occurrence in the same direction
X or Shift-N to search in the opposite direction.
X
X 3. Typing % while the cursor is on a (,),[,],{, or } locates its
X matching pair.
X
X 4. To substitute new for the first old on a line type :s/old/new
X To substitute new for all 'old's on a line type :s/old/new/g
X To substitute phrases between two line #'s type :#,#s/old/new/g
X To substitute all occurrences in the file type :%s/old/new/g
X To ask for confirmation each time add 'c' :%s/old/new/gc
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 5.1 *
X **************
X =====>>>>> HOW TO EXECUTE AN AMIGA COMMAND <<<<<=====
X
X ** Type :! followed by an Amiga command to execute that command. **
X
X 1. Type the familiar command : to set the cursor at the bottom of the
X screen. This allows you to enter a command.
X
X 2. Now type the ! (exclamation point) character. This allows you to
X execute an Amiga shell command.
X
X 3. As an example type ls following the !. This will show you a listing
X of your directory, just as if you were at the % prompt.
X
X---> Note: It is possible to execute any shell command this way.
X
X
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 5.2 *
X **************
X =====>>>>> MORE ON WRITING FILES <<<<<=====
X
X ** To save the changes made to the file, type :w FILENAME. **
X
X 1. Type :!dir to get a listing of your directory.
X
X 2. Choose a filename that is not already in your area, such as TEST.
X
X 3. Now type: :w TEST (where TEST is the filename you chose.)
X
X 4. This saves the whole file (Vim Tutor) under the name TEST.
X To verify this, type :!dir again to see your directory
X
X---> Note that if you were to exit Vim and enter again with the filename TEST,
X the file would be an exact copy of the tutor when you saved it.
X
X 5. Now remove the file from your area by typing: :!delete TEST
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 5.3 *
X **************
X =====>>>>> A SELECTIVE WRITE COMMAND <<<<<=====
X
X ** To save part of the file, type :#,# w FILENAME **
X
X 1. Once again, type :!dir to obtain a listing of your directory and
X choose a suitable filename such as TEST.
X
X 2. Move the cursor to the top of this page and type Ctrl-g to find the
X number of that line. REMEMBER THIS NUMBER!
X
X 3. Now move to the bottom of the page and type Ctrl-g again. REMEMBER THIS
X LINE NUMBER ALSO!
X
X 4. To save ONLY a section to a file, type :#,# w TEST where #,# are
X the two numbers you remembered (top,bottom) and TEST is your filename.
X
X 5. Again, see that the file is there with :!dir but DO NOT remove it.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 5.4 *
X **************
X =====>>>>> RETRIEVING AND MERGING FILES <<<<<=====
X
X ** To insert the contents of a file, type :r FILENAME **
X
X 1. Type :!dir to make sure your TEST filename is present from before.
X
X 2. Place the cursor at the top of this page.
X
XNOTE: After executing Step 3 you will see Lesson 5.3. Then move DOWN to
X this lesson again.
X
X 3. Now retrieve your TEST file using the command :r TEST where TEST is
X the name of the file.
X
XNOTE: The file you retrieve is placed starting where the cursor is located.
X
X 4. To verify that a file was retrieved, cursor back and notice that there
X are now two copies of Lesson 5.3, the original and the file version.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 5 SUMMARY *
X ********************
X
X 1. :!command executes an Amiga system command.
X
X Some useful examples are:
X :!dir - shows a directory listing of your area.
X :!delete FILENAME - removes file FILENAME from your area.
X
X 2. :w FILENAME writes the current Vim file to disk with name FILENAME.
X
X 3. :#,# FILENAME saves the lines # through # in file FILENAME.
X
X 4. :r FILENAME retrieves disk file FILENAME and inserts it into the
X current file following the cursor position.


X
X
X
X
X

X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 6.1 *
X **************
X =====>>>>> THE OPEN COMMAND <<<<<=====
X
X ** Type o to open a line below the cursor and place you in insert mode. **
X
X 1. Move the cursor to the line below marked --->.
X
X 2. Type o (lowercase) to open up a line BELOW the cursor and place you in
X insert mode.
X
X 3. Now copy the line marked ---> and press <ESC> to exit insert mode.
X
X---> After typing o the cursor is placed on the open line in insert mode.
X
X 4. To open up a line ABOVE the cursor, simply type a capital O , rather
X than a lowercase o. Try this on the line below.
XOpen up a line above this by typing Shift-O while the cursor is on this line.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 6.2 *
X **************
X =====>>>>> THE APPEND COMMAND <<<<<=====
X
X ** Type a to insert text AFTER the cursor. **
X
X 1. Move the cursor to the end of the first line below marked ---> by
X typing $ in Command mode.
X
X 2. Type an a (lowercase) to append text AFTER the character under the
X cursor. (Uppercase A appends to the end of the line.)
X
XNote: This avoids typing i , the last character, the text to insert, <ESC>,
X cursor-right, and finally, x , just to append to the end of a line!
X
X 3. Now complete the first line. Note also that append is exactly the same
X as insert mode, except for the location where text is inserted.
X
X---> This line will allow you to practice
X---> This line will allow you to practice appending text to the end of a line.
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 6.3 *
X **************
X =====>>>>> ANOTHER VERSION OF REPLACE <<<<<=====
X
X ** Type a capital R to replace more than one character. **
X
X 1. Move the cursor to the first line below marked --->.
X
X 2. Place the cursor at the beginning of the first word that is different
X from the second line marked ---> (the word 'last').
X
X 3. Now type R and replace the remainder of the text on the first line by
X typing over the old text to make the first line the same as the second.
X
X---> To make the first line the same as the last on this page use the keys.
X---> To make the first line the same as the second, type R and the new text.
X
X 4. Note that when you press <ESC> to exit, any unaltered text remains.
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X **************
X * Lesson 6.4 *
X **************
X =====>>>>> SET ENVIRONMENT VARIABLE <<<<<=====
X
X ** Change environment so a search or substitute ignores case **
X
X
X 1. Search for 'ignore' by entering:
X /ignore
X Repeat several times by hitting the n key
X
X 2. Set the 'ic' (Ignore case) variable by typing:
X :set ic
X
X 3. Now search for 'ignore' again by entering: n
X Repeat search several more times by hitting the n key
X
X
X
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X ********************
X * LESSON 6 SUMMARY *
X ********************
X
X 1. Typing o opens a line BELOW the cursor and places the cursor on the open
X line in insert mode.
X Typing a capital O opens the line ABOVE the line the cursor is on.
X
X 2. Type an a to insert text AFTER the character the cursor is on.
X Typing a capital A automatically appends text to the end of the line.
X
X 3. Typing a capital R enters replace mode until <ESC> is pressed to exit.
X
X 4. Typing ":set xxx" sets the environment variable "xxx"


X
X
X
X
X
X

X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
X
X This concludes the Vim Tutor. It was intended to give a brief overview of
X the Vim editor, just enough to allow you to use the editor fairly easily.
X It is far from complete as Vim has many many more commands.
X
X For more information on Vim editor please refer to:
X
X doc/reference.doc - a complete description of Vim
X doc/index - a short summary of all commands
X doc/difference.doc - summary of differences between vi and Vim
X
X Or hit the HELP key!
X
X This tutorial was written by Michael C. Pierce and Robert K. Ware,
X Colorado School of Mines using ideas supplied by Charles Smith,
X Colorado State University.
X E-mail: bw...@mines.colorado.edu.
X
X Modified for Vim by Bram Moolenaar.
X
X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
END_OF_FILE
if test 28799 -ne `wc -c <'vim/tutor/tutor'`; then
echo shar: \"'vim/tutor/tutor'\" unpacked with wrong size!
fi
# end of 'vim/tutor/tutor'
fi
echo shar: End of archive 19 \(of 26\).
cp /dev/null ark19isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:22 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 39
Archive-name: vim/part20

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/windows.doc vim/doc/winnt.doc vim/src/globals.h
# vim/src/msdos.c vim/todo
# Wrapped by kent@sparky on Mon Aug 15 21:44:11 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 20 (of 26)."'
if test -f 'vim/doc/windows.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/windows.doc'\"
else
echo shar: Extracting \"'vim/doc/windows.doc'\" \(15407 characters\)
sed "s/^X//" >'vim/doc/windows.doc' <<'END_OF_FILE'
XEditing with multiple windows and buffers.
X
XExplained here are commands have been added to use multiple windows and
Xbuffers. Additionally there are explanations for commands that work different
Xwhen used in combination with more than one window.
X
X
XA window is a viewport onto a buffer. You can use multiple windows on one
Xbuffer. Or several windows on different buffers.
X
XA buffer is a file loaded into memory for editing. The original file remains
Xunchanged until you write the buffer to the file.
X
XA buffer can be in one of three states:
X
Xactive: The buffer is displayed in a window. If there is a file for this
X buffer it has been read into the buffer. The buffer may have been
X modified.
Xhidden: The buffer is not displayed. If there is a file for this buffer it
X has been read into the buffer. The buffer may have been modified.
Xinactive: The buffer is not displayed and does not contain anything. Options
X for the buffer are remembered if the file was once loaded.
X
XIn a table:
X
Xstate displayed loaded :buffers
X in window shows
Xactive yes yes ' '
Xhidden no yes 'h'
Xinactive no no '-'
X
X
XStarting Vim
X-----------
X
XBy default Vim starts with one window, just like vi.
X
XThe "-o" command line argument can be used to open a window for each file in
Xthe argument list: "Vim -o file1 file2 file3" will open three windows.
X
X"-oN", where N is a decimal number, opens N windows. If there are more file
Xnames than windows, only N windows are opened, some files do not get a window.
XIf there are more windows than file names, the last few windows will be
Xediting empty buffers.
X
XIf there are many file names the windows will become very small. You might
Xwant to set the 'winheight' option to create a workable situation.
X
X
XOpening a new window
X--------------------
X
XCTRL-W s
XCTRL-W S
XCTRL-W CTRL-S
X:[N]split
X Split current window in two. The result is two viewports on
X the same file. Make new window N high (default is to use half
X the height of the current window). Reduces the current window
X height to create room (and others, if the 'equalalways' option
X is set).
X
XCTRL-W n
XCTRL-W CTRL_N
X:[N]new
X Create a new window and start editing an empty file in it.
X Make new window N high (default is to use half the existing
X height). Reduces the current window height to create room (and
X others, if the 'equalalways' option is set).
X
X:[N]new [+command] fname
X:[N]split [+command] fname
X Create a new window and start editing file fname in it. If
X [+command] is given, execute the command when the file has
X been loaded. Make new window N high (default is to use half
X the existing height). Reduces the current window height to
X create room (and others, if the 'equalalways' option is set).
X
X
XClosing a window
X----------------
X
XCTRL-W q
XCTRL-W CTRL-Q
X:quit Quit current window, unless the buffer was changed and there
X are no other windows for this buffer. When quitting the last
X window, exit Vim.
X
X:quit! Quit current window. If this was the last window for a buffer,
X any changes to that buffer are lost. When quitting the last
X window, exit Vim.
X
XCTRL-W c
X:close Quit current window, unless it is the last window on the
X screen. The buffer becomes hidden (unless there is another
X window editing it). (Note: CTRL-W CTRL-C does not work).
X
XCTRL-W o
XCTRL-W CTRL-O
X:only Make the current window the only one on the screen. All other
X windows are closed. All buffers in the other windows become
X hidden.
X
X
XMoving the cursor to other windows
X----------------------------------
X
XCTRL-W <CURSOR_DOWN>
XCTRL-W CTRL-J
XCTRL-W j move cursor to Nth window below current one.
X
XCTRL-W <CURSOR_UP>
XCTRL-W CTRL-K
XCTRL-W k move cursor to Nth window above current one.
X
XCTRL-W w
XCTRL-W CTRL-W Without count: move cursor to window below current one. If
X there is no window below, go to upper window.
X With count: go to Nth window.
X
XCTRL-W p
XCTRL-W CTRL-P go to previous (last accessed) window.
X
X
XMoving windows around
X---------------------
X
XCTRL-W r
XCTRL-W CTRL-R Rotate windows downwards. The first window becomes the second
X one, the second one the third one, etc. The last window
X becomes the first window. The cursor remains in the same
X window.
X
XCTRL-W R Rotate windows upwards. The second window becomes the first
X one, the third one the second one, etc. The first window
X becomes the last window. The cursor remains in the same
X window.
X
XCTRL-W x
XCTRL-W CTRL-X Without count: Exchange current window with next one. If there
X is no next window, exchange with previous window. With count:
X Exchange current window with Nth window (first window is 1).
X The cursor is put in the other window.
X
X
XWindow resizing
X---------------
X
XCTRL-W = make all windows (almost) equal high.
X
X:resize -N
XCTRL-W - decrease current window height by N
X
X:resize +N
XCTRL-W + increase current window height by N
X
X:resize [N]
XCTRL-W CTRL-_
XCTRL-W _ set current window height to N (default: highest possible)
X
Xz<nr><CR> set current window height to nr
X
XThe option 'winheight' ('wh') is used to set the minimal window height of the
Xcurrent window. This option is used each time another window becomes the
Xcurrent window. If the option is '0' it is disabled. Set 'winheight' to a very
Xlarge value, e.g. '9999', to make the current window always fill all available
Xspace. Set it to a reasonable value, e.g. '10', to make editing in the current
Xwindow comfortable.
X
XWhen the option 'equalalways' ('ea') is set all the windows are automatically
Xmade the same size after splitting or closing a window. If you don't set this
Xoption, splitting a window will reduce the size of the current window and
Xleave the other windows the same. When closing a window the extra lines are
Xgiven the the window above it.
X
XThe option 'commandheight' ('ch') is used to set the height of the command
Xline. If you are annoyed by the "hit return to continue" questions for long
Xmessages, set this option to 2 or 3.
X
XIf there is only one window, resizing that window will also change the command
Xline height. If there are several windows, resizing the current window will
Xalso change the height of the window below it (and sometimes the window above
Xit).
X
X
XExiting Vim with multiple windows or buffers
X--------------------------------------------
X
X:qall Exit Vim, unless there are some buffers which have been
X changed. (Use :bmod to go to the next modified buffer).
X
X:qall! Exit Vim. Any changes to buffers are lost.
X
X:wqall
X:xall Write all changed buffers and exit Vim. If there are buffers
X without a file name, which are readonly or cannot be written
X for another reason, Vim is not quit.
X
X:wqall!
X:xall! Write all changed buffers, also the ones that are readonly,
X and exit Vim. If there are buffers without a file name or
X cannot be written for another reason, Vim is not quit.
X
X
XWriting with multiple buffers
X-----------------------------
X
X:wall Write all changed buffers. Buffers without a file name or
X which are readonly are not written.
X
X:wall! Write all changed buffers, also the ones that are readonly.
X Buffers without a file name are not written.
X
X
XOverview of argument and buffer list commands
X---------------------------------------------
X
X args list buffer list meaning
X1. :[N]argument [N] 11. :[N]buffer [N] to arg/buf N
X2. :[N]next [file ..] 12. :[N]bnext [N] to Nth next arg/buf
X3. :[N]Next [N] 13. :[N]bNext [N] to Nth previous arg/buf
X4. :[N]previous [N] 14. :[N]bprevious [N] to Nth previous arg/buf
X5. :rewind 15. :brewind to first arg/buf
X6. :last 16. :blast to last arg/buf
X7. :all 17. :ball edit all args/buffers
X 18. :unhide edit all loaded buffers
X 19. :[N]bmod [N] to Nth modified buf
X
X split & args list split & buffer list meaning
X21. :[N]sargument [N] 31. :[N]sbuffer [N] split + to arg/buf N
X22. :[N]snext [file ..] 32. :[N]sbnext [N] split + to Nth next arg/buf
X23. :[N]sNext [N] 33. :[N]sbNext [N] split + to Nth previous arg/buf
X24. :[N]sprevious [N] 34. :[N]sbprevious [N] split + to Nth previous arg/buf
X25. :srewind 35. :sbrewind split + to first arg/buf
X26. :slast 36. :sblast split + to last arg/buf
X27. :sall 37: :sball edit all args/buffers
X 38. :sunhide edit all loaded buffers
X 39. :[N]sbmod [N] split + to Nth modified buf
X
X40. :args list of arguments
X41. :buffers list of buffers
X
XThe meaning of [N] depends on the command:
X[N] is number of buffers to go forward/backward on ?2, ?3, ?4
X[N] is an argument number, defaulting to current argument, for 1, 21
X[N] is a buffer number, defaulting to current buffer, for 11, 31
X[N] is a count for 17, 39
X
XNote: ":next" is an exception, because it must accept a list of file names
Xfor compatibility with vi.
X
X
XThe argument list and multiple windows
X--------------------------------------
X
XThe current position in the argument list can be different for each window.
XRemember that when doing ":e file" the position in the argument list stays
Xthe same, but you are not editing the file at that position. Thus the
Xmessage (file N of M) may be misleading (this is inherited from vi).
X
XAll the entries in the argument list are added to the buffer list. Thus you
Xcan also get to them with the buffer list commands, like ":bnext".
X
X:all
X:sall Rearrange the screen to open one window for each argument.
X All other windows are closed (buffers become hidden).
X
X:[N]sargument[!] [N]
X Short for ":split | argument [N]": split window and go to
X Nth argument. But when there is no such argument, of the
X current file cannot be abandoned, the window is not split.
X
X:[N]snext[!] [file ..]
X Short for ":split | [N]next": split window and go to Nth
X next argument. But when there is no next file, or the
X current file cannot be abandoned, the window is not split.
X
X:[N]sprevious[!] [N]
X:[N]sNext[!] [N]
X Short for ":split | Next": split window and go to Nth
X previous argument. But when there is no previous file, or
X the current file cannot be abandoned, the window is not
X split.
X
X:srewind[!] Short for ":split | rewind": split window and go to first
X argument. But when the current file cannot be abandoned the
X window is not split.
X
X:slast[!] Short for ":split | last": split window and go to last
X argument. But when the current file cannot be abandoned the
X window is not split.
X
X
XTag or file name under the cursor
X---------------------------------
X
XCTRL-W ]
XCTRL-W CTRL-] split current window in two. Use identifier under cursor as a
X tag and jump to it in the new upper window. Make new window N
X high.
X
XCTRL-W f
XCTRL-W CTRL-F split current window in two. Edit file name under cursor. Like
X ":split ]f", but window isn't split if the file does not exist.
X
X
XUsing hidden buffers
X--------------------
X
XA hidden buffer is not displayed in a window, but is still loaded into memory.
XThis makes it possible to jump from file to file, without the need to read or
Xwrite the file every time, and having to keep the file in a window.
X
XIf the option 'hidden' ('hid') is set, abandoned buffers are kept for all
Xcommands that start editing another file: ":edit", ":next", ":tag", etc. The
Xcommands that move through the buffer list make the current buffer hidden
Xalthough the 'hidden' option is not set (see below).
X
XYou can make a hidden buffer not hidden, by starting to edit it with any
Xcommand. Or by deleting it with the ":bdelete" command.
X
X:files
X:buffers Show all buffers. Example:
X
X 1 #h "/test/text" line 1
X 2 - "asdf" line 0
X 3 % + "version.c" line 1
X
X Each buffer has a unique number. That number will not change,
X so you can always go to a specific buffer with ":buffer N" or
X "N CTRL-^", where N is the buffer number.
X
X '-' indicates a buffer that is not loaded. 'h' indicates a
X hidden buffer: It is loaded, but currently not displayed in a
X window. '%' indicates the buffer in the current window. '#'
X indicates the alternate buffer for ":e #" or CTRL-^. '+'
X indicates a modified buffer.
X
X:[N]bdelete
X:bdelete [N]
X Unload buffer [N] (default: current buffer) and delete it from
X the buffer list. If the buffer was changed this fails. The
X file remains unaffected. If buffer [N] is the current buffer,
X the next buffer becomes the current buffer.
X
X:[N]bdelete!
X:bdelete! [N]
X Unload buffer [N] (default: current buffer) and delete it from
X the buffer list. If the buffer was changed the changes are
X lost. The file remains unaffected. If buffer [N] is the
X current buffer, the next buffer becomes the current buffer.
X
X:N,Mbdelete[!] do :bdelete[!] for all buffers in the range N to M (inclusive).
X
X:bdelete[!] N1 N2 ..
X do :bdelete[!] for buffer N1, N2, etc.
X
X:[N]bunload
X:bunload [N]
X Unload buffer [N] (default: current buffer). The memory
X allocated for this buffer will be freed. The buffer remains in
X the buffer list. If the buffer was changed this fails. If
X buffer [N] is the current buffer, the next buffer becomes the
X current buffer.
X
X:[N]bunload!
X:bunload! [N]
X Unload buffer [N] (default: current buffer). The memory
X allocated for this buffer will be freed. The buffer remains in
X the buffer list. If the buffer was changed the changes are
X lost. If buffer [N] is the current buffer, the next buffer
X becomes the current buffer.
X
X:N,Mbunload[!] do :bunload[!] for all buffers in the range N to M (inclusive).
X
X:bunload[!] N1 N2 ..
X do :bunload[!] for buffer N1, N2, etc.
X
X:[N]buffer [N]
X Edit buffer [N] from the buffer list. If [N] is not given, the
X current buffer remains being edited.
X
X:[N]bnext [N] Go to [N]th next buffer in buffer list. [N] defaults to one.
X
X:[N]bNext [N]
X:[N]bprev [N] Go to [N]th previous buffer in buffer list. [N] defaults to
X one.
X
X:brewind Go to first buffer in buffer list
X
X:blast Go to last buffer in buffer list
X
X:[N]bmodified [N]
X Go to [N]th next modified buffer in buffer list
X
X:[N]sbuffer [N]
X split window and Edit buffer [N] from the buffer list. If [N]
X is not given, the current buffer is edited.
X
X:[N]sbnext [N] split window and go to [N]th next buffer in buffer list
X
X:[N]sbNext [N]
X:[N]sbprev [N] split window and go to [N]th previous buffer in buffer list
X
X:sbrewind split window and go to first buffer in buffer list
X
X:sblast split window and go to last buffer in buffer list
X
X:[N]sbmodified [N]
X split window and go to [N]th next modified buffer in buffer list
X
X:unhide
X:sunhide Rearrange the screen to open one window for each loaded
X buffer in the buffer list.
X
X:ball
X:sball Rearrange the screen to open one window for each buffer in
X the buffer list.
X
X
XMemory usage limits
X-------------------
X
XThe option 'maxmem' ('mm') is used to set the maximal memory used for one
Xbuffer (in Kbyte). 'maxmemtot' is used to set the maximal memory used for all
Xbuffers (in Kbyte). The defaults depend on the system used. For the Amiga and
XMSDOS 'maxmemtot' is set depending on the amount of memory available. If you
Xdon't like Vim to swap to a file, set 'maxmem' and 'maxmemtot' to a very large
Xvalue. The swap file will then only be used for recovery. If you don't want a
Xswap file at all, set 'updatecount' to 0, or use the "-n" argument when
Xstarting Vim. Note that the 'maxmem' option is only used when a buffer is
Xcreated. Changing this option does not affect buffers that have already been
Xloaded. Thus you can set it to different values for different files.
X'maxmemtot' works always.
END_OF_FILE
if test 15407 -ne `wc -c <'vim/doc/windows.doc'`; then
echo shar: \"'vim/doc/windows.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/windows.doc'
fi
if test -f 'vim/doc/winnt.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/winnt.doc'\"
else
echo shar: Extracting \"'vim/doc/winnt.doc'\" \(419 characters\)
sed "s/^X//" >'vim/doc/winnt.doc' <<'END_OF_FILE'
XThe Windows NT port of Vim has not been tested very much. Be prepared to run
Xinto some problems in the NT specific parts.
X
XKnown problems:
X
XDisplay is not always correct. Type CTRL-L to fix this.
X
XCTRL-C in a child shell (created with ":sh" or CTRL-Z) kills Vim. Hopefully
Xthe recovery mechanism will get your file back, but don't rely on this.
X
XThe Windows NT port was done by Roger Knobbe <Rog...@po.wonderware.com>.
END_OF_FILE
if test 419 -ne `wc -c <'vim/doc/winnt.doc'`; then
echo shar: \"'vim/doc/winnt.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/winnt.doc'
fi
if test -f 'vim/src/globals.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/globals.h'\"
else
echo shar: Extracting \"'vim/src/globals.h'\" \(10417 characters\)
sed "s/^X//" >'vim/src/globals.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X/*
X * definition of global variables
X *
X * EXTERN is only defined in main.c (and in param.h)
X */
X
X#ifndef EXTERN
X# define EXTERN extern
X# define INIT(x)
X#else
X# ifndef INIT
X# define INIT(x) x
X# endif
X#endif
X
X/*
X * Number of Rows and Columns in the screen.
X * Must be long to be able to use them as options in param.c.
X */
XEXTERN long Rows;
XEXTERN long Columns;
X
X/*
X * Cmdline_row is the row where the command line starts, just below the
X * last window.
X * When the cmdline gets longer than the available space the screen gets
X * scrolled up. After a CTRL-D (show matches), after hitting ':' after
X * "hit return", and for the :global command, the command line is
X * temporaraly moved. The old position is restored with the next call to
X * updateScreen().
X */
XEXTERN int cmdline_row;
X
XEXTERN int redraw_cmdline INIT(= FALSE); /* cmdline must be redrawn */
XEXTERN int clear_cmdline INIT(= FALSE); /* cmdline must be cleared */
X
X#ifdef WEBB_COMPLETE
X/*
X * used for completion on the command line
X */
XEXTERN int expand_context INIT(= CONTEXT_UNKNOWN);
XEXTERN char_u *expand_pattern INIT(= NULL);
XEXTERN int expand_interactively INIT(= FALSE);
X#endif /* WEBB_COMPLETE */
X
X/*
X * Functions for putting characters in the command line,
X * while keeping NextScreen updated.
X */
XEXTERN int msg_col;
XEXTERN int msg_row;
XEXTERN int msg_scrolled;
XEXTERN char_u *keep_msg; /* message to be shown after redraw */
XEXTERN int msg_highlight INIT(= FALSE);/* message should be highlighted */
XEXTERN char_u *highlight INIT(= NULL); /* string for start of highlighting */
XEXTERN char_u *unhighlight INIT(= NULL); /* string for end of highlighting */
XEXTERN int scroll_region INIT(= FALSE);/* terminal supports scroll region */
X
X/*
X * All windows are linked in a list. firstwin points to the first entry, lastwin
X * to the last entry (can be the same as firstwin) and curwin to the currently
X * active window.
X */
XEXTERN WIN *firstwin; /* first window */
XEXTERN WIN *lastwin; /* last window */
XEXTERN WIN *curwin; /* currently active window */
X
X/*
X * All buffers are linked in a list. 'firstbuf' points to the first entry,
X * 'lastbuf' to the last entry and 'curbuf' to the currently active buffer.
X */
XEXTERN BUF *firstbuf INIT(= NULL); /* first buffer */
XEXTERN BUF *lastbuf INIT(= NULL); /* last buffer */
XEXTERN BUF *curbuf INIT(= NULL); /* currently active buffer */
X
X/*
X * list of files being edited (argument list)
X */
XEXTERN char_u **arg_files; /* list of files */
XEXTERN int arg_count; /* number of files */
XEXTERN int arg_exp; /* when TRUE arg_files must be freed */
X
XEXTERN int ru_col; /* column for ruler */
XEXTERN int sc_col; /* column for shown command */
X
X/*
X * When starting or exiting some things are done differently (e.g. screen
X * updating).
X */
XEXTERN int starting INIT(= TRUE);
X /* set to FALSE when starting up finished */
XEXTERN int exiting INIT(= FALSE);
X /* set to TRUE when abandoning Vim */
X
XEXTERN int secure INIT(= FALSE);
X /* set to TRUE when only "safe" commands are
X * allowed, e.g. when sourcing .exrc or .vimrc
X * in current directory */
X
XEXTERN FPOS VIsual; /* start position of Visual
X * (VIsual.lnum == 0 when not active) */
XEXTERN int Visual_block INIT(= FALSE);
X /* Visual is blockwise */
X
XEXTERN FPOS Insstart; /* This is where the latest insert/append
X * mode started. */
X
X/*
X * This flag is used to make auto-indent work right on lines where only a
X * <RETURN> or <ESC> is typed. It is set when an auto-indent is done, and
X * reset when any other editting is done on the line. If an <ESC> or <RETURN>
X * is received, and did_ai is TRUE, the line is truncated.
X */
XEXTERN int did_ai INIT(= FALSE);
X
X/*
X * This flag is set when a smart indent has been performed. When the next typed
X * character is a '{' the inserted tab will be deleted again.
X */
XEXTERN int did_si INIT(= FALSE);
X
X/*
X * This flag is set after an auto indent. If the next typed character is a '}'
X * one indent character will be removed.
X */
XEXTERN int can_si INIT(= FALSE);
X
XEXTERN int old_indent INIT(= 0); /* for ^^D command in insert mode */
X
X/*
X * This flag is set after doing a reverse replace in column 0.
X * An extra space has been inserted in column 0.
X */
XEXTERN int extraspace INIT(= FALSE);
X
XEXTERN int State INIT(= NORMAL); /* This is the current state of the command
X * interpreter. */
X
XEXTERN int Recording INIT(= FALSE);/* TRUE when recording into a register */
XEXTERN int Exec_reg INIT(= FALSE); /* TRUE when executing a register */
X
XEXTERN int did_cd INIT(= FALSE); /* TRUE when :cd dir used */
XEXTERN int no_abbr INIT(= TRUE); /* TRUE when no abbreviations loaded */
X
X
XEXTERN char_u *IObuff; /* sprintf's are done in this buffer */
XEXTERN char_u *NameBuff; /* file names are expanded in this buffer */
X
XEXTERN int RedrawingDisabled INIT(= FALSE);
X /* Set to TRUE if doing :g */
X
XEXTERN int readonlymode INIT(= FALSE); /* Set to TRUE for "view" */
XEXTERN int recoverymode INIT(= FALSE); /* Set to TRUE for "-r" option */
X
XEXTERN int KeyTyped; /* TRUE if user typed the character */
XEXTERN int must_redraw INIT(= 0); /* type of redraw necessary */
XEXTERN int skip_redraw INIT(= FALSE); /* skip redraw once */
X
X#define NSCRIPT 15
XEXTERN FILE *scriptin[NSCRIPT]; /* streams to read script from */
XEXTERN int curscript INIT(= 0); /* index in scriptin[] */
XEXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
X
XEXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt
X signal occurred */
XEXTERN int term_console INIT(= FALSE); /* set to TRUE when Amiga window used */
XEXTERN int termcap_active INIT(= FALSE); /* set to TRUE by starttermcap() */
XEXTERN int bangredo INIT(= FALSE); /* set to TRUE whith ! command */
XEXTERN int searchcmdlen; /* length of previous search command */
XEXTERN int reg_ic INIT(= 0); /* p_ic passed to to regexec() */
X
XEXTERN int did_outofmem_msg INIT(= FALSE); /* set after out of memory msg */
XEXTERN int tag_busy INIT(= FALSE); /* doing a search for tag command */
XEXTERN int global_busy INIT(= 0); /* set when :global is executing */
XEXTERN int dont_sleep INIT(= FALSE); /* set when sleep() in emsg() not wanted */
XEXTERN int did_msg; /* set in msg_start, used for :global */
XEXTERN int no_wait_return INIT(= 0); /* don't wait for return now */
XEXTERN int need_wait_return INIT(= 0); /* need to wait for return later */
XEXTERN char_u *last_cmdline INIT(= NULL); /* last command line (for ':' register) */
XEXTERN char_u *new_last_cmdline INIT(= NULL); /* new value for last_cmdline */
X
XEXTERN int postponed_split INIT(= FALSE); /* for CTRL-W CTRL-] command */
XEXTERN int keep_old_search_pattern INIT(= FALSE); /* for myregcomp() */
X
X#ifdef DEBUG
XEXTERN FILE *debugfp INIT(=NULL);
X#endif
X
Xextern char_u *Version; /* this is in version.c */
Xextern char_u *longVersion; /* this is in version.c */
X
X/*
X * The error messages that can be shared are included here.
X * Excluded are very specific errors and debugging messages.
X */
XEXTERN char_u e_abbr[] INIT(="No such abbreviation");
XEXTERN char_u e_abort[] INIT(="Command aborted");
XEXTERN char_u e_ambmap[] INIT(="Ambiguous mapping");
XEXTERN char_u e_argreq[] INIT(="Argument required");
XEXTERN char_u e_backslash[] INIT(="\\ should be followed by /, ? or &");
XEXTERN char_u e_curdir[] INIT(="Command not allowed from from .exrc/.vimrc in current dir");
XEXTERN char_u e_errorf[] INIT(="No errorfile name");
XEXTERN char_u e_exists[] INIT(="File exists (use ! to override)");
XEXTERN char_u e_failed[] INIT(="Command failed");
XEXTERN char_u e_internal[] INIT(="Internal error");
XEXTERN char_u e_interr[] INIT(="Interrupted");
XEXTERN char_u e_invaddr[] INIT(="Invalid address");
XEXTERN char_u e_invarg[] INIT(="Invalid argument");
XEXTERN char_u e_invrange[] INIT(="Invalid range");
XEXTERN char_u e_invcmd[] INIT(="Invalid command");
XEXTERN char_u e_invstring[] INIT(="Invalid search string");
XEXTERN char_u e_nesting[] INIT(="Scripts nested too deep");
XEXTERN char_u e_noalt[] INIT(="No alternate file");
XEXTERN char_u e_nolastcmd[] INIT(="No previous command line");
XEXTERN char_u e_nomap[] INIT(="No such mapping");
XEXTERN char_u e_nomatch[] INIT(="No match");
XEXTERN char_u e_nomore[] INIT(="No more files to edit");
XEXTERN char_u e_noname[] INIT(="No file name");
XEXTERN char_u e_nopresub[] INIT(="No previous substitute");
XEXTERN char_u e_noprev[] INIT(="No previous command");
XEXTERN char_u e_noprevre[] INIT(="No previous regexp");
XEXTERN char_u e_norange[] INIT(="No range allowed");
XEXTERN char_u e_noroom[] INIT(="Not enough room");
XEXTERN char_u e_notcreate[] INIT(="Can't create file %s");
XEXTERN char_u e_notmp[] INIT(="Can't get temp file name");
XEXTERN char_u e_notopen[] INIT(="Can't open file %s");
XEXTERN char_u e_notread[] INIT(="Can't read file %s");
XEXTERN char_u e_nowrtmsg[] INIT(="No write since last change (use ! to override)");
XEXTERN char_u e_null[] INIT(="Null argument");
XEXTERN char_u e_number[] INIT(="Number expected");
XEXTERN char_u e_openerrf[] INIT(="Can't open errorfile %s");
XEXTERN char_u e_outofmem[] INIT(="Out of memory!");
XEXTERN char_u e_patnotf[] INIT(="Pattern not found");
XEXTERN char_u e_positive[] INIT(="Argument must be positive");
XEXTERN char_u e_quickfix[] INIT(="No errorfile; use :cf");
XEXTERN char_u e_re_damg[] INIT(="Damaged match string");
XEXTERN char_u e_re_corr[] INIT(="Corrupted regexp program");
XEXTERN char_u e_readonly[] INIT(="File is readonly");
XEXTERN char_u e_readerrf[] INIT(="Error while reading errorfile");
XEXTERN char_u e_scroll[] INIT(="Invalid scroll size");
XEXTERN char_u e_toocompl[] INIT(="Command too complex");
XEXTERN char_u e_toombra[] INIT(="Too many (");
XEXTERN char_u e_toomket[] INIT(="Too many )");
XEXTERN char_u e_toomsbra[] INIT(="Too many [");
XEXTERN char_u e_toolong[] INIT(="Command too long");
XEXTERN char_u e_toomany[] INIT(="Too many file names");
XEXTERN char_u e_trailing[] INIT(="Trailing characters");
XEXTERN char_u e_umark[] INIT(="Unknown mark");
XEXTERN char_u e_unknown[] INIT(="Unknown");
XEXTERN char_u e_write[] INIT(="Error while writing");
XEXTERN char_u e_zerocount[] INIT(="Zero count");
END_OF_FILE
if test 10417 -ne `wc -c <'vim/src/globals.h'`; then
echo shar: \"'vim/src/globals.h'\" unpacked with wrong size!
fi
# end of 'vim/src/globals.h'
fi
if test -f 'vim/src/msdos.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/msdos.c'\"
else
echo shar: Extracting \"'vim/src/msdos.c'\" \(19401 characters\)
sed "s/^X//" >'vim/src/msdos.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X/*
X * msdos.c
X *
X * MSDOS system-dependent routines.
X * A cheap plastic imitation of the amiga dependent code.
X * A lot in this file was made by Juergen Weigert (jw).


X */
X
X#include <io.h>

X#include "vim.h"
X#include "globals.h"
X#include "param.h"
X#include "proto.h"
X#include <conio.h>
X#include <fcntl.h>
X#include <bios.h>
X#include <alloc.h>
X
Xstatic int WaitForChar __ARGS((int));
Xstatic int change_drive __ARGS((int));


Xstatic int cbrk_handler __ARGS(());
X

Xtypedef struct filelist
X{
X char_u **file;


X int nfiles;
X int maxfiles;
X} FileList;
X

Xstatic void addfile __ARGS((FileList *, char_u *, int));
Xstatic int pstrcmp(); /* __ARGS((char **, char **)); BCC does not like this */
Xstatic void strlowcpy __ARGS((char_u *, char_u *));
Xstatic int expandpath __ARGS((FileList *, char_u *, int, int, int));


X
Xstatic int cbrk_pressed = FALSE; /* set by ctrl-break interrupt */

Xstatic int ctrlc_pressed = FALSE; /* set when ctrl-C or ctrl-break detected */
Xstatic int delayed_redraw = FALSE; /* set when ctrl-C detected */


X
X long
Xmch_avail_mem(special)
X int special;
X{

X return coreleft();
X}


X
X void
Xvim_delay()
X{

X delay(500);
X}
X
X/*


X * this version of remove is not scared by a readonly (backup) file
X *

X * returns -1 on error, 0 otherwise (just like remove())
X */
X int
Xvim_remove(name)
X char_u *name;
X{
X (void)setperm(name, 0); /* default permissions */
X return unlink(name);
X}
X
X/*


X * mch_write(): write the output buffer to the screen
X */

X void
Xmch_write(s, len)
X char_u *s;

X int len;
X{
X char_u *p;


X int row, col;
X

X if (term_console) /* translate ESC | sequences into bios calls */
X while (len--)
X {

X if (s[0] == '\n')

X putch('\r');
X else if (s[0] == ESC && len > 1 && s[1] == '|')
X {


X switch (s[2])
X {

X case 'J': clrscr();
X goto got3;
X
X case 'K': clreol();
X goto got3;
X
X case 'L': insline();
X goto got3;
X
X case 'M': delline();
Xgot3: s += 3;


X len -= 2;
X continue;
X
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':

X case '9': p = s + 2;


X row = getdigits(&p); /* no check for length! */
X if (p > s + len)
X break;

X if (*p == ';')

X {


X ++p;
X col = getdigits(&p); /* no check for length! */
X if (p > s + len)
X break;

X if (*p == 'H' || *p == 'r')
X {
X if (*p == 'H') /* set cursor position */
X gotoxy(col, row);
X else /* set scroll region */
X window(1, row, Columns, col);


X len -= p - s;

X s = p + 1;
X continue;
X }
X }


X else if (*p == 'm')

X {


X if (row == 0)
X normvideo();
X else
X textattr(row);
X len -= p - s;

X s = p + 1;
X continue;
X }
X }
X }
X putch(*s++);
X }
X else
X write(1, s, (unsigned)len);
X}
X

X#define POLL_SPEED 10 /* milliseconds between polls */
X
X/*
X * Simulate WaitForChar() by slowly polling with bioskey(1) or kbhit().
X *
X * If Vim should work over the serial line after a 'ctty com1' we must use
X * kbhit() and getch(). (jw)
X * Usually kbhit() is not used, because then CTRL-C and CTRL-P
X * will be catched by DOS (mool).
X *
X * return TRUE if a character is available, FALSE otherwise


X */
X
X static int

XWaitForChar(msec)
X int msec;
X{


X for (;;)
X {

X if ((p_biosk ? bioskey(1) : kbhit()) || cbrk_pressed)
X return TRUE;
X if (msec <= 0)
X break;
X delay(POLL_SPEED);
X msec -= POLL_SPEED;
X }
X return FALSE;
X}
X
X/*


X * GetChars(): low level input funcion.
X * Get a characters from the keyboard.

X * If time == 0 do not wait for characters.
X * If time == n wait a short time for characters.
X * If time == -1 wait forever for characters.
X *
X * return the number of characters obtained
X */
X int
XGetChars(buf, maxlen, time)


X char_u *buf;
X int maxlen;

X int time;
X{
X int len = 0;
X int c;

X
X/*
X * if we got a ctrl-C when we were busy, there will be a "^C" somewhere
X * on the sceen, so we need to redisplay it.
X */
X if (delayed_redraw)
X {
X delayed_redraw = FALSE;
X updateScreen(CLEAR);
X setcursor();
X flushbuf();
X }
X


X if (time >= 0)
X {

X if (WaitForChar(time) == 0) /* no character available */


X return 0;
X }
X else /* time == -1 */

X {
X /*


X * If there is no character available within 2 seconds (default)
X * write the autoscript file to disk

X */
X if (WaitForChar((int)p_ut) == 0)
X updatescript(0);

X }
X
X/*


X * Try to read as many characters as there are.
X * Works for the controlling tty only.
X */
X --maxlen; /* may get two chars at once */

X /*
X * we will get at least one key. Get more if they are available
X * After a ctrl-break we have to read a 0 (!) from the buffer.
X * bioskey(1) will return 0 if no key is available and when a
X * ctrl-break was typed. When ctrl-break is hit, this does not always
X * implies a key hit.
X */
X cbrk_pressed = FALSE;
X if (p_biosk)
X while ((len == 0 || bioskey(1)) && len < maxlen)
X {
X c = bioskey(0); /* get the key */
X if (c == 0) /* ctrl-break */
X c = 3; /* return a CTRL-C */
X if ((c & 0xff) == 0)
X {
X if (c == 0x0300) /* CTRL-@ is 0x0300, translated into K_ZERO */
X c = K_ZERO;
X else /* extended key code 0xnn00 translated into K_NUL, nn */
X {
X c >>= 8;
X *buf++ = K_NUL;
X ++len;
X }
X }
X
X *buf++ = c;
X len++;
X }
X else


X while ((len == 0 || kbhit()) && len < maxlen)

X {
X switch (c = getch())
X {
X case 0:


X *buf++ = K_NUL;
X break;
X case 3:
X cbrk_pressed = TRUE;
X /*FALLTHROUGH*/
X default:
X *buf++ = c;
X }
X len++;
X }
X return len;

X}
X
X/*


X * return non-zero if a character is available
X */
X int
Xmch_char_avail()
X{
X return WaitForChar(0);

X}
X
X/*
X * We have no job control, fake it by starting a new shell.


X */
X void
Xmch_suspend()
X{

X OUTSTR("new shell started\n");
X (void)call_shell(NULL, 0, TRUE);

X}
X
Xextern int _fmode;

X/*
X * we do not use windows, there is not much to do here
X */
X void
Xmch_windinit()
X{


X _fmode = O_BINARY; /* we do our own CR-LF translation */
X flushbuf();

X (void)mch_get_winsize();
X}


X
X void
Xcheck_win(argc, argv)
X int argc;
X char **argv;
X{
X if (!isatty(0) || !isatty(1))
X {
X fprintf(stderr, "VIM: no controlling terminal\n");
X exit(2);

X }
X /*
X * In some cases with DOS 6.0 on a NEC notebook there is a 12 seconds


X * delay when starting up that can be avoided by the next two lines.
X * Don't ask me why!

X * This could be fixed by removing setver.sys from config.sys. Forget it.
X gotoxy(1,1);
X cputs(" ");
X */
X}
X
X/*


X * fname_case(): Set the case of the filename, if it already exists.

X * msdos filesystem is far to primitive for that. do nothing.

X */
X void
Xfname_case(name)
X char_u *name;

X{
X}
X
X/*
X * mch_settitle(): set titlebar of our window.
X * Dos console has no title.


X */
X void
Xmch_settitle(title, icon)
X char_u *title;
X char_u *icon;

X{
X}
X
X/*
X * Restore the window/icon title. (which we don't have)


X */
X void
Xmch_restore_title(which)
X int which;

X{
X}
X
X/*


X * Get name of current directory into buffer 'buf' of length 'len' bytes.
X * Return OK for success, FAIL for failure.
X */
X int
Xvim_dirname(buf, len)
X char_u *buf;

X int len;
X{
X return (getcwd(buf, len) != NULL ? OK : FAIL);
X}
X
X/*
X * Change default drive (just like _chdrive of Borland C 3.1)


X */
X static int

Xchange_drive(drive)
X int drive;
X{
X unsigned dummy;
X union REGS regs;
X
X regs.h.ah = 0x0e;
X regs.h.dl = drive - 1;
X intdos(&regs, &regs); /* set default drive */
X regs.h.ah = 0x19;
X intdos(&regs, &regs); /* get default drive */
X if (regs.h.al == drive - 1)


X return 0;
X else

X return -1;
X}
X
X/*


X * get absolute filename into buffer 'buf' of length 'len' bytes

X *
X * return FAIL for failure, OK otherwise
X */
X int

XFullName(fname, buf, len)
X char_u *fname, *buf;

X int len;
X{


X if (fname == NULL) /* always fail */
X {
X *buf = NUL;

X return FAIL;
X }
X

X if (isFullName(fname)) /* allready expanded */
X {
X STRNCPY(buf, fname, len);


X return OK;
X }
X

X#ifdef __BORLANDC__ /* the old Turbo C does not have this */
X if (_fullpath(buf, fname, len) == NULL)
X {
X STRNCPY(buf, fname, len); /* failed, use the relative path name */


X return FAIL;
X }
X return OK;

X#else /* almost the same as FullName in unix.c */


X {
X int l;
X char_u olddir[MAXPATHL];

X char_u *p, *q;


X int c;
X int retval = OK;
X

X *buf = 0;
X /*
X * change to the directory for a moment,


X * and then do the getwd() (and get back to where we were).
X * This will get the correct path name with "../" things.
X */

X p = strrchr(fname, '/');
X q = strrchr(fname, '\\');
X if (q && (p == NULL || q > p))
X p = q;
X q = strrchr(fname, ':');
X if (q && (p == NULL || q > p))
X p = q;
X if (p != NULL)
X {
X if (getcwd(olddir, MAXPATHL) == NULL)


X {
X p = NULL; /* can't get current dir: don't chdir */
X retval = FAIL;

X }
X else
X {
X if (*p == ':' || (p > fname && p[-1] == ':'))
X q = p + 1;
X else
X q = p;
X c = *q;
X *q = NUL;
X if (chdir(fname))


X retval = FAIL;
X else
X fname = p + 1;

X *q = c;
X }
X }
X if (getcwd(buf, len) == NULL)
X {


X retval = FAIL;
X *buf = NUL;
X }
X l = STRLEN(buf);

X if (l && buf[l - 1] != '/' && buf[l - 1] != '\\')
X strcat(buf, "\\");
X if (p)
X chdir(olddir);
X strcat(buf, fname);
X return retval;
X }
X#endif
X}
X
X/*


X * return TRUE is fname is an absolute path name
X */
X int
XisFullName(fname)
X char_u *fname;
X{

X return (STRCHR(fname, ':') != NULL);
X}
X
X/*


X * get file permissions for 'name'

X * -1 : error
X * else FA_attributes defined in dos.h

X */
X long
Xgetperm(name)
X char_u *name;
X{

X int r;
X
X r = _chmod(name, 0, 0); /* get file mode */
X return r;
X}
X
X/*


X * set file permission for 'name' to 'perm'

X *
X * return FAIL for failure, OK otherwise
X */
X int

Xsetperm(name, perm)
X char_u *name;

X long perm;
X{
X perm |= FA_ARCH; /* file has changed, set archive bit */
X return (_chmod((char *)name, 1, (int)perm) == -1 ? FAIL : OK);
X}
X
X/*


X * return TRUE if "name" is a directory
X * return FALSE if "name" is not a directory
X * return -1 for error
X *

X * beware of a trailing backslash that may have been added by addfile()


X */
X int
Xisdir(name)
X char_u *name;
X{

X int f;
X char_u *p;
X
X p = name + strlen(name);
X if (p > name)
X --p;
X if (*p == '\\') /* remove trailing backslash for a moment */


X *p = NUL;
X else

X p = NULL;
X f = _chmod(name, 0, 0);


X if (p != NULL)

X *p = '\\';


X if (f == -1)
X return -1; /* file does not exist at all */

X if ((f & FA_DIREC) == 0)
X return FALSE; /* not a directory */
X return TRUE;
X}
X
X/*


X * Careful: mch_windexit() may be called before mch_windinit()!
X */

X void
Xmch_windexit(r)
X int r;
X{
X settmode(0);

X stoptermcap();
X flushbuf();
X ml_close_all(); /* remove all memfiles */
X exit(r);

X}
X
X/*


X * function for ctrl-break interrupt
X */

X void interrupt
Xcatch_cbrk()


X{
X cbrk_pressed = TRUE;

X ctrlc_pressed = TRUE;
X}
X
X/*
X * ctrl-break handler for DOS. Never called when a ctrl-break is typed, because
X * we catch interrupt 1b. If you type ctrl-C while Vim is waiting for a
X * character this function is not called. When a ctrl-C is typed while Vim is
X * busy this function may be called. By that time a ^C has been displayed on
X * the screen, so we have to redisplay the screen. We can't do that here,
X * because we may be called by DOS. The redraw is in GetChars().


X */
X static int

Xcbrk_handler()
X{
X delayed_redraw = TRUE;
X return 1; /* resume operation after ctrl-break */
X}
X
X/*
X * function for critical error interrupt
X * For DOS 1 and 2 return 0 (Ignore).
X * For DOS 3 and later return 3 (Fail)
X */
X void interrupt
Xcatch_cint(bp, di, si, ds, es, dx, cx, bx, ax)
X unsigned bp, di, si, ds, es, dx, cx, bx, ax;
X{
X ax = (ax & 0xff00); /* set AL to 0 */
X if (_osmajor >= 3)
X ax |= 3; /* set AL to 3 */
X}
X
X/*


X * set the tty in (raw) ? "raw" : "cooked" mode
X *

X * Does not change the tty, as bioskey() and kbhit() work raw all the time.
X */
X
Xextern void interrupt CINT_FUNC();


X
X void
Xmch_settmode(raw)
X int raw;
X{

X static int saved_cbrk;
X static void interrupt (*old_cint)();
X static void interrupt (*old_cbrk)();


X
X if (raw)
X {

X saved_cbrk = getcbrk(); /* save old ctrl-break setting */
X setcbrk(0); /* do not check for ctrl-break */
X old_cint = getvect(0x24); /* save old critical error interrupt */
X setvect(0x24, catch_cint); /* install our critical error interrupt */
X old_cbrk = getvect(0x1B); /* save old ctrl-break interrupt */
X setvect(0x1B, catch_cbrk); /* install our ctrl-break interrupt */
X ctrlbrk(cbrk_handler); /* vim's ctrl-break handler */


X if (term_console)
X outstr(T_TP); /* set colors */

X }
X else
X {
X setcbrk(saved_cbrk); /* restore ctrl-break setting */
X setvect(0x24, old_cint); /* restore critical error interrupt */
X setvect(0x1B, old_cbrk); /* restore ctrl-break interrupt */
X /* restore ctrl-break handler, how ??? */


X if (term_console)
X normvideo(); /* restore screen colors */

X }
X}
X
X/*
X * set screen mode


X * return FAIL for failure, OK otherwise
X */
X int

Xmch_screenmode(arg)
X char_u *arg;
X{

X int mode;
X int i;
X static char_u *(names[]) = {"BW40", "C40", "BW80", "C80", "MONO", "C4350"};
X static int modes[] = { BW40, C40, BW80, C80, MONO, C4350};
X
X mode = -1;
X if (isdigit(*arg)) /* mode number given */
X mode = atoi((char *)arg);
X else
X {
X for (i = 0; i < sizeof(names) / sizeof(char_u *); ++i)
X if (stricmp((char *)names[i], (char *)arg) == 0)
X {
X mode = modes[i];
X break;
X }
X }
X if (mode == -1)
X {
X EMSG("Unsupported screen mode");
X return FAIL;
X }
X textmode(mode); /* use Borland function */


X return OK;
X}
X
X/*

X * Structure used by Turbo-C/Borland-C to store video parameters.
X */
Xextern struct text_info _video;
X
X/*
X * try to get the real window size


X * return FAIL for failure, OK otherwise
X */
X int

Xmch_get_winsize()
X{
X int i;
X struct text_info ti;
X/*
X * The screenwidth is returned by the BIOS OK.
X * The screenheight is in a location in the bios RAM, if the display is EGA or VGA.
X */
X if (!term_console)
X return FAIL;
X gettextinfo(&ti);
X Columns = ti.screenwidth;
X Rows = ti.screenheight;
X if (ti.currmode > 10)
X Rows = *(char far *)MK_FP(0x40, 0x84) + 1;
X set_window();
X


X if (Columns < 5 || Columns > MAX_COLUMNS ||
X Rows < 2 || Rows > MAX_COLUMNS)

X {


X /* these values are overwritten by termcap size or default */

X Columns = 80;
X Rows = 25;
X return FAIL;
X }
X check_winsize();


X
X return OK;
X}
X
X/*

X * Set the active window for delline/insline.
X */
X void
Xset_window()
X{
X _video.screenheight = Rows;
X window(1, 1, Columns, Rows);


X}
X
X void
Xmch_set_winsize()
X{
X /* should try to set the window size to Rows and Columns */

X /* may involve switching display mode.... */
X}
X
X/*
X * call shell, return FAIL for failure, OK otherwise
X */
X int
Xcall_shell(cmd, filter, cooked)
X char_u *cmd;


X int filter; /* if != 0: called by dofilter() */
X int cooked;

X{
X int x;
X char_u newcmd[200];


X
X flushbuf();
X
X if (cooked)
X settmode(0); /* set to cooked mode */
X
X if (cmd == NULL)
X x = system(p_sh);
X else

X { /* we use "command" to start the shell, slow but easy */
X sprintf(newcmd, "%s /c %s", p_sh, cmd);


X x = system(newcmd);
X }

X outchar('\n');


X if (cooked)
X settmode(1); /* set to raw mode */
X

X#ifdef WEBB_COMPLETE
X if (x && !expand_interactively)
X#else
X if (x)
X#endif
X {


X outnum((long)x);
X outstrn((char_u *)" returned\n");
X }
X

X resettitle();
X (void)mch_get_winsize(); /* display mode may have been changed */


X return (x ? FAIL : OK);

X}
X
X/*
X * check for an "interrupt signal": CTRL-break or CTRL-C


X */
X void
Xbreakcheck()
X{

X if (ctrlc_pressed)
X {
X ctrlc_pressed = FALSE;
X got_int = TRUE;
X }
X}
X
X#define FL_CHUNK 32
X
X static void
Xaddfile(fl, f, isdir)
X FileList *fl;
X char_u *f;
X int isdir;
X{
X char_u *p;
X
X if (!fl->file)
X {
X fl->file = (char_u **)alloc(sizeof(char_u *) * FL_CHUNK);


X if (!fl->file)
X return;
X fl->nfiles = 0;
X fl->maxfiles = FL_CHUNK;
X }
X if (fl->nfiles >= fl->maxfiles)

X {
X char_u **t;
X int i;
X
X t = (char_u **)lalloc((long_u)(sizeof(char_u *) * (fl->maxfiles + FL_CHUNK)), TRUE);


X if (!t)
X return;
X for (i = fl->nfiles - 1; i >= 0; i--)
X t[i] = fl->file[i];
X free(fl->file);
X fl->file = t;
X fl->maxfiles += FL_CHUNK;
X }

X p = alloc((unsigned)(STRLEN(f) + 1 + isdir));
X if (p)
X {
X STRCPY(p, f);
X if (isdir)
X strcat(p, "\\");
X }
X fl->file[fl->nfiles++] = p;
X}
X
X static int
Xpstrcmp(a, b)
X char_u **a, **b;
X{
X return (strcmp(*a, *b));
X}
X
X int
Xhas_wildcard(s)
X char_u *s;


X{
X if (s)
X for ( ; *s; ++s)
X if (*s == '?' || *s == '*')

X return TRUE;
X return FALSE;

X}
X
X static void

Xstrlowcpy(d, s)
X char_u *d, *s;


X{
X while (*s)
X *d++ = tolower(*s++);

X *d = '\0';
X}
X
X static int
Xexpandpath(fl, path, fonly, donly, notf)
X FileList *fl;
X char_u *path;
X int fonly, donly, notf;
X{
X char_u buf[MAXPATH];
X char_u *p, *s, *e;
X int lastn, c, r;
X struct ffblk fb;


X
X lastn = fl->nfiles;
X
X/*
X * Find the first part in the path name that contains a wildcard.
X * Copy it into buf, including the preceding characters.

X */


X p = buf;
X s = NULL;
X e = NULL;
X while (*path)

X {
X if (*path == '\\' || *path == ':' || *path == '/')
X {
X if (e)
X break;
X else


X s = p;
X }
X if (*path == '*' || *path == '?')
X e = p;
X *p++ = *path++;
X }
X e = p;
X if (s)
X s++;
X else
X s = buf;
X

X /* if the file name ends in "*" and does not contain a ".", addd ".*" */
X if (e[-1] == '*' && STRCHR(s, '.') == NULL)
X {
X *e++ = '.';
X *e++ = '*';


X }
X /* now we have one wildcard component between s and e */
X *e = '\0';
X r = 0;
X /* If we are expanding wildcards we try both files and directories */

X if ((c = findfirst(buf, &fb, (*path || !notf) ? FA_DIREC : 0)) != 0)
X {
X /* not found */
X STRCPY(e, path);


X if (notf)
X addfile(fl, buf, FALSE);
X return 1; /* unexpanded or empty */
X }

X while (!c)
X {
X strlowcpy(s, fb.ff_name);
X /* ignore "." and ".." */


X if (*s != '.' || (s[1] != '\0' && (s[1] != '.' || s[2] != '\0')))

X {


X strcat(buf, path);
X if (!has_wildcard(path))

X addfile(fl, buf, (isdir(buf) == TRUE));


X else
X r |= expandpath(fl, buf, fonly, donly, notf);
X }

X c = findnext(&fb);
X }
X qsort(fl->file + lastn, fl->nfiles - lastn, sizeof(char_u *), pstrcmp);
X return r;
X}
X
X/*


X * MSDOS rebuilt of Scott Ballantynes ExpandWildCard for amiga/arp.
X * jw
X */

X
X int
XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
X int num_pat;
X char_u **pat;
X int *num_file;
X char_u ***file;

X int files_only, list_notfound;
X{
X int i, r = 0;


X FileList f;
X
X f.file = NULL;
X f.nfiles = 0;

X for (i = 0; i < num_pat; i++)
X {


X if (!has_wildcard(pat[i]))

X addfile(&f, pat[i], files_only ? FALSE : (isdir(pat[i]) == TRUE));


X else
X r |= expandpath(&f, pat[i], files_only, 0, list_notfound);
X }

X if (r == 0)
X {


X *num_file = f.nfiles;
X *file = f.file;

X }
X else
X {
X *num_file = 0;


X *file = NULL;
X }
X return (r ? FAIL : OK);

X}
X
X void
XFreeWild(num, file)
X int num;
X char_u **file;
X{

X if (file == NULL || num <= 0)


X return;
X while (num--)
X free(file[num]);
X free(file);

X}
X
X/*


X * The normal chdir() does not change the default drive.
X * This one does.
X */
X#undef chdir
X int

Xvim_chdir(path)
X char_u *path;
X{
X if (path[0] == NUL) /* just checking... */
X return 0;


X if (path[1] == ':') /* has a drive name */

X {
X if (change_drive(toupper(path[0]) - 'A' + 1))


X return -1; /* invalid drive name */
X path += 2;
X }

X if (*path == NUL) /* drive name only */
X return 0;
X return chdir(path); /* let the normal chdir() do the rest */
X}
END_OF_FILE
if test 19401 -ne `wc -c <'vim/src/msdos.c'`; then
echo shar: \"'vim/src/msdos.c'\" unpacked with wrong size!
fi
# end of 'vim/src/msdos.c'
fi
if test -f 'vim/todo' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/todo'\"
else
echo shar: Extracting \"'vim/todo'\" \(19200 characters\)
sed "s/^X//" >'vim/todo' <<'END_OF_FILE'
XKnown problems:
X
XIf file system full and write to swap file failed, get error message for
X lnum > line_count?
XWhen editing same file in two xterms, in second type ":" at first wait-return
X for ".swp file exists", at exit cursor is left at top of window.
XWindows NT: display is not always correct.
XWindows NT: CTRL-C in a child shell (created with ":sh" or CTRL-Z) kills Vim.
XMSDOS: When using smardrive a readonly floppy will cause problems. Test for
X writable directory first?
XSome terminals start inverting at the position where the invert code is put.
X This is not handled correctly. Remove 'weirdinvert' hack.
X":s/\(.*\)/\1" on line with ^M should not replace ^M by linebreaks.
XReplace with 'r' should set last inserted text.
XBS in replace mode does not work correctly with et set and after inserting a TAB.
XIn insert mode CTRL-O . does not repeat the last CTRL-O command but the insertion.
XSometimes the time stamp in the memfile is old. May be caused by opening the
X file r/w when testing for readonly.
XWhen doing a CTRL-Z and typing a command for the shell, while Vim is busy
X (e.g. writing a file), the command for the shell is sometimes eaten by Vim.
XFind out why screen size is changed in unexpected place for Bob Beresh.
X
X
XTo be checked:
XCheck '\n' at end of some : commands (that do not have TRLBAR).
XCheck for '\\' at the start of search commands (undocumented vi feature).
XEnvironment name expansion for 'bdir' default value does not work?
XUsage of isspace() vi-compatible (compared to iswhite())?
XTerminal initializations compared to vi. "vs" used to make cursor very visible,
X or for scrollbars (Webb)?
XMSDOS: After writing on a network the 'w' bit for others is set.
XWhen can the 'p' and 'P' command not be redone??
X
X
XProblems that will probably not be solved:
X
XProlem with HPterm under X (cosentino/2).
XAmiga: When using quickfix with the Manx compiler we only get the first 25
X errors. How do we get the rest?
XAmiga: The ":cq" command does not always abort the Manx compiler. Why?
XLinux: A file with protection r--rw-rw- is seen readonly for others. The access()
X function in GNU libc is probably wrong.
X
X
XFurther extentions and improvements:
X
XAdd icon setting for xterm (riehm/69, mulder/iconname.set).
XMake command line arguments options to be combined after a single dash, eg "-nb".
XWhen started to edit another file, make message "file 1 of 8" different.
XWhen entering text, keep other windows on same buffer updated (when a line
X entered)?
XAmiga: When 'r' protection bit is not set, file can still be opened
X but gives read errors. Check protection before opening.
XBind windows together, scrolling is done in both windows synchronous
X (horizontally and vertically). Use CTRL-W b?
XRe-select last Visual selection with "v." (exactly same text, from '[ to ']).
XDon't write any pages into the swapfile until the buffer has been changed.
XCatch terminating signals and call ml_sync_all(): SIGHUP, SIGINT, SIGQUIT,
X SIGILL, SIGABRT, SIGFPE, SIGPIPE, SIGALRM, SIGTERM, SIGBUS, SIGSEGV.
XChange ".swp" to ".vim", because it give a hint who created the file?
XUse termcap 'ts' and 'fs' entries for setting the window title. Check 'hs'
X and use minimum of 'ws' (if present) and Columns to truncate the title.
XWhen writing check for file exists but no permission, "Permission denied".
XIn dosub() regexec is called twice for the same line. Try to avoid this.
XWhen line is too long to fit on screen, don't display it.
XWhen inserting makes cursor go past end of screen, scroll up in insertchar().
XWindow updating from memline.c: insert/delete/replace line.
XOptimize ml_append() for speed, esp. for reading a file.
XV..c should keep indent when 'ai' is set, just like <count>cc.
XIn visual select mode: Inclusion or exclusion of char under cursor depends
X on movement command. "vwd" and "dw" do the same???
XFind out why macros of Stephen Riehm are working strange.
X:s///p prints the line after a substitution.
XMake CTRL-R (insert register contents) also work in command line mode.
XUpdatescript() can be done faster with a string instead of a char.
XAdd arguments to ":args", like ":next".
XWhen searching with 'n' give message when getting back where the search first
X started. Remember start of search in '/ mark.
XAdd option that scrolls screen to put cursor in middle of screen after search.
XAdd \! to search patterns: matches string that does not match previous atom.
XScreen updating is inefficient with CTRL-F and CTRL-B when there are long lines.
XUse 'backupdir' for all backup files if it starts with '>'.
XWhen writing a file, name it "foo.new". Then rename "foo" to "foo.bak" and
X "foo.new" to "foo". If dir is not writable or on write error copy "foo"
X to "backupdir/foo.bak" and overwrite "foo". Check for correct group/owner
X and try to set it if not. NO: this breaks with hard links.
X INSTEAD: make Amiga and MSDOS work like unix: first make copy of file, then
X truncate and overwrite original file. Use an option for this, default
X on for Unix, off for Amiga/MSDOS.
XUse CTRL-E and CTRL-Y in insert mode for scroll up/down?
XUppercase characters in ex commands can be made lowercase?
XAdd t_del, code for delete key (termcap 'kD') and maybe some other keys:
X 'kI' insert key, 'kL' delete line, t_bs 'bs', etc.
XFiltering a block should only apply to the block, not to the whole lines. When
X the number of lines is increased, add lines. When decreased, padd with
X spaces or delete?
XCTRL-V > should move the block, not whole lines.
XAdd commands to move selected text, without deselecting.
XAdd "p" command to swap selected text with unnamed buffer.
XAdd "P" command to insert contents of unnamed buffer, move selected text to
X position of previous deleted (to swap foo and bar in " + foo")
XIn out-of-memory situations: Free allocated space in undo (after asking).
X8-bit codes between 0x80 and 0xa0 cannot be typed directly (mostly msdos
X problem). Need more codes for delete key and more function keys. Use
X 2-byte code? (see xvim).
XInsert octal numbers with CTRL-V o, hexadecimal with CTRL-V x and binary
X with CTRL-V b.
XList mappings: Once with and without ^ and ~ (meta keys). Use "F1" and "PgUp"
X for MSDOS default mappings.
XAdd option that tells which characters to display directly, e.g.
X ":set gr=32-126,140-244", others are displayed with ^ and ~ and +
XAdd option to show character value in octal, decimal, hex and screen code.
XHow does vi detect whether a filter has messed up the screen? Check source.
X After ":w !command" a wait_return?
XImprove screen updating code for doput() (use s_ins()).
XWith 'p' command on last line: scroll screen up (also for terminals without
X insert line command).
XAmiga: ExpandWildCards in amiga.c: don't expand if there are no wildcards.
Xunix: Speedup wildcard expansion of "*", "~" and "$": do it internally, more
X complicated things can still be done with the shell.
XOnly do wildcard expansion with 'wildchar' when entering a command that has a
X file name as argument (:r :w :! :e :f :n)?
XUnix: When comparing two file names to see if they are the same file use stat()
X and compare device/inode; much faster than FullPathName()
XIn regexp.c: "\^" after "\|" or "\(" is start of line, and "\$" before "\|"
X and "\)" is end of line.
XRemember the "last changed" time of the edited file and check it before
X overwriting; another user may have changed it.
XSupport for command lines longer than 256 characters (for EXINIT).
XOption for filter when reading/writing a file for compression or crypting.
XOption to set time for emsg() sleep. Interrupt sleep when key is typed? sleep
X before second message?
XDelete message after new command has been entered and have waited for key.
XAdd "next tag" command for tags that have multiple hits.
XSupport static tags: first search for tags with current filename: "foo.c:bar",
X then for global tags (without a filename).
XHistory stack for . command?
XUse insert/delete char when terminal supports it.
XWith undo with simple line delete/insert: optimize screen updating.
XOptimize screen redraw for slow terminals.
X"edit" option: when off changing the buffer is not possible.
XAdd "-d null" for editing from a script file without displaying.
XAdd "-R" for readonly mode (ex has it).
XWhen writing to a readonly file, ask for permission to overwrite it (if file can
X be made writable) and restore file to readonly afterwards.
XMSDOS: search for _exrc in the directory where the binary is, instead
X of using $VIM\_exrc.
XIn insert mode: Remember the characters that were removed with backspace and
X re-insert them one at a time with <key1>, all together with <key2>.
XAmiga: Add possibility to set a keymap. The code in amiga.c does not work yet.
XImplement 'redraw' option.
XAdd possibility to put the value of an option into the text: "'lines'p
XUnix: WildExpand: Without csh file name with embedded space will be split in two.
XWith wildcard expansion after '%' and '#', expand current/alternate file name, so
X it can be edited.
XAdd special code to 'sections' option to define something else but '{' or '}'
X as the start of a section (e.g. one shiftwidth to the right).
XNopaste option: Mappings with non-printable characters are OK.
XAdd 'indent' option: Always use this amount of indent when starting a new line
X and when formatting text.
XAdd 'crown' option to 'Q' command: preserve indent of second line.
XWhen formatting with 'Q', break at paragraph boundaries (empty lines).
XWhen 'textwidth' is negative, use for 'Q' only, no automatic formatting.
XAdd option 'comment', initally "/*,*,*/,#", giving the characters at start of
X a line that should be left alone by the internal formatting.
XAfter formatting with Q the cursor is on the end of the last line; with = and
X when formatprg is set it is at the start of the first line. Not good.
XAdd 'scrolloff': scroll when cursor is less then 'scrolloff' lines from top/bottom.
XAdd option to switch off ignoring braces inside quotes for "%" command??
XUse pipes for filtering on unix.
XAllow for +command and -option on any position in argv[].
XAdd commands like ]] and [[ that do not include the line jumped to.
XWhen :unab without matching "from" part and several matching "to" parts,
X delete the entry that was used last, instead of the first in the list.
XAfter :set nowrap remove superflous redraw with wrong hor. offset if cursor
X is right of the screen.
XAdd -x option: crypt/decrypt when writing/reading file.
XAdd count to ':', gives ":.,.+count-1"
XImprove online help: Fit into the window (also small ones), hypertext, etc.
X (See also dh1:text/vi/vi.help). View help just like a file?
XSupport several errorformats, use the first format that matches.
XRecognize "$*" in 'makeprg'; replace it by the arguments to :make.
XAllow multiple arguments to :unmap.
XAdd option that contains characters which are included in identifiers;
X default "[a-bA-B0-9]_", for LISP "[a-bA-B0-9]_-".
XWith :s///c highlight the pattern to be replaced and replace \&, ~, etc. when
X showing the replacement pattern.
XAdd mappings for visual mode; use marks for start/end of selected text.
XWith ambigious mapping, print conflicting entry.
XIn insert mode add # for CTRL-R (alternate filename).
XHighlight search string when found?
XCommand line: cursor up on empty line: go to previous command, on non-empty line:
X go to previous matching command.
XAdd command to clear all mappings, "clearmap".
XAdd text justification option.
XWhen the edited file is a symlink, try to put the .swp file in the same dir as
X the actual file. Adjust FullName().
XAdd new operator: clear, make area white (replace with spaces)
XAdd put function that replaces the text under it.
XAfter "inv"ing an option show the value: ":set invpaste" gives "paste is off".
XAfter ":read" set '[ and '] marks.
XIn fileio.c replace filemess() by outputting strings after each other (only
X one wait_return().
XAfter executing a shell, put tty back in raw mode (for shells that mess with
X the tty settings)
XMake program to transform termcap entries into something that fits in tcarr
X structure.
XImprove error messages: when expanding '%': "no filename to substitute for '%'"
X when expanding '#': "no alternate filename to substitute for '#'"
XPut warnings in some color (errors are inverted, normal messages plain).
XCheck handling of CTRL-V and '\' for ":" commands that do not have TRLBAR.
XWhen a file cannot be opened but does exist, give error message.
XIf file does not exists, check if directory exists.
XMSDOS: t_cv and t_ci not set, but do invert char under cursor.
XAdd option to switch off move to start of line (Waggoner/12 and 13).
XCommand to show keys that are not used and available for mapping.
XSettings edit mode: make file with ":set opt=xx", edit it, parse it as ex commands.
XWhen memory gets low, reduce the number of undo levels (with confirmation).
XAdd 'para_regex' option: regular expression for end of paragraph.
Xtag-completion command: when tag found, replace it by the prototype, when not
X found, replace it by the longest match.
Xmake listings in a more-like way (mappings, files, settings, etc.).
X":set -w all": list one option per line.
XBefore overwriting a non-writable file with ":w!" ask for permission.
XAmiga: test for 'w' flag when reading a file.
XWhen appending to the last line, causing it to wrap, screen redraw first does it
X at a wrong position.
XInclude patches for Russian text (Marinichev/4).
XEx commands in a mapping should not be put in the command line history.
XOption not to change the search string when using a :tag command.
XError message for ambiguous mapping: Include the arguments.
XAdd ":retab". When "et" set, convert tabs to spaces, when "noet" vice versa.
X ":retab 8" will replace tabs and spaces with the current "ts" setting
X to a "ts" of 8.
X:table command (Webb)
XAdd command to go to last non-blank in line (like 0 vs. ^, $ vs. ???)
XAdd 'backupdiralways', 'bda' option for 'bdir', like 'da' for 'dir'.
XAdd option to recognize identifiers with everything but spaces ('forth'?).
X Adjust isidchar().
XMSDOS: How about supporting function keys #11 and #12?
XWith blockwise visual mode and "c" command, insert same text in every line.
XSearch filenames for starting with $HOME and replace it with "~" when displaying.
XFor 'shell' option add possibility to give arguments for fast start (e.g. -f).
X Not to be used for ":shell".
XMake ":e file1 file2" work like ":n file1 file2"?
XGive message "No lines in buffer" when last line in buffer deleted.
XWhen displaying (file xx of yy), add "not" when curbuf is not file xx.
XAdd commands to do things in all buffers: ":Substitute", ":searchall", etc.
XMake ":sleep" accept floating point numbers, like ":sleep 0.01".
XWhen in replace mode and 'expandtab' set, make tab look like spaces.
XSupport multiple search buffers, so macros can be made without side effects.
XWith :read set '[ and '] to start/end of new lines
XMake builtin termcaps with a configuration file and a program to translate
X it into a .h file.
XUse %> and #> for filename without path?
XAllow multiple arguments for ":edit", add them to the argument list.
XAllow multiple arguments for ":read", read all the files.
XMake options from modelines only used in the buffer where the file is read.
XFor visual mode: "." does a search for the string in the marked area. Only
X when less than two lines. What key to use for backward search?
XMatching with "%" should be configurable. 'matchstrings' =
X (/*,*/),(^#if,^#else,^#endif)
XExpanding ~ and $VAR in options should be done not only for the first entry.
XAdd 'resizecmd' option: vi command to be executed when window is resized.
XDo not accept mappings when waiting for key hit with --more--.
XAdd option to make settings from modelines valid only in the file where they
X were set. Reset options when starting to edit another file.
XKeep output from listings in a window, so you can have a look at it while
X working in another window. Put cmdline in a separate window?
XKeyword completion code should use the case from the match.
XAdd regular expression \{m,n\}: m to n matches. \{m\} is m matches, \{m,\} is
X at least m matches. Also do \{,n\}: up to n matches.
XWhen 'backup' is not set and 'writebackup is set, use a unique name for the
X backup file, don't deleted the ".bak" file.
X
XFrom Elvis:
Xfontchanges recognized "\\fB" etc.
X:color command
X:if and friends, conditional statements
XRead .exfilerc when starting to edit a new file (can be used to load macros for
X specific file type).
XChange cursor shape in command/insert mode.
X'flipcase' variable: upper/lower case pairs.
X
XFrom nvi:
X'cdpath' option.
X'remapmax' option.
XAllow editing lines that do not fit in the window.
X
XFrom xvim:
XUse '\' before commands to make them linewise.
XAllow a newline in search patterns (also for :s, can delete newline).
X Add BOW, EOW, NEWL, NLORANY, NLBUTANY, magic 'n' and 'r', etc.
XAdd register for ':', '?' and '/' commands? (yank_buf()).
XSupport mouse control (also weissman/1). With option to switch it off to
X enable copy/paste.
XSearching in help file.
Xget code for backspace from termcap.
XRemember last cursor position, optimize setcursor().
X
XFrom xvi:
XCTRL-_ : swap 8th bit of character
X
XFrom vile:
XCTRL-X e: edit file name under the cursor (like ^] and *)
XShow unprintable characters in hex.
XUse scrollbar.
XWhen horizontal scrolling, use '<' and '>' for lines continuing outside of window.
X
XFar future extentions:
X
XAllow vertical splitting of screen (once).
XAllow editing beyond end of line, just like there are all spaces. Switch this
X on with an option or special insert mode command. Also allow editing
X above start and below end of buffer.
XMSdos: use extended or expanded memory.
XWhen executing macro's: Save each line for undo only once.
XSmart cut/paste: recognize words and adjust spaces before/after them.
XAdd 'notwsuffixes' option: suffixes for files where 'tw' should be 0.
XMake files with suffix in 'suffixes' option always appear in list of matched
X files, but at the end.
XKeyword completion: first look in the file for a match, then in a dictionary (Webb).
XOption verbose; when on keep the screen uptodate, when off only redisplay when
X input needed.
XChange the output to the message line. Don't redraw the screen until the next
X vi command. Remember message line for redraw. Integrate the command line
X in updateScreen().
XMode to keep text formatted while inserting/deleting. Use soft/hard returns with
X an option to switch this off.
XMode to keep C-code formatted (sort of on-line indent). Use colors for
X keywords, comments, etc.
XKorn-shell like command line editing (like editing a single line with vi). Use
X :cmap! for mappings. Can be implemented like a buffer containing command
X lines.
XAdd column numbers to ":" commands (:line1:col1,line2:col2 cmd). Block can be
X selected with CTRL-V.
XAdd 'hidecomment' option: don't display comments in /* */ and after //.
XAdd open mode, use it when terminal has no cursor positioning.
XAdd macro language with real functions.
XFile in local directory to store contents of named registers and named marks.
X Write when quitting, read when starting.
XSpecial "drawing mode": a line is drawn where the cursor is moved to. Backspace
X deletes along the line (from jvim).
XSave cursor position (and other things) for a next editing session.
XPerform commands on multiple windows (:W%s/foo/bar/g), multiple arguments (:A)
X or multiple buffers (:B).
END_OF_FILE
if test 19200 -ne `wc -c <'vim/todo'`; then
echo shar: \"'vim/todo'\" unpacked with wrong size!
fi
# end of 'vim/todo'
fi
echo shar: End of archive 20 \(of 26\).
cp /dev/null ark20isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:30 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 40
Archive-name: vim/part21

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/csearch.c vim/src/main.c vim/src/makefile.unix
# vim/src/regsub.c vim/src/structs.h
# Wrapped by kent@sparky on Mon Aug 15 21:44:12 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 21 (of 26)."'
if test -f 'vim/src/csearch.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/csearch.c'\"
else
echo shar: Extracting \"'vim/src/csearch.c'\" \(14449 characters\)
sed "s/^X//" >'vim/src/csearch.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*
X *

X * csearch.c: dosub() and doglob() for :s, :g and :v
X */
X
X#include "vim.h"
X#include "globals.h"


X#include "proto.h"
X#include "param.h"
X

X/* we use modified Henry Spencer's regular expression routines */
X#include "regexp.h"
X
X/* dosub(lp, up, cmd)
X *
X * Perform a substitution from line 'lp' to line 'up' using the
X * command pointed to by 'cmd' which should be of the form:
X *
X * /pattern/substitution/gc
X *
X * The trailing 'g' is optional and, if present, indicates that multiple
X * substitutions should be performed on each line, if applicable.
X * The trailing 'c' is optional and, if present, indicates that a confirmation
X * will be asked for each replacement.
X * The usual escapes are supported as described in the regexp docs.
X *
X * use_old == 0 for :substitute
X * use_old == 1 for :&
X * use_old == 2 for :~


X */
X
X void

Xdosub(lp, up, cmd, nextcommand, use_old)
X linenr_t lp;
X linenr_t up;
X char_u *cmd;
X char_u **nextcommand;
X int use_old;
X{
X linenr_t lnum;
X long i;
X char_u *ptr;
X char_u *old_line;
X regexp *prog;
X long nsubs = 0;
X linenr_t nlines = 0;
X static int do_all = FALSE; /* do multiple substitutions per line */
X static int do_ask = FALSE; /* ask for confirmation */
X char_u *pat = NULL, *sub = NULL;
X static char_u *old_sub = NULL;
X int delimiter;
X int sublen;
X int got_quit = FALSE;
X int got_match = FALSE;
X int temp;
X int which_pat;
X
X if (use_old == 2)
X which_pat = 2; /* use last used regexp */
X else
X which_pat = 1; /* use last substitute regexp */
X
X /* new pattern and substitution */
X if (use_old == 0 && *cmd != NUL && strchr("0123456789gcr|\"", *cmd) == NULL)
X {
X if (isalpha(*cmd)) /* don't accept alpha for separator */
X {
X emsg(e_invarg);
X return;
X }
X /*
X * undocumented vi feature:
X * "\/sub/" and "\?sub?" use last used search pattern (almost like //sub/r).
X * "\&sub&" use last substitute pattern (like //sub/).


X */
X if (*cmd == '\\')
X {

X ++cmd;
X if (strchr("/?&", *cmd) == NULL)
X {
X emsg(e_backslash);
X return;
X }
X if (*cmd != '&')
X which_pat = 0; /* use last '/' pattern */
X pat = (char_u *)""; /* empty search pattern */
X delimiter = *cmd++; /* remember delimiter character */
X }
X else /* find the end of the regexp */
X {
X delimiter = *cmd++; /* remember delimiter character */
X pat = cmd; /* remember start of search pattern */
X cmd = skip_regexp(cmd, delimiter);
X if (cmd[0] == delimiter) /* end delimiter found */
X *cmd++ = NUL; /* replace it by a NUL */
X }
X
X /*
X * Small incompatibility: vi sees '\n' as end of the command, but in
X * Vim we want to use '\n' to find/substitute a NUL.
X */
X sub = cmd; /* remember the start of the substitution */
X
X while (cmd[0])
X {
X if (cmd[0] == delimiter) /* end delimiter found */
X {
X *cmd++ = NUL; /* replace it by a NUL */
X break;
X }
X if (cmd[0] == '\\' && cmd[1] != 0) /* skip escaped characters */
X ++cmd;
X ++cmd;
X }
X
X free(old_sub);
X old_sub = strsave(sub);
X }
X else /* use previous pattern and substitution */
X {
X if (old_sub == NULL) /* there is no previous command */
X {
X emsg(e_nopresub);
X return;
X }
X pat = NULL; /* myregcomp() will use previous pattern */
X sub = old_sub;
X }
X
X /*
X * find trailing options
X */
X if (!p_ed)
X {
X if (p_gd) /* default is global on */
X do_all = TRUE;
X else
X do_all = FALSE;
X do_ask = FALSE;
X }
X while (*cmd)
X {
X /*
X * Note that 'g' and 'c' are always inverted, also when p_ed is off
X * 'r' is never inverted.
X */
X if (*cmd == 'g')
X do_all = !do_all;
X else if (*cmd == 'c')
X do_ask = !do_ask;
X else if (*cmd == 'r') /* use last used regexp */
X which_pat = 2;
X else
X break;
X ++cmd;
X }
X
X /*
X * check for a trailing count
X */
X skipspace(&cmd);
X if (isdigit(*cmd))
X {
X i = getdigits(&cmd);


X if (i <= 0)

X {
X emsg(e_zerocount);
X return;
X }
X lp = up;
X up += i - 1;
X }
X
X /*
X * check for trailing '|', '"' or '\n'
X */
X skipspace(&cmd);
X if (*cmd)
X {
X if (strchr("|\"\n", *cmd) == NULL)
X {
X emsg(e_trailing);


X return;
X }
X else

X *nextcommand = cmd;
X }
X
X if ((prog = myregcomp(pat, 1, which_pat)) == NULL)
X {
X emsg(e_invcmd);
X return;
X }
X
X /*
X * ~ in the substitute pattern is replaced by the old pattern.
X * We do it here once to avoid it to be replaced over and over again.
X */
X sub = regtilde(sub, (int)p_magic);
X
X old_line = NULL;
X for (lnum = lp; lnum <= up && !(got_int || got_quit); ++lnum)
X {
X ptr = ml_get(lnum);
X if (regexec(prog, ptr, TRUE)) /* a match on this line */
X {
X char_u *new_end, *new_start = NULL;
X char_u *old_match, *old_copy;
X char_u *prev_old_match = NULL;
X char_u *p1;
X int did_sub = FALSE;
X int match, lastone;
X
X /* make a copy of the line, so it won't be taken away when updating
X the screen */
X if ((old_line = strsave(ptr)) == NULL)
X continue;
X regexec(prog, old_line, TRUE); /* match again on this line to update the pointers. TODO: remove extra regexec() */
X if (!got_match)
X {
X setpcmark();
X got_match = TRUE;
X }
X
X old_copy = old_match = old_line;
X for (;;) /* loop until nothing more to replace */
X {
X /*
X * Save the position of the last change for the final cursor
X * position (just like the real vi).
X */


X curwin->w_cursor.lnum = lnum;

X curwin->w_cursor.col = (int)(prog->startp[0] - old_line);
X
X /*
X * Match empty string does not count, except for first match.
X * This reproduces the strange vi behaviour.
X * This also catches endless loops.
X */
X if (old_match == prev_old_match && old_match == prog->endp[0])
X {
X ++old_match;
X goto skip;
X }
X old_match = prog->endp[0];
X prev_old_match = old_match;
X
X while (do_ask) /* loop until 'y', 'n' or 'q' typed */
X {
X temp = RedrawingDisabled;
X RedrawingDisabled = FALSE;
X comp_Botline(curwin);
X updateScreen(CURSUPD);
X /* same highlighting as for wait_return */
X (void)set_highlight('r');
X msg_highlight = TRUE;
X smsg((char_u *)"replace by %s (y/n/q)?", sub);
X showruler(TRUE);
X setcursor();
X RedrawingDisabled = temp;
X if ((i = vgetc()) == 'q' || i == ESC || i == Ctrl('C'))
X {
X got_quit = TRUE;
X break;
X }
X else if (i == 'n')
X goto skip;
X else if (i == 'y')
X break;
X }
X if (got_quit)
X break;
X
X /* get length of substitution part */
X sublen = regsub(prog, sub, old_line, 0, (int)p_magic);
X if (new_start == NULL)
X {
X /*
X * Get some space for a temporary buffer to do the substitution
X * into.
X */
X if ((new_start = alloc((unsigned)(STRLEN(old_line) + sublen + 5))) == NULL)
X goto outofmem;
X *new_start = NUL;
X }
X else
X {
X /*
X * extend the temporary buffer to do the substitution into.
X */
X if ((p1 = alloc((unsigned)(STRLEN(new_start) + STRLEN(old_copy) + sublen + 1))) == NULL)
X goto outofmem;
X STRCPY(p1, new_start);
X free(new_start);
X new_start = p1;
X }
X
X for (new_end = new_start; *new_end; new_end++)
X ;
X /*
X * copy up to the part that matched
X */
X while (old_copy < prog->startp[0])
X *new_end++ = *old_copy++;
X
X regsub(prog, sub, new_end, 1, (int)p_magic);
X nsubs++;
X did_sub = TRUE;
X
X /*
X * Now the trick is to replace CTRL-Ms with a real line break.
X * This would make it impossible to insert CTRL-Ms in the text.
X * That is the way vi works. In Vim the line break can be
X * avoided by preceding the CTRL-M with a CTRL-V. Now you can't
X * precede a line break with a CTRL-V, big deal.
X */
X while ((p1 = STRCHR(new_end, CR)) != NULL)
X {
X if (p1 == new_end || p1[-1] != Ctrl('V'))
X {
X if (u_inssub(lnum)) /* prepare for undo */
X {
X *p1 = NUL; /* truncate up to the CR */
X mark_adjust(lnum, MAXLNUM, 1L);
X ml_append(lnum - 1, new_start, (colnr_t)(p1 - new_start + 1), FALSE);
X ++lnum;
X ++up; /* number of lines increases */
X STRCPY(new_start, p1 + 1); /* copy the rest */
X new_end = new_start;
X }
X }
X else /* remove CTRL-V */
X {
X STRCPY(p1 - 1, p1);
X new_end = p1;
X }
X }
X
X old_copy = prog->endp[0]; /* remember next character to be copied */
X /*
X * continue searching after the match
X * prevent endless loop with patterns that match empty strings,
X * e.g. :s/$/pat/g or :s/[a-z]* /(&)/g
X */
Xskip:
X match = -1;
X lastone = (*old_match == NUL || got_int || got_quit || !do_all);
X if (lastone || do_ask || (match = regexec(prog, old_match, (int)FALSE)) == 0)
X {
X if (new_start)
X {
X /*
X * Copy the rest of the line, that didn't match.
X * Old_match has to be adjusted, we use the end of the line
X * as reference, because the substitute may have changed
X * the number of characters.
X */
X STRCAT(new_start, old_copy);
X i = old_line + STRLEN(old_line) - old_match;
X if (u_savesub(lnum))
X ml_replace(lnum, new_start, TRUE);
X
X free(old_line); /* free the temp buffer */
X old_line = new_start;
X new_start = NULL;
X old_match = old_line + STRLEN(old_line) - i;
X if (old_match < old_line) /* safety check */
X {
X EMSG("dosub internal error: old_match < old_line");
X old_match = old_line;
X }
X old_copy = old_line;
X }
X if (match == -1 && !lastone)
X match = regexec(prog, old_match, (int)FALSE);
X if (match <= 0) /* quit loop if there is no more match */
X break;
X }
X /* breakcheck is slow, don't call it too often */
X if ((nsubs & 15) == 0)
X breakcheck();
X
X }
X if (did_sub)
X ++nlines;
X free(old_line); /* free the copy of the original line */
X old_line = NULL;
X }
X /* breakcheck is slow, don't call it too often */


X if ((lnum & 15) == 0)
X breakcheck();

X }
X
Xoutofmem:
X free(old_line); /* may have to free an allocated copy of the line */
X if (nsubs)
X {
X CHANGED;
X updateScreen(CURSUPD); /* need this to update LineSizes */
X beginline(TRUE);
X if (nsubs > p_report)
X smsg((char_u *)"%s%ld substitution%s on %ld line%s",
X got_int ? "(Interrupted) " : "",
X nsubs, plural(nsubs),
X (long)nlines, plural((long)nlines));
X else if (got_int)
X emsg(e_interr);
X else if (do_ask)
X MSG("");
X }
X else if (got_int) /* interrupted */
X emsg(e_interr);
X else if (got_match) /* did find something but nothing substituted */
X MSG("");
X else /* nothing found */
X emsg(e_nomatch);
X
X free(prog);
X}
X
X/*
X * doglob(cmd)
X *
X * Execute a global command of the form:
X *
X * g/pattern/X : execute X on all lines where pattern matches
X * v/pattern/X : execute X on all lines where pattern does not match
X *
X * where 'X' is an EX command
X *
X * The command character (as well as the trailing slash) is optional, and
X * is assumed to be 'p' if missing.
X *
X * This is implemented in two passes: first we scan the file for the pattern and
X * set a mark for each line that (not) matches. secondly we execute the command
X * for each line that has a mark. This is required because after deleting
X * lines we do not know where to search for the next match.


X */
X
X void

Xdoglob(type, lp, up, cmd)
X int type;
X linenr_t lp, up;
X char_u *cmd;
X{
X linenr_t lnum; /* line number according to old situation */
X linenr_t old_lcount; /* curbuf->b_ml.ml_line_count before the command */
X int ndone;
X
X char_u delim; /* delimiter, normally '/' */
X char_u *pat;
X regexp *prog;
X int match;
X int which_pat;
X
X if (global_busy)
X {
X EMSG("Cannot do :global recursive");
X ++global_busy;
X return;
X }
X
X which_pat = 2; /* default: use last used regexp */
X
X /*
X * undocumented vi feature:
X * "\/" and "\?": use previous search pattern.
X * "\&": use previous substitute pattern.


X */
X if (*cmd == '\\')
X {

X ++cmd;
X if (strchr("/?&", *cmd) == NULL)
X {
X emsg(e_backslash);
X return;
X }
X if (*cmd == '&')
X which_pat = 1; /* use previous substitute pattern */
X else
X which_pat = 0; /* use previous search pattern */
X ++cmd;
X pat = (char_u *)"";
X }
X else
X {
X delim = *cmd; /* get the delimiter */
X if (delim)
X ++cmd; /* skip delimiter if there is one */
X pat = cmd; /* remember start of pattern */
X cmd = skip_regexp(cmd, delim);
X if (cmd[0] == delim) /* end delimiter found */
X *cmd++ = NUL; /* replace it by a NUL */
X }
X
X reg_ic = p_ic; /* set "ignore case" flag appropriately */
X
X if ((prog = myregcomp(pat, 2, which_pat)) == NULL)
X {
X emsg(e_invcmd);
X return;
X }
X MSG("");
X
X/*
X * pass 1: set marks for each (not) matching line
X */
X ndone = 0;
X for (lnum = lp; lnum <= up && !got_int; ++lnum)
X {
X match = regexec(prog, ml_get(lnum), (int)TRUE); /* a match on this line? */
X if ((type == 'g' && match) || (type == 'v' && !match))
X {
X ml_setmarked(lnum);
X ndone++;
X }
X /* breakcheck is slow, don't call it too often */


X if ((lnum & 15) == 0)
X breakcheck();

X }
X
X/*
X * pass 2: execute the command for each line that has been marked
X */
X if (got_int)
X MSG("Interrupted");
X else if (ndone == 0)
X msg(e_nomatch);
X else
X {
X global_busy = 1;
X dont_sleep = 1; /* don't sleep in emsg() */
X no_wait_return = 1; /* dont wait for return until finished */
X need_wait_return = FALSE;
X RedrawingDisabled = TRUE;
X old_lcount = curbuf->b_ml.ml_line_count;
X did_msg = FALSE;
X while (!got_int && (lnum = ml_firstmarked()) != 0 && global_busy == 1)
X {
X /*
X * If there was a message from the previous command, scroll
X * the lines up for the next, otherwise it will be overwritten.
X * did_msg is set by msg_start().
X */
X if (did_msg)
X {
X cmdline_row = msg_row;
X did_msg = FALSE;
X }
X curwin->w_cursor.lnum = lnum;


X curwin->w_cursor.col = 0;

X if (*cmd == NUL || *cmd == '\n')
X docmdline((char_u *)"p");
X else
X docmdline(cmd);
X breakcheck();
X }
X
X RedrawingDisabled = FALSE;
X global_busy = 0;
X dont_sleep = 0;
X no_wait_return = 0;
X if (need_wait_return) /* wait for return now */
X wait_return(FALSE);
X
X screenclear();
X updateScreen(CURSUPD);


X msgmore(curbuf->b_ml.ml_line_count - old_lcount);
X }
X

X ml_clearmarked(); /* clear rest of the marks */
X free(prog);
X}
END_OF_FILE
if test 14449 -ne `wc -c <'vim/src/csearch.c'`; then
echo shar: \"'vim/src/csearch.c'\" unpacked with wrong size!
fi
# end of 'vim/src/csearch.c'
fi
if test -f 'vim/src/main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/main.c'\"
else
echo shar: Extracting \"'vim/src/main.c'\" \(14502 characters\)
sed "s/^X//" >'vim/src/main.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X#define EXTERN
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X
X#ifdef SPAWNO
X# include <spawno.h> /* special MSDOS swapping library */
X#endif
X
Xstatic void usage __PARMS((int));
X
X static void
Xusage(n)
X int n;
X{
X register int i;
X static char_u *(use[]) = {(char_u *)"[file ..]\n",
X (char_u *)"-t tag\n",
X (char_u *)"-e [errorfile]\n"};
X static char_u *(errors[]) = {(char_u *)"Unknown option\n", /* 0 */
X (char_u *)"Too many arguments\n", /* 1 */
X (char_u *)"Argument missing\n", /* 2 */
X };
X
X fprintf(stderr, (char *)errors[n]);
X fprintf(stderr, "usage:");
X for (i = 0; ; ++i)
X {
X fprintf(stderr, " vim [options] ");
X fprintf(stderr, (char *)use[i]);
X if (i == (sizeof(use) / sizeof(char_u *)) - 1)
X break;
X fprintf(stderr, " or:");
X }
X fprintf(stderr, "\noptions:\t-v\t\treadonly mode (view)\n");
X fprintf(stderr, "\t\t-n\t\tno swap file, use memory only\n");
X fprintf(stderr, "\t\t-b\t\tbinary mode\n");
X fprintf(stderr, "\t\t-r\t\trecovery mode\n");
X#ifdef AMIGA
X fprintf(stderr, "\t\t-x\t\tdon't use newcli to open window\n");
X fprintf(stderr, "\t\t-d device\tuse device for I/O\n");
X#endif
X fprintf(stderr, "\t\t-T terminal\tset terminal type\n");
X fprintf(stderr, "\t\t-o[N]\t\topen N windows (def: one for each file)\n");
X fprintf(stderr, "\t\t+\t\tstart at end of file\n");
X fprintf(stderr, "\t\t+lnum\t\tstart at line lnum\n");
X fprintf(stderr, "\t\t-c command\texecute command first\n");
X fprintf(stderr, "\t\t-s scriptin\tread commands from script file\n");
X fprintf(stderr, "\t\t-w scriptout\twrite commands in script file\n");
X mch_windexit(1);
X}
X
X#ifdef USE_LOCALE
X# include <locale.h>
X#endif
X
X void
Xmain(argc, argv)


X int argc;
X char **argv;
X{

X char_u *initstr; /* init string from the environment */
X char_u *term = NULL; /* specified terminal name */
X char_u *fname = NULL; /* file name from command line */
X char_u *command = NULL; /* command from + or -c option */
X char_u *tagname = NULL; /* tag from -t option */
X int c;
X int doqf = 0;
X int i;
X int bin_mode = FALSE; /* -b option used */
X int win_count = 1; /* number of windows to use */
X
X#ifdef USE_LOCALE
X setlocale(LC_ALL, ""); /* for ctype() and the like */
X#endif
X
X/*
X * Check if we have an interactive window.
X * If not, open one with a newcli command (needed for :! to work).
X * check_win will also handle the -d argument (for the Amiga).
X */
X check_win(argc, argv);
X
X/*
X * allocate the first window and buffer. Can't to anything without it
X */
X if ((curwin = win_alloc(NULL)) == NULL ||
X (curbuf = buflist_new(NULL, NULL, 1L, FALSE)) == NULL)
X mch_windexit(0);
X curwin->w_buffer = curbuf;
X
X/*
X * If the executable is called "view" we start in readonly mode.
X */
X if (STRCMP(gettail((char_u *)argv[0]), (char_u *)"view") == 0)
X {
X readonlymode = TRUE;


X curbuf->b_p_ro = TRUE;

X p_uc = 0;
X }
X
X ++argv;
X /*
X * Process the command line arguments
X * '-c {command}' execute command
X * '+{command}' execute command
X * '-s scriptin' read from script file
X * '-w scriptout' write to script file
X * '-v' view
X * '-b' binary
X * '-n' no .vim file
X * '-r' recovery mode
X * '-x' open window directly, not with newcli
X * '-o[N]' open N windows (default: number of files)
X * '-T terminal' terminal name
X */
X while (argc > 1 && ((c = argv[0][0]) == '+' || (c == '-' &&
X strchr("vnbrxocswTd", c = argv[0][1]) != NULL && c != NUL)))
X {
X --argc;
X switch (c)
X {
X case '+': /* + or +{number} or +/{pat} or +{command} */
X c = argv[0][1];


X if (c == NUL)

X command = (char_u *)"$";
X else

X command = (char_u *)&(argv[0][1]);
X break;
X
X case 'v':
X readonlymode = TRUE;
X curbuf->b_p_ro = TRUE;
X /*FALLTHROUGH*/
X
X case 'n':
X p_uc = 0;
X break;
X
X case 'b':
X bin_mode = TRUE; /* postpone to after reading .exrc files */
X break;
X
X case 'r':
X recoverymode = 1;
X break;
X
X case 'x':
X break; /* This is ignored as it is handled in check_win() */
X
X case 'o':
X c = argv[0][2];
X if (c != NUL && !isdigit(c))
X {
X fprintf(stderr, "-o option needs numeric argument (or none)\n");
X mch_windexit(2);
X }
X win_count = atoi(&(argv[0][2])); /* 0 means: number of files */
X break;
X
X default: /* options with argument */
X ++argv;
X --argc;
X if (argc < 1)
X usage(2);
X
X switch (c)
X {
X case 'c': /* -c {command} */
X command = (char_u *)&(argv[0][0]);
X break;
X
X case 's':
X if ((scriptin[0] = fopen(argv[0], READBIN)) == NULL)
X {
X fprintf(stderr, "cannot open %s for reading\n", argv[0]);
X mch_windexit(2);
X }
X break;
X
X case 'w':
X if ((scriptout = fopen(argv[0], APPENDBIN)) == NULL)
X {
X fprintf(stderr, "cannot open %s for output\n", argv[0]);
X mch_windexit(2);
X }
X break;
X
X/*
X * The -T term option is always available and when TERMCAP is supported it
X * overrides the environment variable TERM.


X */
X case 'T':

X term = (char_u *)*argv;
X break;
X
X /* case 'd': This is ignored as it is handled in check_win() */
X }
X }
X ++argv;
X }
X
X /*
X * Allocate space for the generic buffers
X */
X if ((IObuff = alloc(IOSIZE)) == NULL || (NameBuff = alloc(MAXPATHL)) == NULL)
X mch_windexit(0);
X
X /* note that we may use mch_windexit() before mch_windinit()! */
X mch_windinit();
X set_init(); /* after mch_windinit because Rows is used */
X firstwin->w_height = Rows - 1;
X cmdline_row = Rows - 1;
X
X /*
X * Process the other command line arguments.
X */
X if (argc > 1)
X {
X c = argv[0][1];
X switch (argv[0][0])
X {
X case '-':
X switch (c)
X {
X case 'e': /* -e QuickFix mode */
X switch (argc)
X {
X case 2:
X if (argv[0][2]) /* -eerrorfile */
X p_ef = (char_u *)argv[0] + 2;
X break; /* -e */
X
X case 3: /* -e errorfile */
X ++argv;
X p_ef = (char_u *)argv[0];
X break;
X
X default: /* argc > 3: too many arguments */
X usage(1);
X }
X doqf = 1;
X break;
X
X case 't': /* -t tag or -ttag */
X switch (argc)
X {
X case 2:
X if (argv[0][2]) /* -ttag */
X {
X tagname = (char_u *)argv[0] + 2;
X break;
X }
X usage(2); /* argument missing */
X break;
X
X case 3: /* -t tag */
X ++argv;
X tagname = (char_u *)argv[0];
X break;
X
X default: /* argc > 3: too many arguments */
X usage(1);


X }
X break;
X
X default:

X usage(0);
X }
X break;
X
X default: /* must be a file name */
X#if !defined(UNIX) || defined(ARCHIE)
X if (ExpandWildCards(argc - 1, (char_u **)argv, &arg_count,
X &arg_files, TRUE, TRUE) == OK && arg_count != 0)
X {
X fname = arg_files[0];


X arg_exp = TRUE;
X }

X#else
X arg_files = (char_u **)argv;
X arg_count = argc - 1;
X fname = (char_u *)argv[0];
X#endif
X if (arg_count > 1)
X printf("%d files to edit\n", arg_count);


X break;
X }
X }
X

X RedrawingDisabled = TRUE;
X

X curbuf->b_nwindows = 1; /* there is one window */
X win_init(curwin); /* init cursor position */
X init_yank(); /* init yank buffers */
X termcapinit(term); /* get terminal capabilities */
X screenclear(); /* clear screen (just inits screen structures,
X because starting is TRUE) */
X
X#ifdef MSDOS /* default mapping for some often used keys */
X domap(0, "#1 :help\r", NORMAL); /* F1 is help key */
X domap(0, "\316R i", NORMAL); /* INSERT is 'i' */
X domap(0, "\316S \177", NORMAL); /* DELETE is 0x7f */
X domap(0, "\316G 0", NORMAL); /* HOME is '0' */
X domap(0, "\316w H", NORMAL); /* CTRL-HOME is 'H' */
X domap(0, "\316O $", NORMAL); /* END is '$' */
X domap(0, "\316u L", NORMAL); /* CTRL-END is 'L' */
X domap(0, "\316I \002", NORMAL); /* PageUp is '^B' */
X domap(0, "\316\204 1G", NORMAL); /* CTRL-PageUp is '1G' */
X domap(0, "\316Q \006", NORMAL); /* PageDown is '^F' */
X domap(0, "\316v G", NORMAL); /* CTRL-PageDown is 'G' */
X /* insert mode */
X domap(0, "#1 \017:help\r", INSERT); /* F1 is help key */
X domap(0, "\316R \033", INSERT); /* INSERT is ESC */
X /* note: extra space needed to avoid the same memory used for this
X and the one above, domap() will add a NUL to it */
X domap(0, "\316S \177", INSERT+CMDLINE); /* DELETE is 0x7f */
X domap(0, "\316G \017""0", INSERT); /* HOME is '^O0' */
X domap(0, "\316w \017H", INSERT); /* CTRL-HOME is '^OH' */
X domap(0, "\316O \017$", INSERT); /* END is '^O$' */
X domap(0, "\316u \017L", INSERT); /* CTRL-END is '^OL' */
X domap(0, "\316I \017\002", INSERT); /* PageUp is '^O^B' */
X domap(0, "\316\204 \017\061G", INSERT); /* CTRL-PageUp is '^O1G' */
X domap(0, "\316Q \017\006", INSERT); /* PageDown is '^O^F' */
X domap(0, "\316v \017G", INSERT); /* CTRL-PageDown is '^OG' */
X#endif
X
X msg_start(); /* in case a mapping is printed */
X no_wait_return = TRUE;
X
X/*
X * get system wide defaults (for unix)
X */
X#ifdef DEFVIMRC_FILE
X (void)dosource(DEFVIMRC_FILE);
X#endif
X
X/*
X * Try to read initialization commands from the following places:
X * - environment variable VIMINIT
X * - file s:.vimrc ($HOME/.vimrc for Unix)
X * - environment variable EXINIT
X * - file s:.exrc ($HOME/.exrc for Unix)
X * The first that exists is used, the rest is ignored.
X */
X if ((initstr = vimgetenv((char_u *)"VIMINIT")) != NULL)
X docmdline(initstr);
X else if (dosource((char_u *)SYSVIMRC_FILE) == FAIL)
X {
X if ((initstr = vimgetenv((char_u *)"EXINIT")) != NULL)
X docmdline(initstr);
X else
X (void)dosource((char_u *)SYSEXRC_FILE);
X }
X
X/*
X * Read initialization commands from ".vimrc" or ".exrc" in current directory.
X * This is only done if the 'exrc' option is set.
X * Because of security reasons we disallow shell and write commands now,
X * except for unix if the file is owned by the user or 'secure' option has been
X * reset in environmet of global ".exrc" or ".vimrc".
X * Only do this if VIMRC_FILE is not the same as SYSVIMRC_FILE or DEFVIMRC_FILE.
X */
X if (p_exrc)
X {
X#ifdef UNIX
X {
X struct stat s;
X
X /* if ".vimrc" file is not owned by user, set 'secure' mode */
X if (stat(VIMRC_FILE, &s) || s.st_uid != getuid())
X secure = p_secure;
X }
X#else
X secure = p_secure;
X#endif
X
X i = FAIL;
X if (fullpathcmp((char_u *)SYSVIMRC_FILE, (char_u *)VIMRC_FILE)
X#ifdef DEFVIMRC_FILE
X && fullpathcmp((char_u *)DEFVIMRC_FILE, (char_u *)VIMRC_FILE)
X#endif
X )
X i = dosource((char_u *)VIMRC_FILE);
X#ifdef UNIX


X if (i == FAIL)

X {
X struct stat s;
X
X /* if ".exrc" file is not owned by user set 'secure' mode */
X if (stat(EXRC_FILE, &s) || s.st_uid != getuid())
X secure = p_secure;
X else
X secure = 0;
X }
X#endif
X if (i == FAIL && fullpathcmp((char_u *)SYSEXRC_FILE, (char_u *)EXRC_FILE))
X (void)dosource((char_u *)EXRC_FILE);
X }
X
X#ifdef SPAWNO /* special MSDOS swapping library */
X init_SPAWNO("", SWAP_ANY);
X#endif
X/*
X * Call settmode and starttermcap here, so the T_KS and T_TS may be defined
X * by termcapinit and redifined in .exrc.
X */
X settmode(1);
X starttermcap();
X
X no_wait_return = FALSE;
X /* done something that is not allowed or error message */
X if (secure == 2 || need_wait_return)
X wait_return(TRUE); /* must be called after settmode(1) */
X secure = 0;
X
X if (bin_mode) /* -b option used */
X {
X curbuf->b_p_bin = 1; /* binary file I/O */


X curbuf->b_p_tw = 0; /* no automatic line wrap */
X curbuf->b_p_wm = 0; /* no automatic line wrap */
X curbuf->b_p_tx = 0; /* no text mode */
X p_ta = 0; /* no text auto */
X curbuf->b_p_ml = 0; /* no modelines */
X curbuf->b_p_et = 0; /* no expand tab */
X }
X

X (void)setfname(fname, NULL, TRUE);
X maketitle();


X
X if (win_count == 0)

X win_count = arg_count;
X if (win_count > 1)
X win_count = make_windows(win_count);
X else
X win_count = 1;
X
X/*
X * Start putting things on the screen.
X * Scroll screen down before drawing over it
X * Clear screen now, so file message will not be cleared.
X */
X starting = FALSE;


X if (T_CVV != NULL && *T_CVV)
X {

X outstr(T_CVV);
X outstr(T_CV);
X }

X screenclear(); /* clear screen */
X
X if (recoverymode) /* do recover */
X {
X if (ml_open() == FAIL) /* Initialize storage structure */
X getout(1);
X ml_recover();
X }
X else
X (void)open_buffer(); /* create memfile and read file */
X
X setpcmark();
X
X if (doqf && qf_init() == FAIL) /* if reading error file fails: exit */
X mch_windexit(3);
X
X /*
X * If opened more than one window, start editing files in the other windows.
X * Make_windows() has already opened the windows.
X * This is all done by putting commands in the stuff buffer.
X */
X for (i = 1; i < win_count; ++i)
X {


X if (curwin->w_next == NULL) /* just checking */
X break;
X win_enter(curwin->w_next, FALSE);

X /* edit file i, if there is one */
X (void)doecmd(i < arg_count ? arg_files[i] : NULL,
X NULL, NULL, TRUE, (linenr_t)1);


X curwin->w_arg_idx = i;
X }

X win_enter(firstwin, FALSE); /* back to first window */
X
X /*
X * If there are more file names in the argument list than windows,
X * put the rest of the names in the buffer list.
X */
X for (i = win_count; i < arg_count; ++i)


X (void)buflist_add(arg_files[i]);
X

X if (command)
X docmdline(command);
X /*
X * put the :ta command in the stuff buffer here, so that it will not
X * be erased by an emsg().
X */
X if (tagname)
X {


X stuffReadbuff((char_u *)":ta ");

X stuffReadbuff(tagname);
X stuffReadbuff((char_u *)"\n");
X }
X
X RedrawingDisabled = FALSE;
X updateScreen(NOT_VALID);
X
X /* start in insert mode (already taken care of for :ta command) */
X if (p_im && stuff_empty())


X stuffReadbuff((char_u *)"i");

X/*
X * main command loop
X */


X for (;;)
X {

X if (got_int)
X {
X (void)vgetc(); /* flush all buffers */


X got_int = FALSE;
X }

X adjust_cursor(); /* put cursor on an existing line */
X if (skip_redraw) /* skip redraw (for ":" in wait_return()) */
X skip_redraw = FALSE;
X else if (stuff_empty()) /* only when no command pending */
X {


X cursupdate(); /* Figure out where the cursor is based

X on curwin->w_cursor. */
X if (VIsual.lnum)
X updateScreen(INVERTED); /* update inverted part */
X if (must_redraw)
X updateScreen(must_redraw);
X if (keep_msg)
X msg(keep_msg); /* display message after redraw */
X
X showruler(FALSE);
X
X setcursor();
X cursor_on();
X }
X
X normal(); /* get and execute a command */
X }
X /*NOTREACHED*/
X}
X
X void
Xgetout(r)
X int r;
X{


X windgoto((int)Rows - 1, 0);

X outchar('\r');
X outchar('\n');
X mch_windexit(r);
X}
END_OF_FILE
if test 14502 -ne `wc -c <'vim/src/main.c'`; then
echo shar: \"'vim/src/main.c'\" unpacked with wrong size!
fi
# end of 'vim/src/main.c'
fi
if test -f 'vim/src/makefile.unix' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.unix'\"
else
echo shar: Extracting \"'vim/src/makefile.unix'\" \(13424 characters\)
sed "s/^X//" >'vim/src/makefile.unix' <<'END_OF_FILE'
X#
X# Makefile for Vim on Unix
X#
X
X# Note: You MUST uncomment three hardware dependend lines!
X
X# There are three types of defines:
X#
X# 1. configuration dependend
X# Used for "make install". Adjust the path names and protections
X# to your desire. Also defines the root for the X11 files (not required).
X#
X# 2. various choices
X# Can be changed to match your compiler or your preferences (not
X# required).
X#
X# 3. hardware dependend
X# If you machine is in the list, remove one '#' in front of the defines
X# following it. Otherwise: Find a machine that is similar and change the
X# defines to make it work. Normally you can just try and see what error
X# messages you get. (REQUIRED).
X
X# The following systems have entries below. They have been tested and should
X# work without modification. But later code changes may cause small problems.
X# There are entries for other systems, but these have not been tested recently.
X
X#system: tested configurations: tested by:
X
X#Sun 4.1.x cc gcc X11 no X11 (jw) (mool)
X#FreeBSD cc gcc X11 no X11 (mool)
X#linux 1.0 cc X11
X#Linux 1.0.9 gcc no X11 (jw)
X#ULTRIX 4.2A on MIPS cc gcc no X11 (mool)
X#HPUX cc gcc X11 no X11 (jw) (mool)
X#irix 4.0.5H cc X11
X#IRIX 4.0 SGI cc X11 (jw)
X#SINIX-L 5.41 cc no X11
X#MOT188 cc no X11
X#Sequent/ptx 1.3 cc no X11 (jw)
X#osf1 cc no X11 (jw)
X#Unisys 6035 cc no X11
X#SCO 3.2 cc gcc no X11 j...@oce.nl
X#Solaris cc X11
X#Solaris/Sun OS 5.3 cc no X11 (jw)
X#AIX (rs6000) cc no X11 (jw)
X#RISCos on MIPS cc X11 no X11 (jw)
X
X# configurations marked by (jw) have been tested by Juergen Weigert:
X# jnwe...@uni-erlangen.de
X
X#
X# PART 1: configuration dependend
X#
X
X### root directory for X11 files (unless overruled in hardware-dependend part)
X### Unfortunately there is no standard for these, everybody puts them
X### somewhere else
XX11LIBDIR = /usr/openwin/lib
XX11INCDIR = /usr/openwin/include
X### for some hpux systems:
X#X11LIBDIR = /usr/lib/X11R5
X#X11INCDIR = /usr/include/X11R5
X
X### Prefix for location of files
XPREFIX = /usr/local
X
X### Location of binary
XBINLOC = $(PREFIX)/bin
X
X### Name of target
XTARGET = vim
X
X### Location of man page
XMANLOC = $(PREFIX)/man/man1
X
X### Location of help file
XHELPLOC = $(PREFIX)/lib
X
X### Program to run on installed binary
XSTRIP = strip
X
X### Permissions for vim binary
XBINMOD = 755
X
X### Permissions for man page
XMANMOD = 644
X
X### Permissions for help file
XHELPMOD = 644
X
XMANFILE = ../doc/vim.1
X
XHELPFILE = ../doc/vim.hlp
X
X#
X# PART 2: various choices
X#
X
X### -DDIGRAPHS digraph support
X### -DNO_FREE_NULL do not call free() with a null pointer
X### -DCOMPATIBLE start in vi-compatible mode
X### -DNOBACKUP default is no backup file
X### -DDEBUG output a lot of debugging garbage
X### -DSTRNCASECMP use strncasecmp() instead of internal function
X### -DUSE_LOCALE use setlocale() to change ctype() and others
X### -DTERMCAP full termcap/terminfo file support
X### -DTERMINFO use terminfo instead of termcap entries for builtin terms
X### -DNO_BUILTIN_TCAPS do not include builtin termcap entries
X### (use only with -DTERMCAP)
X### -DSOME_BUILTIN_TCAPS include most useful builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DALL_BUILTIN_TCAPS include all builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DMAXNAMLEN 31 maximum length of a file name (if not defined in sys/dir.h)
X### -Dconst= for compilers that don't have type const
X### -DVIMRC_FILE=name name of the .vimrc file in current dir
X### -DEXRC_FILE=name name of the .exrc file in current dir
X### -DSYSVIMRC_FILE=name name of the global .vimrc file
X### -DSYSEXRC_FILE=name name of the global .exrc file
X### -DDEFVIMRC_FILE=name name of the system-wide .vimrc file
X### -DVIM_HLP=name name of the help file
X### -DUSE_SYSTEM use system() instead of fork/exec for starting a shell
X### -DVIM_ISSPACE use when isspace() can't handle meta chars
X### -DNOLIMITS limits.h does not exist
X### -DNOSTDLIB stdlib.h does not exist
X### -DUSE_X11 include code for xterm title saving
X### -DWEBB_COMPLETE include Webb's code for command line completion
X### -DWEBB_KEYWORD_COMPL include Webb's code for keyword completion
X### -DNOTITLE 'title' option off by default
XDEFS = -DDIGRAPHS -DTERMCAP -DSOME_BUILTIN_TCAPS -DNO_FREE_NULL -DVIM_ISSPACE \
X -DWEBB_COMPLETE -DWEBB_KEYWORD_COMPL \
X -DVIM_HLP=\"$(HELPLOC)/vim.hlp\"
X
X#
X# PART 3: hardware dependend
X#
X
X### CC entry: name and arguments for the compiler (also for linking)
X### MACHINE entry: defines used for compiling (not for linking)
X### LIBS: defines used for linking
X
X# generic for Sun, NeXT, POSIX and SYSV R4 (?) (TESTED for Sun 4.1.x)
X# standard cc with optimizer
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=cc -O -I$(X11INCDIR)
X#LIBS = -ltermlib -L$(X11LIBDIR) -lX11
X
X# generic for Sun, FreeBSD, NetBSD, NeXT, POSIX and SYSV R4 (?) without x11 code
X# (TESTED for Sun 4.1.x and FreeBSD)
X# standard cc with optimizer
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE
X#CC=cc -O
X#LIBS = -ltermlib
X
X# FreeBSD and NetBSD with Xfree (TESTED for FreeBSD)
X# standard cc with optimizer
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=cc -O -L/usr/X386/lib -I/usr/X386/include
X#LIBS = -ltermlib -lX11
X
X# FreeBSD and NetBSD with Xfree (TESTED for FreeBSD)
X# gcc with optimizer
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=gcc -O -Wall -traditional -Dconst= -I/usr/X386/include
X#LIBS = -ltermlib -L/usr/X386/lib -lX11
X
X# like generic, but with termcap, for Linux, NeXT and others (NOT TESTED YET)
X# standard cc with optimizer
X#
X#MACHINE = -DBSD_UNIX
X#CC=cc -O
X#LIBS = -ltermcap
X
X# linux 1.0 with X11 (TESTED)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=cc -O -I/usr/X11/include
X#LIBS = -ltermcap -L/usr/X11/lib -lX11
X
X# like generic, but with debugging (NOT TESTED YET)
X#
X#MACHINE = -DBSD_UNIX -g
X#CC=cc
X#LIBS = -ltermlib
X
X# like generic, but with gcc and X11 (TESTED on Sun 4.1.x)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=gcc -O -Wall -traditional -Dconst= -L$(X11LIBDIR) -I$(X11INCDIR)
X#LIBS = -ltermlib -lX11
X
X# like generic, but with gcc, without X11 (TESTED on ULTRIX 4.2A on MIPS)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE
X#CC=gcc -O -Wall -traditional -Dconst=
X#LIBS = -ltermlib
X
X# like generic, but with gcc 2.5.8 (TESTED on Sun 4.1.3_U1)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE
X#CC=gcc -O1000
X#LIBS = -ltermlib
X
X# standard cc with optimizer for ULTRIX 4.2A on MIPS (ultrix defined) (TESTED)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE
X#CC=cc -O -Olimit 1500
X#LIBS = -ltermlib
X
X# GCC (2.2.2d) on Linux (1.0.9) (TESTED)
X#
X#MACHINE = -DBSD_UNIX
X#CC=gcc -O6 -Wall
X#LIBS = -ltermcap
X
X# Apollo DOMAIN (with SYSTYPE = bsd4.3) (NOT TESTED YET)
X#
X#MACHINE = -DBSD_UNIX -DDOMAIN
X#CC=cc -O -A systype,bsd4.3
X#LIBS = -ltermlib
X
X# HPUX with X11 (TESTED) (hpux is defined)
X#
X#MACHINE = -DBSD_UNIX -DTERMINFO -DUSE_X11
X#CC=cc -O -I$(X11INCDIR)
X#LIBS = -ltermcap -L$(X11LIBDIR) -lX11
X
X# HPUX (TESTED) (hpux is defined)
X#
X#MACHINE = -DBSD_UNIX -DTERMINFO
X#CC=cc -O
X#LIBS = -ltermcap
X
X# HPUX with gcc (TESTED) (hpux is defined)
X#
X#MACHINE = -DBSD_UNIX -DTERMINFO
X#CC=gcc -O
X#LIBS = -ltermcap
X
X# hpux 9.01 (with termlib instead of termcap) (TESTED)
X# irix 4.0.5H (TESTED)
X#
X#MACHINE = -DBSD_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=cc -O -I$(X11INCDIR)
X#LIBS = -ltermlib -L$(X11LIBDIR) -lX11
X
X# IRIX 4.0 (Silicon Graphics Indigo, __sgi will be defined) (TESTED)
X#
X#MACHINE = -DBSD_UNIX -DUSE_X11
X#CC=cc -O -Olimit 1500
X#LIBS = -ltermlib -lX11 -lmalloc -lc_s
X
X# Convex (NOT TESTED YET)
X#
X#MACHINE = -DBSD_UNIX -DCONVEX
X#CC=cc -O
X#LIBS = -ltermcap
X
X# generic SYSV_UNIX for Dynix/PTX and SYSV R3 (and R4?) (TESTED on SINIX-L 5.41)
X# (TESTED on MOT188) (TESTED on Sequent/ptx 1.3) (TESTED on osf1)
X# First try the line with locale. If this gives error messages try the other one.
X#
X#MACHINE = -DSYSV_UNIX -DUSE_LOCALE
X#MACHINE = -DSYSV_UNIX
X#CC=cc -O
X#LIBS = -ltermlib
X
X# generic SYSV_UNIX with LOCALE (TESTED on Unisys 6035)
X#
X#MACHINE = -DSYSV_UNIX -DUSE_LOCALE -DUNISYS
X#CC=cc -O
X#LIBS = -ltermlib
X
X# SCO Xenix (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -DSCO
X#CC=cc -O
X#LIBS = -ltermlib
X
X# GCC on SCO 3.2 (TESTED by j...@oce.nl)
X# cc works too.
X#
X#MACHINE = -DSYSV_UNIX -UM_XENIX -DSCO
X#CC=gcc -O -Wall
X#LIBS = -ltinfo
X
X# GCC on another SCO Unix (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -UM_XENIX -DSCO -g
X#CC=gcc -O6 -fpcc-struct-return -fwritable-strings
X#LIBS = -ltermlib -lmalloc
X
X# Dynix with gcc (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX
X#CC=gcc -O -Wall -traditional
X#LIBS = -ltermlib
X
X# SOLARIS with X11 anc cc (TESTED)
X#
X#MACHINE = -DSYSV_UNIX -DSOLARIS -DTERMINFO -DUSE_X11
X#CC=cc -O -Xa -v -R$(X11LIBDIR) -L$(X11LIBDIR) -I$(X11INCDIR)
X#LIBS = -ltermlib -lX11
X
X# SOLARIS with X11 and gcc (TESTED with SOLARIS 2.3 and gcc 2.5.8)
X#
X#MACHINE = -DSYSV_UNIX -DSOLARIS -DTERMINFO -DUSE_X11
X#CC=gcc -O -R$(X11LIBDIR) -L$(X11LIBDIR) -I$(X11INCDIR)
X#LIBS = -ltermlib -lX11
X
X# SOLARIS (also works for Esix 4.0.3, SYSV R4?) (TESTED on Sun OS 5.3)
X#
X#MACHINE = -DSYSV_UNIX -DSOLARIS -DTERMINFO
X#CC=cc -O -Xa -v
X#LIBS = -ltermlib
X
X# UNICOS (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -DUNICOS
X#CC=cc -O
X#LIBS = -ltermlib
X
X# AIX (rs6000) (TESTED)
X#
X#MACHINE = -DSYSV_UNIX -DAIX
X#CC=cc -O
X#LIBS=-lcur
X
X# UTS2 for Amdahl UTS 2.1.x (disable termcap below) (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -DUTS2
X#CC=cc -O
X#LIBS = -ltermlib -lsocket
X
X# UTS4 for Amdahl UTS 4.x (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -DUTS4 -Xa
X#CC=cc -O
X#LIBS = -ltermlib
X
X# USL for Unix Systems Laboratories (SYSV 4.2) (NOT TESTED YET)
X#
X#MACHINE = -DSYSV_UNIX -DUSL
X#CC=cc -O
X#LIBS = -ltermlib
X
X# RISCos on MIPS without X11 (TESTED)
X#
X#MACHINE = -DSYSV_UNIX -DMIPS
X#CC=cc -O
X#LIBS = -ltermlib
X
X# RISCos on MIPS with X11 (TESTED)
X#
X#MACHINE=-DSYSV_UNIX -DUSE_LOCALE -DUSE_X11
X#CC=cc -O -I$(X11INCDIR)
X#LIBS=-ltermlib -L$(X11LIBDIR) -lX11 -lsun
X
X################################################
X## no changes required below this line ##
X################################################
X
XCFLAGS = -c $(MACHINE) $(DEFS)
X
XINCL = vim.h globals.h param.h keymap.h macros.h ascii.h term.h unix.h structs.h proto.h
X
XOBJ = alloc.o unix.o buffer.o charset.o cmdcmds.o cmdline.o \
X csearch.o digraph.o edit.o fileio.o getchar.o help.o \
X linefunc.o main.o mark.o memfile.o memline.o message.o misccmds.o \
X normal.o ops.o param.o quickfix.o regexp.o \
X regsub.o screen.o search.o \
X tag.o term.o undo.o window.o $(TERMLIB)
X
X$(TARGET): $(OBJ) version.c
X $(CC) $(CFLAGS) version.c
X $(CC) -o $(TARGET) $(OBJ) version.o $(LIBS)
X
Xdebug: $(OBJ) version.c
X $(CC) $(CFLAGS) version.c
X $(CC) -o $(TARGET) -g $(OBJ) version.o $(LIBS)
X
Xctags:
X ctags *.c *.h
X
Xinstall: $(TARGET)
X -mkdir $(BINLOC)
X cp $(TARGET) $(BINLOC)
X chmod $(BINMOD) $(BINLOC)/$(TARGET)
X $(STRIP) $(BINLOC)/$(TARGET)
X -mkdir $(MANLOC)
X cp $(MANFILE) $(MANLOC)
X chmod $(MANMOD) $(MANLOC)/vim.1
X -mkdir $(HELPLOC)
X cp $(HELPFILE) $(HELPLOC)
X chmod $(HELPMOD) $(HELPLOC)/vim.hlp
X
Xclean:
X -rm -f $(OBJ) mkcmdtab.o version.o core $(TARGET) mkcmdtab cmdtab.h
X -rm -f *.bak
X
X#use this in case the files have been transported via an MSDOS system
X
XFILES = *.c *.h makefile makefile.* cmdtab.tab proto/*.pro tags
X
Xdos2unix:
X -mv arp_prot.h arp_proto.h
X -mv ptx_stdl.h ptx_stdlib.h
X -mv sun_stdl.h sun_stdlib.h
X -mv makefile.dic makefile.dice
X -mv makefile.uni makefile.unix
X -mv makefile.man makefile.manx
X -mv makefile.6sa makefile.6sas
X -mv makefile.5sa makefile.5sas
X for i in $(FILES); do tr -d '\r\032' < $$i > ~tmp~; mv ~tmp~ $$i; echo $$i; done
X
X###########################################################################
X
Xalloc.o: alloc.c $(INCL)
X $(CC) $(CFLAGS) alloc.c
X
Xunix.o: unix.c $(INCL)
X $(CC) $(CFLAGS) unix.c
X
Xbuffer.o: buffer.c $(INCL)
X $(CC) $(CFLAGS) buffer.c
X
Xcharset.o: charset.c $(INCL)
X $(CC) $(CFLAGS) charset.c
X
Xcmdcmds.o: cmdcmds.c $(INCL)
X $(CC) $(CFLAGS) cmdcmds.c
X
Xcmdline.o: cmdline.c $(INCL) cmdtab.h ops.h
X $(CC) $(CFLAGS) cmdline.c
X
Xcsearch.o: csearch.c $(INCL)
X $(CC) $(CFLAGS) csearch.c
X
Xdigraph.o: digraph.c $(INCL)
X $(CC) $(CFLAGS) digraph.c
X
Xedit.o: edit.c $(INCL) ops.h
X $(CC) $(CFLAGS) edit.c
X
Xfileio.o: fileio.c $(INCL)
X $(CC) $(CFLAGS) fileio.c
X
Xgetchar.o: getchar.c $(INCL)
X $(CC) $(CFLAGS) getchar.c
X
Xhelp.o: help.c $(INCL)
X $(CC) $(CFLAGS) help.c
X
Xlinefunc.o: linefunc.c $(INCL)
X $(CC) $(CFLAGS) linefunc.c
X
Xmain.o: main.c $(INCL)
X $(CC) $(CFLAGS) main.c
X
Xmark.o: mark.c $(INCL)
X $(CC) $(CFLAGS) mark.c
X
Xmemfile.o: memfile.c $(INCL)
X $(CC) $(CFLAGS) memfile.c
X
Xmemline.o: memline.c $(INCL)
X $(CC) $(CFLAGS) memline.c
X
Xmessage.o: message.c $(INCL)
X $(CC) $(CFLAGS) message.c
X
Xmisccmds.o: misccmds.c $(INCL)
X $(CC) $(CFLAGS) misccmds.c
X
Xnormal.o: normal.c $(INCL) ops.h
X $(CC) $(CFLAGS) normal.c
X
Xops.o: ops.c $(INCL) ops.h
X $(CC) $(CFLAGS) ops.c
X
Xparam.o: param.c $(INCL)
X $(CC) $(CFLAGS) param.c
X
Xquickfix.o: quickfix.c $(INCL)
X $(CC) $(CFLAGS) quickfix.c
X
Xregexp.o: regexp.c $(INCL)
X $(CC) $(CFLAGS) regexp.c
X
Xregsub.o: regsub.c $(INCL)
X $(CC) $(CFLAGS) regsub.c
X
Xscreen.o: screen.c $(INCL)
X $(CC) $(CFLAGS) screen.c
X
Xsearch.o: search.c $(INCL) ops.h
X $(CC) $(CFLAGS) search.c
X
Xtag.o: tag.c $(INCL)
X $(CC) $(CFLAGS) tag.c
X
Xterm.o: term.c $(INCL)
X $(CC) $(CFLAGS) term.c
X
Xundo.o: undo.c $(INCL)
X $(CC) $(CFLAGS) undo.c
X
Xwindow.o: window.c $(INCL)
X $(CC) $(CFLAGS) window.c
X
Xcmdtab.h: cmdtab.tab mkcmdtab
X ./mkcmdtab cmdtab.tab cmdtab.h
X
Xmkcmdtab: mkcmdtab.o
X $(CC) -o mkcmdtab mkcmdtab.o
X
Xmkcmdtab.o: mkcmdtab.c
X $(CC) $(CFLAGS) mkcmdtab.c
END_OF_FILE
if test 13424 -ne `wc -c <'vim/src/makefile.unix'`; then
echo shar: \"'vim/src/makefile.unix'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.unix'
fi
if test -f 'vim/src/regsub.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/regsub.c'\"
else
echo shar: Extracting \"'vim/src/regsub.c'\" \(7512 characters\)
sed "s/^X//" >'vim/src/regsub.c' <<'END_OF_FILE'
X/* vi:ts=4:sw=4


X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE

X *


X * This is NOT the original regular expression code as written by
X * Henry Spencer. This code has been modified specifically for use
X * with the VIM editor, and should not be used apart from compiling
X * VIM. If you want a good regular expression library, get the
X * original code. The copyright notice that follows is from the
X * original.
X *
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *

X * regsub
X *


X * Copyright (c) 1986 by University of Toronto.
X * Written by Henry Spencer. Not derived from licensed software.
X *
X * Permission is granted to anyone to use this software for any
X * purpose on any computer system, and to redistribute it freely,
X * subject to the following restrictions:

X *


X * 1. The author is not responsible for the consequences of use of
X * this software, no matter how awful, even if they arise
X * from defects in it.

X *


X * 2. The origin of this software must not be misrepresented, either
X * by explicit claim or by omission.
X *
X * 3. Altered versions must be plainly marked as such, and must not
X * be misrepresented as being the original software.
X *

X * $Log: regsub.c,v $
X * Revision 1.2 88/04/28 08:11:25 tony


X * First modification of the regexp library. Added an external variable
X * 'reg_ic' which can be set to indicate that case should be ignored.
X * Added a new parameter to regexec() to indicate that the given string
X * comes from the beginning of a line and is thus eligible to match

X * 'beginning-of-line'.
X *


X * Revisions by Olaf 'Rhialto' Seibert, rhi...@cs.kun.nl:
X * Changes for vi: (the semantics of several things were rather different)
X * - Added lexical analyzer, because in vi magicness of characters
X * is rather difficult, and may change over time.
X * - Added support for \< \> \1-\9 and ~
X * - Left some magic stuff in, but only backslashed: \| \+
X * - * and \+ still work after \) even though they shouldn't.
X */
X

X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X
X#ifdef MSDOS
X# define __ARGS(a) a
X#endif
X
X#define CASECONVERT


X
X#include <stdio.h>
X#include "regexp.h"
X#include "regmagic.h"

X
X#ifdef LATTICE
X# include <sys/types.h> /* for size_t */
X#endif
X
X#ifndef CHARBITS
X#define UCHARAT(p) ((int)*(char_u *)(p))


X#else
X#define UCHARAT(p) ((int)*(p)&CHARBITS)
X#endif
X

Xextern char_u *reg_prev_sub;
X
X#ifdef CASECONVERT
X /*
X * We should define ftpr as a pointer to a function returning a pointer to
X * a function returning a pointer to a function ...
X * This is impossible, so we declare a pointer to a function returning a
X * pointer to a function returning void. This should work for all compilers.
X */
Xtypedef void (*(*fptr) __ARGS((char_u *, int)))();
Xstatic fptr strnfcpy __ARGS((fptr, char_u *, char_u *, int));
X
Xstatic fptr do_Copy __ARGS((char_u *, int));
Xstatic fptr do_upper __ARGS((char_u *, int));
Xstatic fptr do_Upper __ARGS((char_u *, int));
Xstatic fptr do_lower __ARGS((char_u *, int));
Xstatic fptr do_Lower __ARGS((char_u *, int));
X
X static fptr
Xdo_Copy(d, c)
X char_u *d;
X int c;
X{
X *d = c;
X
X return (fptr)do_Copy;
X}
X
X static fptr
Xdo_upper(d, c)
X char_u *d;
X int c;
X{
X *d = TO_UPPER(c);
X
X return (fptr)do_Copy;
X}
X
X static fptr
Xdo_Upper(d, c)
X char_u *d;
X int c;
X{
X *d = TO_UPPER(c);
X
X return (fptr)do_Upper;
X}
X
X static fptr
Xdo_lower(d, c)
X char_u *d;
X int c;
X{
X *d = TO_LOWER(c);
X
X return (fptr)do_Copy;
X}
X
X static fptr
Xdo_Lower(d, c)
X char_u *d;
X int c;
X{
X *d = TO_LOWER(c);
X
X return (fptr)do_Lower;
X}
X
X static fptr
Xstrnfcpy(f, d, s, n)
X fptr f;
X char_u *d;
X char_u *s;
X int n;
X{
X while (n-- > 0) {
X f = (fptr)(f(d, *s)); /* Turbo C complains without the typecast */
X if (!*s++)
X break;
X d++;
X }
X
X return f;
X}
X#endif
X
X/*
X * regtilde: replace tildes in the pattern by the old pattern
X *
X * Short explanation of the tilde: it stands for the previous replacement
X * pattern. If that previous pattern also contains a ~ we should go back
X * a step further... but we insert the previous pattern into the current one
X * and remember that.
X * This still does not handle the case where "magic" changes. TODO?
X *
X * New solution: The tilde's are parsed once before the first call to regsub().
X * In the old solution (tilde handled in regsub()) is was possible to get an
X * endless loop.


X */
X char_u *

Xregtilde(source, magic)
X char_u *source;
X int magic;
X{
X char_u *newsub = NULL;
X char_u *tmpsub;
X char_u *p;
X int len;
X int prevlen;
X
X for (p = source; *p; ++p)
X {
X if ((*p == '~' && magic) || (*p == '\\' && *(p + 1) == '~' && !magic))
X {
X if (reg_prev_sub)
X {
X /* length = len(current) - 1 + len(previous) + 1 */
X prevlen = STRLEN(reg_prev_sub);
X tmpsub = alloc((unsigned)(STRLEN(source) + prevlen));
X if (tmpsub)
X {
X /* copy prefix */
X len = (int)(p - source); /* not including ~ */
X STRNCPY(tmpsub, source, (size_t)len);
X /* interpretate tilde */
X STRCPY(tmpsub + len, reg_prev_sub);
X /* copy postfix */
X if (!magic)
X ++p; /* back off \ */
X STRCAT(tmpsub + len, p + 1);
X
X free(newsub);
X newsub = tmpsub;
X p = newsub + len + prevlen;
X }
X }
X else if (magic)
X STRCPY(p, p + 1); /* remove '~' */
X else
X STRCPY(p, p + 2); /* remove '\~' */
X }
X else if (*p == '\\' && p[1]) /* skip escaped characters */
X ++p;
X }
X
X free(reg_prev_sub);
X if (newsub)
X {
X source = newsub;
X reg_prev_sub = newsub;
X }
X else
X reg_prev_sub = strsave(source);
X return source;
X}
X
X/*
X - regsub - perform substitutions after a regexp match
X *
X * Returns the size of the replacement, including terminating \0.
X */
X int
Xregsub(prog, source, dest, copy, magic)
X regexp *prog;
X char_u *source;
X char_u *dest;
X int copy;
X int magic;


X{
X register char_u *src;
X register char_u *dst;

X register int c;
X register int no;
X register int len;
X#ifdef CASECONVERT
X fptr func = (fptr)do_Copy;
X#endif
X
X if (prog == NULL || source == NULL || dest == NULL)
X {
X emsg(e_null);
X return 0;
X }


X if (UCHARAT(prog->program) != MAGIC)

X {
X emsg(e_re_corr);
X return 0;
X }
X src = source;
X dst = dest;
X
X while ((c = *src++) != '\0')
X {
X no = -1;
X if (c == '&' && magic)
X no = 0;
X else if (c == '\\' && *src != NUL)
X {
X if (*src == '&' && !magic)
X {
X ++src;
X no = 0;
X }
X else if ('0' <= *src && *src <= '9')
X {
X no = *src++ - '0';
X }
X#ifdef CASECONVERT
X else if (strchr("uUlLeE", *src))
X {
X switch (*src++)
X {
X case 'u': func = (fptr)do_upper;
X continue;
X case 'U': func = (fptr)do_Upper;
X continue;
X case 'l': func = (fptr)do_lower;
X continue;
X case 'L': func = (fptr)do_Lower;
X continue;
X case 'e':
X case 'E': func = (fptr)do_Copy;
X continue;
X }
X }
X#endif
X }
X if (no < 0) /* Ordinary character. */
X {
X if (c == '\\' && *src != NUL)
X c = *src++;
X if (copy)
X {
X#ifdef CASECONVERT
X func = (fptr)(func(dst, c));
X /* Turbo C complains without the typecast */
X#else
X *dst = c;
X#endif
X }
X dst++;
X }
X else if (prog->startp[no] != NULL && prog->endp[no] != NULL)
X {
X len = (int)(prog->endp[no] - prog->startp[no]);
X if (copy)
X {
X#ifdef CASECONVERT
X func = strnfcpy(func, dst, prog->startp[no], len);
X#else
X (void) STRNCPY(dst, prog->startp[no], len);
X#endif
X }
X dst += len;
X if (copy && len != 0 && *(dst - 1) == '\0') { /* strncpy hit NUL. */
X emsg(e_re_damg);
X goto exit;
X }
X }
X }
X if (copy)
X *dst = '\0';
X
Xexit:
X return (int)((dst - dest) + 1);
X}
END_OF_FILE
if test 7512 -ne `wc -c <'vim/src/regsub.c'`; then
echo shar: \"'vim/src/regsub.c'\" unpacked with wrong size!
fi
# end of 'vim/src/regsub.c'
fi
if test -f 'vim/src/structs.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/structs.h'\"
else
echo shar: Extracting \"'vim/src/structs.h'\" \(14475 characters\)
sed "s/^X//" >'vim/src/structs.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * This file contains various definitions of structures that are used by Vim
X */
X
X/*
X * file position
X */
X
Xtypedef struct fpos FPOS;
X/*
X * there is something wrong in the SAS compiler that makes typedefs not
X * valid in include files
X */
X#ifdef SASC
Xtypedef long linenr_t;
Xtypedef unsigned colnr_t;
Xtypedef unsigned short short_u;
X#endif
X
Xstruct fpos
X{
X linenr_t lnum; /* line number */
X colnr_t col; /* column number */
X};
X
X/*
X * marks: positions in a file
X * (a normal mark is a lnum/col pair, the same as a file position)
X */
X
X#define NMARKS 26 /* max. # of named marks */
X#define JUMPLISTSIZE 30 /* max. # of marks in jump list */
X#define TAGSTACKSIZE 20 /* max. # of tags in tag stack */
X
Xstruct filemark
X{
X FPOS mark; /* cursor position */
X int fnum; /* file number */
X};
X
X/*
X * the taggy struct is used to store the information about a :tag command:
X * the tag name and the cursor position BEFORE the :tag command
X */
Xstruct taggy
X{
X char_u *tagname; /* tag name */
X struct filemark fmark; /* cursor position */
X};
X
X/*
X * line number list
X */
X
X/*
X * Each window can have a different line number associated with a buffer.
X * The window-pointer/line-number pairs are kept in the line number list.
X * The list of line numbers is kept in most-recently-used order.
X */
X
Xtypedef struct window WIN;
Xtypedef struct winlnum WINLNUM;
X
Xstruct winlnum
X{
X WINLNUM *wl_next; /* next entry or NULL for last entry */
X WINLNUM *wl_prev; /* previous entry or NULL for first entry */
X WIN *wl_win; /* pointer to window that did set wl_lnum */
X linenr_t wl_lnum; /* last cursor line in the file */
X};
X
X/*
X * stuctures used for undo
X */
X
Xstruct u_entry
X{
X struct u_entry *ue_next; /* pointer to next entry in list */
X linenr_t ue_top; /* number of line above undo block */
X linenr_t ue_bot; /* number of line below undo block */
X linenr_t ue_lcount; /* linecount when u_save called */
X char_u **ue_array; /* array of lines in undo block */
X long ue_size; /* number of lines in ue_array */
X};
X
Xstruct u_header
X{
X struct u_header *uh_next; /* pointer to next header in list */
X struct u_header *uh_prev; /* pointer to previous header in list */
X struct u_entry *uh_entry; /* pointer to first entry */
X FPOS uh_cursor; /* cursor position before saving */
X int uh_changed;/* b_changed flag before undo/after redo */
X FPOS uh_namedm[NMARKS]; /* marks before undo/after redo */
X};
X
X/*
X * stuctures used in undo.c
X */
X#ifdef UNIX
X# define ALIGN_LONG /* longword alignment and use filler byte */
X# define ALIGN_SIZE (sizeof(long))
X#else
X# define ALIGN_SIZE (sizeof(short))
X#endif
X
X#define ALIGN_MASK (ALIGN_SIZE - 1)
X
Xtypedef struct m_info info_t;
X
X/*
X * stucture used to link chunks in one of the free chunk lists.
X */
Xstruct m_info
X{
X#ifdef ALIGN_LONG
X long_u m_size; /* size of the chunk (including m_info) */
X#else
X short_u m_size; /* size of the chunk (including m_info) */
X#endif
X info_t *m_next; /* pointer to next free chunk in the list */
X};
X
X/*
X * structure used to link blocks in the list of allocated blocks.
X */
Xstruct m_block
X{
X struct m_block *mb_next; /* pointer to next allocated block */
X info_t mb_info; /* head of free chuck list for this block */
X};
X
X/*
X * things used in memfile.c
X */
X
Xtypedef struct block_hdr BHDR;
Xtypedef struct memfile MEMFILE;
Xtypedef long blocknr_t;
X
X/*
X * for each (previously) used block in the memfile there is one block header.
X *
X * The block may be linked in the used list OR in the free list.
X * The used blocks are also kept in hash lists.
X *
X * The used list is a doubly linked list, most recently used block first.
X * The blocks in the used list have a block of memory allocated.
X * mf_used_count is the number of pages in the used list.
X * The hash lists are used to quickly find a block in the used list.
X * The free list is a single linked list, not sorted.
X * The blocks in the free list have no block of memory allocated and
X * the contents of the block in the file (if any) is irrelevant.
X */
X
Xstruct block_hdr
X{
X BHDR *bh_next; /* next block_hdr in free or used list */
X BHDR *bh_prev; /* previous block_hdr in used list */
X BHDR *bh_hash_next; /* next block_hdr in hash list */
X BHDR *bh_hash_prev; /* previous block_hdr in hash list */
X blocknr_t bh_bnum; /* block number */
X char_u *bh_data; /* pointer to memory (for used block) */
X int bh_page_count; /* number of pages in this block */
X
X#define BH_DIRTY 1
X#define BH_LOCKED 2
X char bh_flags; /* BH_DIRTY or BH_LOCKED */
X};
X
X/*
X * when a block with a negative number is flushed to the file, it gets
X * a positive number. Because the reference to the block is still the negative
X * number, we remember the translation to the new positive number in the
X * double linked trans lists. The structure is the same as the hash lists.
X */
Xtypedef struct nr_trans NR_TRANS;
X
Xstruct nr_trans
X{
X NR_TRANS *nt_next; /* next nr_trans in hash list */
X NR_TRANS *nt_prev; /* previous nr_trans in hash list */
X blocknr_t nt_old_bnum; /* old, negative, number */
X blocknr_t nt_new_bnum; /* new, positive, number */
X};
X
X/*
X * Simplistic hashing scheme to quickly locate the blocks in the used list.
X * 64 blocks are found directly (64 * 4K = 256K, most files are smaller).
X */
X#define MEMHASHSIZE 64
X#define MEMHASH(nr) ((nr) & (MEMHASHSIZE - 1))
X
Xstruct memfile
X{
X char_u *mf_fname; /* name of the file */
X char_u *mf_xfname; /* idem, full path */
X int mf_fd; /* file descriptor */
X BHDR *mf_free_first; /* first block_hdr in free list */
X BHDR *mf_used_first; /* mru block_hdr in used list */
X BHDR *mf_used_last; /* lru block_hdr in used list */
X unsigned mf_used_count; /* number of pages in used list */
X unsigned mf_used_count_max; /* maximum number of pages in memory */
X BHDR *mf_hash[MEMHASHSIZE]; /* array of hash lists */
X NR_TRANS *mf_trans[MEMHASHSIZE]; /* array of trans lists */
X blocknr_t mf_blocknr_max; /* highest positive block number + 1*/
X blocknr_t mf_blocknr_min; /* lowest negative block number - 1 */
X blocknr_t mf_neg_count; /* number of negative blocks numbers */
X blocknr_t mf_infile_count; /* number of pages in the file */
X unsigned mf_page_size; /* number of bytes in a page */
X int mf_dirty; /* Set to TRUE if there are dirty blocks */
X};
X
X/*
X * things used in memline.c
X */
Xtypedef struct info_pointer IPTR; /* block/index pair */
X
X/*
X * When searching for a specific line, we remember what blocks in the tree
X * are the branches leading to that block. This is stored in ml_stack.
X * Each entry is a pointer to info in a block (may be data block or pointer block)
X */
Xstruct info_pointer
X{
X blocknr_t ip_bnum; /* block number */
X linenr_t ip_low; /* lowest lnum in this block */
X linenr_t ip_high; /* highest lnum in this block */
X int ip_index; /* index for block with current lnum */
X};
X
Xtypedef struct memline MEMLINE;
X
X/*
X * the memline structure holds all the information about a memline
X */
Xstruct memline
X{
X linenr_t ml_line_count; /* number of lines in the buffer */
X
X MEMFILE *ml_mfp; /* pointer to associated memfile */
X
X#define ML_EMPTY 1 /* empty buffer (one empty line */
X#define ML_LINE_DIRTY 2 /* cached line was changed and allocated */
X#define ML_LOCKED_DIRTY 4 /* ml_locked was changed */
X#define ML_LOCKED_POS 8 /* ml_locked needs positive block number */
X int ml_flags;
X
X IPTR *ml_stack; /* stack of pointer blocks (array of IPTRs) */
X int ml_stack_top; /* current top if ml_stack */
X int ml_stack_size; /* total number of entries in ml_stack */
X
X linenr_t ml_line_lnum; /* line number of cached line, 0 if not valid */
X char_u *ml_line_ptr; /* pointer to cached line */
X
X BHDR *ml_locked; /* block used by last ml_get */
X linenr_t ml_locked_low; /* first line in ml_locked */
X linenr_t ml_locked_high; /* last line in ml_locked */
X int ml_locked_lineadd; /* number of lines inserted in ml_locked */
X};
X
X/*
X * buffer: structure that holds information about one file
X *
X * Several windows can share a single Buffer
X * A buffer is unallocated if there is no memfile for it.
X * A buffer is new if the associated file has never been loaded yet.
X */
X
Xtypedef struct buffer BUF;
X
Xstruct buffer
X{
X MEMLINE b_ml; /* associated memline (also contains
X * line count) */
X
X BUF *b_next; /* links in list of buffers */
X BUF *b_prev;
X
X int b_changed; /* Set to 1 if something in the file has
X * been changed and not written out. */
X
X int b_notedited; /* Set to TRUE when file name is
X * changed after starting to edit,
X * reset when file is written out. */
X
X int b_nwindows; /* nr of windows open on this buffer */
X
X int b_neverloaded; /* file has never been loaded into
X * buffer, many variables still need
X * to be set */
X
X /*
X * b_filename has the full path of the file.
X * b_sfilename is the name as the user typed it.
X * b_xfilename is the same as b_sfilename, unless did_cd is set, then it
X * is the same as b_filename.
X */
X char_u *b_filename;
X char_u *b_sfilename;
X char_u *b_xfilename;
X
X int b_fnum; /* file number for this file. */
X WINLNUM *b_winlnum; /* list of last used lnum for
X * each window */
X
X long b_mtime; /* last change time of original file */
X
X /*
X * The following only used in mark.c.
X */
X FPOS b_namedm[NMARKS]; /* current marks */
X
X /*
X * start and end of an operator, also used for '[ and ']
X */
X FPOS b_startop;
X FPOS b_endop;
X
X /*
X * The following only used in undo.c.
X */
X struct u_header *b_u_oldhead; /* pointer to oldest header */
X struct u_header *b_u_newhead; /* pointer to newest header */
X struct u_header *b_u_curhead; /* pointer to current header */
X int b_u_numhead; /* current number of headers */
X int b_u_synced; /* entry lists are synced */
X
X /*
X * variables for "U" command in undo.c
X */
X char_u *b_u_line_ptr; /* saved line for "U" command */
X linenr_t b_u_line_lnum; /* line number of line in u_line */
X colnr_t b_u_line_colnr; /* optional column number */
X
X /*
X * The following only used in undo.c
X */
X struct m_block b_block_head; /* head of allocated memory block list */
X info_t *b_m_search; /* pointer to chunk before previously
X * allocated/freed chunk */
X struct m_block *b_mb_current; /* block where m_search points in */
X
X /*
X * Variables "local" to a buffer.
X * They are here because their value depends on the type of file
X * or contents of the file being edited.
X * The "save" options are for when the paste option is set.
X */
X int b_p_ai, b_p_si, b_p_ro;
X int b_p_bin, b_p_eol, b_p_et, b_p_ml, b_p_sn, b_p_tx;
X long b_p_sw, b_p_ts, b_p_tw, b_p_wm;
X int b_p_ai_save, b_p_si_save;
X long b_p_tw_save, b_p_wm_save;
X
X char b_did_warn; /* Set to 1 if user has been warned on
X * first change of a read-only file */
X
X#ifndef MSDOS
X int b_shortname; /* this file has an 8.3 filename */
X#endif
X};
X
X/*
X * Structure which contains all information that belongs to a window
X *
X * All row numbers are relative to the start of the window, except w_winpos.
X */
X
Xstruct window
X{
X BUF *w_buffer; /* buffer we are a window into */
X
X WIN *w_prev; /* link to previous window (above) */
X WIN *w_next; /* link to next window (below) */
X
X FPOS w_cursor; /* cursor's position in buffer */
X
X /*
X * These elements are related to the cursor's position in the window.
X * This is related to character positions in the window, not in the file.
X */
X int w_row, w_col; /* cursor's position in window */
X
X colnr_t w_virtcol; /* column number of the file's actual */
X /* line, as opposed to the column */
X /* number we're at on the screen. */
X /* This makes a difference on lines */
X /* which span more than one screen */
X /* line. */
X
X colnr_t w_curswant; /* The column we'd like to be at. */
X /* This is used to try to stay in */
X /* the same column through up/down */
X /* cursor motions. */
X
X int w_set_curswant; /* If set, then update w_curswant */
X /* the next time through cursupdate() */
X /* to the current virtual column */
X
X linenr_t w_topline; /* number of the line at the top of
X * the screen */
X linenr_t w_botline; /* number of the line below the bottom
X * of the screen */
X int w_empty_rows; /* number of ~ rows in window */
X
X int w_winpos; /* row of topline of window in screen */
X int w_height; /* number of rows in window, excluding
X status/command line */
X int w_status_height; /* number of status lines (0 or 1) */
X
X int w_redr_status; /* if TRUE status line must be redrawn */
X int w_redr_type; /* type of redraw to be performed on win */
X
X int w_leftcol; /* starting column of the screen */
X
X/*
X * The height of the lines currently in the window is remembered
X * to avoid recomputing it every time. The number of entries is w_nrows.
X */
X int w_lsize_valid; /* nr. of valid LineSizes */
X linenr_t *w_lsize_lnum; /* array of line numbers for w_lsize */
X char_u *w_lsize; /* array of line heights */
X
X int w_alt_fnum; /* alternate file (for # and CTRL-^) */
X
X int w_arg_idx; /* current index in argument list */
X
X /*
X * Variables "local" to a window.
X * They are here because they influence the layout of the window or
X * depend on the window layout.
X */
X int w_p_list,
X w_p_nu,
X w_p_wrap;
X long w_p_scroll;
X
X /*
X * The w_prev_pcmark field is used to check whether we really did jump to
X * a new line after setting the w_pcmark. If not, then we revert to
X * using the previous w_pcmark.
X */
X FPOS w_pcmark; /* previous context mark */
X FPOS w_prev_pcmark; /* previous w_pcmark */
X
X /*
X * the jumplist contains old cursor positions
X */
X struct filemark w_jumplist[JUMPLISTSIZE];
X int w_jumplistlen; /* number of active entries */
X int w_jumplistidx; /* current position */
X
X /*
X * the tagstack grows from 0 upwards:
X * entry 0: older
X * entry 1: newer
X * entry 2: newest
X */
X struct taggy w_tagstack[TAGSTACKSIZE]; /* the tag stack */
X int w_tagstackidx; /* index just below active entry */
X int w_tagstacklen; /* number of tags on the stack */
X
X};
END_OF_FILE
if test 14475 -ne `wc -c <'vim/src/structs.h'`; then
echo shar: \"'vim/src/structs.h'\" unpacked with wrong size!
fi
# end of 'vim/src/structs.h'
fi
echo shar: End of archive 21 \(of 26\).
cp /dev/null ark21isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:38 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 41
Archive-name: vim/part22

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/.exrc vim/doc/index vim/src/cmdcmds.c vim/src/cmdtab.h
# vim/src/digraph.c.UU vim/src/makefile.nt vim/src/tag.c
# Wrapped by kent@sparky on Mon Aug 15 21:44:13 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 22 (of 26)."'
if test -f 'vim/.exrc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/.exrc'\"
else
echo shar: Extracting \"'vim/.exrc'\" \(30 characters\)
sed "s/^X//" >'vim/.exrc' <<'END_OF_FILE'
Xset ai bs=2 shell=csh nojs ru
END_OF_FILE
if test 30 -ne `wc -c <'vim/.exrc'`; then
echo shar: \"'vim/.exrc'\" unpacked with wrong size!
fi
# end of 'vim/.exrc'
fi
if test -f 'vim/doc/index' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/index'\"
else
echo shar: Extracting \"'vim/doc/index'\" \(12449 characters\)
sed "s/^X//" >'vim/doc/index' <<'END_OF_FILE'
Xindex of vim commands for
X 1. insert mode
X 2. VI commands (normal mode)
X 3. command line editing
X 4. EX commands
X
X(for an overview of options see the end of reference.doc)
X
X1. INSERT MODE
X==============
X
Xchar action
X-----------------------------------------------------------------------
X^@ insert previously inserted text and stop insert {vi: up to 128
X chars}
X^A insert previously inserted text {not in Vi}
X^B toggle 'revins' option.
X^C quit insert mode, without checking for abbreviation.
X^D delete one shiftwidth of indent in the current line {vi:
X only after auto-indent}
X when preceded with <0> or <^>, delete all indent, with <^>
X restore it in the next line
X^E insert the character which is below the cursor
X^H <BS> delete character before the cursor {vi: does not cross lines,


X does not delete autoindents}

X^J <LF> begin new line
X^K {char1} {char2} enter digraph (only when compiled with it) {vi: no digraphs}
X^M <CR> begin new line
X^N find next match for keyword in front of the cursor
X^O execute a single command and return to insert mode
X^P find previous match for keyword in front of the cursor
X^R <0-9a-z"%:> insert contents of register <0-9a-z"%:> {not in vi}
X^T insert one shiftwidth of indent in current line {vi: only in
X autoindent}
X^U delete all entered characters in the current line
X^V insert next non-digit literally, insert three digit decimal
X number as a single byte.
X^W delete word before the cursor
X^Y insert the character which is above the cursor
X^[ <ESC> end insert mode
X<DEL> same as ^H <BS>


X<C_UP> cursor one line up
X<C_DOWN> cursor one line down
X<C_LEFT> cursor one character left
X<C_RIGHT> cursor one character right

X<SC_UP> one screenfull backward
X<SC_DOWN> one screenfull forward


X<SC_LEFT> cursor one word left
X<SC_RIGHT> cursor one word right

X{char1}<BS>{char2} enter digraph (only when compiled with it and 'digraph'
X option set) {vi: no digraphs}
X
X
X2. VI COMMANDS
X==============
X
XCHAR means non-blank char
XWORD means sequences of non-blank chars
XN is number entered before the command
X<move> is a cursor movement command
XNmove is the text that is moved over with a cursor movement command
XSECTION is a section that possibly starts with '}' instead of '{'
X
Xnote: 1 = cursor movement command; 2 = can be undone/redone
X
Xchar note vim normal mode (vi: what the unix vi does)
X------------------------------------------------------------------------------
X^@ error
X^A 2 add N to number at/after cursor {vi: no ^A}
X^B 1 scroll N screens Backwards
X^C interrupt current (search) command
X^D scroll Down N lines (default: half a screen)
X^E scroll N lines upwards (N lines Extra)
X^F 1 scroll N screens Forward
X^G display current file name and position
X^H <BS> 1 cursor N chars to the left
X^I <TAB> 1 go to N newer entry in jump list
X^J <LF> 1 cursor N lines downward
X^K error
X^L redraw screen
X^M <CR> 1 cursor to the first CHAR N lines lower
X^N 1 cursor N lines downward
X^O 1 go to N older entry in jump list
X^P 1 cursor N lines upward
X^Q error (used for xon/xoff)
X^R 2 redo changes which were undone with 'u' (vi: retype
X the screen)
X^S error (used for xon/xoff)
X^T jump to N older Tag in tag list
X^U scroll N lines Upwards (default: half a screen)
X^V start blockwise Visual (vi: no Visual)
X^W window commands, followed by another character (vi: not)
X^X 2 subtract N from number at/after cursor {vi: no ^X}
X^Y scroll N lines downwards
X^Z suspend program (or start new shell)
X^[ <ESC> error
X^\ error
X^] :ta to ident under cursor
X^^ edit Nth alternate file (equivalent to :e #N)
X^_ error
X
X<SPACE> 1 cursor N chars to the right
X!<move><filter> filter Nmove text through the "filter" command
X!!<filter> filter N lines through the "filter" command
X"<a-zA-Z0-9.> use buffer <a-zA-Z0-9.> for next delete, yank or put
X (upper case to append)(<.> only works for put)
X# 1 search backward for the Nth occurrence of the ident under
X the cursor {not in vi}
X$ 1 cursor to the end of line N from the cursor
X% 1 find the next (curly/square) bracket on this line and go
X to its match. With count: go to N percentage in the file.
X& 2 repeat last :s
X'<a-zA-Z> 1 cursor to the first CHAR on the line with mark <a-zA-Z>
X'[ 1 cursor to the first CHAR on the line of the start of
X last operated text or start of putted text
X'] 1 cursor to the first CHAR on the line of the end of
X last operated text or end of putted text
X'' 1 cursor to the first CHAR of the line where the cursor was
X before the latest jump.
X( 1 cursor N sentences backward
X) 1 cursor N sentences forward
X* 1 search forward for the Nth occurrence of the ident under
X the cursor {not in vi}
X+ 1 cursor to the first CHAR N lines lower
X, 1 repeat latest f, t, F or T in opposite direction N times
X- 1 cursor to the first CHAR N lines higher
X. 2 repeat last change with count replaced by N
X/<pattern> 1 search forward for the Nth occurrence of <pattern>
X0 1 cursor to the first char of the line
X1 prepend to command to give a count
X2 "
X3 "
X4 "
X5 "
X6 "
X7 "
X8 "
X9 "
X: Ex command (see below)
X; 1 repeat latest f, t, F or T N times
X<<move> 2 shift the Nmove lines one shiftwidth leftwards
X<< 2 shift N lines one shiftwidth leftwards
X=<move> 2 filter Nmove lines through "indent" (vi: when option
X 'lisp' is set autoindent Nmove lines)
X== 2 filter N lines through "indent"
X><move> 2 shift Nmove lines one shiftwidth rightwards
X>> 2 shift N lines one shiftwidth rightwards
X?<pattern> 1 search backward for the Nth previous occurrence of
X <pattern>
X@<a-z> 2 execute the contents of named buffer <a-z> N times
X@@ 2 repeat the previous @<a-z> N times
XA 2 append text at the end of the line N times
XB 1 cursor N WORDS backward
X<"x>C 2 change from the cursor position to the end of the line,
X and N-1 more lines [into buffer x]; synonym for c$
X<"x>D 2 delete the characters under the cursor until the end of
X the line and N-1 more lines [into buffer x]; synonym for d$
XE 1 cursor forward to the end of WORD N
XF<char> cursor to the Nth occurrence of <char> to the left
XG 1 cursor to line N, default last line
XH 1 cursor to line N from top of screen
XI 2 insert text before the first CHAR on the line N times
XJ 2 Join N lines; default is 2
XK lookup Keyword under the cursor with 'keywordprg'
XL 1 cursor to line N from bottom of screen
XM 1 cursor to middle line of screen
XN 1 repeat the latest '/' or '?' N times in opposite
X direction
XO 2 begin a new line above the cursor and insert text, repeat
X N times (vi: blank N screen lines)
X<"x>P 2 put the text [from buffer x] before the cursor N times
XV start Visual mode on lines (vi: go to Ex mode)
XR 2 enter replace mode: overtype existing characters, repeat the
X entered text N-1 times
X<"x>S 2 delete N lines [into buffer x] and start insert; synonym
X for ^cc or 0cc, depending on autoindent
XT<char> 1 cursor till after Nth occurrence of <char> to the left
XU 2 undo all latest changes on one line (vi: while not moved
X off of it)
X While in Visual mode: make uppercase
XQ<move> 2 Join N lines and re-format them
XW 1 cursor N WORDS forward
X<"x>X 2 delete N characters before the cursor [into buffer x]
X<"x>Y yank N lines [into buffer x]; synonym for yy
XZZ store current file, if modified, and exit
X[[ 1 cursor N sections backward
X[] 1 cursor N SECTIONS backward
X[{ 1 cursor N times back to unmatched '{' (vi: not)
X[( 1 cursor N times back to unmatched '(' (vi: not)
X[f edit file name under the cursor
X[p 2 like "p", but adjust indent to current line
X\ error
X]] 1 cursor N sections forward
X][ 1 cursor N SECTIONS forward
X]} 1 cursor N times forward to unmatched '}' (vi: not)
X]) 1 cursor N times forward to unmatched ')' (vi: not)
X]f edit file name under the cursor
X]p 2 like "P", but adjust indent to current line
X^ 1 cursor to the first CHAR of the line
X_ 1 cursor to the first CHAR N - 1 lines lower
X`<a-zA-Z> 1 cursor to the mark <a-zA-Z>
X`[ 1 cursor to the start of last operated text or start of
X putted text
X`] 1 cursor to the end of last operated text or end of
X putted text
X`` 1 cursor to the position before latest jump
Xa 2 append text after the cursor N times
Xb 1 cursor N words backward
X<"x>c<move> 2 delete Nmove text [into buffer x] and start insert
X<"x>cc 2 delete N lines [into buffer x] and start insert
X<"x>d<move> 2 delete Nmove text [into buffer x]
X<"x>dd 2 delete N lines [into buffer x]
Xe 1 cursor forward to the end of word N
Xf<char> 1 cursor to Nth occurrence of <char> to the right
Xgs goto sleep for N seconds (default 1) (vi: not)
Xgf edit file name under the cursor
Xh 1 cursor N chars to the left
Xi 2 insert text before the cursor N times
Xj 1 cursor N lines downward
Xk 1 cursor N lines upward
Xl 1 cursor N chars to the right
Xm<a-z> set mark <a-z> at cursor position
Xn 1 repeat the latest '/' or '?' N times
Xo 2 begin a new line below the cursor and insert text, repeat
X N times (vi: blank N screen lines)
X While Visual: cursor moves other end
X<"x>p 2 put the text [from buffer x] after the cursor N times
Xv start Visual mode with characters (vi: no Visual)
Xr<char> 2 replace N chars by <char>
X<"x>s 2 (substitute) delete N characters [into buffer x] and
X start insert
Xt<char> 1 cursor till before Nth occurrence of <char> to the right
Xu 2 undo changes (vi: only one level)
X With Visual: make lowercase (vi: no Visual)
Xq<a-zA-Z> record typed characters into named buffer <a-zA-Z>
X (upper case to append)
Xq stops recording (vi: no recording)
Xw 1 cursor N words forward
X<"x>x 2 delete N characters under and after the cursor [into
X buffer x]
X<"x>y<move> yank Nmove text [into buffer x]
X<"x>yy yank N lines [into buffer x]
Xz<CR> redraw, cursor line to top of window, first non-blank
Xz. redraw, cursor line to center of window, first non-blank
Xz- redraw, cursor line at bottom of window, first non-blank
Xzb redraw, cursor line at bottom of window
Xzt redraw, cursor line at top of window
Xzz redraw, cursor line at center of window
X{ 1 cursor N paragraphs backward
X| 1 cursor to column N
X} 1 cursor N paragraphs forward
X~ 2 option notildeop: switch case of N characters under
X cursor and move the cursor N characters to the right
X (vi: no count)
X~<move> option tildeop: switch case of Nmove text (vi: no tildeop
X option)
X<DEL> when entering a number: remove the last digit
X<HELP> show the file vim:vim.hlp page by page (vi: no help)
X<C_UP> 1 move cursor N lines upwards
X<C_DOWN> 1 move cursor N lines downwards
X<C_LEFT> 1 move cursor N chars to the left
X<C_RIGHT> 1 move cursor N chars to the right
X<SC_UP> 1 scroll N screens Backwards (same as ^B)
X<SC_DOWN> 1 scroll N screens Forwards (same as ^F)
X<SC_LEFT> 1 cursor N words backward (same as b)
X<SC_RIGHT> 1 cursor N words forward (same as w)
X
X
X3. command line editing
X=======================
X
XGet to the command line with the ':', '!', '/' or '?' commands.
XNormal characters are inserted at the current cursor position.
X(vi: can only alter last character in the line)
X
X^A do filename completion on the pattern in front of the cursor
X and insert all matches
X^B cursor to begin of command line
X^D list filenames that match the pattern in front of the cursor
X^E cursor to end of command line
X^H delete the character in front of the cursor
X^L do filename completion on the pattern in front of the cursor
X and insert the longest common part
X^N after an <ESC> with multiple matches: go to next match
X otherwise: same as <C_DOWN>
X^P after an <ESC> with multiple matches: go to previous match
X otherwise: same as <C_UP>
X^U remove all characters
X^V insert next non-digit literally, insert three digit decimal
X number as a single byte. {Vi: type the CTRL-V twice to get one}
X^W delete the word in front of the cursor
X'wildchar' option (default <TAB>)
X do filename completion on the pattern in front of the cursor
X<DEL> delete the character under the cursor
X<C_UP> recall previous command line from history
X<C_DOWN> recall next command line from history


X<C_LEFT> cursor left
X<C_RIGHT> cursor right
X<SC_LEFT> cursor one word left
X<SC_RIGHT> cursor one word right

X<SC_UP> recall previous command line that matches pattern in front of
X the cursor
X<SC_DOWN> recall next command line that matches pattern in front of the
X cursor
X
X
X4. EX commands
X==============
X
XFor an index of EX commands, type CTRL-D at the ex command prompt.
XOr look in "src/cmdtab.tab".
X
END_OF_FILE
if test 12449 -ne `wc -c <'vim/doc/index'`; then
echo shar: \"'vim/doc/index'\" unpacked with wrong size!
fi
# end of 'vim/doc/index'
fi
if test -f 'vim/src/cmdcmds.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/cmdcmds.c'\"
else
echo shar: Extracting \"'vim/src/cmdcmds.c'\" \(11550 characters\)
sed "s/^X//" >'vim/src/cmdcmds.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * cmdcmds.c: functions for command line commands


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

X#if defined(LATTICE) || defined(NT)
X# define mktemp(a) tmpnam(a)
X#endif


X
Xextern char *mktemp __ARGS((char *));
X

X/*
X * align text:
X * type = -1 left aligned
X * type = 0 centered
X * type = 1 right aligned
X */
X void
Xdo_align(start, end, width, type)
X linenr_t start;
X linenr_t end;
X int width;
X int type;
X{
X FPOS pos;
X int len;
X int indent = 0;


X
X pos = curwin->w_cursor;

X if (type == -1) /* left align: width is used for new indent */
X {
X if (width >= 0)
X indent = width;


X }
X else
X {
X /*

X * if 'textwidth' set, use it
X * else if 'wrapmargin' set, use it
X * if invalid value, use 80
X */
X if (width <= 0)
X width = curbuf->b_p_tw;
X if (width == 0 && curbuf->b_p_wm > 0)
X width = Columns - curbuf->b_p_wm;
X if (width <= 0)
X width = 80;
X }
X
X if (!u_save((linenr_t)(start - 1), (linenr_t)(end + 1)))
X return;
X for (curwin->w_cursor.lnum = start; curwin->w_cursor.lnum <= end; ++curwin->w_cursor.lnum)
X {
X set_indent(indent, TRUE); /* remove existing indent */
X if (type == -1) /* left align */
X continue;
X len = strsize(ml_get(curwin->w_cursor.lnum)); /* get line lenght */
X if (len < width)
X switch (type)
X {
X case 0: set_indent((width - len) / 2, FALSE); /* center */
X break;
X case 1: set_indent(width - len, FALSE); /* right */
X break;
X }
X }


X curwin->w_cursor = pos;

X beginline(TRUE);
X updateScreen(NOT_VALID);
X}
X
X/*
X * :move command - move lines line1-line2 to line n


X *
X * return FAIL for failure, OK otherwise
X */
X int

Xdo_move(line1, line2, n)
X linenr_t line1;
X linenr_t line2;
X linenr_t n;
X{
X char_u *q;
X int has_mark;
X
X if (n >= line1 && n < line2 && line2 > line1)
X {
X EMSG("Move lines into themselves");
X return FAIL;
X }
X
X /*
X * adjust line marks (global marks done below)
X * if the lines are moved down, the marks in the moved lines
X * move down and the marks in the lines between the old and
X * new position move up.
X * If the lines are moved up it is just the other way round
X */
X if (n >= line2) /* move down */
X {
X mark_adjust(line1, line2, n - line2);
X mark_adjust(line2 + 1, n, -(line2 - line1 + 1));
X }
X else /* move up */
X {
X mark_adjust(line1, line2, -(line1 - n - 1));
X mark_adjust(n + 1, line1 - 1, line2 - line1 + 1);
X }
X
X if (n >= line1)
X {
X --n;
X curwin->w_cursor.lnum = n - (line2 - line1) + 1;
X }
X else
X curwin->w_cursor.lnum = n + 1;
X while (line1 <= line2)
X {
X /* this undo is not efficient, but it works */
X u_save(line1 - 1, line1 + 1);
X q = strsave(ml_get(line1));
X if (q != NULL)
X {
X /*
X * marks from global command go with the line
X */
X has_mark = ml_has_mark(line1);
X ml_delete(line1);
X u_save(n, n + 1);
X ml_append(n, q, (colnr_t)0, FALSE);
X free(q);
X if (has_mark)
X ml_setmarked(n + 1);
X }
X if (n < line1)
X {
X ++n;
X ++line1;
X }
X else
X --line2;


X }
X CHANGED;
X return OK;

X}
X
X/*
X * :copy command - copy lines line1-line2 to line n
X */
X void
Xdo_copy(line1, line2, n)
X linenr_t line1;
X linenr_t line2;
X linenr_t n;
X{
X linenr_t lnum;
X char_u *p;
X
X mark_adjust(n + 1, MAXLNUM, line2 - line1 + 1);
X
X /*
X * there are three situations:
X * 1. destination is above line1
X * 2. destination is between line1 and line2
X * 3. destination is below line2
X *
X * n = destination (when starting)
X * curwin->w_cursor.lnum = destination (while copying)
X * line1 = start of source (while copying)
X * line2 = end of source (while copying)
X */
X u_save(n, n + 1);
X curwin->w_cursor.lnum = n;
X lnum = line2 - line1 + 1;
X while (line1 <= line2)
X {
X /* need to use strsave() because the line will be unlocked
X within ml_append */
X p = strsave(ml_get(line1));


X if (p != NULL)
X {

X ml_append(curwin->w_cursor.lnum, p, (colnr_t)0, FALSE);
X free(p);
X }
X /* situation 2: skip already copied lines */
X if (line1 == n)
X line1 = curwin->w_cursor.lnum;
X ++line1;
X if (curwin->w_cursor.lnum < line1)
X ++line1;
X if (curwin->w_cursor.lnum < line2)
X ++line2;
X ++curwin->w_cursor.lnum;
X }
X CHANGED;
X msgmore((long)lnum);
X}
X
X/*
X * handle the :! command.
X * We replace the extra bangs by the previously entered command and remember
X * the command.
X */
X void
Xdobang(addr_count, line1, line2, forceit, arg)
X int addr_count;
X linenr_t line1, line2;
X int forceit;
X char_u *arg;
X{
X static char_u *prevcmd = NULL; /* the previous command */
X char_u *t;
X char_u *trailarg;
X int len;
X
X /*
X * Disallow shell commands from .exrc and .vimrc in current directory for


X * security reasons.
X */
X if (secure)
X {
X secure = 2;
X emsg(e_curdir);

X return;
X }
X len = STRLEN(arg) + 1;
X
X autowrite_all();
X /*
X * try to find an embedded bang, like in :!<cmd> ! [args]
X * (:!! is indicated by the 'forceit' variable)
X */
X trailarg = arg;
X skiptospace(&trailarg);
X skipspace(&trailarg);
X if (*trailarg == '!')
X *trailarg++ = NUL;
X else
X trailarg = NULL;
X
X if (forceit || trailarg != NULL) /* use the previous command */
X {
X if (prevcmd == NULL)
X {
X emsg(e_noprev);
X return;
X }
X len += STRLEN(prevcmd) * (trailarg != NULL && forceit ? 2 : 1);
X }
X
X if (len > CMDBUFFSIZE)
X {
X emsg(e_toolong);
X return;
X }
X if ((t = alloc(len)) == NULL)
X return;
X *t = NUL;
X if (forceit)
X STRCPY(t, prevcmd);
X STRCAT(t, arg);
X if (trailarg != NULL)
X {
X STRCAT(t, prevcmd);
X STRCAT(t, trailarg);
X }
X free(prevcmd);
X prevcmd = t;
X
X if (bangredo) /* put cmd in redo buffer for ! command */
X {
X AppendToRedobuff(prevcmd);
X AppendToRedobuff((char_u *)"\n");
X bangredo = FALSE;
X }
X /* echo the command */
X msg_start();
X msg_outchar(':');
X if (addr_count) /* :range! */
X {
X msg_outnum((long)line1);
X msg_outchar(',');
X msg_outnum((long)line2);
X }
X msg_outchar('!');
X msg_outtrans(prevcmd, -1);
X msg_ceol();
X
X if (addr_count == 0) /* :! */
X doshell(prevcmd);
X else /* :range! */
X dofilter(line1, line2, prevcmd, TRUE, TRUE);
X}
X
X/*
X * call a shell to execute a command
X */
X void
Xdoshell(cmd)
X char_u *cmd;
X{
X BUF *buf;
X
X /*
X * Disallow shell commands from .exrc and .vimrc in current directory for


X * security reasons.
X */
X if (secure)
X {
X secure = 2;
X emsg(e_curdir);

X msg_end();
X return;
X }
X stoptermcap();
X msg_outchar('\n'); /* may shift screen one line up */
X
X /* warning message before calling the shell */
X if (p_warn)
X for (buf = firstbuf; buf; buf = buf->b_next)


X if (buf->b_changed)
X {

X msg_outstr((char_u *)"[No write since last change]\n");
X break;
X }
X


X windgoto((int)Rows - 1, 0);

X cursor_on();
X (void)call_shell(cmd, 0, TRUE);
X
X#ifdef AMIGA
X wait_return(term_console ? -1 : TRUE); /* see below */
X#else
X wait_return(TRUE); /* includes starttermcap() */
X#endif
X
X /*
X * In an Amiga window redrawing is caused by asking the window size.
X * If we got an interrupt this will not work. The chance that the window
X * size is wrong is very small, but we need to redraw the screen.
X * Don't do this if ':' hit in wait_return().
X * THIS IS UGLY but it save an extra redraw.
X */
X#ifdef AMIGA
X if (skip_redraw) /* ':' hit in wait_return() */
X must_redraw = CLEAR;
X else if (term_console)
X {
X OUTSTR("\033[0 q"); /* get window size */
X if (got_int)
X must_redraw = CLEAR; /* if got_int is TRUE we have to redraw */
X else
X must_redraw = 0; /* no extra redraw needed */
X }
X#endif /* AMIGA */
X}
X
X/*
X * dofilter: filter lines through a command given by the user
X *
X * We use temp files and the call_shell() routine here. This would normally
X * be done using pipes on a UNIX machine, but this is more portable to
X * the machines we usually run on. The call_shell() routine needs to be able
X * to deal with redirection somehow, and should handle things like looking
X * at the PATH env. variable, and adding reasonable extensions to the
X * command name given by the user. All reasonable versions of call_shell()
X * do this.
X * We use input redirection if do_in is TRUE.
X * We use output redirection if do_out is TRUE.
X */
X void
Xdofilter(line1, line2, buff, do_in, do_out)
X linenr_t line1, line2;
X char_u *buff;
X int do_in, do_out;
X{
X#ifdef LATTICE
X char_u itmp[L_tmpnam]; /* use tmpnam() */
X char_u otmp[L_tmpnam];
X#else
X char_u itmp[TMPNAMELEN];
X char_u otmp[TMPNAMELEN];
X#endif
X linenr_t linecount;
X
X /*
X * Disallow shell commands from .exrc and .vimrc in current directory for


X * security reasons.
X */
X if (secure)
X {
X secure = 2;
X emsg(e_curdir);

X return;
X }
X if (*buff == NUL) /* no filter command */
X return;
X linecount = line2 - line1 + 1;
X curwin->w_cursor.lnum = line1;


X curwin->w_cursor.col = 0;

X /* cursupdate(); */
X
X /*
X * 1. Form temp file names
X * 2. Write the lines to a temp file
X * 3. Run the filter command on the temp file
X * 4. Read the output of the command into the buffer
X * 5. Delete the original lines to be filtered
X * 6. Remove the temp files
X */
X
X#ifndef LATTICE
X /* for lattice we use tmpnam(), which will make its own name */
X STRCPY(itmp, TMPNAME1);
X STRCPY(otmp, TMPNAME2);
X#endif
X
X if ((do_in && *mktemp((char *)itmp) == NUL) || (do_out && *mktemp((char *)otmp) == NUL))
X {
X emsg(e_notmp);
X return;
X }
X
X/*
X * ! command will be overwritten by next mesages
X * This is a trade off between showing the command and not scrolling the
X * text one line up (problem on slow terminals).
X */
X must_redraw = CLEAR; /* screen has been shifted up one line */
X ++no_wait_return; /* don't call wait_return() while busy */
X if (do_in && buf_write(curbuf, itmp, NULL, line1, line2, FALSE, 0, FALSE) == FAIL)
X {
X msg_outchar('\n'); /* keep message from writeit() */
X --no_wait_return;
X (void)emsg2(e_notcreate, itmp); /* will call wait_return */
X return;
X }
X if (!do_out)


X outchar('\n');
X

X#if defined(UNIX) && !defined(ARCHIE)
X/*
X * put braces around the command (for concatenated commands)
X */
X sprintf((char *)IObuff, "(%s)", (char *)buff);
X if (do_in)
X {
X STRCAT(IObuff, " < ");
X STRCAT(IObuff, itmp);
X }
X if (do_out)
X {
X STRCAT(IObuff, " > ");
X STRCAT(IObuff, otmp);
X }
X#else
X/*
X * for shells that don't understand braces around commands, at least allow
X * the use of commands in a pipe.
X */
X STRCPY(IObuff, buff);
X if (do_in)
X {
X char_u *p;
X /*
X * If there is a pipe, we have to put the '<' in front of it
X */
X p = STRCHR(IObuff, '|');
X if (p)
X *p = NUL;
X STRCAT(IObuff, " < ");
X STRCAT(IObuff, itmp);
X p = STRCHR(buff, '|');
X if (p)
X STRCAT(IObuff, p);
X }
X if (do_out)
X {
X STRCAT(IObuff, " > ");
X STRCAT(IObuff, otmp);
X }
X#endif


X
X windgoto((int)Rows - 1, 0);

X cursor_on();
X /* errors are ignored, so you can see the error
X messages from the command; use 'u' to fix the text */
X (void)call_shell(IObuff, 1, FALSE);
X
X if (do_out)
X {
X if (!u_save((linenr_t)(line2), (linenr_t)(line2 + 1)))
X {
X linecount = 0;
X goto error;
X }
X if (readfile(otmp, NULL, line2, FALSE, (linenr_t)0, MAXLNUM) == FAIL)
X {
X outchar('\n');
X emsg2(e_notread, otmp);
X linecount = 0;


X goto error;
X }
X

X if (do_in)
X {
X curwin->w_cursor.lnum = line1;
X dellines(linecount, TRUE, TRUE);
X }
X --no_wait_return;
X }
X else
X {
Xerror:
X --no_wait_return;
X wait_return(FALSE);
X }
X updateScreen(CLEAR); /* do this before messages below */
X
X if (linecount > p_report)
X {
X if (!do_in && do_out)
X msgmore(linecount);
X else
X smsg((char_u *)"%ld lines filtered", (long)linecount);
X }
X remove((char *)itmp);
X remove((char *)otmp);
X}
END_OF_FILE
if test 11550 -ne `wc -c <'vim/src/cmdcmds.c'`; then
echo shar: \"'vim/src/cmdcmds.c'\" unpacked with wrong size!
fi
# end of 'vim/src/cmdcmds.c'
fi
if test -f 'vim/src/cmdtab.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/cmdtab.h'\"
else
echo shar: Extracting \"'vim/src/cmdtab.h'\" \(11638 characters\)
sed "s/^X//" >'vim/src/cmdtab.h' <<'END_OF_FILE'
X/* vi:ts=4


X *
X * VIM - Vi IMproved

X *
X * Code Contributions By: Bram Moolenaar mo...@oce.nl
X * Tim Thompson twitch!tjt
X * Tony Andrews onecom!wldrdg!tony
X * G. R. (Fred) Walter watmath!watcgl!grwalter

X */
X
X/*
X * THIS FILE IS AUTOMATICALLY PRODUCED - DO NOT EDIT
X */
X
X#define RANGE 0x01 /* allow a linespecs */
X#define BANG 0x02 /* allow a ! after the command name */
X#define EXTRA 0x04 /* allow extra args after command name */
X#define XFILE 0x08 /* expand wildcards in extra part */
X#define NOSPC 0x10 /* no spaces allowed in the extra part */
X#define DFLALL 0x20 /* default file range is 1,$ */
X#define NODFL 0x40 /* do not default to the current file name */
X#define NEEDARG 0x80 /* argument required */
X#define TRLBAR 0x100 /* check for trailing vertical bar */
X#define REGSTR 0x200 /* allow "x for register designation */
X#define COUNT 0x400 /* allow count in argument, after command */
X#define NOTRLCOM 0x800 /* no trailing comment allowed */
X#define ZEROR 0x1000 /* zero line number allowed */
X#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
X#define NOTADR 0x4000 /* number before command is not an address */
X#define FILES (XFILE + EXTRA) /* multiple extra files allowed */
X#define WORD1 (EXTRA + NOSPC) /* one extra word allowed */
X#define FILE1 (FILES + NOSPC) /* 1 file allowed, defaults to current file */
X#define NAMEDF (FILE1 + NODFL) /* 1 file allowed, defaults to "" */
X#define NAMEDFS (FILES + NODFL) /* multiple files allowed, default is "" */
X
X/*
X * This array maps ex command names to command codes. The order in which
X * command names are listed below is significant -- ambiguous abbreviations
X * are always resolved to be the first possible match (e.g. "r" is taken
X * to mean "read", not "rewind", because "read" comes before "rewind").
X * Not supported commands are included to avoid ambiguities.
X */
Xstatic struct
X{
X char_u *cmd_name; /* name of the command */
X short cmd_argt; /* command line arguments permitted/needed/used */
X} cmdnames[] =
X{
X {(char_u *)"append", BANG+RANGE+TRLBAR}, /* not supported */
X#define CMD_append 0
X {(char_u *)"all", TRLBAR},
X#define CMD_all 1
X {(char_u *)"abbreviate", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_abbreviate 2
X {(char_u *)"args", RANGE+NOTADR+BANG+NAMEDFS},
X#define CMD_args 3
X {(char_u *)"argument", BANG+RANGE+NOTADR+COUNT+EXTRA},
X#define CMD_argument 4
X {(char_u *)"buffer", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_buffer 5
X {(char_u *)"ball", TRLBAR},
X#define CMD_ball 6
X {(char_u *)"buffers", TRLBAR},
X#define CMD_buffers 7
X {(char_u *)"bdelete", BANG+RANGE+NOTADR+COUNT+EXTRA+TRLBAR},
X#define CMD_bdelete 8
X {(char_u *)"bunload", BANG+RANGE+NOTADR+COUNT+EXTRA+TRLBAR},
X#define CMD_bunload 9
X {(char_u *)"bmodified", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_bmodified 10
X {(char_u *)"bnext", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_bnext 11
X {(char_u *)"bNext", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_bNext 12
X {(char_u *)"bprevious", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_bprevious 13
X {(char_u *)"brewind", RANGE+TRLBAR},
X#define CMD_brewind 14
X {(char_u *)"blast", RANGE+TRLBAR},
X#define CMD_blast 15
X {(char_u *)"change", BANG+RANGE+COUNT+TRLBAR}, /* not supported */
X#define CMD_change 16
X {(char_u *)"cabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_cabbrev 17
X {(char_u *)"cc", TRLBAR+WORD1+BANG},
X#define CMD_cc 18
X {(char_u *)"cd", NAMEDF+TRLBAR},
X#define CMD_cd 19
X {(char_u *)"center", TRLBAR+RANGE+EXTRA},
X#define CMD_center 20
X {(char_u *)"cf", TRLBAR+FILE1+BANG},
X#define CMD_cf 21
X {(char_u *)"chdir", NAMEDF+TRLBAR},
X#define CMD_chdir 22
X {(char_u *)"cl", TRLBAR},
X#define CMD_cl 23
X {(char_u *)"close", BANG+TRLBAR},
X#define CMD_close 24
X {(char_u *)"cmap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_cmap 25
X {(char_u *)"cn", TRLBAR+WORD1+BANG},
X#define CMD_cn 26
X {(char_u *)"cnoremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_cnoremap 27
X {(char_u *)"cnoreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_cnoreabbrev 28
X {(char_u *)"copy", RANGE+EXTRA+TRLBAR},
X#define CMD_copy 29
X {(char_u *)"cp", TRLBAR+WORD1+BANG},
X#define CMD_cp 30
X {(char_u *)"cq", TRLBAR+BANG},
X#define CMD_cq 31
X {(char_u *)"cunmap", BANG+EXTRA+TRLBAR+USECTRLV},
X#define CMD_cunmap 32
X {(char_u *)"cunabbrev", EXTRA+TRLBAR+USECTRLV},
X#define CMD_cunabbrev 33
X {(char_u *)"delete", RANGE+REGSTR+COUNT+TRLBAR},
X#define CMD_delete 34
X {(char_u *)"display", TRLBAR},
X#define CMD_display 35
X {(char_u *)"digraphs", EXTRA+TRLBAR},
X#define CMD_digraphs 36
X {(char_u *)"edit", BANG+FILE1},
X#define CMD_edit 37
X {(char_u *)"ex", BANG+FILE1},
X#define CMD_ex 38
X {(char_u *)"exit", BANG+FILE1+DFLALL+TRLBAR},
X#define CMD_exit 39
X {(char_u *)"file", FILE1+TRLBAR},
X#define CMD_file 40
X {(char_u *)"files", TRLBAR},
X#define CMD_files 41
X {(char_u *)"global", RANGE+BANG+EXTRA+DFLALL},
X#define CMD_global 42
X {(char_u *)"help", TRLBAR},
X#define CMD_help 43
X {(char_u *)"insert", BANG+RANGE+TRLBAR}, /* not supported */
X#define CMD_insert 44
X {(char_u *)"iabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_iabbrev 45
X {(char_u *)"imap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_imap 46
X {(char_u *)"inoremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_inoremap 47
X {(char_u *)"inoreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_inoreabbrev 48
X {(char_u *)"iunmap", BANG+EXTRA+TRLBAR+USECTRLV},
X#define CMD_iunmap 49
X {(char_u *)"iunabbrev", EXTRA+TRLBAR+USECTRLV},
X#define CMD_iunabbrev 50
X {(char_u *)"join", RANGE+COUNT+TRLBAR},
X#define CMD_join 51
X {(char_u *)"jumps", TRLBAR},
X#define CMD_jumps 52
X {(char_u *)"k", RANGE+WORD1+TRLBAR},
X#define CMD_k 53
X {(char_u *)"list", RANGE+COUNT+TRLBAR},
X#define CMD_list 54
X {(char_u *)"last", EXTRA+BANG},
X#define CMD_last 55
X {(char_u *)"left", TRLBAR+RANGE+EXTRA},
X#define CMD_left 56
X {(char_u *)"move", RANGE+EXTRA+TRLBAR},
X#define CMD_move 57
X {(char_u *)"mark", RANGE+WORD1+TRLBAR},
X#define CMD_mark 58
X {(char_u *)"marks", TRLBAR},
X#define CMD_marks 59
X {(char_u *)"map", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_map 60
X {(char_u *)"make", NEEDARG+EXTRA+TRLBAR+XFILE},
X#define CMD_make 61
X {(char_u *)"mkexrc", BANG+FILE1+TRLBAR},
X#define CMD_mkexrc 62
X {(char_u *)"mkvimrc", BANG+FILE1+TRLBAR},
X#define CMD_mkvimrc 63
X {(char_u *)"mfstat", TRLBAR}, /* for debugging */
X#define CMD_mfstat 64
X {(char_u *)"mode", WORD1+TRLBAR},
X#define CMD_mode 65
X {(char_u *)"next", RANGE+NOTADR+BANG+NAMEDFS},
X#define CMD_next 66
X {(char_u *)"new", BANG+FILE1+RANGE+NOTADR},
X#define CMD_new 67
X {(char_u *)"number", RANGE+COUNT+TRLBAR},
X#define CMD_number 68
X {(char_u *)"#", RANGE+COUNT+TRLBAR},
X#define CMD_pound 69
X {(char_u *)"noremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_noremap 70
X {(char_u *)"noreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},
X#define CMD_noreabbrev 71
X {(char_u *)"Next", EXTRA+RANGE+NOTADR+COUNT+BANG},
X#define CMD_Next 72
X {(char_u *)"only", BANG+TRLBAR},
X#define CMD_only 73
X {(char_u *)"print", RANGE+COUNT+TRLBAR},
X#define CMD_print 74
X {(char_u *)"pop", RANGE+NOTADR+COUNT+TRLBAR+ZEROR},
X#define CMD_pop 75
X {(char_u *)"put", RANGE+BANG+REGSTR+TRLBAR},
X#define CMD_put 76
X {(char_u *)"preserve", TRLBAR},
X#define CMD_preserve 77
X {(char_u *)"previous", EXTRA+RANGE+NOTADR+COUNT+BANG},
X#define CMD_previous 78
X {(char_u *)"pwd", TRLBAR},
X#define CMD_pwd 79
X {(char_u *)"quit", BANG+TRLBAR},
X#define CMD_quit 80
X {(char_u *)"qall", BANG+TRLBAR},
X#define CMD_qall 81
X {(char_u *)"read", RANGE+NAMEDF+TRLBAR+ZEROR},
X#define CMD_read 82
X {(char_u *)"rewind", EXTRA+BANG},
X#define CMD_rewind 83
X {(char_u *)"recover", FILE1+TRLBAR}, /* not supported */
X#define CMD_recover 84
X {(char_u *)"redo", TRLBAR},
X#define CMD_redo 85
X {(char_u *)"right", TRLBAR+RANGE+EXTRA},
X#define CMD_right 86
X {(char_u *)"resize", TRLBAR+WORD1},
X#define CMD_resize 87
X {(char_u *)"substitute", RANGE+EXTRA},
X#define CMD_substitute 88
X {(char_u *)"sargument", BANG+RANGE+NOTADR+COUNT+EXTRA},
X#define CMD_sargument 89
X {(char_u *)"sall", TRLBAR},
X#define CMD_sall 90
X {(char_u *)"sbuffer", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_sbuffer 91
X {(char_u *)"sball", TRLBAR},
X#define CMD_sball 92
X {(char_u *)"sbmodified", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_sbmodified 93
X {(char_u *)"sbnext", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_sbnext 94
X {(char_u *)"sbNext", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_sbNext 95
X {(char_u *)"sbprevious", RANGE+NOTADR+COUNT+TRLBAR},
X#define CMD_sbprevious 96
X {(char_u *)"sbrewind", TRLBAR},
X#define CMD_sbrewind 97
X {(char_u *)"sblast", TRLBAR},
X#define CMD_sblast 98
X {(char_u *)"suspend", TRLBAR+BANG},
X#define CMD_suspend 99
X {(char_u *)"set", EXTRA+TRLBAR},
X#define CMD_set 100
X {(char_u *)"setkeymap", NAMEDF+TRLBAR},
X#define CMD_setkeymap 101
X {(char_u *)"shell", TRLBAR},
X#define CMD_shell 102
X {(char_u *)"sleep", RANGE+COUNT+NOTADR+TRLBAR},
X#define CMD_sleep 103
X {(char_u *)"source", NAMEDF+NEEDARG+TRLBAR},
X#define CMD_source 104
X {(char_u *)"split", BANG+FILE1+RANGE+NOTADR},
X#define CMD_split 105
X {(char_u *)"snext", RANGE+NOTADR+BANG+NAMEDFS},
X#define CMD_snext 106
X {(char_u *)"sNext", EXTRA+RANGE+NOTADR+COUNT+BANG},
X#define CMD_sNext 107
X {(char_u *)"sprevious", EXTRA+RANGE+NOTADR+COUNT+BANG},
X#define CMD_sprevious 108
X {(char_u *)"srewind", EXTRA+BANG},
X#define CMD_srewind 109
X {(char_u *)"slast", EXTRA+BANG},
X#define CMD_slast 110
X {(char_u *)"stop", TRLBAR+BANG},
X#define CMD_stop 111
X {(char_u *)"sunhide", TRLBAR},
X#define CMD_sunhide 112
X {(char_u *)"swapname", TRLBAR},
X#define CMD_swapname 113
X {(char_u *)"t", RANGE+EXTRA+TRLBAR},
X#define CMD_t 114
X {(char_u *)"tag", RANGE+NOTADR+COUNT+BANG+WORD1+TRLBAR+ZEROR},
X#define CMD_tag 115
X {(char_u *)"tags", TRLBAR},
X#define CMD_tags 116
X {(char_u *)"unabbreviate", EXTRA+TRLBAR+USECTRLV},
X#define CMD_unabbreviate 117
X {(char_u *)"undo", TRLBAR},
X#define CMD_undo 118
X {(char_u *)"unhide", TRLBAR},
X#define CMD_unhide 119
X {(char_u *)"unmap", BANG+EXTRA+TRLBAR+USECTRLV},
X#define CMD_unmap 120
X {(char_u *)"vglobal", RANGE+EXTRA+DFLALL},
X#define CMD_vglobal 121
X {(char_u *)"version", TRLBAR},
X#define CMD_version 122
X {(char_u *)"visual", RANGE+BANG+FILE1},
X#define CMD_visual 123
X {(char_u *)"write", RANGE+BANG+FILE1+DFLALL+TRLBAR},
X#define CMD_write 124
X {(char_u *)"wnext", RANGE+NOTADR+BANG+FILE1+TRLBAR},
X#define CMD_wnext 125
X {(char_u *)"wNext", RANGE+NOTADR+BANG+FILE1+TRLBAR},
X#define CMD_wNext 126
X {(char_u *)"wprevious", RANGE+NOTADR+BANG+FILE1+TRLBAR},
X#define CMD_wprevious 127
X {(char_u *)"winsize", EXTRA+NEEDARG+TRLBAR},
X#define CMD_winsize 128
X {(char_u *)"wq", BANG+FILE1+DFLALL+TRLBAR},
X#define CMD_wq 129
X {(char_u *)"wall", BANG+TRLBAR},
X#define CMD_wall 130
X {(char_u *)"wqall", BANG+FILE1+DFLALL+TRLBAR},
X#define CMD_wqall 131
X {(char_u *)"xit", BANG+FILE1+DFLALL+TRLBAR},
X#define CMD_xit 132
X {(char_u *)"xall", BANG+TRLBAR},
X#define CMD_xall 133
X {(char_u *)"yank", RANGE+REGSTR+COUNT+TRLBAR},
X#define CMD_yank 134
X {(char_u *)"z", RANGE+COUNT+TRLBAR}, /* not supported */
X#define CMD_z 135
X {(char_u *)"@", RANGE+EXTRA+TRLBAR},
X#define CMD_at 136
X {(char_u *)"!", RANGE+NAMEDFS},
X#define CMD_bang 137
X {(char_u *)"<", RANGE+COUNT+TRLBAR},
X#define CMD_lshift 138
X {(char_u *)">", RANGE+COUNT+TRLBAR},
X#define CMD_rshift 139
X {(char_u *)"=", RANGE+TRLBAR},
X#define CMD_equal 140
X {(char_u *)"&", RANGE+EXTRA},
X#define CMD_and 141
X {(char_u *)"~", RANGE+EXTRA}
X#define CMD_tilde 142
X#define CMD_SIZE 143
X
X};
END_OF_FILE
if test 11638 -ne `wc -c <'vim/src/cmdtab.h'`; then
echo shar: \"'vim/src/cmdtab.h'\" unpacked with wrong size!
fi
# end of 'vim/src/cmdtab.h'
fi
if test -f 'vim/src/digraph.c.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/digraph.c.UU'\"
else
echo shar: Extracting \"'vim/src/digraph.c.UU'\" \(11504 characters\)
sed "s/^X//" >'vim/src/digraph.c.UU' <<'END_OF_FILE'
Xbegin 644 vim/src/digraph.c
XM+RH@=FDZ=',]-#IS=STT"B J"B J(%9)32 M(%9I($E-<')O=F5D"0EB>2!"
XM<F%M($UO;VQE;F%A<@H@*@H@*B!296%D('1H92!F:6QE(")C<F5D:71S+G1X
XM="(@9F]R(&$@;&ES="!O9B!P96]P;&4@=VAO(&-O;G1R:6)U=&5D+@H@*B!2
XM96%D('1H92!F:6QE(")U9V%N9&$N='AT(B!F;W(@8V]P>6EN9R!A;F0@=7-A
XM9V4@8V]N9&ET:6]N<RX*("HO"@HC:69D968@1$E'4D%02%,*+RH*("H@9&EG
XM<F%P:"YC.B!C;V1E(&9O<B!D:6=R87!H<PH@*B\*"B-I;F-L=61E(")V:6TN
XM:"(*(VEN8VQU9&4@(F=L;V)A;',N:"(*(VEN8VQU9&4@(G!R;W1O+F@B"B-I
XM;F-L=61E(")P87)A;2YH(@H*<W1A=&EC('9O:60@<')I;G1D:6=R87!H(%]?
XM05)'4R@H8VAA<E]U("HI*3L*"F-H87)?=0DH*F1I9W)A<&AN97<I6S-=.PD)
XM"2\J('!O:6YT97(@=&\@861D960@9&EG<F%P:',@*B\*:6YT"0ED:6=R87!H
XM8V]U;G0@/2 P.PD)"2\J(&YU;6)E<B!O9B!A9&1E9"!D:6=R87!H<R J+PH*
XM(VEF9&5F($U31$]3"F-H87)?=0ED:6=R87!H9&5F875L=%M=6S-=(#T@"0DO
XM*B!S=&%N9&%R9"!-4T1/4R!D:6=R87!H<R J+PH)(" @>WLG0R<L("<L)RP@
XM,3(X?2P)+RH@@" J+PH)"7LG=2<L("<B)RP@,3(Y?2P)+RH@@2 J+PH)"7LG
XM92<L("=<)R<L(#$S,'TL"2\J(((@*B\*"0E[)V$G+" G7B<L(#$S,7TL"2\J
XM((,@*B\*"0E[)V$G+" G(B<L(#$S,GTL"2\J((0@*B\*"0E[)V$G+" G8"<L
XM(#$S,WTL"2\J((4@*B\*"0E[)V$G+" G0"<L(#$S-'TL"2\J((8@*B\*"0E[
XM)V,G+" G+"<L(#$S-7TL"2\J('Y'("A305,@0R!C86XG="!H86YD;&4@=&AE
XM(')E86P@8VAA<BD@*B\*"0E[)V4G+" G7B<L(#$S-GTL"2\J('Y(("A305,@
XM0R!C86XG="!H86YD;&4@=&AE(')E86P@8VAA<BD@*B\*"0E[)V4G+" G(B<L
XM(#$S-WTL"2\J((D@*B\*"0E[)V4G+" G8"<L(#$S.'TL"2\J((H@*B\*"0E[
XM)VDG+" G(B<L(#$S.7TL"2\J((L@*B\*"0E[)VDG+" G7B<L(#$T,'TL"2\J
XM((P@*B\*"0E[)VDG+" G8"<L(#$T,7TL"2\J((T@*B\*"0E[)T$G+" G(B<L
XM(#$T,GTL"2\J((X@*B\*"0E[)T$G+" G0"<L(#$T,WTL"2\J((\@*B\*"0E[
XM)T4G+" G7"<G+" Q-#1]+ DO*B"0("HO"@D)>R=A)RP@)V4G+" Q-#5]+ DO
XM*B"1("HO"@D)>R=!)RP@)T4G+" Q-#9]+ DO*B"2("HO"@D)>R=O)RP@)UXG
XM+" Q-#=]+ DO*B"3("HO"@D)>R=O)RP@)R(G+" Q-#A]+ DO*B"4("HO"@D)
XM>R=O)RP@)V G+" Q-#E]+ DO*B"5("HO"@D)>R=U)RP@)UXG+" Q-3!]+ DO
XM*B"6("HO"@D)>R=U)RP@)V G+" Q-3%]+ DO*B"7("HO"@D)>R=Y)RP@)R(G
XM+" Q-3)]+ DO*B"8("HO"@D)>R=/)RP@)R(G+" Q-3-]+ DO*B"9("HO"@D)
XM>R=5)RP@)R(G+" Q-31]+ DO*B":("HO"@D@(" @>R=C)RP@)WPG+" Q-35]
XM+ DO*B";("HO"@D@(" @>R<D)RP@)R0G+" Q-39]+ DO*B"<("HO"@D@(" @
XM>R=9)RP@)RTG+" Q-3=]+ DO*B!^72 H4T%3($,@8V%N)W0@:&%N9&QE('1H
XM92!R96%L(&-H87(I("HO"@D@(" @>R=0)RP@)W0G+" Q-3A]+ DO*B">("HO
XM"@D@(" @>R=F)RP@)V8G+" Q-3E]+ DO*B"?("HO"@D)>R=A)RP@)UPG)RP@
XM,38P?2P)+RH@H" J+PH)"7LG:2<L("=<)R<L(#$V,7TL"2\J(*$@*B\*"0E[
XM)V\G+" G7"<G+" Q-C)]+ DO*B"B("HO"@D)>R=U)RP@)UPG)RP@,38S?2P)
XM+RH@>'@@*%-!4R!#(&-A;B=T(&AA;F1L92!T:&4@<F5A;"!C:&%R*2 J+PH)
XM"7LG;B<L("=^)RP@,38T?2P)+RH@I" J+PH)"7LG3B<L("=^)RP@,38U?2P)
XM+RH@I2 J+PH)"7LG82<L("=A)RP@,38V?2P)+RH@IB J+PH)"7LG;R<L("=O
XM)RP@,38W?2P)+RH@IR J+PH)"7LG?B<L("<_)RP@,38X?2P)+RH@J" J+PH)
XM"7LG+2<L("=A)RP@,38Y?2P)+RH@J2 J+PH)"7LG82<L("<M)RP@,3<P?2P)
XM+RH@JB J+PH)"7LG,2<L("<R)RP@,3<Q?2P)+RH@JR J+PH)"7LG,2<L("<T
XM)RP@,3<R?2P)+RH@K" J+PH)"7LG?B<L("<A)RP@,3<S?2P)+RH@K2 J+PH)
XM"7LG/"<L("<\)RP@,3<T?2P)+RH@KB J+PH)"7LG/B<L("<^)RP@,3<U?2P)
XM+RH@KR J+PH*"0E[)W,G+" G<R<L(#(R-7TL"2\J(.$@*B\*"0E[)VHG+" G
XM=2<L(#(S,'TL"2\J(.8@*B\*"0E[)V\G+" G+R<L(#(S-WTL"2\J(.T@*B\*
XM"0E[)RLG+" G+2<L(#(T,7TL"2\J(/$@*B\*"0E[)SXG+" G/2<L(#(T,GTL
XM"2\J(/(@*B\*"0E[)SPG+" G/2<L(#(T,WTL"2\J(/,@*B\*"0E[)SHG+" G
XM+2<L(#(T-GTL"2\J(/8@*B\*"0E[)WXG+" G?B<L(#(T-WTL"2\J(/<@*B\*
XM"0E[)WXG+" G;R<L(#(T.'TL"2\J(/@@*B\*"0E[)S(G+" G,B<L(#(U,WTL
XM"2\J(/T@*B\*"0E[3E5,+"!.54PL($Y53'T*"0E].PH*(V5L<V4)+RH@35-$
XM3U,@*B\*"F-H87)?=0ED:6=R87!H9&5F875L=%M=6S-=(#T@"0DO*B!S=&%N
XM9&%R9"!)4T\@9&EG<F%P:',@*B\*"2 @('M[)WXG+" G(2<L(#$V,7TL"2\J
XM(*$@*B\*"2 @("![)V,G+" G?"<L(#$V,GTL"2\J(*(@*B\*"2 @("![)R0G
XM+" G)"<L(#$V,WTL"2\J(*,@*B\*"2 @("![)V\G+" G>"<L(#$V-'TL"2\J
XM(*0@*B\*"2 @("![)UDG+" G+2<L(#$V-7TL"2\J(*4@*B\*"2 @("![)WPG
XM+" G?"<L(#$V-GTL"2\J(*8@*B\*"2 @("![)W G+" G82<L(#$V-WTL"2\J
XM(*<@*B\*"2 @("![)R(G+" G(B<L(#$V.'TL"2\J(*@@*B\*"2 @("![)V,G
XM+" G3R<L(#$V.7TL"2\J(*D@*B\*"0E[)V$G+" G+2<L(#$W,'TL"2\J(*H@
XM*B\*"0E[)SPG+" G/"<L(#$W,7TL"2\J(*L@*B\*"0E[)RTG+" G+"<L(#$W
XM,GTL"2\J(*P@*B\*"0E[)RTG+" G+2<L(#$W,WTL"2\J(*T@*B\*"0E[)W(G
XM+" G3R<L(#$W-'TL"2\J(*X@*B\*"0E[)RTG+" G/2<L(#$W-7TL"2\J(*\@
XM*B\*"0E[)WXG+" G;R<L(#$W-GTL"2\J(+ @*B\*"0E[)RLG+" G+2<L(#$W
XM-WTL"2\J(+$@*B\*"0E[)S(G+" G,B<L(#$W.'TL"2\J(+(@*B\*"0E[)S,G
XM+" G,R<L(#$W.7TL"2\J(+,@*B\*"0E[)UPG)RP@)UPG)RP@,3@P?2P)+RH@
XMM" J+PH)"7LG:B<L("=U)RP@,3@Q?2P)+RH@M2 J+PH)"7LG<"<L("=P)RP@
XM,3@R?2P)+RH@MB J+PH)"7LG?B<L("<N)RP@,3@S?2P)+RH@MR J+PH)"7LG
XM+"<L("<L)RP@,3@T?2P)+RH@N" J+PH)"7LG,2<L("<Q)RP@,3@U?2P)+RH@
XMN2 J+PH)"7LG;R<L("<M)RP@,3@V?2P)+RH@NB J+PH)"7LG/B<L("<^)RP@
XM,3@W?2P)+RH@NR J+PH)"7LG,2<L("<T)RP@,3@X?2P)+RH@O" J+PH)"7LG
XM,2<L("<R)RP@,3@Y?2P)+RH@O2 J+PH)"7LG,R<L("<T)RP@,3DP?2P)+RH@
XMOB J+PH)"7LG?B<L("<_)RP@,3DQ?2P)+RH@OR J+PH)"7LG02<L("=@)RP@
XM,3DR?2P)+RH@P" J+PH)"7LG02<L("=<)R<L(#$Y,WTL"2\J(,$@*B\*"0E[
XM)T$G+" G7B<L(#$Y-'TL"2\J(,(@*B\*"0E[)T$G+" G?B<L(#$Y-7TL"2\J
XM(,,@*B\*"0E[)T$G+" G(B<L(#$Y-GTL"2\J(,0@*B\*"0E[)T$G+" G0"<L
XM(#$Y-WTL"2\J(,4@*B\*"0E[)T$G+" G12<L(#$Y.'TL"2\J(,8@*B\*"0E[
XM)T,G+" G+"<L(#$Y.7TL"2\J(,<@*B\*"0E[)T4G+" G8"<L(#(P,'TL"2\J
XM(,@@*B\*"0E[)T4G+" G7"<G+" R,#%]+ DO*B#)("HO"@D)>R=%)RP@)UXG
XM+" R,#)]+ DO*B#*("HO"@D)>R=%)RP@)R(G+" R,#-]+ DO*B#+("HO"@D)
XM>R=))RP@)V G+" R,#1]+ DO*B#,("HO"@D)>R=))RP@)UPG)RP@,C U?2P)
XM+RH@S2 J+PH)"7LG22<L("=>)RP@,C V?2P)+RH@SB J+PH)"7LG22<L("<B
XM)RP@,C W?2P)+RH@SR J+PH)"7LG1"<L("<M)RP@,C X?2P)+RH@T" J+PH)
XM"7LG3B<L("=^)RP@,C Y?2P)+RH@T2 J+PH)"7LG3R<L("=@)RP@,C$P?2P)
XM+RH@TB J+PH)"7LG3R<L("=<)R<L(#(Q,7TL"2\J(-,@*B\*"0E[)T\G+" G
XM7B<L(#(Q,GTL"2\J(-0@*B\*"0E[)T\G+" G?B<L(#(Q,WTL"2\J(-4@*B\*
XM"0E[)T\G+" G(B<L(#(Q-'TL"2\J(-8@*B\*"0E[)R\G+" G7%PG+" R,35]
XM+ DO*B#7("HO"@D)>R=/)RP@)R\G+" R,39]+ DO*B#8("HO"@D)>R=5)RP@
XM)V G+" R,3=]+ DO*B#9("HO"@D)>R=5)RP@)UPG)RP@,C$X?2P)+RH@VB J
XM+PH)"7LG52<L("=>)RP@,C$Y?2P)+RH@VR J+PH)"7LG52<L("<B)RP@,C(P
XM?2P)+RH@W" J+PH)"7LG62<L("=<)R<L(#(R,7TL"2\J(-T@*B\*"0E[)TDG
XM+" G<"<L(#(R,GTL"2\J(-X@*B\*"0E[)W,G+" G<R<L(#(R,WTL"2\J(-\@
XM*B\*"0E[)V$G+" G8"<L(#(R-'TL"2\J(. @*B\*"0E[)V$G+" G7"<G+" R
XM,C5]+ DO*B#A("HO"@D)>R=A)RP@)UXG+" R,C9]+ DO*B#B("HO"@D)>R=A
XM)RP@)WXG+" R,C=]+ DO*B#C("HO"@D)>R=A)RP@)R(G+" R,CA]+ DO*B#D
XM("HO"@D)>R=A)RP@)T G+" R,CE]+ DO*B#E("HO"@D)>R=A)RP@)V4G+" R
XM,S!]+ DO*B#F("HO"@D)>R=C)RP@)RPG+" R,S%]+ DO*B#G("HO"@D)>R=E
XM)RP@)V G+" R,S)]+ DO*B#H("HO"@D)>R=E)RP@)UPG)RP@,C,S?2P)+RH@
XMZ2 J+PH)"7LG92<L("=>)RP@,C,T?2P)+RH@ZB J+PH)"7LG92<L("<B)RP@
XM,C,U?2P)+RH@ZR J+PH)"7LG:2<L("=@)RP@,C,V?2P)+RH@[" J+PH)"7LG
XM:2<L("=<)R<L(#(S-WTL"2\J(.T@*B\*"0E[)VDG+" G7B<L(#(S.'TL"2\J
XM(.X@*B\*"0E[)VDG+" G(B<L(#(S.7TL"2\J(.\@*B\*"0E[)V0G+" G+2<L
XM(#(T,'TL"2\J(/ @*B\*"0E[)VXG+" G?B<L(#(T,7TL"2\J(/$@*B\*"0E[
XM)V\G+" G8"<L(#(T,GTL"2\J(/(@*B\*"0E[)V\G+" G7"<G+" R-#-]+ DO
XM*B#S("HO"@D)>R=O)RP@)UXG+" R-#1]+ DO*B#T("HO"@D)>R=O)RP@)WXG
XM+" R-#5]+ DO*B#U("HO"@D)>R=O)RP@)R(G+" R-#9]+ DO*B#V("HO"@D)
XM>R<Z)RP@)RTG+" R-#=]+ DO*B#W("HO"@D)>R=O)RP@)R\G+" R-#A]+ DO
XM*B#X("HO"@D)>R=U)RP@)V G+" R-#E]+ DO*B#Y("HO"@D)>R=U)RP@)UPG
XM)RP@,C4P?2P)+RH@^B J+PH)"7LG=2<L("=>)RP@,C4Q?2P)+RH@^R J+PH)
XM"7LG=2<L("<B)RP@,C4R?2P)+RH@_" J+PH)"7LG>2<L("=<)R<L(#(U,WTL
XM"2\J(/T@*B\*"0E[)VDG+" G<"<L(#(U-'TL"2\J(/X@*B\*"0E[)WDG+" G
XM(B<L(#(U-7TL"2\J(/\@*B\*"0E[3E5,+"!.54PL($Y53'T*"0E].PHC96YD
XM:68)+RH@35-$3U,@*B\*( HO*@H@*B!H86YD;&4@9&EG<F%P:',@869T97(@
XM='EP:6YG(&$@8VAA<F%C=&5R"B J+PH):6YT"F1O9&EG<F%P:"AC*0H):6YT
XM"0EC.PI["@ES=&%T:6,@:6YT"6)A8VMS<&%C960["0DO*B!C:&%R86-T97(@
XM8F5F;W)E($)3("HO"@ES=&%T:6,@:6YT"6QA<W1C:&%R.PD)+RH@;&%S="!T
XM>7!E9"!C:&%R86-T97(@*B\*"@EI9B H8R ]/2 M,2D)"0D)+RH@:6YI="!V
XM86QU97,@*B\*"7L*"0EB86-K<W!A8V5D(#T@+3$["@E]"@EE;'-E(&EF("AP
XM7V1G*0H)>PH)"6EF("AB86-K<W!A8V5D(#X](# I"@D)"6,@/2!G971D:6=R
XM87!H*&)A8VMS<&%C960L(&,L($9!3%-%*3L*"0EB86-K<W!A8V5D(#T@+3$[
XM"@D):68@*&,@/3T@0E,@)B8@;&%S=&-H87(@/CT@,"D*"0D)8F%C:W-P86-E
XM9" ](&QA<W1C:&%R.PH)?0H);&%S=&-H87(@/2!C.PH)<F5T=7)N(&,["GT*
XM"B\J"B J(&QO;VMU<"!T:&4@<&%I<B!C:&%R,2P@8VAA<C(@:6X@=&AE(&1I
XM9W)A<&@@=&%B;&5S"B J(&EF(&YO(&UA=&-H+"!R971U<FX@8VAA<C(*("HO
XM"@EI;G0*9V5T9&EG<F%P:"AC:&%R,2P@8VAA<C(L(&UE=&$I"@EI;G0)8VAA
XM<C$["@EI;G0)8VAA<C(["@EI;G0);65T83L*>PH):6YT"0EI.PH):6YT"0ER
XM971V86P["@H)<F5T=F%L(#T@,#L*"69O<B H:2 ](# [(#L@*RMI*0D)"2\J
XM('-E87)C:"!A9&1E9"!D:6=R87!H<R!F:7)S=" J+PH)>PH)"6EF("AI(#T]
XM(&1I9W)A<&AC;W5N="D)+RH@96YD(&]F(&%D9&5D('1A8FQE+"!S96%R8V@@
XM9&5F875L=',@*B\*"0E["@D)"69O<B H:2 ](# [(&1I9W)A<&AD969A=6QT
XM6VE=6S!=("$](# [("LK:2D*"0D)"6EF("AD:6=R87!H9&5F875L=%MI75LP
XM72 ]/2!C:&%R,2 F)B!D:6=R87!H9&5F875L=%MI75LQ72 ]/2!C:&%R,BD*
XM"0D)"7L*"0D)"0ER971V86P@/2!D:6=R87!H9&5F875L=%MI75LR73L*"0D)
XM"0EB<F5A:SL*"0D)"7T*"0D)8G)E86L["@D)?0H)"6EF("AD:6=R87!H;F5W
XM6VE=6S!=(#T](&-H87(Q("8F(&1I9W)A<&AN97=;:5U;,5T@/3T@8VAA<C(I
XM"@D)>PH)"0ER971V86P@/2!D:6=R87!H;F5W6VE=6S)=.PH)"0EB<F5A:SL*
XM"0E]"@E]"@H):68@*')E='9A;" ]/2 P*0D)"2\J(&1I9W)A<&@@9&5L971E
XM9"!O<B!N;W0@9F]U;F0@*B\*"7L*"0EI9B H8VAA<C$@/3T@)R G("8F(&UE
XM=&$I"0DO*B \<W!A8V4^(#QC:&%R/B M+3X@;65T82UC:&%R("HO"@D)"7)E
XM='5R;B H8VAA<C(@?" P>#@P*3L*"0ER971U<FX@8VAA<C(["@E]"@ER971U
XM<FX@<F5T=F%L.PI]"@HO*@H@*B!P=70@=&AE(&1I9W)A<&AS(&EN('1H92!A
XM<F=U;65N="!S=')I;F<@:6X@=&AE(&1I9W)A<&@@=&%B;&4*("H@9F]R;6%T
XM.B![8S%]>V,R?2!C:&%R('MC,7U[8S)](&-H87(@+BXN"B J+PH)=F]I9 IP
XM=71D:6=R87!H*'-T<BD*"6-H87)?=2 J<W1R.PI["@EI;G0)"6-H87(Q+"!C
XM:&%R,BP@;CL*"6-H87)?=0DH*FYE=W1A8BE;,UT["@EI;G0)"6D["@H)=VAI
XM;&4@*"IS='(I"@E["@D)<VMI<'-P86-E*"9S='(I.PH)"6EF("@H8VAA<C$@
XM/2 J<W1R*RLI(#T](# @?'P@*&-H87(R(#T@*G-T<BLK*2 ]/2 P*0H)"0ER
XM971U<FX["@D):68@*&-H87(Q(#T]($530R!\?"!C:&%R,B ]/2!%4T,I"@D)
XM>PH)"0E%35-'*")%<V-A<&4@;F]T(&%L;&]W960@:6X@9&EG<F%P:"(I.PH)
XM"0ER971U<FX["@D)?0H)"7-K:7!S<&%C92@F<W1R*3L*"0EI9B H(6ES9&EG
XM:70H*G-T<BDI"@D)>PH)"0EE;7-G*&5?;G5M8F5R*3L*"0D)<F5T=7)N.PH)
XM"7T*"0EN(#T@9V5T9&EG:71S*"9S='(I.PH)"6EF("AD:6=R87!H;F5W*0D)
XM+RH@<V5A<F-H('1H92!T86)L92!F;W(@97AI<W1I;F<@96YT<GD@*B\*"0E[
XM"@D)"69O<B H:2 ](# [(&D@/"!D:6=R87!H8V]U;G0[("LK:2D*"0D)"6EF
XM("AD:6=R87!H;F5W6VE=6S!=(#T](&-H87(Q("8F(&1I9W)A<&AN97=;:5U;
XM,5T@/3T@8VAA<C(I"@D)"0E["@D)"0D)9&EG<F%P:&YE=UMI75LR72 ](&X[
XM"@D)"0D)8G)E86L["@D)"0E]"@D)"6EF("AI(#P@9&EG<F%P:&-O=6YT*0H)
XM"0D)8V]N=&EN=64["@D)?0H)"6YE=W1A8B ]("AC:&%R7W4@*"HI6S-=*6%L
XM;&]C*&1I9W)A<&AC;W5N=" J(#,@*R S*3L*"0EI9B H;F5W=&%B*0H)"7L*
XM"0D);65M;6]V92@H8VAA<B J*6YE=W1A8BP@*&-H87(@*BED:6=R87!H;F5W
XM+" H<VEZ95]T*2AD:6=R87!H8V]U;G0@*B S*2D["@D)"69R964H9&EG<F%P
XM:&YE=RD["@D)"61I9W)A<&AN97<@/2!N97=T86(["@D)"61I9W)A<&AN97=;
XM9&EG<F%P:&-O=6YT75LP72 ](&-H87(Q.PH)"0ED:6=R87!H;F5W6V1I9W)A
XM<&AC;W5N=%U;,5T@/2!C:&%R,CL*"0D)9&EG<F%P:&YE=UMD:6=R87!H8V]U
XM;G1=6S)=(#T@;CL*"0D)*RMD:6=R87!H8V]U;G0["@D)?0H)?0I]"@H)=F]I
XM9 IL:7-T9&EG<F%P:',H*0I["@EI;G0)"6D["@H)<')I;G1D:6=R87!H*$Y5
XM3$PI.PH);7-G7W-T87)T*"D["@EM<V=?;W5T8VAA<B@G7&XG*3L*"69O<B H
XM:2 ](# [(&1I9W)A<&AD969A=6QT6VE=6S!=("8F("%G;W1?:6YT.R K*VDI
XM"@E["@D):68@*&=E=&1I9W)A<&@H9&EG<F%P:&1E9F%U;'1;:5U;,%TL(&1I
XM9W)A<&AD969A=6QT6VE=6S%=+"!&04Q312D@/3T@9&EG<F%P:&1E9F%U;'1;
XM:5U;,ETI"@D)"7!R:6YT9&EG<F%P:"AD:6=R87!H9&5F875L=%MI72D["@D)
XM8G)E86MC:&5C:R...@I.PH)?0H)9F]R("AI(#T@,#L@:2 \(&1I9W)A<&AC;W5N
XM=" F)B A9V]T7VEN=#L@*RMI*0H)>PH)"7!R:6YT9&EG<F%P:"AD:6=R87!H
XM;F5W6VE=*3L*"0EB<F5A:V-H96-K*"D["@E]"@EM<V=?;W5T8VAA<B@G7&XG
XM*3L*"7=A:71?<F5T=7)N*%12544I.PD)+RH@8VQE87(@<V-R965N+"!B96-A
XM=7-E('-O;64@9&EG<F%P:',@;6%Y(&)E('=R;VYG+ H)"0D)"0D)("H@:6X@
XM=VAI8V@@8V%S92!W92!M97-S960@=7 @3F5X=%-C<F5E;B J+PI]"@H)<W1A
XM=&EC('9O:60*<')I;G1D:6=R87!H*' I"@EC:&%R7W4@*G ["GL*"6-H87)?
XM=0D)8G5F6SE=.PH)<W1A=&EC(&EN= EL96X["@H):68@*' @/3T@3E5,3"D*
XM"0EL96X@/2 P.PH)96QS92!I9B H<%LR72 A/2 P*0H)>PH)"6EF("AL96X@
XM/B!#;VQU;6YS("T@,3$I"@D)>PH)"0EM<V=?;W5T8VAA<B@G7&XG*3L*"0D)
XM;&5N(#T@,#L*"0E]"@D):68@*&QE;BD*"0D);7-G7V]U='-T<B@H8VAA<E]U
XM("HI(B @("(I.PH)"7-P<FEN=&8H*&-H87(@*BEB=68L("(E8R5C("5C("4S
XM9"(L('!;,%TL('!;,5TL('!;,ETL('!;,ETI.PH)"6US9U]O=71S='(H8G5F
XL*3L*"0EL96X@*ST@,3$["@E]"GT*"B-E;F1I9B O*B!$24=205!(4R J+PIF
X
Xend
END_OF_FILE
if test 11504 -ne `wc -c <'vim/src/digraph.c.UU'`; then
echo shar: \"'vim/src/digraph.c.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/src/digraph.c'\" \(8324 characters\)
cat vim/src/digraph.c.UU | uudecode
if test 8324 -ne `wc -c <'vim/src/digraph.c'`; then
echo shar: \"'vim/src/digraph.c'\" uudecoded with wrong size!
else
rm vim/src/digraph.c.UU
fi
fi
# end of 'vim/src/digraph.c.UU'
fi
if test -f 'vim/src/makefile.nt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.nt'\"
else
echo shar: Extracting \"'vim/src/makefile.nt'\" \(5138 characters\)
sed "s/^X//" >'vim/src/makefile.nt' <<'END_OF_FILE'
X!include <ntwin32.mak>
X#
X# Makefile for VIM on WINNT, using MS SDK
X#
X
X#>>>>> choose options:
X### -DDIGRAPHS digraph support (at the cost of 1.6 Kbyte code)


X### -DCOMPATIBLE start in vi-compatible mode
X### -DNOBACKUP default is no backup file
X### -DDEBUG output a lot of debugging garbage

X### -DTERMCAP include termcap file support


X### -DNO_BUILTIN_TCAPS do not include builtin termcap entries
X### (use only with -DTERMCAP)
X### -DSOME_BUILTIN_TCAPS include most useful builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DALL_BUILTIN_TCAPS include all builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)

X### -DVIMRC_FILE name of the .vimrc file in current dir
X### -DEXRC_FILE name of the .exrc file in current dir
X### -DSYSVIMRC_FILE name of the global .vimrc file
X### -DSYSEXRC_FILE name of the global .exrc file
X### -DDEFVIMRC_FILE name of the system-wide .vimrc file
X### -DVIM_HLP name of the help file


X### -DWEBB_COMPLETE include Webb's code for command line completion
X### -DWEBB_KEYWORD_COMPL include Webb's code for keyword completion
X### -DNOTITLE 'title' option off by default

XDEFINES = -DDIGRAPHS -DWEBB_COMPLETE -DWEBB_KEYWORD_COMPL
X
X#>>>>> name of the compiler and linker, name of lib directory
XCC = cl
XLINK = cl /ML /Fe$@ /Zi
XLIB = c:\mstools\lib
X
X#CFLAGS = -c -DMSDOS -DNT $(DEFINES) /Zi
XCFLAGS = -c -DMSDOS -DNT $(DEFINES) /Ox
X
X
X#>>>>> end of choices
X###########################################################################
X
XINCL = vim.h globals.h param.h keymap.h macros.h ascii.h term.h msdos.h structs.h
X
XOBJ = obj/alloc.obj obj/winnt.obj obj/buffer.obj obj/charset.obj obj/cmdcmds.obj obj/cmdline.obj \
X obj/csearch.obj obj/digraph.obj obj/edit.obj obj/fileio.obj obj/getchar.obj obj/help.obj \
X obj/linefunc.obj obj/main.obj obj/mark.obj obj/memfile.obj obj/memline.obj obj/message.obj obj/misccmds.obj \
X obj/normal.obj obj/ops.obj obj/param.obj obj/quickfix.obj obj/regexp.obj \
X obj/regsub.obj obj/screen.obj obj/search.obj \
X obj/tag.obj obj/term.obj obj/undo.obj obj/window.obj $(TERMLIB)
X
X..\vim: $(OBJ) version.obj
X $(link) $(linkdebug) $(conflags) -out:$*.exe $** $(conlibs) \
X user32.lib
X del version.obj
X
Xctags:
X command /c ctags *.c *.h
X
Xclean:
X del $(OBJ) version.obj mkcmdtab.obj ..\vim mkcmdtab cmdtab.h
X
Xaddcr: addcr.c
X $(CC) addcr.c
X command /c addcr.bat
X
X###########################################################################
X
Xobj/alloc.obj: alloc.c $(INCL)
X $(CC) $(CFLAGS) alloc.c /Foobj/alloc.obj
X
Xobj/winnt.obj: msdos.c $(INCL) msdos.h
X $(CC) $(CFLAGS) winnt.c /Foobj/winnt.obj
X
Xobj/buffer.obj: buffer.c $(INCL)
X $(CC) $(CFLAGS) buffer.c /Foobj/buffer.obj
X
Xobj/charset.obj: charset.c $(INCL)
X $(CC) $(CFLAGS) charset.c /Foobj/charset.obj
X
Xobj/cmdcmds.obj: cmdcmds.c $(INCL)
X $(CC) $(CFLAGS) cmdcmds.c /Foobj/cmdcmds.obj
X
Xobj/cmdline.obj: cmdline.c $(INCL) cmdtab.h
X $(CC) $(CFLAGS) cmdline.c /Foobj/cmdline.obj
X
Xobj/csearch.obj: csearch.c $(INCL)
X $(CC) $(CFLAGS) csearch.c /Foobj/csearch.obj
X
Xobj/digraph.obj: digraph.c $(INCL)
X $(CC) $(CFLAGS) digraph.c /Foobj/digraph.obj
X
Xobj/edit.obj: edit.c $(INCL)
X $(CC) $(CFLAGS) edit.c /Foobj/edit.obj
X
Xobj/fileio.obj: fileio.c $(INCL)
X $(CC) $(CFLAGS) fileio.c /Foobj/fileio.obj
X
Xobj/getchar.obj: getchar.c $(INCL)
X $(CC) $(CFLAGS) getchar.c /Foobj/getchar.obj
X
Xobj/help.obj: help.c $(INCL)
X $(CC) $(CFLAGS) help.c /Foobj/help.obj
X
Xobj/linefunc.obj: linefunc.c $(INCL)
X $(CC) $(CFLAGS) linefunc.c /Foobj/linefunc.obj
X
Xobj/main.obj: main.c $(INCL)
X $(CC) $(CFLAGS) main.c /Foobj/main.obj
X
Xobj/mark.obj: mark.c $(INCL)
X $(CC) $(CFLAGS) mark.c /Foobj/mark.obj
X
Xobj/memfile.obj: memfile.c $(INCL)
X $(CC) $(CFLAGS) memfile.c /Foobj/memfile.obj
X
Xobj/memline.obj: memline.c $(INCL)
X $(CC) $(CFLAGS) memline.c /Foobj/memline.obj
X
Xobj/message.obj: message.c $(INCL)
X $(CC) $(CFLAGS) message.c /Foobj/message.obj
X
Xobj/misccmds.obj: misccmds.c $(INCL)
X $(CC) $(CFLAGS) misccmds.c /Foobj/misccmds.obj
X
Xobj/normal.obj: normal.c $(INCL) ops.h
X $(CC) $(CFLAGS) normal.c /Foobj/normal.obj
X
Xobj/ops.obj: ops.c $(INCL) ops.h
X $(CC) $(CFLAGS) ops.c /Foobj/ops.obj
X
Xobj/param.obj: param.c $(INCL)
X $(CC) $(CFLAGS) param.c /Foobj/param.obj
X
Xobj/quickfix.obj: quickfix.c $(INCL)
X $(CC) $(CFLAGS) quickfix.c /Foobj/quickfix.obj
X
Xobj/regexp.obj: regexp.c $(INCL)
X $(CC) $(CFLAGS) regexp.c /Foobj/regexp.obj
X
Xobj/regsub.obj: regsub.c $(INCL)
X $(CC) $(CFLAGS) regsub.c /Foobj/regsub.obj
X
Xobj/screen.obj: screen.c $(INCL)
X $(CC) $(CFLAGS) screen.c /Foobj/screen.obj
X
Xobj/search.obj: search.c $(INCL)
X $(CC) $(CFLAGS) search.c /Foobj/search.obj
X
Xobj/tag.obj: tag.c $(INCL)
X $(CC) $(CFLAGS) tag.c /Foobj/tag.obj
X
Xobj/term.obj: term.c $(INCL)
X $(CC) $(CFLAGS) term.c /Foobj/term.obj
X
Xobj/undo.obj: undo.c $(INCL)
X $(CC) $(CFLAGS) undo.c /Foobj/undo.obj
X
Xobj/window.obj: window.c $(INCL)
X $(CC) $(CFLAGS) window.c /Foobj/window.obj
X
Xcmdtab.h: cmdtab.tab mkcmdtab.exe
X mkcmdtab cmdtab.tab cmdtab.h
X
Xmkcmdtab.exe: obj/mkcmdtab.obj
X $(link) $(linkdebug) $(conflags) -out:$*.exe $** $(conlibs) \
X user32.lib
X
Xobj/mkcmdtab.obj: mkcmdtab.c
X $(CC) $(CFLAGS) mkcmdtab.c /Foobj/mkcmdtab.obj
END_OF_FILE
if test 5138 -ne `wc -c <'vim/src/makefile.nt'`; then
echo shar: \"'vim/src/makefile.nt'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.nt'
fi
if test -f 'vim/src/tag.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/tag.c'\"
else
echo shar: Extracting \"'vim/src/tag.c'\" \(11552 characters\)
sed "s/^X//" >'vim/src/tag.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Code to handle tags and the tag stack


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic int findtag __ARGS((char_u *));
Xstatic char_u *bottommsg = (char_u *)"at bottom of tag stack";
Xstatic char_u *topmsg = (char_u *)"at top of tag stack";
X
X/*
X * Jump to tag; handling of tag stack
X *
X * *tag != NUL (:tag): jump to new tag, add to tag stack
X * type == 1 (:pop) || type == 2 (CTRL-T): jump to old position
X * type == 0 (:tag): jump to old tag
X */
X void
Xdotag(tag, type, count)
X char_u *tag;
X int type;
X int count;
X{
X int i;
X struct taggy *tagstack = curwin->w_tagstack;
X int tagstackidx = curwin->w_tagstackidx;
X int tagstacklen = curwin->w_tagstacklen;
X
X if (*tag != NUL) /* new pattern, add to the stack */
X {
X /*
X * if last used entry is not at the top, delete all tag stack entries
X * above it.
X */
X while (tagstackidx < tagstacklen)
X free(tagstack[--tagstacklen].tagname);
X
X /* if tagstack is full: remove oldest entry */
X if (++tagstacklen > TAGSTACKSIZE)
X {
X tagstacklen = TAGSTACKSIZE;
X free(tagstack[0].tagname);
X for (i = 1; i < tagstacklen; ++i)
X tagstack[i - 1] = tagstack[i];
X --tagstackidx;
X }
X /*
X * put the tag name in the tag stack
X * the position is added below
X */
X tagstack[tagstackidx].tagname = strsave(tag);
X }
X else if (tagstacklen == 0) /* empty stack */
X {
X EMSG("tag stack empty");
X goto end_dotag;
X }
X else if (type) /* go to older position */
X {
X if ((tagstackidx -= count) < 0)
X {
X emsg(bottommsg);
X if (tagstackidx + count == 0)
X {
X /* We did ^T (or <num>^T) from the bottom of the stack */
X tagstackidx = 0;
X goto end_dotag;
X }
X /* We weren't at the bottom of the stack, so jump all the way to
X * the bottom.
X */
X tagstackidx = 0;
X }
X else if (tagstackidx >= tagstacklen) /* must have been count == 0 */
X {
X emsg(topmsg);
X goto end_dotag;
X }
X if (tagstack[tagstackidx].fmark.fnum != curbuf->b_fnum) /* jump to other file */
X {
X if (buflist_getfile(tagstack[tagstackidx].fmark.fnum, tagstack[tagstackidx].fmark.mark.lnum, TRUE) == FAIL)
X {
X /* emsg(e_notopen); */
X goto end_dotag;
X }
X }
X else
X curwin->w_cursor.lnum = tagstack[tagstackidx].fmark.mark.lnum;
X curwin->w_cursor.col = tagstack[tagstackidx].fmark.mark.col;


X curwin->w_set_curswant = TRUE;

X goto end_dotag;
X }
X else /* go to newer pattern */
X {
X if ((tagstackidx += count - 1) >= tagstacklen)
X {
X tagstackidx = tagstacklen - 1;
X emsg(topmsg);
X }
X else if (tagstackidx < 0) /* must have been count == 0 */
X {
X emsg(bottommsg);
X tagstackidx = 0;
X goto end_dotag;
X }
X }
X /*
X * For :tag [arg], remember position before the jump
X */
X if (type == 0)
X {
X tagstack[tagstackidx].fmark.mark = curwin->w_cursor;
X tagstack[tagstackidx].fmark.fnum = curbuf->b_fnum;
X }
X if (findtag(tagstack[tagstackidx].tagname) > 0)
X ++tagstackidx;
X
Xend_dotag:
X curwin->w_tagstackidx = tagstackidx;
X curwin->w_tagstacklen = tagstacklen;
X}
X
X/*
X * Print the tag stack
X */
X void
Xdotags()
X{
X int i;
X char_u *name;
X struct taggy *tagstack = curwin->w_tagstack;
X int tagstackidx = curwin->w_tagstackidx;
X int tagstacklen = curwin->w_tagstacklen;
X
X gotocmdline(TRUE, NUL);
X msg_outstr((char_u *)"\n # TO tag FROM line in file\n");
X for (i = 0; i < tagstacklen; ++i)
X {
X if (tagstack[i].tagname != NULL)
X {
X name = fm_getname(&(tagstack[i].fmark));
X if (name == NULL) /* file name not available */
X continue;
X
X sprintf((char *)IObuff, "%c%2d %-15s %4ld %s\n",
X i == tagstackidx ? '>' : ' ',
X i + 1,
X tagstack[i].tagname,
X tagstack[i].fmark.mark.lnum,
X name);
X msg_outstr(IObuff);
X }


X flushbuf(); /* show one line at a time */
X }

X if (tagstackidx == tagstacklen) /* idx at top of stack */


X msg_outstr((char_u *)">\n");

X wait_return(FALSE);
X}
X
X/*
X * findtag(tag) - goto tag
X * return 0 for failure, 1 for success


X */
X static int

Xfindtag(tag)
X char_u *tag;
X{
X FILE *tp;
X char_u lbuf[LSIZE];
X char_u pbuf[LSIZE]; /* search pattern buffer */
X char_u *fname, *str;
X int cmplen;
X char_u *m = (char_u *)"No tags file";
X char_u *marg = NULL;
X register char_u *p;
X char_u *p2;
X char_u *np; /* pointer into file name string */
X char_u sbuf[CMDBUFFSIZE + 1]; /* tag file name */
X int i;
X int save_secure;
X int save_p_ws;
X
X if (tag == NULL) /* out of memory condition */
X return 0;
X
X if ((cmplen = p_tl) == 0)
X cmplen = 999;
X
X /* get stack of tag file names from tags option */
X for (np = p_tags; *np; )
X {
X for (i = 0; i < CMDBUFFSIZE && *np; ++i) /* copy next file name into lbuf */
X {
X if (*np == ' ')
X {
X ++np;
X break;
X }
X sbuf[i] = *np++;
X }
X sbuf[i] = 0;
X if ((tp = fopen((char *)sbuf, "r")) == NULL)
X continue;
X reg_ic = p_ic; /* for cstrncmp() */
X while (fgets((char *)lbuf, LSIZE, tp) != NULL)
X {
X m = (char_u *)"Format error in tags file %s"; /* default error message */
X marg = sbuf;
X
X /* find start of file name, after first white space */
X fname = lbuf;
X skiptospace(&fname); /* skip tag */


X if (*fname == NUL)

X goto erret;
X *fname++ = '\0';
X
X if (cstrncmp(lbuf, tag, cmplen) == 0) /* Tag found */
X {
X fclose(tp);
X skipspace(&fname);
X
X /* find start of search command, after second white space */
X str = fname;
X skiptospace(&str);
X if (*str == NUL)
X goto erret;
X *str++ = '\0';
X skipspace(&str);
X
X /*
X * If the command is a string like "/^function fname"
X * scan through the search string. If we see a magic
X * char, we have to quote it. This lets us use "real"
X * implementations of ctags.
X */
X if (*str == '/' || *str == '?')
X {
X p = pbuf;
X *p++ = *str++; /* copy the '/' or '?' */
X if (*str == '^')
X *p++ = *str++; /* copy the '^' */


X
X while (*str)
X {

X switch (*str)
X {
X case '\\': if (str[1] == '(') /* remove '\' before '(' */
X ++str;
X else
X *p++ = *str++;


X break;
X
X case '\r':

X case '\n': *str = pbuf[0]; /* copy '/' or '?' */
X str[1] = NUL; /* delete NL after CR */


X break;
X
X /*

X * if string ends in search character: skip it
X * else escape it with '\'
X */
X case '/':
X case '?': if (*str != pbuf[0]) /* not the search char */
X break;
X /* last char */
X if (str[1] == '\n' || str[1] == '\r')
X {


X ++str;
X continue;
X }

X case '[':
X if (!p_magic)


X break;
X case '^':

X case '*':
X case '.': *p++ = '\\';
X break;
X }
X *p++ = *str++;
X }
X }
X else /* not a search command, just copy it */
X for (p = pbuf; *str && *str != '\n'; )
X *p++ = *str++;
X *p = NUL;
X
X /*
X * expand filename (for environment variables)
X */
X if ((p = ExpandOne((char_u *)fname, 1, -1)) != NULL)
X fname = p;
X /*
X * if 'tagrelative' option set, may change file name
X */
X if (p_tr && !isFullName(fname) && (p2 = gettail(sbuf)) != sbuf)
X {
X STRNCPY(p2, fname, CMDBUFFSIZE - (p2 - sbuf));
X fname = sbuf;
X }
X /*
X * check if file for tag exists before abandoning current file
X */
X if (getperm(fname) < 0)
X {
X m = (char_u *)"File \"%s\" does not exist";
X marg = fname;
X goto erret;


X }
X
X RedrawingDisabled = TRUE;

X /*
X * if it was a CTRL-W CTRL-] command split window now
X */
X if (postponed_split)
X win_split(0L, FALSE);
X i = getfile(fname, NULL, TRUE, (linenr_t)0);
X if (p)
X free(p);


X if (i <= 0)
X {

X curwin->w_set_curswant = TRUE;

X postponed_split = FALSE;


X
X RedrawingDisabled = FALSE;

X save_secure = secure;
X secure = 1;
X tag_busy = TRUE; /* don't set marks for this search */
X keep_old_search_pattern = TRUE;
X
X /*
X * if the command is a search, try here
X *
X * Rather than starting at line one, just turn wrap-scan
X * on temporarily, this ensures that tags on line 1 will
X * be found, and makes sure our guess searches search the
X * whole file when repeated -- webb.
X */
X if (pbuf[0] == '/' || pbuf[0] == '?')
X {
X save_p_ws = p_ws;
X p_ws = TRUE; /* Switch wrap-scan on temporarily */
X if (!dosearch(pbuf[0], pbuf + 1, FALSE, (long)1, FALSE, FALSE))
X {
X register int notfound = FALSE;
X
X /*
X * Failed to find pattern, take a guess:
X */
X sprintf((char *)pbuf, "^%s(", lbuf);
X if (!dosearch('/', pbuf, FALSE, (long)1, FALSE, FALSE))
X {
X /* Guess again: */
X sprintf((char *)pbuf, "^[#a-zA-Z_].*%s(", lbuf);
X if (!dosearch('/', pbuf, FALSE, (long)1, FALSE, FALSE))
X notfound = TRUE;
X }
X if (notfound)
X EMSG("Can't find tag pattern");
X else
X {
X MSG("Couldn't find tag, just guessing!");
X sleep(1);
X }
X }
X p_ws = save_p_ws;
X }
X else
X {
X curwin->w_cursor.lnum = 1; /* start command in line 1 */
X docmdline(pbuf);
X }
X
X tag_busy = FALSE;
X keep_old_search_pattern = FALSE;
X if (secure == 2) /* done something that is not allowed */
X wait_return(TRUE);
X secure = save_secure;
X
X /* print the file message after redraw */
X if (p_im && i == -1)
X stuffReadbuff((char_u *)"\033\007i"); /* ESC CTRL-G i */
X else
X stuffcharReadbuff('\007'); /* CTRL-G */
X return 1;


X }
X RedrawingDisabled = FALSE;

X if (postponed_split) /* close the window */
X {
X close_window(FALSE);
X postponed_split = FALSE;
X }


X return 0;
X }
X }

X m = NULL;
X
Xerret:
X fclose(tp);
X if (m)
X emsg2(m, marg);
X }
X if (m == NULL)
X EMSG("tag not found");
X else if (marg == NULL)
X emsg(m);


X return 0;
X}
X

X#ifdef WEBB_COMPLETE
X int
XExpandTags(prog, num_file, file)
X regexp *prog;


X int *num_file;
X char_u ***file;

X{
X char_u **matches, **new_matches;
X char_u tag_file[CMDBUFFSIZE + 1];
X char_u line[LSIZE];
X char_u *np;
X char_u *p;
X int limit = 100;
X int index;
X int i;
X int lnum;
X FILE *fp;
X
X matches = (char_u **) alloc((unsigned)(limit * sizeof(char_u *)));
X if (matches == NULL)
X return FAIL;
X index = 0;
X for (np = p_tags; *np; )
X {
X for (i = 0; i < CMDBUFFSIZE && *np && *np != ' '; i++)
X tag_file[i] = *np++;
X tag_file[i] = NUL;
X skipspace(&np);
X if ((fp = fopen((char *)tag_file, "r")) == NULL)
X continue;
X lnum = 0;
X while (!vim_fgets(line, LSIZE, fp, &lnum))
X {
X if (regexec(prog, line, TRUE))
X {
X p = line;
X skiptospace(&p);
X *p = NUL;
X if (index == limit)
X {
X limit *= 2;
X new_matches = (char_u **) alloc((unsigned)(limit * sizeof(char_u *)));
X if (new_matches == NULL)
X {
X /* We'll miss some matches, oh well */
X *file = matches;
X *num_file = index;
X return OK;
X }
X for (i = 0; i < index; i++)
X new_matches[i] = matches[i];
X free(matches);
X matches = new_matches;
X }
X matches[index++] = strsave(line);
X }
X }
X }
X if (index > 0)
X {
X new_matches = *file = (char_u **) alloc((unsigned)(index * sizeof(char_u *)));
X if (new_matches == NULL)
X {
X *file = matches;
X *num_file = index;
X return OK;
X }
X for (i = 0; i < index; i++)
X new_matches[i] = matches[i];
X }
X free(matches);
X *num_file = index;
X return OK;


X}
X#endif /* WEBB_COMPLETE */
END_OF_FILE

if test 11552 -ne `wc -c <'vim/src/tag.c'`; then
echo shar: \"'vim/src/tag.c'\" unpacked with wrong size!
fi
# end of 'vim/src/tag.c'
fi
echo shar: End of archive 22 \(of 26\).
cp /dev/null ark22isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:03:45 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 42
Archive-name: vim/part23

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/src/makefile.dos vim/src/makefile.manx
# vim/src/makefile.sas vim/src/mark.c vim/src/message.c
# vim/src/proto/cmdline.pro vim/src/quickfix.c vim/src/vim.h
# Wrapped by kent@sparky on Mon Aug 15 21:44:14 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 23 (of 26)."'
if test -f 'vim/src/makefile.dos' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.dos'\"
else
echo shar: Extracting \"'vim/src/makefile.dos'\" \(5010 characters\)
sed "s/^X//" >'vim/src/makefile.dos' <<'END_OF_FILE'
X#
X# Makefile for VIM on MSDOS, using Turbo C

XCC = tcc
XLINK = tlink
XLIB = c:\turboc\lib


X
X#>>>>> end of choices
X###########################################################################
X
XINCL = vim.h globals.h param.h keymap.h macros.h ascii.h term.h msdos.h structs.h

XCFLAGS = -c -ml -DMSDOS $(DEFINES)
X
XOBJ = obj/alloc.obj obj/msdos.obj obj/buffer.obj obj/charset.obj obj/cmdcmds.obj obj/cmdline.obj \


X obj/csearch.obj obj/digraph.obj obj/edit.obj obj/fileio.obj obj/getchar.obj obj/help.obj \
X obj/linefunc.obj obj/main.obj obj/mark.obj obj/memfile.obj obj/memline.obj obj/message.obj obj/misccmds.obj \
X obj/normal.obj obj/ops.obj obj/param.obj obj/quickfix.obj obj/regexp.obj \
X obj/regsub.obj obj/screen.obj obj/search.obj \
X obj/tag.obj obj/term.obj obj/undo.obj obj/window.obj $(TERMLIB)
X

X..\vim: $(OBJ) version.c
X $(CC) $(CFLAGS) version.c
X $(LINK) /c /m $(LIB)\C0l @vimresp,..\vim,..\vim,$(LIB)\emu $(LIB)\Cl


X
Xctags:
X command /c ctags *.c *.h
X
Xclean:
X del $(OBJ) version.obj mkcmdtab.obj ..\vim mkcmdtab cmdtab.h
X
Xaddcr: addcr.c
X $(CC) addcr.c
X command /c addcr.bat
X
X###########################################################################
X
Xobj/alloc.obj: alloc.c $(INCL)

X $(CC) $(CFLAGS) alloc.c -o obj/alloc.obj
X
Xobj/msdos.obj: msdos.c $(INCL) msdos.h
X $(CC) $(CFLAGS) msdos.c -o obj/msdos.obj
X
Xobj/buffer.obj: buffer.c $(INCL)
X $(CC) $(CFLAGS) buffer.c -o obj/buffer.obj
X
Xobj/charset.obj: charset.c $(INCL)
X $(CC) $(CFLAGS) charset.c -o obj/charset.obj
X
Xobj/cmdcmds.obj: cmdcmds.c $(INCL)
X $(CC) $(CFLAGS) cmdcmds.c -o obj/cmdcmds.obj


X
Xobj/cmdline.obj: cmdline.c $(INCL) cmdtab.h

X $(CC) $(CFLAGS) cmdline.c -o obj/cmdline.obj
X
Xobj/csearch.obj: csearch.c $(INCL)
X $(CC) $(CFLAGS) csearch.c -o obj/csearch.obj
X
Xobj/digraph.obj: digraph.c $(INCL)
X $(CC) $(CFLAGS) digraph.c -o obj/digraph.obj
X
Xobj/edit.obj: edit.c $(INCL)
X $(CC) $(CFLAGS) edit.c -o obj/edit.obj
X
Xobj/fileio.obj: fileio.c $(INCL)
X $(CC) $(CFLAGS) fileio.c -o obj/fileio.obj
X
Xobj/getchar.obj: getchar.c $(INCL)
X $(CC) $(CFLAGS) getchar.c -o obj/getchar.obj
X
Xobj/help.obj: help.c $(INCL)
X $(CC) $(CFLAGS) help.c -o obj/help.obj
X
Xobj/linefunc.obj: linefunc.c $(INCL)
X $(CC) $(CFLAGS) linefunc.c -o obj/linefunc.obj
X
Xobj/main.obj: main.c $(INCL)
X $(CC) $(CFLAGS) main.c -o obj/main.obj
X
Xobj/mark.obj: mark.c $(INCL)
X $(CC) $(CFLAGS) mark.c -o obj/mark.obj
X
Xobj/memfile.obj: memfile.c $(INCL)
X $(CC) $(CFLAGS) memfile.c -o obj/memfile.obj
X
Xobj/memline.obj: memline.c $(INCL)
X $(CC) $(CFLAGS) memline.c -o obj/memline.obj
X
Xobj/message.obj: message.c $(INCL)
X $(CC) $(CFLAGS) message.c -o obj/message.obj
X
Xobj/misccmds.obj: misccmds.c $(INCL)
X $(CC) $(CFLAGS) misccmds.c -o obj/misccmds.obj


X
Xobj/normal.obj: normal.c $(INCL) ops.h

X $(CC) $(CFLAGS) normal.c -o obj/normal.obj


X
Xobj/ops.obj: ops.c $(INCL) ops.h

X $(CC) $(CFLAGS) ops.c -o obj/ops.obj
X
Xobj/param.obj: param.c $(INCL)
X $(CC) $(CFLAGS) param.c -o obj/param.obj
X
Xobj/quickfix.obj: quickfix.c $(INCL)
X $(CC) $(CFLAGS) quickfix.c -o obj/quickfix.obj
X
Xobj/regexp.obj: regexp.c $(INCL)
X $(CC) $(CFLAGS) regexp.c -o obj/regexp.obj
X
Xobj/regsub.obj: regsub.c $(INCL)
X $(CC) $(CFLAGS) regsub.c -o obj/regsub.obj
X
Xobj/screen.obj: screen.c $(INCL)
X $(CC) $(CFLAGS) screen.c -o obj/screen.obj
X
Xobj/search.obj: search.c $(INCL)
X $(CC) $(CFLAGS) search.c -o obj/search.obj
X
Xobj/tag.obj: tag.c $(INCL)
X $(CC) $(CFLAGS) tag.c -o obj/tag.obj
X
Xobj/term.obj: term.c $(INCL)
X $(CC) $(CFLAGS) term.c -o obj/term.obj
X
Xobj/undo.obj: undo.c $(INCL)
X $(CC) $(CFLAGS) undo.c -o obj/undo.obj
X
Xobj/window.obj: window.c $(INCL)
X $(CC) $(CFLAGS) window.c -o obj/window.obj


X
Xcmdtab.h: cmdtab.tab mkcmdtab.exe
X mkcmdtab cmdtab.tab cmdtab.h
X
Xmkcmdtab.exe: obj/mkcmdtab.obj

X $(CC) -ml -o mkcmdtab obj/mkcmdtab.obj
X
Xobj/mkcmdtab.obj: mkcmdtab.c
X $(CC) $(CFLAGS) mkcmdtab.c -o obj/mkcmdtab.obj
END_OF_FILE
if test 5010 -ne `wc -c <'vim/src/makefile.dos'`; then
echo shar: \"'vim/src/makefile.dos'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.dos'
fi
if test -f 'vim/src/makefile.manx' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.manx'\"
else
echo shar: Extracting \"'vim/src/makefile.manx'\" \(10141 characters\)
sed "s/^X//" >'vim/src/makefile.manx' <<'END_OF_FILE'
X#
X# Makefile for VIM on the Amiga, using Aztec/Manx C 5.0 or later
X#
X# Note: not all dependencies are included. This was done to avoid having
X# to compile everything when a global variable or function is added


X#
X
X#>>>>> choose options:
X### -DDIGRAPHS digraph support (at the cost of 1.6 Kbyte code)

X### -DNO_ARP do not use arp.library, DOS 2.0 required


X### -DCOMPATIBLE start in vi-compatible mode
X### -DNOBACKUP default is no backup file
X### -DDEBUG output a lot of debugging garbage
X### -DTERMCAP include termcap file support
X### -DNO_BUILTIN_TCAPS do not include builtin termcap entries
X### (use only with -DTERMCAP)
X### -DSOME_BUILTIN_TCAPS include most useful builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DALL_BUILTIN_TCAPS include all builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)

X### -Dconst for compilers that don't have type const


X### -DVIMRC_FILE name of the .vimrc file in current dir
X### -DEXRC_FILE name of the .exrc file in current dir
X### -DSYSVIMRC_FILE name of the global .vimrc file
X### -DSYSEXRC_FILE name of the global .exrc file
X### -DDEFVIMRC_FILE name of the system-wide .vimrc file
X### -DVIM_HLP name of the help file

X### -DNOTITLE 'title' option off by default
X### -DWEBB_COMPLETE include Webb's code for command line completion
X### -DWEBB_KEYWORD_COMPL include Webb's code for keyword completion
X

XDEFINES = -DDIGRAPHS -DSOME_BUILTIN_TCAPS -DVIM_ISSPACE \
X -DWEBB_COMPLETE -DWEBB_KEYWORD_COMPL
X
X#>>>>> if TERMCAP is defined obj/termlib.o has to be used
X#TERMLIB = obj/termlib.o
XTERMLIB =
X
X#>>>>> choose between debugging (-bs) or optimizing (-so)
XOPTIONS = -so
X#OPTIONS = -bs


X
X#>>>>> end of choices
X###########################################################################
X

XCFLAGS = $(OPTIONS) -wapruq -ps -qf $(DEFINES) -DAMIGA
X
XLIBS = -lc16
XSYMS = vim.syms
X
XOBJ = obj/alloc.o obj/amiga.o obj/buffer.o obj/charset.o obj/cmdcmds.o obj/cmdline.o \
X obj/csearch.o obj/digraph.o obj/edit.o obj/fileio.o obj/getchar.o obj/help.o \
X obj/linefunc.o obj/main.o obj/mark.o obj/memfile.o obj/memline.o obj/message.o obj/misccmds.o \
X obj/normal.o obj/ops.o obj/param.o obj/quickfix.o obj/regexp.o \
X obj/regsub.o obj/screen.o obj/search.o \
X obj/tag.o obj/term.o obj/undo.o obj/window.o $(TERMLIB)
X
XPRO = proto/alloc.pro proto/buffer.pro proto/charset.pro proto/cmdcmds.pro proto/cmdline.pro \
X proto/csearch.pro proto/digraph.pro proto/edit.pro proto/fileio.pro \
X proto/getchar.pro proto/help.pro proto/linefunc.pro proto/main.pro proto/mark.pro \
X proto/memfile.pro proto/memline.pro proto/message.pro proto/misccmds.pro proto/normal.pro proto/ops.pro \
X proto/param.pro proto/quickfix.pro proto/regexp.pro proto/regsub.pro \
X proto/screen.pro proto/search.pro \
X proto/tag.pro proto/term.pro proto/termlib.pro \
X proto/undo.pro proto/window.pro proto/amiga.pro
X
X/Vim: $(OBJ) version.c
X cc $(CFLAGS) version.c -o obj/version.o
X ln +q -m -o /Vim $(OBJ) obj/version.o $(LIBS)
X
Xdebug: $(OBJ) version.c
X cc $(CFLAGS) version.c -o obj/version.o
X ln +q -m -g -o /Vim $(OBJ) obj/version.o $(LIBS)
X
Xproto: $(SYMS) $(PRO)
X
Xctags:
X csh -c ctags *.c *.h
X
X# can't use delete here, too many file names
Xclean:
X csh -c rm -f $(OBJ) obj/version.o obj/mkcmdtab.o obj/termlib.o /Vim $(SYMS) mkcmdtab cmdtab.h
X
X$(SYMS) : vim.h keymap.h macros.h ascii.h term.h structs.h amiga.h
X cc $(CFLAGS) -ho$(SYMS) vim.h
X
X###########################################################################
X
Xobj/alloc.o: alloc.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) alloc.c -o obj/alloc.o
X
Xproto/alloc.pro: alloc.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) alloc.c
X csh -c mv -f alloc.pro proto
X
Xobj/amiga.o: amiga.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) amiga.c -o obj/amiga.o
X
Xproto/amiga.pro: amiga.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) amiga.c
X csh -c mv -f amiga.pro proto
X
Xobj/buffer.o: buffer.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) buffer.c -o obj/buffer.o
X
Xproto/buffer.pro: buffer.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) buffer.c
X csh -c mv -f buffer.pro proto
X
Xobj/charset.o: charset.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) charset.c -o obj/charset.o
X
Xproto/charset.pro: charset.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) charset.c
X csh -c mv -f charset.pro proto
X
Xobj/cmdcmds.o: cmdcmds.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) cmdcmds.c -o obj/cmdcmds.o
X
Xproto/cmdcmds.pro: cmdcmds.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) cmdcmds.c
X csh -c mv -f cmdcmds.pro proto
X
Xobj/cmdline.o: cmdline.c $(SYMS) cmdtab.h
X cc $(CFLAGS) -hi$(SYMS) cmdline.c -o obj/cmdline.o
X
Xproto/cmdline.pro: cmdline.c $(SYMS) cmdtab.h
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) cmdline.c
X csh -c mv -f cmdline.pro proto
X
Xobj/csearch.o: csearch.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) csearch.c -o obj/csearch.o
X
Xproto/csearch.pro: csearch.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) csearch.c
X csh -c mv -f csearch.pro proto
X
Xobj/digraph.o: digraph.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) digraph.c -o obj/digraph.o
X
Xproto/digraph.pro: digraph.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) digraph.c
X csh -c mv -f digraph.pro proto
X
Xobj/edit.o: edit.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) edit.c -o obj/edit.o
X
Xproto/edit.pro: edit.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) edit.c
X csh -c mv -f edit.pro proto
X
Xobj/fileio.o: fileio.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) fileio.c -o obj/fileio.o
X
Xproto/fileio.pro: fileio.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) fileio.c
X csh -c mv -f fileio.pro proto
X
Xobj/getchar.o: getchar.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) getchar.c -o obj/getchar.o
X
Xproto/getchar.pro: getchar.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) getchar.c
X csh -c mv -f getchar.pro proto
X
Xobj/help.o: help.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) help.c -o obj/help.o
X
Xproto/help.pro: help.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) help.c
X csh -c mv -f help.pro proto
X
Xobj/linefunc.o: linefunc.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) linefunc.c -o obj/linefunc.o
X
Xproto/linefunc.pro: linefunc.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) linefunc.c
X csh -c mv -f linefunc.pro proto
X
Xobj/main.o: main.c $(SYMS) param.h globals.h
X cc $(CFLAGS) -hi$(SYMS) main.c -o obj/main.o
X
Xproto/main.pro: main.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) main.c
X csh -c mv -f main.pro proto
X
Xobj/mark.o: mark.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) mark.c -o obj/mark.o
X
Xproto/mark.pro: mark.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) mark.c
X csh -c mv -f mark.pro proto
X
Xobj/memfile.o: memfile.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) memfile.c -o obj/memfile.o
X
Xproto/memfile.pro: memfile.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) memfile.c
X csh -c mv -f memfile.pro proto
X
Xobj/memline.o: memline.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) memline.c -o obj/memline.o
X
Xproto/memline.pro: memline.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) memline.c
X csh -c mv -f memline.pro proto
X
Xobj/message.o: message.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) message.c -o obj/message.o
X
Xproto/message.pro: message.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) message.c
X csh -c mv -f message.pro proto
X
Xobj/misccmds.o: misccmds.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) misccmds.c -o obj/misccmds.o
X
Xproto/misccmds.pro: misccmds.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) misccmds.c
X csh -c mv -f misccmds.pro proto
X
Xobj/normal.o: normal.c $(SYMS) ops.h
X cc $(CFLAGS) -hi$(SYMS) normal.c -o obj/normal.o
X
Xproto/normal.pro: normal.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) normal.c
X csh -c mv -f normal.pro proto
X
Xobj/ops.o: ops.c $(SYMS) ops.h
X cc $(CFLAGS) -hi$(SYMS) ops.c -o obj/ops.o
X
Xproto/ops.pro: ops.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) ops.c
X csh -c mv -f ops.pro proto
X
Xobj/param.o: param.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) param.c -o obj/param.o
X
Xproto/param.pro: param.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) param.c
X csh -c mv -f param.pro proto
X
Xobj/quickfix.o: quickfix.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) quickfix.c -o obj/quickfix.o
X
Xproto/quickfix.pro: quickfix.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) quickfix.c
X csh -c mv -f quickfix.pro proto
X
Xobj/regexp.o: regexp.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) regexp.c -o obj/regexp.o
X
Xproto/regexp.pro: regexp.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) regexp.c
X csh -c mv -f regexp.pro proto
X
Xobj/regsub.o: regsub.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) regsub.c -o obj/regsub.o
X
Xproto/regsub.pro: regsub.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) regsub.c
X csh -c mv -f regsub.pro proto
X
Xobj/screen.o: screen.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) screen.c -o obj/screen.o
X
Xproto/screen.pro: screen.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) screen.c
X csh -c mv -f screen.pro proto
X
Xobj/search.o: search.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) search.c -o obj/search.o
X
Xproto/search.pro: search.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) search.c
X csh -c mv -f search.pro proto
X
Xobj/tag.o: tag.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) tag.c -o obj/tag.o
X
Xproto/tag.pro: tag.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) tag.c
X csh -c mv -f tag.pro proto
X
Xobj/term.o: term.c $(SYMS) term.h
X cc $(CFLAGS) -hi$(SYMS) term.c -o obj/term.o
X
Xproto/term.pro: term.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) term.c
X csh -c mv -f term.pro proto
X
Xobj/termlib.o: termlib.c $(SYMS)
X cc $(CFLAGS) termlib.c -o obj/termlib.o
X
Xproto/termlib.pro: termlib.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO termlib.c
X#the manx compiler generates a wrong prototype for tputs
X vim -s termlib.fix termlib.pro
X csh -c mv -f termlib.pro proto
X
Xobj/undo.o: undo.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) undo.c -o obj/undo.o
X
Xproto/undo.pro: undo.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) undo.c
X csh -c mv -f undo.pro proto
X
Xobj/window.o: window.c $(SYMS)
X cc $(CFLAGS) -hi$(SYMS) window.c -o obj/window.o
X
Xproto/window.pro: window.c $(SYMS)
X cc -qa -qp $(CFLAGS) -DPROTO -hi$(SYMS) window.c
X csh -c mv -f window.pro proto
X
Xcmdtab.h: cmdtab.tab mkcmdtab


X mkcmdtab cmdtab.tab cmdtab.h
X

Xmkcmdtab: obj/mkcmdtab.o
X ln +q -o mkcmdtab obj/mkcmdtab.o -lc16
X
Xobj/mkcmdtab.o: mkcmdtab.c
X cc $(CFLAGS) mkcmdtab.c -o obj/mkcmdtab.o
END_OF_FILE
if test 10141 -ne `wc -c <'vim/src/makefile.manx'`; then
echo shar: \"'vim/src/makefile.manx'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.manx'
fi
if test -f 'vim/src/makefile.sas' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.sas'\"
else
echo shar: Extracting \"'vim/src/makefile.sas'\" \(9401 characters\)
sed "s/^X//" >'vim/src/makefile.sas' <<'END_OF_FILE'
X#
X# Makefile for VIM on the Amiga, using SAS/Lattice C 6.0 to 6.3
X#
X# Do NOT use the peephole optimizer! It messes up all kinds of things.
X# For 6.0 and 6.1, expand_env() will not work correctly.
X# For 6.2 and 6.3 the call to free_line in u_freeentry is wrong.
X# Don't know about 6.50, might work...
X# You should use Manx Aztec C whenever possible.
X#
X# The prototypes from Manx and SAS are incompatible. If the prototypes
X# were generated by Manx, first do "touch *.c; make proto" before "make".
X#
X# Note: not all dependencies are included. This was done to avoid having
X# to compile everything when a global variable or function is added


X#
X
X#>>>>> choose options:

X### DEF=DIGRAPHS digraph support (at the cost of 1.6 Kbyte code)
X### DEF=NO_ARP do not use arp.library, DOS 2.0 required
X### DEF=COMPATIBLE start in vi-compatible mode
X### DEF=NOBACKUP default is no backup file
X### DEF=DEBUG output a lot of debugging garbage
X### DEF=TERMCAP include termcap file support
X### DEF=NO_BUILTIN_TCAPS do not include builtin termcap entries


X### (use only with -DTERMCAP)

X### DEF=SOME_BUILTIN_TCAPS include most useful builtin termcap entries


X### (use only without -DNO_BUILTIN_TCAPS)

X### DEF=ALL_BUILTIN_TCAPS include all builtin termcap entries


X### (use only without -DNO_BUILTIN_TCAPS)

X### DEF=WEBB_COMPLETE include Webb's code for command line completion
X### DEF=WEBB_KEYWORD_COMPL include Webb's code for keyword completion
X### DEF=NOTITLE 'title' option off by default
XDEFINES = DEF=DIGRAPHS DEF=SOME_BUILTIN_TCAPS \
X DEF=WEBB_COMPLETE DEF=WEBB_KEYWORD_COMPL
X
X#>>>>> if TERMCAP is defined obj/termlib.o has to be used
X#TERMLIB = obj/termlib.o
XTERMLIB =
X
X#>>>>> choose NODEBUG for normal compiling, the other for debugging and profiling
X# don't switch on debugging when generating proto files, it crashes the compiler.
XDBG = NODEBUG
X#DBG = DBG=SF
X
X#>>>>> choose NOOPTPEEP for 6.0 to 6.3, NOOPT for debugging
X# when all the optimizer bugs are finally solved you can use OPT
X#OPTIMIZE=OPT
XOPTIMIZE=NOOPTPEEP
X#OPTIMIZE=NOOPT


X
X#>>>>> end of choices
X###########################################################################
X

XCC = sc
XGST = vim.gst
XCOPTS = SINT SCODE SDATA
X
XCFLAGS = NOLINK $(OPTIMIZE) $(COPTS) DEF=AMIGA DEF=SASC $(DBG) $(DEFINES) GST=$(GST)
X
XPROPT = DEF=PROTO GPROTO GPPARM
X
XOBJ = obj/alloc.o obj/amiga.o obj/buffer.o obj/charset.o obj/cmdcmds.o obj/cmdline.o \
X obj/csearch.o obj/digraph.o obj/edit.o obj/fileio.o obj/getchar.o obj/help.o \
X obj/linefunc.o obj/main.o obj/mark.o obj/memfile.o obj/memline.o obj/message.o obj/misccmds.o \
X obj/normal.o obj/ops.o obj/param.o obj/quickfix.o obj/regexp.o \
X obj/regsub.o obj/screen.o obj/search.o \
X obj/tag.o obj/term.o obj/undo.o obj/window.o $(TERMLIB)
X
XPRO = proto/alloc.pro proto/buffer.pro proto/charset.pro proto/cmdcmds.pro proto/cmdline.pro \
X proto/csearch.pro proto/digraph.pro proto/edit.pro proto/fileio.pro \
X proto/getchar.pro proto/help.pro proto/linefunc.pro proto/main.pro proto/mark.pro \
X proto/memfile.pro proto/memline.pro proto/message.pro proto/misccmds.pro proto/normal.pro proto/ops.pro \
X proto/param.pro proto/quickfix.pro proto/regexp.pro proto/regsub.pro \
X proto/screen.pro proto/search.pro \
X proto/tag.pro proto/term.pro proto/termlib.pro \
X proto/undo.pro proto/window.pro proto/amiga.pro
X
X/Vim: $(OBJ) version.c
X $(CC) $(CFLAGS) version.c OBJNAME=obj/
X $(CC) LINK $(COPTS) $(OBJ) obj/version.o $(DBG) PNAME=/Vim
X
Xdebug: $(OBJ) version.c
X $(CC) $(CFLAGS) version.c OBJNAME=obj/
X $(CC) LINK $(COPTS) $(OBJ) obj/version.o $(DBG) PNAME=/Vim
X
Xproto: $(GST) $(PRO)
X
Xctags:
X csh -c ctags *.c *.h
X
X# can't use delete here, too many file names
Xclean:
X csh -c rm -f $(OBJ) obj/version.o obj/mkcmdtab.o /Vim $(GST) mkcmdtab cmdtab.h
X
X$(GST) : vim.h keymap.h macros.h ascii.h term.h structs.h
X $(CC) $(CFLAGS) MGST=$(GST) vim.h
X
X###########################################################################
X
Xobj/alloc.o: alloc.c $(GST)
X $(CC) $(CFLAGS) alloc.c OBJNAME=obj/
X
Xproto/alloc.pro: alloc.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/alloc.pro $(PROPT) alloc.c
X
Xobj/amiga.o: amiga.c $(GST)
X $(CC) $(CFLAGS) amiga.c OBJNAME=obj/
X
Xproto/amiga.pro: amiga.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/amiga.pro $(PROPT) amiga.c
X
Xobj/buffer.o: buffer.c $(GST)
X $(CC) $(CFLAGS) buffer.c OBJNAME=obj/
X
Xproto/buffer.pro: buffer.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/buffer.pro $(PROPT) buffer.c
X
Xobj/charset.o: charset.c $(GST)
X $(CC) $(CFLAGS) charset.c OBJNAME=obj/
X
Xproto/charset.pro: charset.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/charset.pro $(PROPT) charset.c
X
Xobj/cmdcmds.o: cmdcmds.c $(GST)
X $(CC) $(CFLAGS) cmdcmds.c OBJNAME=obj/
X
Xproto/cmdcmds.pro: cmdcmds.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/cmdcmds.pro $(PROPT) cmdcmds.c
X
Xobj/cmdline.o: cmdline.c $(GST) cmdtab.h
X $(CC) $(CFLAGS) cmdline.c OBJNAME=obj/
X
Xproto/cmdline.pro: cmdline.c $(GST) cmdtab.h
X $(CC) $(CFLAGS) GPFILE=proto/cmdline.pro $(PROPT) cmdline.c
X
Xobj/csearch.o: csearch.c $(GST)
X $(CC) $(CFLAGS) csearch.c OBJNAME=obj/
X
Xproto/csearch.pro: csearch.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/csearch.pro $(PROPT) csearch.c
X
Xobj/digraph.o: digraph.c $(GST)
X $(CC) $(CFLAGS) digraph.c OBJNAME=obj/
X
Xproto/digraph.pro: digraph.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/digraph.pro $(PROPT) digraph.c
X
Xobj/edit.o: edit.c $(GST)
X $(CC) $(CFLAGS) edit.c OBJNAME=obj/
X
Xproto/edit.pro: edit.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/edit.pro $(PROPT) edit.c
X
Xobj/fileio.o: fileio.c $(GST)
X $(CC) $(CFLAGS) fileio.c OBJNAME=obj/
X
Xproto/fileio.pro: fileio.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/fileio.pro $(PROPT) fileio.c
X
Xobj/getchar.o: getchar.c $(GST)
X $(CC) $(CFLAGS) getchar.c OBJNAME=obj/
X
Xproto/getchar.pro: getchar.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/getchar.pro $(PROPT) getchar.c
X
Xobj/help.o: help.c $(GST)
X $(CC) $(CFLAGS) help.c OBJNAME=obj/
X
Xproto/help.pro: help.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/help.pro $(PROPT) help.c
X
Xobj/linefunc.o: linefunc.c $(GST)
X $(CC) $(CFLAGS) linefunc.c OBJNAME=obj/
X
Xproto/linefunc.pro: linefunc.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/linefunc.pro $(PROPT) linefunc.c
X
Xobj/main.o: main.c $(GST)
X $(CC) $(CFLAGS) main.c OBJNAME=obj/
X
Xproto/main.pro: main.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/main.pro $(PROPT) main.c
X
Xobj/mark.o: mark.c $(GST)
X $(CC) $(CFLAGS) mark.c OBJNAME=obj/
X
Xproto/mark.pro: mark.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/mark.pro $(PROPT) mark.c
X
Xobj/memfile.o: memfile.c $(GST)
X $(CC) $(CFLAGS) memfile.c OBJNAME=obj/
X
Xproto/memfile.pro: memfile.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/memfile.pro $(PROPT) memfile.c
X
Xobj/memline.o: memline.c $(GST)
X $(CC) $(CFLAGS) memline.c OBJNAME=obj/
X
Xproto/memline.pro: memline.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/memline.pro $(PROPT) memline.c
X
Xobj/message.o: message.c $(GST)
X $(CC) $(CFLAGS) message.c OBJNAME=obj/
X
Xproto/message.pro: message.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/message.pro $(PROPT) message.c
X
Xobj/misccmds.o: misccmds.c $(GST)
X $(CC) $(CFLAGS) misccmds.c OBJNAME=obj/
X
Xproto/misccmds.pro: misccmds.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/misccmds.pro $(PROPT) misccmds.c
X
Xobj/normal.o: normal.c $(GST) ops.h
X $(CC) $(CFLAGS) normal.c OBJNAME=obj/
X
Xproto/normal.pro: normal.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/normal.pro $(PROPT) normal.c
X
Xobj/ops.o: ops.c $(GST) ops.h
X $(CC) $(CFLAGS) ops.c OBJNAME=obj/
X
Xproto/ops.pro: ops.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/ops.pro $(PROPT) ops.c
X
Xobj/param.o: param.c $(GST)
X $(CC) $(CFLAGS) param.c OBJNAME=obj/
X
Xproto/param.pro: param.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/param.pro $(PROPT) param.c
X
Xobj/quickfix.o: quickfix.c $(GST)
X $(CC) $(CFLAGS) quickfix.c OBJNAME=obj/
X
Xproto/quickfix.pro: quickfix.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/quickfix.pro $(PROPT) quickfix.c
X
Xobj/regexp.o: regexp.c $(GST)
X $(CC) $(CFLAGS) regexp.c OBJNAME=obj/
X
Xproto/regexp.pro: regexp.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/regexp.pro $(PROPT) regexp.c
X
Xobj/regsub.o: regsub.c $(GST)
X $(CC) $(CFLAGS) regsub.c OBJNAME=obj/
X
Xproto/regsub.pro: regsub.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/regsub.pro $(PROPT) regsub.c
X
Xobj/screen.o: screen.c $(GST)
X $(CC) $(CFLAGS) screen.c OBJNAME=obj/
X
Xproto/screen.pro: screen.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/screen.pro $(PROPT) screen.c
X
Xobj/search.o: search.c $(GST)
X $(CC) $(CFLAGS) search.c OBJNAME=obj/
X
Xproto/search.pro: search.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/search.pro $(PROPT) search.c
X
Xobj/tag.o: tag.c $(GST)
X $(CC) $(CFLAGS) tag.c OBJNAME=obj/
X
Xproto/tag.pro: tag.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/tag.pro $(PROPT) tag.c
X
Xobj/term.o: term.c $(GST)
X $(CC) $(CFLAGS) term.c OBJNAME=obj/
X
Xproto/term.pro: term.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/term.pro $(PROPT) term.c
X
Xobj/termlib.o: termlib.c $(GST)
X $(CC) $(CFLAGS) termlib.c OBJNAME=obj/
X
Xproto/termlib.pro: termlib.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/termlib.pro $(PROPT) termlib.c
X
Xobj/undo.o: undo.c $(GST)
X $(CC) $(CFLAGS) undo.c OBJNAME=obj/
X
Xproto/undo.pro: undo.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/undo.pro $(PROPT) undo.c
X
Xobj/window.o: window.c $(GST)
X $(CC) $(CFLAGS) window.c OBJNAME=obj/
X
Xproto/window.pro: window.c $(GST)
X $(CC) $(CFLAGS) GPFILE=proto/window.pro $(PROPT) window.c
X
Xcmdtab.h: cmdtab.tab mkcmdtab


X mkcmdtab cmdtab.tab cmdtab.h
X

Xobj/mkcmdtab.o: mkcmdtab.c
X $(CC) $(CFLAGS) mkcmdtab.c OBJNAME=obj/
X
Xmkcmdtab: obj/mkcmdtab.o
X $(CC) LINK $(COPTS) obj/mkcmdtab.o PNAME=mkcmdtab
END_OF_FILE
if test 9401 -ne `wc -c <'vim/src/makefile.sas'`; then
echo shar: \"'vim/src/makefile.sas'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.sas'
fi
if test -f 'vim/src/mark.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/mark.c'\"
else
echo shar: Extracting \"'vim/src/mark.c'\" \(10133 characters\)
sed "s/^X//" >'vim/src/mark.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * mark.c: functions for setting marks and jumping to them


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"

X
X/*
X * This file contains routines to maintain and manipulate marks.
X */
X
Xstatic struct filemark namedfm[NMARKS]; /* new marks with file nr */
X
X/*
X * setmark(c) - set named mark 'c' at current cursor position
X *
X * Returns OK on success, FAIL if no room for mark or bad name given.
X */
X int
Xsetmark(c)
X int c;


X{
X int i;
X

X if (islower(c))
X {
X i = c - 'a';
X curbuf->b_namedm[i] = curwin->w_cursor;
X return OK;
X }
X if (isupper(c))
X {
X i = c - 'A';
X namedfm[i].mark = curwin->w_cursor;
X namedfm[i].fnum = curbuf->b_fnum;
X return OK;
X }
X return FAIL;
X}
X
X/*
X * setpcmark() - set the previous context mark to the current position
X * and insert it into the jump list
X */
X void
Xsetpcmark()
X{
X int i;
X#ifdef ROTATE
X struct filemark tempmark;
X#endif
X
X curwin->w_prev_pcmark = curwin->w_pcmark;
X curwin->w_pcmark = curwin->w_cursor;
X
X#ifndef ROTATE
X /*
X * simply add the new entry at the end of the list
X */
X curwin->w_jumplistidx = curwin->w_jumplistlen;
X#else
X /*
X * If last used entry is not at the top, put it at the top by rotating
X * the stack until it is (the newer entries will be at the bottom).
X * Keep one entry (the last used one) at the top.
X */
X if (curwin->w_jumplistidx < curwin->w_jumplistlen)
X ++curwin->w_jumplistidx;
X while (curwin->w_jumplistidx < curwin->w_jumplistlen)
X {
X tempmark = curwin->w_jumplist[curwin->w_jumplistlen - 1];
X for (i = curwin->w_jumplistlen - 1; i > 0; --i)
X curwin->w_jumplist[i] = curwin->w_jumplist[i - 1];
X curwin->w_jumplist[0] = tempmark;
X ++curwin->w_jumplistidx;
X }
X#endif
X
X /* only add new entry if it differs from the last one */
X if (curwin->w_jumplistlen == 0 ||
X curwin->w_jumplist[curwin->w_jumplistidx - 1].mark.lnum !=
X curwin->w_pcmark.lnum ||
X curwin->w_jumplist[curwin->w_jumplistidx - 1].fnum !=
X curbuf->b_fnum)
X {
X /* if jumplist is full: remove oldest entry */
X if (++curwin->w_jumplistlen > JUMPLISTSIZE)
X {
X curwin->w_jumplistlen = JUMPLISTSIZE;
X for (i = 1; i < curwin->w_jumplistlen; ++i)
X curwin->w_jumplist[i - 1] = curwin->w_jumplist[i];
X --curwin->w_jumplistidx;
X }
X
X#ifdef ARCHIE
X /* Workaround for a bug in gcc 2.4.5 R2 on the Archimedes
X * Should be fixed in 2.5.x.
X */
X curwin->w_jumplist[curwin->w_jumplistidx].mark.ptr = curwin->w_pcmark.ptr;
X curwin->w_jumplist[curwin->w_jumplistidx].mark.col = curwin->w_pcmark.col;
X#else
X curwin->w_jumplist[curwin->w_jumplistidx].mark = curwin->w_pcmark;
X#endif
X curwin->w_jumplist[curwin->w_jumplistidx].fnum = curbuf->b_fnum;
X ++curwin->w_jumplistidx;
X }
X}
X
X/*
X * checkpcmark() - To change context, call setpcmark(), then move the current
X * position to where ever, then call checkpcmark(). This
X * ensures that the previous context will only be changed if
X * the cursor moved to a different line. -- webb.
X * If pcmark was deleted (with "dG") the previous mark is restored.
X */
X void
Xcheckpcmark()
X{
X if (curwin->w_prev_pcmark.lnum != 0 &&
X (curwin->w_pcmark.lnum == curwin->w_cursor.lnum ||
X curwin->w_pcmark.lnum == 0))
X {
X curwin->w_pcmark = curwin->w_prev_pcmark;
X curwin->w_prev_pcmark.lnum = 0; /* Show it has been checked */
X }
X}
X
X/*
X * move "count" positions in the jump list (count may be negative)
X */
X FPOS *
Xmovemark(count)
X int count;
X{
X FPOS *pos;
X
X if (curwin->w_jumplistlen == 0) /* nothing to jump to */
X return (FPOS *)NULL;
X
X if (curwin->w_jumplistidx + count < 0 ||
X curwin->w_jumplistidx + count >= curwin->w_jumplistlen)
X return (FPOS *)NULL;
X
X /*
X * if first CTRL-O or CTRL-I command after a jump, add cursor position to list
X */
X if (curwin->w_jumplistidx == curwin->w_jumplistlen)
X {
X setpcmark();
X --curwin->w_jumplistidx; /* skip the new entry */
X }
X
X curwin->w_jumplistidx += count;
X /* jump to other file */
X if (curwin->w_jumplist[curwin->w_jumplistidx].fnum != curbuf->b_fnum)
X {
X if (buflist_getfile(curwin->w_jumplist[curwin->w_jumplistidx].fnum,
X curwin->w_jumplist[curwin->w_jumplistidx].mark.lnum, FALSE) == FAIL)
X return (FPOS *)NULL;
X curwin->w_cursor.col = curwin->w_jumplist[curwin->w_jumplistidx].mark.col;
X pos = (FPOS *)-1;
X }
X else
X pos = &(curwin->w_jumplist[curwin->w_jumplistidx].mark);
X return pos;
X}
X
X/*
X * getmark(c) - find mark for char 'c'
X *
X * Return pointer to FPOS if found
X * NULL if no such mark.
X * -1 if mark is in other file (only if changefile is TRUE)


X */
X FPOS *

Xgetmark(c, changefile)
X int c;
X int changefile;
X{
X FPOS *posp;
X static FPOS pos_copy;
X
X posp = NULL;
X if (c == '\'' || c == '`') /* previous context mark */
X {
X pos_copy = curwin->w_pcmark; /* need to make a copy because b_pcmark */
X posp = &pos_copy; /* may be changed soon */
X }
X else if (c == '[') /* to start of previous operator */
X {
X if (curbuf->b_startop.lnum > 0 &&
X curbuf->b_startop.lnum <= curbuf->b_ml.ml_line_count)
X posp = &(curbuf->b_startop);
X }
X else if (c == ']') /* to end of previous operator */
X {
X if (curbuf->b_endop.lnum > 0 &&
X curbuf->b_endop.lnum <= curbuf->b_ml.ml_line_count)
X posp = &(curbuf->b_endop);
X }
X else if (islower(c)) /* normal named mark */
X posp = &(curbuf->b_namedm[c - 'a']);
X else if (isupper(c)) /* named file mark */
X {
X c -= 'A';
X posp = &(namedfm[c].mark);
X if (namedfm[c].fnum != curbuf->b_fnum &&
X namedfm[c].mark.lnum != 0 && changefile)
X {
X if (buflist_getfile(namedfm[c].fnum, namedfm[c].mark.lnum, TRUE) == OK)
X {
X curwin->w_cursor.col = namedfm[c].mark.col;
X posp = (FPOS *)-1;
X }
X }
X }
X return posp;
X}
X
X/*
X * clrallmarks() - clear all marks in the buffer 'buf'
X *
X * Used mainly when trashing the entire buffer during ":e" type commands
X */
X void
Xclrallmarks(buf)
X BUF *buf;
X{
X static int i = -1;
X
X if (i == -1) /* first call ever: initialize */
X for (i = 0; i < NMARKS; i++)
X namedfm[i].mark.lnum = 0;
X
X for (i = 0; i < NMARKS; i++)
X buf->b_namedm[i].lnum = 0;
X buf->b_startop.lnum = 0; /* start/end op mark cleared */
X buf->b_endop.lnum = 0;
X}
X
X/*
X * get name of file from a filemark


X */
X char_u *

Xfm_getname(fmark)
X struct filemark *fmark;
X{
X char_u *name;
X
X if (fmark->fnum != curbuf->b_fnum) /* not current file */
X {
X name = buflist_nr2name(fmark->fnum);


X if (name == NULL)

X return (char_u *)"-unknown-";
X return name;
X }
X return (char_u *)"-current-";
X}
X
X/*
X * print the marks (use the occasion to update the line numbers)
X */
X void
Xdomarks()


X{
X int i;
X char_u *name;
X

X gotocmdline(TRUE, NUL);
X msg_outstr((char_u *)"\nmark line file\n");
X for (i = 0; i < NMARKS; ++i)
X {
X if (curbuf->b_namedm[i].lnum != 0)
X {
X sprintf((char *)IObuff, " %c %5ld\n", i + 'a',
X curbuf->b_namedm[i].lnum);


X msg_outstr(IObuff);
X }
X flushbuf();

X }
X for (i = 0; i < NMARKS; ++i)
X {
X if (namedfm[i].mark.lnum != 0)
X {
X name = fm_getname(&namedfm[i]);


X if (name == NULL) /* file name not available */
X continue;
X

X sprintf((char *)IObuff, " %c %5ld %s\n",
X i + 'A',
X namedfm[i].mark.lnum,


X name);
X msg_outstr(IObuff);
X }
X flushbuf(); /* show one line at a time */
X }

X msg_end();
X}
X
X/*
X * print the jumplist
X */
X void
Xdojumps()


X{
X int i;
X char_u *name;
X

X gotocmdline(TRUE, NUL);
X msg_outstr((char_u *)"\n jump line file\n");
X for (i = 0; i < curwin->w_jumplistlen; ++i)
X {
X if (curwin->w_jumplist[i].mark.lnum != 0)
X {
X name = fm_getname(&curwin->w_jumplist[i]);


X if (name == NULL) /* file name not available */
X continue;
X

X sprintf((char *)IObuff, "%c %2d %5ld %s\n",
X i == curwin->w_jumplistidx ? '>' : ' ',
X i + 1,
X curwin->w_jumplist[i].mark.lnum,


X name);
X msg_outstr(IObuff);
X }
X flushbuf();

X }
X if (curwin->w_jumplistidx == curwin->w_jumplistlen)


X msg_outstr((char_u *)">\n");

X msg_end();
X}
X
X/*
X * adjust marks between line1 and line2 (inclusive) to move 'inc' lines
X * If 'inc' is MAXLNUM the mark is made invalid.
X */
X void
Xmark_adjust(line1, line2, inc)


X linenr_t line1;
X linenr_t line2;

X long inc;
X{
X int i;
X int fnum = curbuf->b_fnum;
X linenr_t *lp;
X WIN *win;
X
X/* named marks, lower case and upper case */
X for (i = 0; i < NMARKS; i++)
X {
X lp = &(curbuf->b_namedm[i].lnum);
X if (*lp >= line1 && *lp <= line2)
X {
X if (inc == MAXLNUM)
X *lp = 0;
X else
X *lp += inc;
X }
X if (namedfm[i].fnum == fnum)
X {
X lp = &(namedfm[i].mark.lnum);
X if (*lp >= line1 && *lp <= line2)
X {
X if (inc == MAXLNUM)
X *lp = 0;
X else
X *lp += inc;
X }
X }
X }
X
X/* previous context mark */
X lp = &(curwin->w_pcmark.lnum);
X if (*lp >= line1 && *lp <= line2)
X {
X if (inc == MAXLNUM)
X *lp = 0;
X else
X *lp += inc;
X }
X
X/* previous pcmark */
X lp = &(curwin->w_prev_pcmark.lnum);
X if (*lp >= line1 && *lp <= line2)
X {
X if (inc == MAXLNUM)
X *lp = 0;
X else
X *lp += inc;
X }
X
X/* quickfix marks */
X qf_mark_adjust(line1, line2, inc);
X
X/* jumplist marks */
X for (win = firstwin; win != NULL; win = win->w_next)
X {
X for (i = 0; i < win->w_jumplistlen; ++i)
X if (win->w_jumplist[i].fnum == fnum)
X {
X lp = &(win->w_jumplist[i].mark.lnum);
X if (*lp >= line1 && *lp <= line2)
X {
X if (inc == MAXLNUM)
X *lp = 0;
X else
X *lp += inc;
X }
X }
X /*
X * also adjust the line at the top of the window and the cursor position
X * for windows with the same buffer.
X */
X if (win != curwin && win->w_buffer == curbuf)
X {
X if (win->w_topline >= line1 && win->w_topline <= line2)
X {
X if (inc == MAXLNUM) /* topline is deleted */
X win->w_topline = line1;
X else /* keep topline on the same line */
X win->w_topline += inc;
X }
X if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2)
X {
X if (inc == MAXLNUM) /* line with cursor is deleted */
X {
X win->w_cursor.lnum = line1;
X win->w_cursor.col = 0;
X }
X else /* keep cursor on the same line */
X win->w_cursor.lnum += inc;
X }
X }
X }
X}
END_OF_FILE
if test 10133 -ne `wc -c <'vim/src/mark.c'`; then
echo shar: \"'vim/src/mark.c'\" unpacked with wrong size!
fi
# end of 'vim/src/mark.c'
fi
if test -f 'vim/src/message.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/message.c'\"
else
echo shar: Extracting \"'vim/src/message.c'\" \(9490 characters\)
sed "s/^X//" >'vim/src/message.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * message.c: functions for displaying messages on the command line


X */
X
X#include "vim.h"
X#include "globals.h"

X#define MESSAGE /* don't include prototype for smsg() */


X#include "proto.h"
X#include "param.h"
X

Xstatic int msg_check_screen __ARGS((void));
X
Xstatic int lines_left = -1; /* lines left for listing */
X
X/*
X * msg(s) - displays the string 's' on the status line
X * return TRUE if wait_return not called
X */
X int
Xmsg(s)
X char_u *s;
X{
X if (!screen_valid()) /* terminal not initialized */
X {
X fprintf(stderr, (char *)s);
X fflush(stderr);


X return TRUE;
X }
X

X msg_start();
X if (msg_highlight) /* actually it is highlighting instead of invert */
X start_highlight();
X msg_outtrans(s, -1);
X if (msg_highlight)
X {
X stop_highlight();
X msg_highlight = FALSE; /* clear for next call */
X }
X msg_ceol();
X return msg_end();
X}
X
X#ifndef PROTO /* automatic prototype generation does not understand this */
X/* VARARGS */
X void
Xsmsg(s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
X char_u *s;
X long a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
X{
X sprintf((char *)IObuff, (char *)s, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
X msg(IObuff);
X}
X#endif
X
X/*
X * emsg() - display an error message
X *
X * Rings the bell, if appropriate, and calls message() to do the real work
X *
X * return TRUE if wait_return not called
X */
X int
Xemsg(s)
X char_u *s;
X{
X if (p_eb)
X beep(); /* also includes flush_buffers() */
X else


X flush_buffers(FALSE); /* flush internal buffers */

X (void)set_highlight('e'); /* set highlight mode for error messages */
X msg_highlight = TRUE;
X/*
X * Msg returns TRUE if wait_return() was not called.
X * In that case may call sleep() to give the user a chance to read the message.
X * Don't call sleep() if dont_sleep is set.
X */
X if (msg(s))
X {
X if (dont_sleep)
X {
X msg_outchar('\n'); /* one message per line, don't overwrite */
X cmdline_row = msg_row;
X need_wait_return = TRUE;
X }
X else
X sleep(1); /* give the user a chance to read the message */
X return TRUE;
X }


X return FALSE;
X}
X

X int
Xemsg2(s, a1)
X char_u *s, *a1;
X{
X sprintf((char *)IObuff, (char *)s, (char *)a1);
X return emsg(IObuff);
X}
X
X/*
X * wait for the user to hit a key (normally a return)
X * if 'redraw' is TRUE, clear and redraw the screen
X * if 'redraw' is FALSE, just redraw the screen
X * if 'redraw' is -1, don't redraw at all
X */
X void
Xwait_return(redraw)
X int redraw;
X{
X int c;
X int oldState;
X int tmpState;
X
X/*
X * With the global command (and some others) we only need one return at the
X * end. Adjust cmdline_row to avoid the next message overwriting the last one.
X */
X if (no_wait_return)
X {
X need_wait_return = TRUE;
X cmdline_row = msg_row;
X if (!termcap_active)
X starttermcap();
X return;
X }
X need_wait_return = FALSE;
X lines_left = -1;
X oldState = State;
X State = HITRETURN;
X if (got_int)
X msg_outstr((char_u *)"Interrupt: ");
X
X (void)set_highlight('r');
X start_highlight();
X#ifdef ORG_HITRETURN
X msg_outstr("Press RETURN to continue");
X stop_highlight();
X do {
X c = vgetc();
X } while (strchr("\r\n: ", c) == NULL);
X if (c == ':') /* this can vi too (but not always!) */
X stuffcharReadbuff(c);
X#else
X msg_outstr((char_u *)"Press RETURN or enter command to continue");
X stop_highlight();
X do


X {
X c = vgetc();

X got_int = FALSE;
X } while (c == Ctrl('C'));
X breakcheck();
X if (strchr("\r\n ", c) == NULL)
X stuffcharReadbuff(c);
X#endif
X
X /*
X * If the user hits ':' we get a command line from the next line.
X */
X if (c == ':')


X cmdline_row = msg_row;
X

X if (!termcap_active) /* start termcap before redrawing */
X starttermcap();
X
X/*
X * If the window size changed set_winsize() will redraw the screen.
X * Otherwise the screen is only redrawn if 'redraw' is set and no ':' typed.
X */
X tmpState = State;
X State = oldState; /* restore State before set_winsize */
X msg_check();
X if (tmpState == SETWSIZE) /* got resize event while in vgetc() */
X set_winsize(0, 0, FALSE);
X else if (redraw == TRUE)
X {
X if (c == ':')


X must_redraw = CLEAR;
X else

X updateScreen(CLEAR);
X }
X else if (msg_scrolled && c != ':' && redraw != -1)
X updateScreen(VALID);
X
X if (c == ':')
X skip_redraw = TRUE; /* skip redraw once */
X}
X
X/*
X * Prepare for outputting characters in the command line.
X */
X void
Xmsg_start()
X{
X did_msg = TRUE; /* for doglob() */
X keep_msg = NULL; /* don't display old message now */
X msg_pos(cmdline_row, 0);
X cursor_off();
X lines_left = cmdline_row;
X}
X
X/*
X * Move message position. This should always be used after moving the cursor.
X * Use negative value if row or col does not have to be changed.
X */
X void
Xmsg_pos(row, col)


X int row, col;
X{

X if (row >= 0)
X msg_row = row;
X if (col >= 0)
X msg_col = col;
X screen_start();
X}
X
X void
Xmsg_outchar(c)
X int c;
X{
X char_u buf[2];
X


X buf[0] = c;

X buf[1] = NUL;
X msg_outstr(buf);
X}
X
X void
Xmsg_outnum(n)
X long n;
X{
X char_u buf[20];
X
X sprintf((char *)buf, "%ld", n);
X msg_outstr(buf);
X}
X
X/*
X * output 'len' characters in 'str' (including NULs) with translation
X * if 'len' is -1, output upto a NUL character
X * return the number of characters it takes on the screen
X */
X int
Xmsg_outtrans(str, len)
X register char_u *str;
X register int len;
X{
X int retval = 0;
X
X if (len == -1)
X len = STRLEN(str);
X while (--len >= 0)
X {
X msg_outstr(transchar(*str));
X retval += charsize(*str);
X ++str;
X }
X return retval;
X}
X
X/*
X * print line for :p command
X */
X void
Xmsg_prt_line(s)
X char_u *s;
X{
X register int si = 0;
X register int c;
X register int col = 0;
X
X int n_extra = 0;
X int n_spaces = 0;
X char_u *p = NULL; /* init to make SASC shut up */
X int n;
X


X for (;;)
X {

X if (n_extra)
X {
X --n_extra;
X c = *p++;


X }
X else if (n_spaces)
X {

X --n_spaces;
X c = ' ';
X }
X else
X {
X c = s[si++];
X if (c == TAB && !curwin->w_p_list)


X {
X /* tab amount depends on current column */

X n_spaces = curbuf->b_p_ts - col % curbuf->b_p_ts - 1;
X c = ' ';
X }
X else if (c == NUL && curwin->w_p_list)
X {
X p = (char_u *)"";


X n_extra = 1;
X c = '$';
X }

X else if (c != NUL && (n = charsize(c)) > 1)
X {
X n_extra = n - 1;
X p = transchar(c);
X c = *p++;
X }
X }
X
X if (c == NUL)
X break;
X
X msg_outchar(c);
X col++;
X }
X}
X
X/*
X * output a string to the screen at position msg_row, msg_col
X * Update msg_row and msg_col for the next message.
X */
X void
Xmsg_outstr(s)
X char_u *s;
X{
X int c;
X
X /*
X * if there is no valid screen, use fprintf so we can see error messages
X */
X if (!msg_check_screen())
X {
X fprintf(stderr, (char *)s);
X return;
X }
X
X while (*s)
X {
X /*
X * the screen is scrolled up when:
X * - When outputting a newline in the last row
X * - when outputting a character in the last column of the last row
X * (some terminals scroll automatically, some don't. To avoid problems
X * we scroll ourselves)
X */
X if (msg_row >= Rows - 1 && (*s == '\n' || msg_col >= Columns - 1))
X {
X screen_del_lines(0, 0, 1, (int)Rows); /* always works */
X msg_row = Rows - 2;
X if (msg_col >= Columns) /* can happen after screen resize */
X msg_col = Columns - 1;
X ++msg_scrolled;
X if (cmdline_row > 0)
X --cmdline_row;
X /*
X * if screen is completely filled wait for a character
X */
X if (p_more && --lines_left == 0)


X {
X windgoto((int)Rows - 1, 0);

X outstr((char_u *)"-- more --");
X c = vgetc();
X if (c == CR || c == NL)
X lines_left = 1;
X else if (c == 'q' || c == Ctrl('C'))
X got_int = TRUE;
X else
X lines_left = Rows - 1;
X outstr((char_u *)"\r ");
X }
X screen_start();
X }
X if (*s == '\n')
X {
X msg_col = 0;
X ++msg_row;
X }
X else
X {
X screen_outchar(*s, msg_row, msg_col);
X if (++msg_col >= Columns)
X {
X msg_col = 0;
X ++msg_row;
X }
X }
X ++s;
X }
X}
X
X/*
X * msg_check_screen - check if the screen is initialized.
X * Also check msg_row and msg_col, if they are too big it may cause a crash.


X */
X static int

Xmsg_check_screen()
X{
X if (!screen_valid())
X return FALSE;
X
X if (msg_row >= Rows)
X msg_row = Rows - 1;
X if (msg_col >= Columns)
X msg_col = Columns - 1;
X return TRUE;
X}
X
X/*
X * clear from current message position to end of screen
X * Note: msg_col is not updated, so we remember the end of the message
X * for msg_check().
X */
X void
Xmsg_ceol()
X{
X if (!msg_check_screen())
X return;
X screen_fill(msg_row, msg_row + 1, msg_col, (int)Columns, ' ', ' ');
X screen_fill(msg_row + 1, (int)Rows, 0, (int)Columns, ' ', ' ');
X}
X
X/*
X * end putting a message on the screen
X * call wait_return if the message does not fit in the available space
X * return TRUE if wait_return not called.
X */
X int
Xmsg_end()
X{
X lines_left = -1;
X /*
X * if the string is larger than the window,
X * or the ruler option is set and we run into it,
X * we have to redraw the window.
X * Do not do this if we are abandoning the file or editing the command line.
X */
X if (!exiting && msg_check() && State != CMDLINE)


X {
X msg_outchar('\n');

X wait_return(FALSE);
X return FALSE;
X }
X flushbuf();
X return TRUE;
X}
X
X/*
X * If the written message has caused the screen to scroll up, or if we
X * run into the shown command or ruler, we have to redraw the window later.
X */
X int
Xmsg_check()
X{
X lines_left = -1;
X if (msg_scrolled || (msg_row == Rows - 1 && msg_col >= sc_col))
X {
X if (must_redraw < NOT_VALID)
X must_redraw = NOT_VALID;
X redraw_cmdline = TRUE;
X return TRUE;
X }


X return FALSE;
X}
END_OF_FILE

if test 9490 -ne `wc -c <'vim/src/message.c'`; then
echo shar: \"'vim/src/message.c'\" unpacked with wrong size!
fi
# end of 'vim/src/message.c'
fi
if test -f 'vim/src/proto/cmdline.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/cmdline.pro'\"
else
echo shar: Extracting \"'vim/src/proto/cmdline.pro'\" \(761 characters\)
sed "s/^X//" >'vim/src/proto/cmdline.pro' <<'END_OF_FILE'
X/* cmdline.c */
Xint getcmdline __PARMS((int firstc, unsigned char *buff));
Xvoid redrawcmdline __PARMS((void));
Xvoid compute_cmdrow __PARMS((void));
Xvoid redrawcmd __PARMS((void));
Xint docmdline __PARMS((unsigned char *cmdline));
Xint autowrite __PARMS((struct buffer *buf));
Xvoid autowrite_all __PARMS((void));
Xint doecmd __PARMS((unsigned char *fname, unsigned char *sfname, unsigned char *command, int hide, long newlnum));
Xvoid gotocmdline __PARMS((int clr, int firstc));
Xvoid gotocmdend __PARMS((void));
Xint check_fname __PARMS((void));
Xint getfile __PARMS((unsigned char *fname, unsigned char *sfname, int setpm, long lnum));
Xunsigned char *ExpandOne __PARMS((unsigned char *str, int list_notfound, int mode));
Xint dosource __PARMS((unsigned char *fname));
END_OF_FILE
if test 761 -ne `wc -c <'vim/src/proto/cmdline.pro'`; then
echo shar: \"'vim/src/proto/cmdline.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/cmdline.pro'
fi
if test -f 'vim/src/quickfix.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/quickfix.c'\"
else
echo shar: Extracting \"'vim/src/quickfix.c'\" \(9335 characters\)
sed "s/^X//" >'vim/src/quickfix.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * quickfix.c: functions for quickfix mode, using a file with error messages


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic void qf_free __ARGS((void));
Xstatic char_u *qf_types __ARGS((int, int));
X
X/*
X * for each error the next struct is allocated and linked in a list
X */
Xstruct qf_line
X{
X struct qf_line *qf_next; /* pointer to next error in the list */
X struct qf_line *qf_prev; /* pointer to previous error in the list */
X linenr_t qf_lnum; /* line number where the error occurred */
X int qf_fnum; /* file number for the line */
X int qf_col; /* column where the error occurred */
X int qf_nr; /* error number */
X char_u *qf_text; /* description of the error */
X char_u qf_cleared;/* set to TRUE if line has been deleted */
X char_u qf_type; /* type of the error (mostly 'E') */
X char_u qf_valid; /* valid error message detected */
X};
X
Xstatic struct qf_line *qf_start; /* pointer to the first error */
Xstatic struct qf_line *qf_ptr; /* pointer to the current error */
X
Xstatic int qf_count = 0; /* number of errors (0 means no error list) */
Xstatic int qf_index; /* current index in the error list */
Xstatic int qf_nonevalid; /* set to TRUE if not a single valid entry found */
X
X/*
X * Read the errorfile into memory, line by line, building the error list.
X * Return FAIL for error, OK for success.
X */
X int
Xqf_init()
X{
X char_u namebuf[CMDBUFFSIZE + 1];
X char_u errmsg[CMDBUFFSIZE + 1];
X int col;
X int type;
X int valid;
X long lnum;
X int enr;
X FILE *fd;
X struct qf_line *qfp = NULL;
X struct qf_line *qfprev = NULL; /* init to make SASC shut up */
X char_u *pfmt, *fmtstr;
X#ifdef UTS2
X char_u *(adr[7]);
X#else
X void *(adr[7]);
X#endif
X int adr_cnt = 0;
X int maxlen;
X int i;
X
X if (p_ef == NULL || *p_ef == NUL)
X {
X emsg(e_errorf);
X return FAIL;
X }
X if ((fd = fopen((char *)p_ef, "r")) == NULL)
X {
X emsg2(e_openerrf, p_ef);
X return FAIL;
X }
X qf_free();
X qf_index = 0;
X for (i = 0; i < 7; ++i)
X adr[i] = NULL;
X
X/*
X * The format string is copied and modified from p_efm to fmtstr.
X * Only a few % characters are allowed.
X */
X /* get some space to modify the format string into */
X /* must be able to do the largest expansion 7 times (7 x 3) */
X maxlen = STRLEN(p_efm) + 25;
X fmtstr = alloc(maxlen);
X if (fmtstr == NULL)
X goto error2;
X for (pfmt = p_efm, i = 0; *pfmt; ++pfmt, ++i)
X {
X if (pfmt[0] != '%') /* copy normal character */
X fmtstr[i] = pfmt[0];
X else
X {
X fmtstr[i++] = '%';
X switch (pfmt[1])
X {
X case 'f': /* filename */
X adr[adr_cnt++] = namebuf;
X
X case 'm': /* message */
X if (pfmt[1] == 'm')
X adr[adr_cnt++] = errmsg;
X fmtstr[i++] = '[';
X fmtstr[i++] = '^';
X if (pfmt[2])
X fmtstr[i++] = pfmt[2];
X else
X#ifdef MSDOS
X fmtstr[i++] = '\r';
X#else
X fmtstr[i++] = '\n';
X#endif
X fmtstr[i] = ']';
X break;
X case 'c': /* column */
X adr[adr_cnt++] = &col;
X fmtstr[i] = 'd';
X break;
X case 'l': /* line */
X adr[adr_cnt++] = &lnum;
X fmtstr[i++] = 'l';
X fmtstr[i] = 'd';
X break;
X case 'n': /* error number */
X adr[adr_cnt++] = &enr;
X fmtstr[i] = 'd';
X break;
X case 't': /* error type */
X adr[adr_cnt++] = &type;
X fmtstr[i] = 'c';
X break;
X case '%': /* %% */
X case '*': /* %*: no assignment */
X fmtstr[i] = pfmt[1];
X break;
X default:
X EMSG("invalid % in format string");
X goto error2;
X }
X if (adr_cnt == 7)
X {
X EMSG("too many % in format string");
X goto error2;
X }
X ++pfmt;
X }
X if (i >= maxlen - 6)
X {
X EMSG("invalid format string");
X goto error2;
X }
X }
X fmtstr[i] = NUL;
X
X while (fgets((char *)IObuff, CMDBUFFSIZE, fd) != NULL && !got_int)
X {
X if ((qfp = (struct qf_line *)alloc((unsigned)sizeof(struct qf_line))) == NULL)
X goto error2;
X
X IObuff[CMDBUFFSIZE] = NUL; /* for very long lines */
X namebuf[0] = NUL;
X errmsg[0] = NUL;
X lnum = 0;
X col = 0;
X enr = -1;
X type = 0;
X valid = TRUE;
X
X if (sscanf((char *)IObuff, (char *)fmtstr, adr[0], adr[1], adr[2], adr[3],
X adr[4], adr[5]) != adr_cnt)
X {
X namebuf[0] = NUL; /* something failed, remove file name */
X valid = FALSE;
X STRCPY(errmsg, IObuff); /* copy whole line to error message */
X if ((pfmt = STRRCHR(errmsg, '\n')) != NULL)
X *pfmt = NUL;
X#ifdef MSDOS
X if ((pfmt = STRRCHR(errmsg, '\r')) != NULL)
X *pfmt = NUL;
X#endif
X }
X
X if (namebuf[0] == NUL) /* no file name */
X qfp->qf_fnum = 0;
X else
X qfp->qf_fnum = buflist_add(namebuf);
X if ((qfp->qf_text = strsave(errmsg)) == NULL)
X goto error1;
X qfp->qf_lnum = lnum;
X qfp->qf_col = col;
X qfp->qf_nr = enr;
X qfp->qf_type = type;
X qfp->qf_valid = valid;
X
X if (qf_count == 0) /* first element in the list */
X {
X qf_start = qfp;
X qfp->qf_prev = qfp; /* first element points to itself */
X }
X else
X {
X qfp->qf_prev = qfprev;
X qfprev->qf_next = qfp;
X }
X qfp->qf_next = qfp; /* last element points to itself */
X qfp->qf_cleared = FALSE;
X qfprev = qfp;
X ++qf_count;
X if (qf_index == 0 && qfp->qf_valid) /* first valid entry */
X {
X qf_index = qf_count;
X qf_ptr = qfp;
X }
X breakcheck();
X }
X free(fmtstr);
X if (!ferror(fd))
X {
X if (qf_index == 0) /* no valid entry found */
X {
X qf_ptr = qf_start;
X qf_index = 1;
X qf_nonevalid = TRUE;
X }
X else
X qf_nonevalid = FALSE;
X fclose(fd);
X qf_jump(0, 0); /* display first error */
X return OK;
X }
X emsg(e_readerrf);
Xerror1:
X free(qfp);
Xerror2:
X fclose(fd);
X qf_free();


X return FAIL;
X}
X
X/*

X * jump to a quickfix line
X * if dir == FORWARD go "errornr" valid entries forward
X * if dir == BACKWARD go "errornr" valid entries backward
X * else if "errornr" is zero, redisplay the same line
X * else go to entry "errornr"
X */
X void
Xqf_jump(dir, errornr)
X int dir;
X int errornr;
X{
X linenr_t i;
X
X if (qf_count == 0)
X {
X emsg(e_quickfix);
X return;
X }
X
X if (dir == FORWARD) /* next valid entry */
X {
X while (errornr--)
X {
X do
X {
X if (qf_index == qf_count || qf_ptr->qf_next == NULL)
X break;
X ++qf_index;
X qf_ptr = qf_ptr->qf_next;
X } while (!qf_nonevalid && !qf_ptr->qf_valid);
X }
X }
X else if (dir == BACKWARD) /* previous valid entry */
X {
X while (errornr--)
X {
X do
X {
X if (qf_index == 1 || qf_ptr->qf_prev == NULL)
X break;
X --qf_index;
X qf_ptr = qf_ptr->qf_prev;
X } while (!qf_nonevalid && !qf_ptr->qf_valid);
X }
X }
X else if (errornr != 0) /* go to specified number */
X {
X while (errornr < qf_index && qf_index > 1 && qf_ptr->qf_prev != NULL)
X {
X --qf_index;
X qf_ptr = qf_ptr->qf_prev;
X }
X while (errornr > qf_index && qf_index < qf_count && qf_ptr->qf_next != NULL)
X {
X ++qf_index;
X qf_ptr = qf_ptr->qf_next;
X }
X }
X
X /*
X * If there is a file name,
X * read the wanted file if needed, and check autowrite etc.
X */
X if (qf_ptr->qf_fnum == 0 || buflist_getfile(qf_ptr->qf_fnum, (linenr_t)1, TRUE) == OK)
X {
X /*
X * Go to line with error, unless qf_lnum is 0.
X */
X i = qf_ptr->qf_lnum;
X if (i > 0)
X {
X if (i > curbuf->b_ml.ml_line_count)
X i = curbuf->b_ml.ml_line_count;
X curwin->w_cursor.lnum = i;
X }
X curwin->w_cursor.col = qf_ptr->qf_col;
X adjust_cursor();
X cursupdate();
X smsg((char_u *)"(%d of %d) %s%s: %s", qf_index, qf_count,
X qf_ptr->qf_cleared ? (char_u *)"(line deleted) " : (char_u *)"",
X qf_types(qf_ptr->qf_type, qf_ptr->qf_nr), qf_ptr->qf_text);
X }
X}
X
X/*
X * list all errors
X */
X void
Xqf_list()
X{
X struct qf_line *qfp;
X int i;
X
X if (qf_count == 0)
X {
X emsg(e_quickfix);
X return;
X }
X qfp = qf_start;
X gotocmdline(TRUE, NUL);
X for (i = 1; !got_int && i <= qf_count; ++i)
X {
X sprintf((char *)IObuff, "%2d line %3ld col %2d %s: %s",
X i,
X (long)qfp->qf_lnum,
X qfp->qf_col,
X qf_types(qfp->qf_type, qfp->qf_nr),
X qfp->qf_text);
X msg_outstr(IObuff);
X msg_outchar('\n');
X qfp = qfp->qf_next;


X flushbuf(); /* show one line at a time */

X breakcheck();
X }


X wait_return(FALSE);
X}
X
X/*

X * free the error list


X */
X static void

Xqf_free()
X{
X struct qf_line *qfp;
X
X while (qf_count)
X {
X qfp = qf_start->qf_next;
X free(qf_start->qf_text);
X free(qf_start);
X qf_start = qfp;
X --qf_count;
X }
X}
X
X/*
X * qf_mark_adjust: adjust marks
X */
X void
Xqf_mark_adjust(line1, line2, inc)


X linenr_t line1;
X linenr_t line2;

X long inc;


X{
X register int i;

X struct qf_line *qfp;
X
X if (qf_count)
X for (i = 0, qfp = qf_start; i < qf_count; ++i, qfp = qfp->qf_next)
X if (qfp->qf_fnum == curbuf->b_fnum &&
X qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2)
X {
X if (inc == MAXLNUM)
X qfp->qf_cleared = TRUE;
X else
X qfp->qf_lnum += inc;
X }
X}
X
X/*
X * Make a nice message out of the error character and the error number:
X * char number message
X * e or E 0 " Error"
X * w or W 0 "Warning"
X * other 0 ""
X * w or W n "Warning n"
X * other n " Error n"


X */
X static char_u *

Xqf_types(c, nr)
X int c, nr;
X{
X static char_u buf[20];
X char_u *p1;
X
X p1 = (char_u *)" Error";
X if (c == 'W' || c == 'w')
X p1 = (char_u *)"Warning";
X else if (nr <= 0 && c != 'E' && c != 'e')
X p1 = (char_u *)"";
X
X if (nr <= 0)
X return p1;
X
X sprintf((char *)buf, "%s %3d", p1, nr);


X return buf;
X}
END_OF_FILE

if test 9335 -ne `wc -c <'vim/src/quickfix.c'`; then
echo shar: \"'vim/src/quickfix.c'\" unpacked with wrong size!
fi
# end of 'vim/src/quickfix.c'
fi
if test -f 'vim/src/vim.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/vim.h'\"
else
echo shar: Extracting \"'vim/src/vim.h'\" \(8836 characters\)
sed "s/^X//" >'vim/src/vim.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X#if defined(SYSV_UNIX) || defined(BSD_UNIX)
X# ifndef UNIX
X# define UNIX
X# endif
X#endif
X
X/*
X * Shorhand for unsinged variables. Many systems, but not all, have u_char
X * already defined, so we use char_u to avoid trouble.


X */
Xtypedef unsigned char char_u;

Xtypedef unsigned short short_u;
Xtypedef unsigned int int_u;
Xtypedef unsigned long long_u;
X
X#include <stdio.h>
X#include <ctype.h>
X
X#if !defined(DOMAIN) && !defined(NOLIMITS)
X# include <limits.h> /* For INT_MAX, remove this if it does not exist */
X#endif
X
X#ifdef BSD_UNIX
X# ifndef apollo
X# include <strings.h>
X# endif
X# ifdef __STDC__
X# include <string.h>
X# endif
X#else
X# include <string.h>
X#endif
X
X#include "ascii.h"
X#include "keymap.h"
X#include "term.h"
X#include "macros.h"


X
X#ifdef LATTICE
X# include <sys/types.h>

X# include <sys/stat.h>
X#else
X# ifdef _DCC
X# include <sys/stat.h>


X# else
X# ifdef MSDOS

X# include <sys\stat.h>
X# else
X# ifdef UNIX
X# ifndef linux
X# define volatile /* needed for gcc */
X# define signed /* needed for gcc */
X# endif
X# include <sys/types.h>
X# include <sys/stat.h>
X# else
X# include <stat.h>
X# endif


X# endif
X# endif
X#endif
X

X#if !defined(DOMAIN) && !defined(NOSTDLIB)
X# include <stdlib.h>
X#endif
X
X#ifdef AMIGA
X/*
X * arpbase.h must be included before functions.h
X */
X# include <libraries/arpbase.h>
X
X/*
X * This won't be needed if you have a version of Lattice 4.01 without broken
X * break signal handling.
X */
X# include <signal.h>
X#endif
X
X#ifndef AMIGA
X/*
X * For the Amiga we use a version of getenv that does local variables under 2.0
X */
X# define vimgetenv(x) (char_u *)getenv((char *)x)
X#endif
X
X#ifdef AZTEC_C
X# include <functions.h>
X# define __ARGS(x) x
X# define __PARMS(x) x
X#endif
X
X#ifdef SASC
X# include <clib/exec_protos.h>
X# define __ARGS(x) x
X# define __PARMS(x) x
X#endif
X
X#ifdef _DCC
X# include <functions.h>
X# define __ARGS(x) x
X# define __PARMS(x) x
X#endif
X
X#ifdef __TURBOC__
X# define __ARGS(x) x
X#endif
X
X#if defined(MSDOS) && !defined(NT)
X# include <dos.h>
X# include <dir.h>
X#endif
X
X#ifdef SOLARIS
X# include <stdlib.h>
X#endif
X
X#ifdef UNIX
X# include <unistd.h> /* any unix that doesn't have it? */
X# ifdef SCO
X# undef M_XENIX
X# include <sys/ndir.h> /* for MAXNAMLEN */
X# else
X# if defined(SOLARIS) || defined(AIX) || defined(ARCHIE)
X# include <dirent.h> /* for MAXNAMLEN */
X# else
X# include <sys/dir.h> /* for MAXNAMLEN */
X# endif
X# endif
X# ifdef USL
X# define MAXNAMLEN DIRSIZ
X# endif
X# if defined(UFS_MAXNAMLEN) && !defined(MAXNAMLEN)
X# define MAXNAMLEN UFS_MAXNAMLEN /* for dynix/ptx */
X# endif
X# if defined(NAME_MAX) && !defined(MAXNAMLEN)
X# define MAXNAMLEN NAME_MAX /* for Linux before .99p3 */
X# endif
X# if !defined(MAXNAMLEN)
X# define MAXNAMLEN 512 /* for all other Unix */
X# endif
X#endif
X
X#ifdef UNICOS /* would make sense for other systems too */
X# include <errno.h>
X#endif
X
X#if defined(__STDC__) || defined(__GNUC__)
X# ifndef __ARGS
X# define __ARGS(x) x
X# endif /* __ARGS */
X# if defined(_SEQUENT_)
X# include "ptx_stdlib.h"
X# endif
X# if defined(sun) && !defined(SOLARIS)
X# include "sun_stdlib.h"
X# endif
X#else /*__STDC__*/
X# if defined(_SEQUENT_) && !defined(_STDLIB_H_)
X extern char *getenv();
X extern void *malloc();
X# endif
X#endif /* __STDC__ */
X
X#ifndef __ARGS
X#define __ARGS(x) ()
X#endif
X#ifndef __PARMS
X#define __PARMS(x) ()
X#endif
X
X/*
X * for systems that do not allow free(NULL)
X */
X#ifdef NO_FREE_NULL
X# define free(x) nofreeNULL(x)
X extern void nofreeNULL __ARGS((void *));
X#endif
X
X/*
X * fnamecmp() is used to compare filenames.
X * On some systems case in a filename does not matter, on others it does.
X * (this does not account for maximum name lengths, thus it is not 100% accurate!)


X */
X#if defined(AMIGA) || defined(MSDOS)

X# define fnamecmp(x, y) stricmp((char *)(x), (char *)(y))
X#else
X# define fnamecmp(x, y) strcmp((char *)(x), (char *)(y))
X#endif
X
X/*
X * flags for updateScreen()
X * The higher the value, the higher the priority
X */
X#define VALID 10 /* buffer not changed */
X#define INVERTED 20 /* redisplay inverted part */
X#define VALID_TO_CURSCHAR 30 /* buffer at/below cursor changed */
X#define NOT_VALID 40 /* buffer changed */
X#define CURSUPD 50 /* buffer changed, update cursor first */
X#define CLEAR 60 /* screen messed up, clear it */
X
X/* values for State */
X/*
X * The lowest three bits are used to distinguish normal/cmdline/insert+replace
X * mode. This is used for mapping.
X */
X#define NORMAL 0x01
X#define NORMAL_BUSY 0x11 /* busy interpreting a command */
X#define CMDLINE 0x02
X#define INSERT 0x04
X#define REPLACE 0x24 /* replace mode */
X#define HELP 0x30 /* displaying help */
X#define NOMAPPING 0x40 /* no :mapping mode for vgetc() */
X#define ONLYKEY 0x70 /* like NOMAPPING, but keys allowed */
X#define HITRETURN 0x51 /* waiting for a return */
X#define SETWSIZE 0x60 /* window size has changed */
X#define ABBREV 0x80 /* abbreviation instead of mapping */
X
X/* directions */
X#define FORWARD 1
X#define BACKWARD -1
X
X/* return values for functions */
X#define OK 1
X#define FAIL 0
X
X/* for GetChars */
X#define T_PEEK 1 /* do not wait at all */
X#define T_WAIT 2 /* wait for a short time */
X#define T_BLOCK 3 /* wait forever */
X
X#define VISUALLINE MAXCOL /* Visual is linewise */
X
X#ifdef WEBB_COMPLETE
X/*
X * values for command line completion
X */
X#define CONTEXT_UNKNOWN -2
X#define EXPAND_UNSUCCESSFUL -1
X#define EXPAND_NOTHING 0
X#define EXPAND_COMMANDS 1
X#define EXPAND_FILES 2
X#define EXPAND_DIRECTORIES 3
X#define EXPAND_SETTINGS 4
X#define EXPAND_BOOL_SETTINGS 5
X#define EXPAND_TAGS 6
X#endif /* WEBB_COMPLETE */
X/*
X * Boolean constants
X */
X#ifndef TRUE
X#define FALSE (0) /* note: this is an int, not a long! */
X#define TRUE (1)
X#endif
X
X/*
X * Maximum and minimum screen size (height is unlimited)
X */
X#ifdef UNIX
X# define MAX_COLUMNS 1024L
X#else
X# define MAX_COLUMNS 255L
X#endif
X#define MIN_COLUMNS 5
X#define MIN_ROWS 1
X#define STATUS_HEIGHT 1 /* height of a status line under a window */
X
X/*
X * Buffer sizes
X */
X#ifdef UNIX /* Unix has plenty of memory */
X# define CMDBUFFSIZE 1024 /* size of the command processing buffer */
X#else
X# define CMDBUFFSIZE 256 /* size of the command processing buffer */
X#endif
X
X#define LSIZE 512 /* max. size of a line in the tags file */
X
X#define IOSIZE (1024+1) /* file i/o and sprintf buffer size */
X
X#define TERMBUFSIZE 1024
X
X#ifdef linux
X# define TBUFSZ 2048 /* buffer size for termcap entry */
X#else
X# define TBUFSZ 1024 /* buffer size for termcap entry */
X#endif
X
X/*
X * maximum length of a file name path
X */
X#ifdef UNIX
X# define MAXPATHL 1024 /* Unix has long paths and plenty of memory */
X#else
X# define MAXPATHL 128 /* not too long to put name on stack */
X#endif
X
X#ifdef MSDOS
X# define WRITEBIN "wb" /* no CR-LF translation */
X# define READBIN "rb"
X# define APPENDBIN "ab"
X#else
X# define WRITEBIN "w"
X# define READBIN "r"
X# define APPENDBIN "a"
X#endif
X
X#define CHANGED set_Changed()
X#define UNCHANGED(buf) unset_Changed(buf)
X
X/*
X * defines to avoid typecasts from (char_u *) to (char *) and back
X */
X#define STRCHR(s, c) (char_u *)strchr((char *)(s), c)
X#define STRRCHR(s, c) (char_u *)strrchr((char *)(s), c)
X#define STRLEN(s) strlen((char *)(s))
X#define STRCPY(d, s) strcpy((char *)(d), (char *)(s))
X#define STRNCPY(d, s, n) strncpy((char *)(d), (char *)(s), n)
X#define STRCMP(d, s) strcmp((char *)(d), (char *)(s))
X#define STRNCMP(d, s, n) strncmp((char *)(d), (char *)(s), n)
X#define STRCAT(d, s) strcat((char *)(d), (char *)(s))
X
X#define MSG(s) msg((char_u *)(s))
X#define EMSG(s) emsg((char_u *)(s))
X#define EMSG2(s, p) emsg2((char_u *)(s), (char_u *)(p))
X#define OUTSTR(s) outstr((char_u *)(s))
X#define OUTSTRN(s) outstrn((char_u *)(s))
X
Xtypedef long linenr_t; /* line number type */
Xtypedef unsigned colnr_t; /* column number type */
X
X#define MAXLNUM (0x7fffffff) /* maximum (invalid) line number */
X#ifdef INT_MAX
X# define MAXCOL INT_MAX /* maximum column number */
X#else
X# define MAXCOL 32767 /* maximum column number, 15 bits */
X#endif
X
X/*
X * Some versions of isspace() handle Meta characters like a space!
X * This define fixes that.
X */
X#ifdef VIM_ISSPACE
X# ifdef isspace
X# undef isspace
X# endif /* isspace */
X# define isspace(x) (((x) >= 9 && (x) <= 13) || ((x) == 32))
X#endif /* VIM_ISSPACE */
X
X/*
X * iswhite() is used for "^" and the like
X */
X#define iswhite(x) ((x) == ' ' || (x) == '\t')
X
X#include "structs.h" /* file that defines many structures */
X
X#ifdef AMIGA
X# include "amiga.h"
X#endif
X
X#ifdef ARCHIE
X# include "archie.h"
X#endif
X
X#ifdef MSDOS
X# include "msdos.h"
X#endif
X
X#ifdef UNIX
X# include "unix.h"
X#endif
END_OF_FILE
if test 8836 -ne `wc -c <'vim/src/vim.h'`; then
echo shar: \"'vim/src/vim.h'\" unpacked with wrong size!
fi
# end of 'vim/src/vim.h'
fi
echo shar: End of archive 23 \(of 26\).
cp /dev/null ark23isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:04:00 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 43
Archive-name: vim/part24

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/doc/Amiga.doc vim/doc/msdos.doc vim/src/alloc.c
# vim/src/arp_proto.h vim/src/cmdtab.tab vim/src/help.c
# vim/src/linefunc.c vim/src/makefile.archie vim/src/makefile.bcc
# vim/src/makefile.dice vim/src/param.h vim/src/unix.h vim/termcap
# Wrapped by kent@sparky on Mon Aug 15 21:44:15 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 24 (of 26)."'
if test -f 'vim/doc/Amiga.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/Amiga.doc'\"
else
echo shar: Extracting \"'vim/doc/Amiga.doc'\" \(2310 characters\)
sed "s/^X//" >'vim/doc/Amiga.doc' <<'END_OF_FILE'
XThis file contains the particularities for the Amiga version of Vim.
X
XInstallation on the Amiga:
X- Assign "vim:" to the directory where the vim.hlp file is (for the help
X command).
X- With DOS 1.3 or earlier: Put "arp.library" in "libs:". Make sure that
X newcli and run are in "c:" (for executing external commands).
X- Put a shell that accepts a command with "-c" (e.g. "Csh" from Fish disk
X 624) in "c:" or in any other directory that is in your search path (for
X executing external commands).
X
XIf you have sufficient memory you can avoid startup delays by making Vim and
Xcsh resident with the command "rez csh vim". You will have to put
X"rezlib.library" in your "libs:" directory. Under 2.0 you will need rez
Xversion 0.5.
X
XIf you do not use digraphs, you can save some memory by recompiling without
Xthe DIGRAPHS option. If you want to use Vim with other terminals you can
Xrecompile with the TERMCAP option. Vim compiles with Manx 5.x and SAS 6.x.
XSee the makefiles.
X
XIf you want to use different colors set the termcap codes:
X t_ti (for inverted text)
X t_tb (for bold text)
X t_tp (for normal text after t_ti and t_tb)
X t_so (for standout mode)
X t_se (for normal text after t_so)
X
XStandard ANSI escape sequences are used. The codes are:
X30 grey char 40 grey cell >0 grey background 0 all attributes off
X31 black char 41 black cell >1 black background 1 boldface
X32 white char 42 white cell >2 white background 2 faint
X33 blue char 43 blue cell >3 blue background 3 italic
X34 grey char 44 grey cell >4 grey background 4 underscore
X35 black char 45 black cell >5 black background 7 reverse video
X36 white char 46 white cell >6 white background 8 invisible
X37 blue char 47 blue cell >7 blue background
X
XThe codes with '>' must be the last. The cell and background color should be
Xthe same. The codes can be combined by separating them with a semicolon. For
Xexample to get white text on a blue background:
X :set t_tp=^V<ESC>[0;32;43;>3m
X
XWhen using multiple commands with a filter command, e.g.
X :r! echo this; echo that
XOnly the output of the last command is used. To fix this you have to group the
Xcommands. This depends on the shell you use (that is why it is not done
Xautomatically in Vim). Examples:
X :r! (echo this; echo that)
X :r! {echo this; echo that}
END_OF_FILE
if test 2310 -ne `wc -c <'vim/doc/Amiga.doc'`; then
echo shar: \"'vim/doc/Amiga.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/Amiga.doc'
fi
if test -f 'vim/doc/msdos.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/msdos.doc'\"
else
echo shar: Extracting \"'vim/doc/msdos.doc'\" \(7386 characters\)
sed "s/^X//" >'vim/doc/msdos.doc' <<'END_OF_FILE'
XThis file contains the particularities for the MSDOS version of Vim.
X
XKnown problem: When using smartdrive with write-behind caching, it is
Xpossible that Vim will try to create a swap file on a read-only file system
X(e.g. write protected floppy). You will then be given the message
X "A serious disk error has occurred .., Retry (r)? "
XThere is nothing you can do but unprotecting the floppy or switch off the
Xcomputer. Even CTRL-ALT-DEL will not get you out of this. This is really a
Xproblem of smartdrive, not Vim. Smartdrive works fine otherwise. If this
Xbothers you don't use the write-behind caching.
X
XThe default output method for the screen is to use bios calls. This will work
Xright away on most systems. You do not need ansi.sys. You can use ":mode" to
Xset the current screen mode. See reference.doc, section 20.3.
X
XYou can set the color used in vim with five termcap options:
X
X ":set t_ti=^V^[\|xxm" start of invert mode
X ":set t_tb=^V^[\|xxm" start of bold mode
X ":set t_tp=^V^[\|xxm" back to normal text
X
X ":set t_so=^V^[\|xxm" start of standout mode
X ":set t_se=^V^[\|xxm" back to normal text
X
XWhich of the three modes is used for which action depends on the 'highlight'
X('hl') option. See reference.doc.
X
X^V is CTRL-V
X^[ is ESC
Xxx must be replaced by a decimal code: The foreground color number and
X background color number added together:
X
XCOLOR FOREGROUND BACKGROUND
Xblack 0 0
Xblue 1 16
Xgreen 2 32
Xcyan 3 48
Xred 4 64
Xmagenta 5 80
Xbrown 6 96
Xlighgray 7 112
Xdarkgray 8
Xlightblue 9
Xlightgreen 10
Xlighcyan 11
Xlightred 12
Xlighmagenta 13
Xyellow 14
Xwhite 15
Xblink 128
X
XWhen you use 0, the color is reset to the one used when you started Vim. This
Xis the default for t_tp. The default for t_ti is black on grey, 0 + 112 = 112.
XThe default for t_tb is white on cyan, 15 + 48 = 63. The default for t_so is
Xwhite on blue, 15 + 16 = 31. These colors where choosen, because the also look
Xgood when using an inverted display. But you can change them as you like.
X
XThe termcap codes that are translated into bios calls are:
X ESC |J clear screen
X ESC |K clear to end of line
X ESC |L insert line
X ESC |M delete line
X ESC |row;colH position cursor
X ESC |attrm set character attribute
X
XIf you set these with the ":set" command, don't forget to put a backslash
Xbefore the '|', otherwise it will be recognized as the end of the command.
X
XIf you want to use another output method (e.g. when using a terminal on a COM
Xport), set the terminal name to "pcansi". You can change the termcap options
Xwhen needed (see chapter 20 of reference.doc). Note that the normal IBM
Xansi.sys does not support all the codes of the builtin pcansi terminal. If
Xyou use ansi.sys you will need to delete the termcap entries t_il and t_dl
Xwith
X ":set t_il= t_dl=".
XOtherwise the screen will not be updated correctly. It is better to use
Xnansi.sys, nnansi.sys or the like instead of ansi.sys.
X
XIf you want to use Vim on a terminal connected to a COM: port, reset the
X'bioskey' option. Otherwise the commands will be read from the PC keyboard.
XCTRL-C and CTRL-P may not work correctly with 'bioskey' reset.
X
XIf the "tx" (textmode) option is set (which is the default), Vim will accept a
Xsingle <LF> or a <CR><LF> pair for end-of-line. When writing a file Vim will
Xuse <CR><LF>. Thus if you edit a file and write it, <LF> is replaced with
X<CR><LF>. If the "tx" option is not set the single <LF> will be used for
Xend-of-line. A <CR> will be shown as ^M. You can use Vim to replace <LF> by
X<CR><LF> by reading in any mode and writing in text mode. You can use Vim to
Xreplace <CR><LF> by <LF> by reading in text mode and writing in non-text
Xmode. 'textmode' is set automatically when 'textauto' is on (which is the
Xdefault), so you don't really have to worry about what you are doing.
X
XIf you want to edit a script file or a binary file you should reset the
X'textmode' and 'textauto' options before loading the file. Script files
Xcontain single <LF> characters which would be replaced by <CR><LF>. You can
Xdo this by starting Vim with the "-b" (binary) option.
X
XThe default help filename is "$VIM\vim.hlp". If the environment variable $VIM
Xis not defined or the file is not found, the DOS search path is used to
Xsearch for the file "vim.hlp". If you do not want to put "vim.hlp" in your
Xsearch path, use the command ":set helpfile=pathname" to tell Vim where the
Xhelp file is.
X
XThe ":cd" command recognizes the drive specifier and changes the current
Xdrive. Use ":cd c:" to make drive C the active drive. Use ":cd d:\dos" to go
Xto the directory "dos" in the root of drive D.
X
XThe files "_vimrc" and "_exrc" are used instead of ".vimrc" and ".exrc".
XThe files "$VIM\_vimrc" and "$VIM\_exrc" are used instead of "s:.vimrc" and
X"s:.exrc". To use the file "c:\_vimrc" use the command "set vim=c:".
X
XUse CTRL-break instead of CTRL-C to interrupt searches. The CTRL-C is not
Xdetected until a key is read.
X
XUse CTRL-arrow-left and CTRL-arrow-right instead of SHIFT-arrow-left and
XSHIFT-arrow-right. The arrow-up and arrow-down cannot be used with SHIFT or
XCTRL.
X
XTemporary files (for filtering) are put in the current directory.
X
XThe default for the sh (shell) option is "command". If COMSPEC is defined it
Xis used instead. External commands are started with "command /c
X<command_name>". Typing CTRL-Z starts a new command shell. Return to Vim with
X"exit".
X
XMS-DOS allows for only one filename extention. Therefore, in the original
Xfilename the '.' is replaced by a '_', the name is truncated to 8 characters
Xand the new extention ".vim" or ".bak" is appended. Two examples: "test.c"
Xbecomes "test_c.bak", "ditiseen.tst" becomes "ditiseen.bak". The 'shortname'
Xoption is not available.
X
XThe MS-DOS binary was compiled with Borland-C++ version 3.1, using
Xmakefile.bcc. Other compilers should also work. Use makefile.dos for Turbo-C
X2.0. Use makefile.bcc for other Borland compilers, also Turbo-C++ 3.0 (with
Xsmall changes). If you get all kinds of strange error messages when compiling,
Xyou have to add <CR> characters at the end of each line. This can be done with
Xthe addcr program: "make addcr". This will compile addcr.c to addcr.exe and
Xexecute the addcr.bat file. Sometimes this fails. Then execute the addcr.bat
Xfile from the DOS prompt.
X
XThe "spawno" library by Ralf Brown was used in order to free memory when Vim
Xstarts a shell or other external command. Only about 200 bytes are taken from
Xconventional memory. When recompiling get the spawno library from Simtel,
Xdirectory "msdos/c". It is called something like "spwno413.zip". Or remove the
Xlibrary from the makefile.
X
XA swap file is used to store most of the text. You should be able to edit very
Xlarge files. However, memory is used for undo and other things. If you delete
Xa lot of text you can still run out of memory.
X
XIf Vim gives an "Out of memory" warning you should stop editing. Result of
Xfurther editing actions is unpredictable. Setting 'undolevels' to 0 saves some
Xmemory. Running the maze macros on a big maze is guaranteed to run out of
Xmemory, because each change is remembered for undo. In this case set
X'undolevels' to a negative number. This will switch off undo completely. In a
Xfuture release extended memory will be used to avoid these problems.
X
XThe *.info files are for the Amiga. You don't need them with MSDOS.
END_OF_FILE
if test 7386 -ne `wc -c <'vim/doc/msdos.doc'`; then
echo shar: \"'vim/doc/msdos.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/msdos.doc'
fi
if test -f 'vim/src/alloc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/alloc.c'\"
else
echo shar: Extracting \"'vim/src/alloc.c'\" \(4132 characters\)
sed "s/^X//" >'vim/src/alloc.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * alloc.c
X *
X * This file contains various routines dealing with allocation and
X * deallocation of memory. And some funcions for copying text.


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X
X/*

X * Some memory is reserved for error messages and for being able to
X * call mf_release_all(), which needs some memory for mf_trans_add().
X */
X#define KEEP_ROOM 8192L
X
X/*
X * Note: if unsinged is 16 bits we can only allocate up to 64K with alloc().
X * Use lalloc for larger blocks.


X */
X char_u *

Xalloc(size)
X unsigned size;
X{
X return (lalloc((long_u)size, TRUE));


X}
X
X char_u *

Xlalloc(size, message)
X long_u size;
X int message;
X{
X register char_u *p; /* pointer to new storage space */
X static int releasing = FALSE; /* don't do mf_release_all() recursive */
X int try_again;
X
X#ifdef MSDOS
X if (size >= 0xfff0) /* in MSDOS we can't deal with >64K blocks */
X p = NULL;
X else
X#endif
X
X /*
X * If out of memory, try to release some memfile blocks.
X * If some blocks are released call malloc again.
X */


X for (;;)
X {

X if ((p = (char_u *)malloc(size)) != NULL)
X {
X if (mch_avail_mem(TRUE) < KEEP_ROOM && !releasing)
X { /* System is low... no go! */
X free((char *)p);
X p = NULL;
X }
X }
X /*
X * Remember that mf_release_all() is being called to avoid an endless loop,
X * because mf_release_all() may call alloc() recursively.
X */
X if (p != NULL || releasing)
X break;
X releasing = TRUE;
X try_again = mf_release_all();
X releasing = FALSE;
X if (!try_again)
X break;
X }
X
X /*
X * Avoid repeating the error message many times (they take 1 second each).
X * Did_outofmem_msg is reset when a character is read.
X */
X if (message && p == NULL && !did_outofmem_msg)
X {
X emsg(e_outofmem);
X did_outofmem_msg = TRUE;
X }
X return (p);
X}
X
X/*
X * copy a string into newly allocated memory


X */
X char_u *

Xstrsave(string)
X char_u *string;


X{
X char_u *p;
X

X p = alloc((unsigned) (STRLEN(string) + 1));


X if (p != NULL)

X STRCPY(p, string);
X return p;


X}
X
X char_u *

Xstrnsave(string, len)
X char_u *string;
X int len;
X{
X char_u *p;
X
X p = alloc((unsigned) (len + 1));


X if (p != NULL)
X {

X STRNCPY(p, string, (size_t)len);
X p[len] = NUL;
X }
X return p;
X}
X
X/*
X * copy a number of spaces
X */
X void
Xcopy_spaces(ptr, count)
X char_u *ptr;
X size_t count;
X{
X register size_t i = count;
X register char_u *p = ptr;
X
X while (i--)
X *p++ = ' ';
X}
X
X/*
X * delete spaces at the end of the string
X */
X void
Xdel_spaces(ptr)
X char_u *ptr;


X{
X char_u *q;
X

X q = ptr + STRLEN(ptr);
X while (--q > ptr && isspace(q[0]) && q[-1] != '\\' && q[-1] != Ctrl('V'))
X *q = NUL;
X}
X
X#ifdef NO_FREE_NULL
X#undef free
X/*
X * replacement for free() that cannot handle NULL pointers
X */
X void
XnofreeNULL(x)
X void *x;
X{
X if (x != NULL)
X free(x);
X}
X#endif
X
X#ifdef BSD_UNIX
X char *
Xbsdmemset(ptr, c, size)
X char *ptr;
X int c;
X long size;
X{
X register char *p = ptr;
X
X while (size-- > 0)
X *p++ = c;
X return ptr;
X}
X#endif
X
X#ifdef MEMMOVE
X/*
X * Version of memmove that handles overlapping source and destination.
X * For systems that don't have a function that is guaranteed to do that (SYSV).
X */
X void *
X#ifdef __sgi
Xmemmove(desti, source, len)
X void *source, *desti;
X size_t len;
X#else
Xmemmove(desti, source, len)
X void *source, *desti;
X int len;
X#endif
X{
X char *src = (char *)source;
X char *dst = (char *)desti;
X
X if (dst > src && dst < src + len) /* overlap, copy backwards */
X {
X src +=len;
X dst +=len;
X while (len-- > 0)


X *--dst = *--src;
X }

X else /* copy forwards */
X while (len-- > 0)
X *dst++ = *src++;
X return desti;
X}
X#endif
X
X/*
X * compare two strings, ignoring case
X * return 0 for match, 1 for difference
X */
X int
Xvim_strnicmp(s1, s2, len)
X char_u *s1;
X char_u *s2;
X size_t len;


X{
X while (len)
X {

X if (TO_UPPER(*s1) != TO_UPPER(*s2))
X return 1; /* this character different */
X if (*s1 == NUL)
X return 0; /* strings match until NUL */
X ++s1;
X ++s2;
X --len;
X }
X return 0; /* strings match */
X}
END_OF_FILE
if test 4132 -ne `wc -c <'vim/src/alloc.c'`; then
echo shar: \"'vim/src/alloc.c'\" unpacked with wrong size!
fi
# end of 'vim/src/alloc.c'
fi
if test -f 'vim/src/arp_proto.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/arp_proto.h'\"
else
echo shar: Extracting \"'vim/src/arp_proto.h'\" \(6655 characters\)
sed "s/^X//" >'vim/src/arp_proto.h' <<'END_OF_FILE'
X#ifndef PROTO_ARP_H
X#define PROTO_ARP_H 1
X
X/*
X ************************************************************************
X * The arp copies of the dos.library calls... *


X ************************************************************************
X */
X

X/* Only include these if you can use ARP.library without dos.library... */
X#ifdef DO_ARP_COPIES
X#pragma amicall(ArpBase, 0x1E, Open(d1, d2))
X#pragma amicall(ArpBase, 0x24, Close(d1))
X#pragma amicall(ArpBase, 0x2A, Read(d1, d2, d3))
X#pragma amicall(ArpBase, 0x30, Write(d1, d2, d3))
X#pragma amicall(ArpBase, 0x36, Input())
X#pragma amicall(ArpBase, 0x3C, Output())
X#pragma amicall(ArpBase, 0x42, Seek(d1, d2, d3))
X#pragma amicall(ArpBase, 0x48, DeleteFile(d1))
X#pragma amicall(ArpBase, 0x4E, Rename(d1, d2))
X#pragma amicall(ArpBase, 0x54, Lock(d1, d2))
X#pragma amicall(ArpBase, 0x5A, UnLock(d1))
X#pragma amicall(ArpBase, 0x60, DupLock(d1))
X#pragma amicall(ArpBase, 0x66, Examine(d1, d2))
X#pragma amicall(ArpBase, 0x6C, ExNext(d1, d2))
X#pragma amicall(ArpBase, 0x72, Info(d1, d2))
X#pragma amicall(ArpBase, 0x78, CreateDir(d1))
X#pragma amicall(ArpBase, 0x7E, CurrentDir(d1))
X#pragma amicall(ArpBase, 0x84, IoErr())
X#pragma amicall(ArpBase, 0x8A, CreateProc(d1, d2, d3, d4))
X#pragma amicall(ArpBase, 0x90, Exit(d1))
X#pragma amicall(ArpBase, 0x96, LoadSeg(d1))
X#pragma amicall(ArpBase, 0x9C, UnLoadSeg(d1))
X#pragma amicall(ArpBase, 0xAE, DeviceProc(d1))
X#pragma amicall(ArpBase, 0xB4, SetComment(d1, d2))
X#pragma amicall(ArpBase, 0xBA, SetProtection(d1, d2))
X#pragma amicall(ArpBase, 0xC0, DateStamp(d1))
X#pragma amicall(ArpBase, 0xC6, Delay(d1))
X#pragma amicall(ArpBase, 0xCC, WaitForChar(d1, d2))
X#pragma amicall(ArpBase, 0xD2, ParentDir(d1))
X#pragma amicall(ArpBase, 0xD8, IsInteractive(d1))
X#pragma amicall(ArpBase, 0xDE, Execute(d1, d2, d3))


X#endif
X
X/*
X ************************************************************************

X * Stuff only in arp.library *
X ************************************************************************
X */
X/* amicall(ArpBase, 0x0E4, Printf(a0, a1)) This does not work without glue */
X/* amicall(ArpBase, 0x0EA, FPrintf(d0, a0, a1)) This does not work without glue */
X#pragma amicall(ArpBase, 0x0F0, Puts(a1))
X#pragma amicall(ArpBase, 0x0F6, Readline(a0))
X#pragma amicall(ArpBase, 0x0FC, GADS(a0, d0, a1, a2, a3))
X#pragma amicall(ArpBase, 0x102, Atol(a0))
X#pragma amicall(ArpBase, 0x108, EscapeString(a0))
X#pragma amicall(ArpBase, 0x10E, CheckAbort(a1))
X#pragma amicall(ArpBase, 0x114, CheckBreak(d1, a1))
X#pragma amicall(ArpBase, 0x11A, Getenv(a0, a1, d0))
X#pragma amicall(ArpBase, 0x120, Setenv(a0, a1))
X#pragma amicall(ArpBase, 0x126, FileRequest(a0))
X#pragma amicall(ArpBase, 0x12C, CloseWindowSafely(a0, a1))
X#pragma amicall(ArpBase, 0x132, CreatePort(a0, d0))
X#pragma amicall(ArpBase, 0x138, DeletePort(a1))
X#pragma amicall(ArpBase, 0x13E, SendPacket(d0, a0, a1))
X#pragma amicall(ArpBase, 0x144, InitStdPacket(d0, a0, a1, a2))
X#pragma amicall(ArpBase, 0x14A, PathName(d0, a0, d1))
X#pragma amicall(ArpBase, 0x150, Assign(a0, a1))
X#pragma amicall(ArpBase, 0x156, DosAllocMem(d0))
X#pragma amicall(ArpBase, 0x15C, DosFreeMem(a1))
X#pragma amicall(ArpBase, 0x162, BtoCStr(a0, d0, d1))
X#pragma amicall(ArpBase, 0x168, CtoBStr(a0, d0, d1))
X#pragma amicall(ArpBase, 0x16E, GetDevInfo(a2))
X#pragma amicall(ArpBase, 0x174, FreeTaskResList())
X#pragma amicall(ArpBase, 0x17A, ArpExit(d0, d2))
X#pragma amicall(ArpBase, 0x180, ArpAlloc(d0))
X/* amicall(ArpBase, 0x186, ArpAllocMem(d0, d1)) Secondary result - IoErr() */
X/* amicall(ArpBase, 0x18C, ArpOpen(d1, d2)) Secondary result - IoErr() */
X/* amicall(ArpBase, 0x192, ArpDupLock(d1)) Secondary result - IoErr() */
X/* amicall(ArpBase, 0x198, ArpLock(d1, d2)) Secondary result - IoErr() */
X/* amicall(ArpBase, 0x19E, RListAlloc(a0, d0)) Secondary result - IoErr() */
X#pragma amicall(ArpBase, 0x1A4, FindCLI(d0))
X#pragma amicall(ArpBase, 0x1AA, QSort(a0, d0, d1, a1))
X
X#pragma amicall(ArpBase, 0x1B0, PatternMatch(a0, a1))
X#pragma amicall(ArpBase, 0x1B6, FindFirst(d0, a0))
X#pragma amicall(ArpBase, 0x1BC, FindNext(a0))
X#pragma amicall(ArpBase, 0x1C2, FreeAnchorChain(a0))
X
X#pragma amicall(ArpBase, 0x1C8, CompareLock(d0, d1))
X
X#pragma amicall(ArpBase, 0x1CE, FindTaskResList())
X#pragma amicall(ArpBase, 0x1D4, CreateTaskResList())
X#pragma amicall(ArpBase, 0x1DA, FreeResList(a1))
X#pragma amicall(ArpBase, 0x1E0, FreeTrackedItem(a1))
X/* amicall(ArpBase, 0x1E6, GetTracker()) Stores the ID in the tracker */
X
X#pragma amicall(ArpBase, 0x1EC, GetAccess(a1))
X#pragma amicall(ArpBase, 0x1F2, FreeAccess(a1))
X
X#pragma amicall(ArpBase, 0x1F8, FreeDAList(a1))
X#pragma amicall(ArpBase, 0x1FE, AddDANode(a0, a1, d0, d1))
X#pragma amicall(ArpBase, 0x204, AddDADevs(a0, d0))
X
X#pragma amicall(ArpBase, 0x20A, Strcmp(a0, a1))
X#pragma amicall(ArpBase, 0x210, Strncmp(a0, a1, d0))
X#pragma amicall(ArpBase, 0x216, Toupper(d0))
X#pragma amicall(ArpBase, 0x21C, SyncRun(a0, a1, d0, d1))
X
X/*
X ************************************************************************
X * Added V32 of arp.library *
X * Note that SpawnShell is ASyncRun but was added at V39 of arp... *
X ************************************************************************
X */
X#pragma amicall(ArpBase, 0x222, ASyncRun(a0, a1, a2))
X#pragma amicall(ArpBase, 0x222, SpawnShell(a0, a1, a2))
X#pragma amicall(ArpBase, 0x228, LoadPrg(d1))
X#pragma amicall(ArpBase, 0x22E, PreParse(a0, a1))


X
X/*
X ************************************************************************
X * Added V33 of arp.library *
X ************************************************************************
X */

X#pragma amicall(ArpBase, 0x234, StamptoStr(a0))
X#pragma amicall(ArpBase, 0x23A, StrtoStamp(a0))
X
X#pragma amicall(ArpBase, 0x240, ObtainResidentPrg(a0))
X#pragma amicall(ArpBase, 0x246, AddResidentPrg(d1, a0))
X#pragma amicall(ArpBase, 0x24C, RemResidentPrg(a0))
X#pragma amicall(ArpBase, 0x252, UnLoadPrg(d1))
X#pragma amicall(ArpBase, 0x258, LMult(d0, d1))
X#pragma amicall(ArpBase, 0x25E, LDiv(d0, d1))
X#pragma amicall(ArpBase, 0x264, LMod(d0, d1))
X
X#pragma amicall(ArpBase, 0x26A, CheckSumPrg(d1))
X#pragma amicall(ArpBase, 0x270, TackOn(a0, a1))
X#pragma amicall(ArpBase, 0x276, BaseName(a0))
X#pragma amicall(ArpBase, 0x27C, ReleaseResidentPrg(d1))


X
X/*
X ************************************************************************
X * Added V36 of arp.library *
X ************************************************************************
X */

X/* amicall(ArpBase, 0x282, SPrintf(d0, a0, a1)) This does not work without glue */
X#pragma amicall(ArpBase, 0x288, GetKeywordIndex(a0, a1))
X/* amicall(ArpBase, 0x28E, ArpOpenLibrary(a1, d0)) Secondary result - IoErr() */
X#pragma amicall(ArpBase, 0x294, ArpAllocFreq())
X
X#endif
END_OF_FILE
if test 6655 -ne `wc -c <'vim/src/arp_proto.h'`; then
echo shar: \"'vim/src/arp_proto.h'\" unpacked with wrong size!
fi
# end of 'vim/src/arp_proto.h'
fi
if test -f 'vim/src/cmdtab.tab' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/cmdtab.tab'\"
else
echo shar: Extracting \"'vim/src/cmdtab.tab'\" \(8606 characters\)
sed "s/^X//" >'vim/src/cmdtab.tab' <<'END_OF_FILE'
X/* vi:ts=4


X *
X * VIM - Vi IMproved

X *
X * Code Contributions By: Bram Moolenaar mo...@oce.nl
X * Tim Thompson twitch!tjt
X * Tony Andrews onecom!wldrdg!tony
X * G. R. (Fred) Walter watmath!watcgl!grwalter

X */
X
X/*
X * |This file is read by mkcmdtab to produce cmdtab.h.
X *
X * The bars are used to recognize file positions. Do not insert/delete them.|


X */
X
X#define RANGE 0x01 /* allow a linespecs */
X#define BANG 0x02 /* allow a ! after the command name */
X#define EXTRA 0x04 /* allow extra args after command name */
X#define XFILE 0x08 /* expand wildcards in extra part */
X#define NOSPC 0x10 /* no spaces allowed in the extra part */
X#define DFLALL 0x20 /* default file range is 1,$ */
X#define NODFL 0x40 /* do not default to the current file name */
X#define NEEDARG 0x80 /* argument required */
X#define TRLBAR 0x100 /* check for trailing vertical bar */
X#define REGSTR 0x200 /* allow "x for register designation */
X#define COUNT 0x400 /* allow count in argument, after command */
X#define NOTRLCOM 0x800 /* no trailing comment allowed */
X#define ZEROR 0x1000 /* zero line number allowed */
X#define USECTRLV 0x2000 /* do not remove CTRL-V from argument */
X#define NOTADR 0x4000 /* number before command is not an address */
X#define FILES (XFILE + EXTRA) /* multiple extra files allowed */
X#define WORD1 (EXTRA + NOSPC) /* one extra word allowed */
X#define FILE1 (FILES + NOSPC) /* 1 file allowed, defaults to current file */
X#define NAMEDF (FILE1 + NODFL) /* 1 file allowed, defaults to "" */

X#define NAMEDFS (FILES + NODFL) /* multiple files allowed, default is "" */
X
X/*


X * This array maps ex command names to command codes. The order in which
X * command names are listed below is significant -- ambiguous abbreviations
X * are always resolved to be the first possible match (e.g. "r" is taken
X * to mean "read", not "rewind", because "read" comes before "rewind").
X * Not supported commands are included to avoid ambiguities.
X */
Xstatic struct
X{
X char_u *cmd_name; /* name of the command */
X short cmd_argt; /* command line arguments permitted/needed/used */
X} cmdnames[] =
X{
X| {(char_u *)"append", BANG+RANGE+TRLBAR}, /* not supported */

X {(char_u *)"all", TRLBAR},

X {(char_u *)"abbreviate", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"args", RANGE+NOTADR+BANG+NAMEDFS},

X {(char_u *)"argument", BANG+RANGE+NOTADR+COUNT+EXTRA},

X {(char_u *)"buffer", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"ball", TRLBAR},

X {(char_u *)"buffers", TRLBAR},

X {(char_u *)"bdelete", BANG+RANGE+NOTADR+COUNT+EXTRA+TRLBAR},
X {(char_u *)"bunload", BANG+RANGE+NOTADR+COUNT+EXTRA+TRLBAR},


X {(char_u *)"bmodified", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"bnext", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"bNext", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"bprevious", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"brewind", RANGE+TRLBAR},

X {(char_u *)"blast", RANGE+TRLBAR},

X {(char_u *)"change", BANG+RANGE+COUNT+TRLBAR}, /* not supported */

X {(char_u *)"cabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"cc", TRLBAR+WORD1+BANG},

X {(char_u *)"cd", NAMEDF+TRLBAR},

X {(char_u *)"center", TRLBAR+RANGE+EXTRA},

X {(char_u *)"cf", TRLBAR+FILE1+BANG},

X {(char_u *)"chdir", NAMEDF+TRLBAR},

X {(char_u *)"cl", TRLBAR},

X {(char_u *)"close", BANG+TRLBAR},

X {(char_u *)"cmap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"cn", TRLBAR+WORD1+BANG},

X {(char_u *)"cnoremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"cnoreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"copy", RANGE+EXTRA+TRLBAR},

X {(char_u *)"cp", TRLBAR+WORD1+BANG},

X {(char_u *)"cq", TRLBAR+BANG},

X {(char_u *)"cunmap", BANG+EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"cunabbrev", EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"delete", RANGE+REGSTR+COUNT+TRLBAR},

X {(char_u *)"display", TRLBAR},

X {(char_u *)"digraphs", EXTRA+TRLBAR},

X {(char_u *)"edit", BANG+FILE1},

X {(char_u *)"ex", BANG+FILE1},

X {(char_u *)"exit", BANG+FILE1+DFLALL+TRLBAR},

X {(char_u *)"file", FILE1+TRLBAR},

X {(char_u *)"files", TRLBAR},

X {(char_u *)"global", RANGE+BANG+EXTRA+DFLALL},

X {(char_u *)"help", TRLBAR},

X {(char_u *)"insert", BANG+RANGE+TRLBAR}, /* not supported */

X {(char_u *)"iabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"imap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"inoremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"inoreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"iunmap", BANG+EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"iunabbrev", EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"join", RANGE+COUNT+TRLBAR},

X {(char_u *)"jumps", TRLBAR},

X {(char_u *)"k", RANGE+WORD1+TRLBAR},

X {(char_u *)"list", RANGE+COUNT+TRLBAR},

X {(char_u *)"last", EXTRA+BANG},

X {(char_u *)"left", TRLBAR+RANGE+EXTRA},

X {(char_u *)"move", RANGE+EXTRA+TRLBAR},

X {(char_u *)"mark", RANGE+WORD1+TRLBAR},

X {(char_u *)"marks", TRLBAR},

X {(char_u *)"map", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"make", NEEDARG+EXTRA+TRLBAR+XFILE},

X {(char_u *)"mkexrc", BANG+FILE1+TRLBAR},

X {(char_u *)"mkvimrc", BANG+FILE1+TRLBAR},

X {(char_u *)"mfstat", TRLBAR}, /* for debugging */

X {(char_u *)"mode", WORD1+TRLBAR},

X {(char_u *)"next", RANGE+NOTADR+BANG+NAMEDFS},

X {(char_u *)"new", BANG+FILE1+RANGE+NOTADR},

X {(char_u *)"number", RANGE+COUNT+TRLBAR},

X {(char_u *)"#", RANGE+COUNT+TRLBAR},

X {(char_u *)"noremap", BANG+EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"noreabbrev", EXTRA+TRLBAR+NOTRLCOM+USECTRLV},

X {(char_u *)"Next", EXTRA+RANGE+NOTADR+COUNT+BANG},

X {(char_u *)"only", BANG+TRLBAR},

X {(char_u *)"print", RANGE+COUNT+TRLBAR},

X {(char_u *)"pop", RANGE+NOTADR+COUNT+TRLBAR+ZEROR},

X {(char_u *)"put", RANGE+BANG+REGSTR+TRLBAR},

X {(char_u *)"preserve", TRLBAR},

X {(char_u *)"previous", EXTRA+RANGE+NOTADR+COUNT+BANG},

X {(char_u *)"pwd", TRLBAR},

X {(char_u *)"quit", BANG+TRLBAR},

X {(char_u *)"qall", BANG+TRLBAR},

X {(char_u *)"read", RANGE+NAMEDF+TRLBAR+ZEROR},

X {(char_u *)"rewind", EXTRA+BANG},

X {(char_u *)"recover", FILE1+TRLBAR}, /* not supported */

X {(char_u *)"redo", TRLBAR},

X {(char_u *)"right", TRLBAR+RANGE+EXTRA},

X {(char_u *)"resize", TRLBAR+WORD1},

X {(char_u *)"substitute", RANGE+EXTRA},

X {(char_u *)"sargument", BANG+RANGE+NOTADR+COUNT+EXTRA},

X {(char_u *)"sall", TRLBAR},

X {(char_u *)"sbuffer", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"sball", TRLBAR},

X {(char_u *)"sbmodified", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"sbnext", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"sbNext", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"sbprevious", RANGE+NOTADR+COUNT+TRLBAR},

X {(char_u *)"sbrewind", TRLBAR},

X {(char_u *)"sblast", TRLBAR},

X {(char_u *)"suspend", TRLBAR+BANG},

X {(char_u *)"set", EXTRA+TRLBAR},

X {(char_u *)"setkeymap", NAMEDF+TRLBAR},

X {(char_u *)"shell", TRLBAR},

X {(char_u *)"sleep", RANGE+COUNT+NOTADR+TRLBAR},

X {(char_u *)"source", NAMEDF+NEEDARG+TRLBAR},

X {(char_u *)"split", BANG+FILE1+RANGE+NOTADR},

X {(char_u *)"snext", RANGE+NOTADR+BANG+NAMEDFS},

X {(char_u *)"sNext", EXTRA+RANGE+NOTADR+COUNT+BANG},

X {(char_u *)"sprevious", EXTRA+RANGE+NOTADR+COUNT+BANG},

X {(char_u *)"srewind", EXTRA+BANG},

X {(char_u *)"slast", EXTRA+BANG},

X {(char_u *)"stop", TRLBAR+BANG},

X {(char_u *)"sunhide", TRLBAR},

X {(char_u *)"swapname", TRLBAR},

X {(char_u *)"t", RANGE+EXTRA+TRLBAR},

X {(char_u *)"tag", RANGE+NOTADR+COUNT+BANG+WORD1+TRLBAR+ZEROR},

X {(char_u *)"tags", TRLBAR},

X {(char_u *)"unabbreviate", EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"undo", TRLBAR},

X {(char_u *)"unhide", TRLBAR},

X {(char_u *)"unmap", BANG+EXTRA+TRLBAR+USECTRLV},

X {(char_u *)"vglobal", RANGE+EXTRA+DFLALL},

X {(char_u *)"version", TRLBAR},

X {(char_u *)"visual", RANGE+BANG+FILE1},

X {(char_u *)"write", RANGE+BANG+FILE1+DFLALL+TRLBAR},

X {(char_u *)"wnext", RANGE+NOTADR+BANG+FILE1+TRLBAR},

X {(char_u *)"wNext", RANGE+NOTADR+BANG+FILE1+TRLBAR},

X {(char_u *)"wprevious", RANGE+NOTADR+BANG+FILE1+TRLBAR},

X {(char_u *)"winsize", EXTRA+NEEDARG+TRLBAR},

X {(char_u *)"wq", BANG+FILE1+DFLALL+TRLBAR},

X {(char_u *)"wall", BANG+TRLBAR},

X {(char_u *)"wqall", BANG+FILE1+DFLALL+TRLBAR},

X {(char_u *)"xit", BANG+FILE1+DFLALL+TRLBAR},

X {(char_u *)"xall", BANG+TRLBAR},

X {(char_u *)"yank", RANGE+REGSTR+COUNT+TRLBAR},

X {(char_u *)"z", RANGE+COUNT+TRLBAR}, /* not supported */

X {(char_u *)"@", RANGE+EXTRA+TRLBAR},

X {(char_u *)"!", RANGE+NAMEDFS},

X {(char_u *)"<", RANGE+COUNT+TRLBAR},
X {(char_u *)">", RANGE+COUNT+TRLBAR},

X {(char_u *)"=", RANGE+TRLBAR},

X {(char_u *)"&", RANGE+EXTRA},

X {(char_u *)"~", RANGE+EXTRA}

X|
X};
X|
END_OF_FILE
if test 8606 -ne `wc -c <'vim/src/cmdtab.tab'`; then
echo shar: \"'vim/src/cmdtab.tab'\" unpacked with wrong size!
fi
# end of 'vim/src/cmdtab.tab'
fi
if test -f 'vim/src/help.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/help.c'\"
else
echo shar: Extracting \"'vim/src/help.c'\" \(3737 characters\)
sed "s/^X//" >'vim/src/help.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * help.c: display help from the vim.hlp file


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X

Xstatic long helpfilepos; /* position in help file */
Xstatic FILE *helpfd; /* file descriptor of help file */
X
X#define MAXSCREENS 52 /* one screen for a-z and A-Z */
X
X void
Xhelp()
X{
X int c;
X int eof;
X int screens;
X int i;
X long filepos[MAXSCREENS]; /* seek position for each screen */
X int screennr; /* screen number; index == 0, 'c' == 1, 'd' == 2, etc */
X#if defined(MSDOS) && !defined(NT)
X char_u *fnamep;
X#endif
X
X/*
X * try to open the file specified by the "helpfile" option
X */
X if ((helpfd = fopen((char *)p_hf, READBIN)) == NULL)


X {
X#if defined(MSDOS) && !defined(NT)

X /*
X * for MSDOS: try the DOS search path
X */
X fnamep = searchpath("vim.hlp");
X if (fnamep == NULL || (helpfd = fopen((char *)fnamep, READBIN)) == NULL)
X {
X smsg((char_u *)"Sorry, help file \"%s\" and \"vim.hlp\" not found", p_hf);
X return;
X }
X#else
X smsg((char_u *)"Sorry, help file \"%s\" not found", p_hf);
X return;
X#endif
X }
X helpfilepos = 0;
X screennr = 0;
X for (i = 0; i < MAXSCREENS; ++i)
X filepos[i] = 0;
X State = HELP;


X for (;;)
X {

X screens = redrawhelp(); /* show one or more screens */
X eof = (screens < 0);
X if (!eof && screennr + screens < MAXSCREENS)
X filepos[screennr + screens] = ftell(helpfd);
X
X if ((c = vgetc()) == '\n' || c == '\r' || c == Ctrl('C') || c == ESC)
X break;
X
X if (c == ' ' ||
X#ifdef MSDOS
X (c == K_NUL && vpeekc() == 'Q') || /* page down */
X#endif
X c == Ctrl('F')) /* one screen forwards */
X {
X if (screennr < MAXSCREENS && !eof)
X ++screennr;
X }
X else if (c == 'a') /* go to first screen */
X screennr = 0;
X else if (c == 'b' ||
X#ifdef MSDOS
X (c == K_NUL && vpeekc() == 'I') || /* page up */
X#endif
X c == Ctrl('B')) /* go one screen backwards */
X {
X if (screennr > 0)
X --screennr;
X }
X else if (isalpha(c)) /* go to specified screen */
X {
X if (isupper(c))
X c = c - 'A' + 'z' + 1; /* 'A' comes after 'z' */
X screennr = c - 'b';
X }
X#ifdef MSDOS
X if (c == K_NUL)
X c = vgetc();
X#endif
X for (i = screennr; i > 0; --i)
X if (filepos[i])
X break;
X fseek(helpfd, filepos[i], 0);
X while (i < screennr)
X {
X while ((c = getc(helpfd)) != '\f' && c != -1)
X ;
X if (c == -1)
X break;
X filepos[++i] = ftell(helpfd); /* store the position just after the '\f' */
X }
X screennr = i; /* required when end of file reached */
X helpfilepos = filepos[screennr];


X }
X State = NORMAL;

X fclose(helpfd);
X updateScreen(CLEAR);
X}
X
X/*
X * redraw the help info for the current position in the help file
X *
X * return the number of screens displayed, or -1 if end of file reached
X */
X int
Xredrawhelp()
X{
X int nextc;
X int col;
X int line = 0;
X int screens = 1;
X
X fseek(helpfd, helpfilepos, 0);
X outstr(T_ED);
X (void)set_highlight('h');
X windgoto(0,0);
X while ((nextc = getc(helpfd)) != -1 && (nextc != '\f' || line < Rows - 24))
X {
X if (nextc == Ctrl('B')) /* begin of standout */
X start_highlight();
X else if (nextc == Ctrl('E')) /* end of standout */
X stop_highlight();
X else if (nextc == '\f') /* start of next screen */
X {
X ++screens;
X outchar('\n');
X ++line;
X }
X else
X {
X outchar(nextc);
X if (nextc == '\n')
X ++line;
X }
X }
X windgoto(0, (int)(Columns - STRLEN(Version) - 1));
X outstrn(Version);
X col = (int)Columns - 52;
X if (col < 0)
X col = 0;
X windgoto((int)Rows - 1, col);
X OUTSTRN("<space = next; return = quit; a = index; b = back>");
X return (nextc == -1 ? -1 : screens);
X}
END_OF_FILE
if test 3737 -ne `wc -c <'vim/src/help.c'`; then
echo shar: \"'vim/src/help.c'\" unpacked with wrong size!
fi
# end of 'vim/src/help.c'
fi
if test -f 'vim/src/linefunc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/linefunc.c'\"
else
echo shar: Extracting \"'vim/src/linefunc.c'\" \(2906 characters\)
sed "s/^X//" >'vim/src/linefunc.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * linefunc.c: some functions to move to the next/previous line and
X * to the next/previous character


X */
X
X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X
X/*

X * coladvance(col)
X *
X * Try to advance the Cursor to the specified column.


X */
X
X void

Xcoladvance(wcol)
X colnr_t wcol;
X{
X int index;
X register char_u *ptr;
X register colnr_t col;


X
X ptr = ml_get(curwin->w_cursor.lnum);
X

X /* try to advance to the specified column */
X index = -1;
X col = 0;
X while (col <= wcol && *ptr)
X {
X ++index;


X /* Count a tab for what it's worth (if list mode not on) */

X col += chartabsize(*ptr, (long)col);
X ++ptr;
X }
X /*
X * in insert mode it is allowed to be one char beyond the end of the line
X */
X if ((State & INSERT) && col <= wcol)
X ++index;
X if (index < 0)
X curwin->w_cursor.col = 0;
X else
X curwin->w_cursor.col = index;
X}
X
X/*
X * inc(p)
X *
X * Increment the line pointer 'p' crossing line boundaries as necessary.
X * Return 1 when crossing a line, -1 when at end of file, 0 otherwise.
X */
X int
Xinc_cursor()
X{
X return inc(&curwin->w_cursor);
X}
X
X int
Xinc(lp)
X register FPOS *lp;
X{
X register char_u *p = ml_get_pos(lp);


X
X if (*p != NUL)

X { /* still within line */
X lp->col++;
X return ((p[1] != NUL) ? 0 : 1);
X }
X if (lp->lnum != curbuf->b_ml.ml_line_count)
X { /* there is a next line */
X lp->col = 0;
X lp->lnum++;
X return 1;
X }
X return -1;
X}
X
X/*
X * incl(lp): same as inc(), but skip the NUL at the end of non-empty lines
X */
X int
Xincl(lp)
X register FPOS *lp;
X{
X register int r;
X
X if ((r = inc(lp)) == 1 && lp->col)
X r = inc(lp);
X return r;
X}
X
X/*
X * dec(p)
X *
X * Decrement the line pointer 'p' crossing line boundaries as necessary.
X * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
X */
X int
Xdec_cursor()
X{
X return dec(&curwin->w_cursor);
X}
X
X int
Xdec(lp)
X register FPOS *lp;
X{
X if (lp->col > 0)
X { /* still within line */
X lp->col--;
X return 0;
X }
X if (lp->lnum > 1)
X { /* there is a prior line */
X lp->lnum--;
X lp->col = STRLEN(ml_get(lp->lnum));
X return 1;
X }
X return -1; /* at start of file */
X}
X
X/*
X * decl(lp): same as dec(), but skip the NUL at the end of non-empty lines
X */
X int
Xdecl(lp)
X register FPOS *lp;
X{
X register int r;
X
X if ((r = dec(lp)) == 1 && lp->col)
X r = dec(lp);
X return r;
X}
X
X/*
X * make sure curwin->w_cursor in on a valid character
X */
X void
Xadjust_cursor()
X{
X int len;
X
X if (curwin->w_cursor.lnum == 0)


X curwin->w_cursor.lnum = 1;

X if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)


X curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
X

X len = STRLEN(ml_get(curwin->w_cursor.lnum));


X if (len == 0)

X curwin->w_cursor.col = 0;

X else if (curwin->w_cursor.col >= len)
X curwin->w_cursor.col = len - 1;
X}
END_OF_FILE
if test 2906 -ne `wc -c <'vim/src/linefunc.c'`; then
echo shar: \"'vim/src/linefunc.c'\" unpacked with wrong size!
fi
# end of 'vim/src/linefunc.c'
fi
if test -f 'vim/src/makefile.archie' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.archie'\"
else
echo shar: Extracting \"'vim/src/makefile.archie'\" \(2888 characters\)
sed "s/^X//" >'vim/src/makefile.archie' <<'END_OF_FILE'
X#
X# Makefile for Vim on Acorn Archimedes, using gcc and UnixLib
X#
X
XMACHINE = -DARCHIE
X
X### gcc on the Arc.
XCC=gcc


X
X### Name of target
XTARGET = vim
X

X# To keep the command line down, all the defs have gone into
X# the macro file "defs"
XDEFS = -include defs -O2
X
X#>>>>> link with termlib or termcap only if TERMCAP is defined
X### default
XLIBS =


X
X#>>>>> end of choices
X###########################################################################
X

XCFLAGS = -c $(MACHINE) $(DEFS)
X

XINCL = h.vim h.globals h.param h.keymap h.macros h.ascii h.term h.unix h.debug
X
XOBJ = o.alloc o.archie o.buffer o.charset o.cmdcmds o.cmdline o.csearch o.digraph \
X o.edit o.fileio o.getchar o.help o.linefunc o.main o.mark o.memfile o.memline o.message o.misccmds \
X o.normal o.ops o.param o.quickfix o.regexp o.regsub o.screen \
X o.search o.tag o.term o.undo o.window
X
X$(TARGET): $(OBJ) c.version
X $(CC) $(CFLAGS) version.c
X rename o.mkcmdtab tempfile
X $(CC) -o $(TARGET) o.* $(LIBS)
X rename tempfile o.mkcmdtab
X
X###########################################################################
X
Xo.alloc: c.alloc $(INCL)
X $(CC) $(CFLAGS) alloc.c
X
Xo.archie: c.archie $(INCL) h.archie
X $(CC) $(CFLAGS) archie.c
X
Xo.buffer: c.buffer $(INCL)
X $(CC) $(CFLAGS) buffer.c
X
Xo.charset: c.charset $(INCL)
X $(CC) $(CFLAGS) charset.c
X
Xo.cmdcmds: c.cmdcmds $(INCL)
X $(CC) $(CFLAGS) cmdcmds.c
X
Xo.cmdline: c.cmdline $(INCL) h.cmdtab


X $(CC) $(CFLAGS) cmdline.c
X

Xo.csearch: c.csearch $(INCL)
X $(CC) $(CFLAGS) csearch.c
X
Xo.digraph: c.digraph $(INCL)
X $(CC) $(CFLAGS) digraph.c
X
Xo.edit: c.edit $(INCL)
X $(CC) $(CFLAGS) edit.c
X
Xo.fileio: c.fileio $(INCL)
X $(CC) $(CFLAGS) fileio.c
X
Xo.getchar: c.getchar $(INCL)
X $(CC) $(CFLAGS) getchar.c
X
Xo.help: c.help $(INCL)
X $(CC) $(CFLAGS) help.c
X
Xo.linefunc: c.linefunc $(INCL)
X $(CC) $(CFLAGS) linefunc.c
X
Xo.main: c.main $(INCL)
X $(CC) $(CFLAGS) main.c
X
Xo.mark: c.mark $(INCL)
X $(CC) $(CFLAGS) mark.c
X
Xo.memfile: c.memfile $(INCL)
X $(CC) $(CFLAGS) memfile.c
X
Xo.memline: c.memline $(INCL)
X $(CC) $(CFLAGS) memline.c
X
Xo.message: c.message $(INCL)
X $(CC) $(CFLAGS) message.c
X
Xo.misccmds: c.misccmds $(INCL)
X $(CC) $(CFLAGS) misccmds.c
X
Xo.normal: c.normal $(INCL) h.ops


X $(CC) $(CFLAGS) normal.c
X

Xo.ops: c.ops $(INCL) h.ops


X $(CC) $(CFLAGS) ops.c
X

Xo.param: c.param $(INCL)
X $(CC) $(CFLAGS) param.c
X
Xo.quickfix: c.quickfix $(INCL)
X $(CC) $(CFLAGS) quickfix.c
X
Xo.regexp: c.regexp $(INCL)
X $(CC) $(CFLAGS) regexp.c
X
Xo.regsub: c.regsub $(INCL)
X $(CC) $(CFLAGS) regsub.c
X
Xo.screen: c.screen $(INCL)
X $(CC) $(CFLAGS) screen.c
X
Xo.search: c.search $(INCL)
X $(CC) $(CFLAGS) search.c
X
Xo.tag: c.tag $(INCL)
X $(CC) $(CFLAGS) tag.c
X
Xo.term: c.term $(INCL)
X $(CC) $(CFLAGS) term.c
X
Xo.undo: c.undo $(INCL)
X $(CC) $(CFLAGS) undo.c
X
Xo.window: c.window $(INCL)
X $(CC) $(CFLAGS) window.c
X
Xh.cmdtab: cmdtab mkcmdtab
X mkcmdtab cmdtab h.cmdtab
X
Xmkcmdtab: o.mkcmdtab


X $(CC) -o mkcmdtab mkcmdtab.o

END_OF_FILE
if test 2888 -ne `wc -c <'vim/src/makefile.archie'`; then
echo shar: \"'vim/src/makefile.archie'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.archie'
fi
if test -f 'vim/src/makefile.bcc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.bcc'\"
else
echo shar: Extracting \"'vim/src/makefile.bcc'\" \(4338 characters\)
sed "s/^X//" >'vim/src/makefile.bcc' <<'END_OF_FILE'
X#
X# Makefile for Borland C++ 2.0
X# Can also be used for Turbo C++
X#
X# The options are at the end of this file
X#
X
X.AUTODEPEND
X
X# *Translator Definitions*
X# use tcc for Turbo C++
XCC = bcc +VIM.CFG
X#CC = tcc +VIM.CFG
XTASM = TASM
XTLIB = tlib
XTLINK = tlink
X#
X# Adjust the paths for your environment
X# use the first two if you don't have the spawno library
X# then also remove the SPAWNO define further down and the line
X# with spawnl.lib
X#
X#LIBPATH = C:\BORLANDC\LIB
X#INCLUDEPATH = C:\BORLANDC\INCLUDE
XLIBPATH = C:\BORLANDC\LIB;C:\CC\SPAWN
XINCLUDEPATH = C:\BORLANDC\INCLUDE;C:\CC\SPAWN
X
X
X# *Implicit Rules*
X#
X# use -v for debugging
X#
X.c.obj:
X $(CC) -c {$< }
X# $(CC) -c -v {$< }
X
X# *List Macros*
X
X
XEXE_dependencies = \
X alloc.obj \
X buffer.obj \
X charset.obj \
X cmdcmds.obj \
X cmdline.obj \
X csearch.obj \
X digraph.obj \
X edit.obj \
X fileio.obj \
X getchar.obj \
X help.obj \
X linefunc.obj \
X main.obj \
X mark.obj \
X memfile.obj \
X memline.obj \
X message.obj \
X misccmds.obj \
X msdos.obj \
X normal.obj \
X ops.obj \
X param.obj \
X quickfix.obj \
X regexp.obj \
X regsub.obj \
X screen.obj \
X search.obj \
X tag.obj \
X term.obj \
X undo.obj \
X window.obj \
X version.obj
X
X# *Explicit Rules*
X# add /v to TLINK for degubbing
Xvim.exe: vim.cfg $(EXE_dependencies)
X $(CC) -c version.c
X $(TLINK) /x/c/L$(LIBPATH) @&&|
Xc0l.obj+
Xalloc.obj+
Xbuffer.obj+
Xcharset.obj+
Xcmdcmds.obj+
Xcmdline.obj+
Xcsearch.obj+
Xdigraph.obj+
Xedit.obj+
Xfileio.obj+
Xgetchar.obj+
Xhelp.obj+
Xlinefunc.obj+
Xmain.obj+
Xmark.obj+
Xmemfile.obj+
Xmemline.obj+
Xmessage.obj+
Xmisccmds.obj+
Xmsdos.obj+
Xnormal.obj+
Xops.obj+
Xparam.obj+
Xquickfix.obj+
Xregexp.obj+
Xregsub.obj+
Xscreen.obj+
Xsearch.obj+
Xtag.obj+
Xterm.obj+
Xundo.obj+
Xwindow.obj+
Xversion.obj
Xvim
X # no map file
Xfp87.lib+
Xmathl.lib+
Xspawnl.lib+
Xcl.lib
X|
X
X
X# *Individual File Dependencies*
Xalloc.obj: alloc.c
X
Xbuffer.obj: buffer.c
X
Xcharset.obj: charset.c
X
Xcmdcmds.obj: cmdcmds.c
X
Xcmdline.obj: cmdline.c cmdtab.h


X
Xcmdtab.h: cmdtab.tab mkcmdtab.exe
X mkcmdtab cmdtab.tab cmdtab.h
X

Xmkcmdtab.exe: mkcmdtab.obj
X $(CC) -ml -omkcmdtab mkcmdtab.obj
X
Xmkcmdtab.obj: mkcmdtab.c
X $(CC) $(CFLAGS) mkcmdtab.c
X
Xcsearch.obj: csearch.c
X
Xdigraph.obj: digraph.c
X
Xedit.obj: edit.c
X
Xfileio.obj: fileio.c
X
Xgetchar.obj: getchar.c
X
Xhelp.obj: help.c
X
Xlinefunc.obj: linefunc.c
X
Xmain.obj: main.c globals.h param.h
X
Xmark.obj: mark.c
X
Xmemfile.obj: memfile.c
X
Xmemline.obj: memline.c
X
Xmessage.obj: message.c
X
Xmisccmds.obj: misccmds.c
X
Xmsdos.obj: msdos.c
X
Xnormal.obj: normal.c ops.h
X
Xops.obj: ops.c ops.h
X
Xparam.obj: param.c
X
Xquickfix.obj: quickfix.c
X
Xregexp.obj: regexp.c
X
Xregsub.obj: regsub.c
X
Xscreen.obj: screen.c
X
Xsearch.obj: search.c
X
Xtag.obj: tag.c
X
Xterm.obj: term.c term.h
X
Xundo.obj: undo.c
X
Xwindow.obj: window.c
X
Xversion.obj: version.c
X
X# *Compiler Configuration File*
X# The following compile options can be changed for better machines.
X# replace -1- with -2 to produce code for a 80286 or higher
X# replace -1- with -3 to produce code for a 80386 or higher
X# add -v for source debugging
Xvim.cfg: makefile
X copy &&|
X-ml
X-1-
X-f-
X-C
X-N
X-O
X-Z
X-k-
X-d
X-h
X-vi-
X-H=VIM.SYM
X-w-par
X-w-pro
X-weas
X-wpre
X-I$(INCLUDEPATH)
X-L$(LIBPATH)
X-DPC;MSDOS;SPAWNO;DIGRAPHS;WEBB_COMPLETE;WEBB_KEYWORD_COMPL
X| vim.cfg
X
X#
X# options:


X### -DDIGRAPHS digraph support (at the cost of 1.6 Kbyte code)
X### -DNO_ARP do not use arp.library, DOS 2.0 required
X### -DCOMPATIBLE start in vi-compatible mode
X### -DNOBACKUP default is no backup file
X### -DDEBUG output a lot of debugging garbage
X### -DTERMCAP include termcap file support
X### -DNO_BUILTIN_TCAPS do not include builtin termcap entries
X### (use only with -DTERMCAP)
X### -DSOME_BUILTIN_TCAPS include most useful builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DALL_BUILTIN_TCAPS include all builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)

X### -DVIMRC_FILE name of the .vimrc file in current dir
X### -DEXRC_FILE name of the .exrc file in current dir
X### -DSYSVIMRC_FILE name of the global .vimrc file
X### -DSYSEXRC_FILE name of the global .exrc file
X### -DDEFVIMRC_FILE name of the system-wide .vimrc file
X### -DVIM_HLP name of the help file
X### -DWEBB_COMPLETE include Webb's code for command line completion
X### -DWEBB_KEYWORD_COMPL include Webb's code for keyword completion
X### -DNOTITLE 'title' option off by default

END_OF_FILE
if test 4338 -ne `wc -c <'vim/src/makefile.bcc'`; then
echo shar: \"'vim/src/makefile.bcc'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.bcc'
fi
if test -f 'vim/src/makefile.dice' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/makefile.dice'\"
else
echo shar: Extracting \"'vim/src/makefile.dice'\" \(3750 characters\)
sed "s/^X//" >'vim/src/makefile.dice' <<'END_OF_FILE'
X#
X# Makefile for VIM, using DICE 2.06.40 and 2.06.21
X#
X# LAST CHANGES NOT TESTED


X#
X
X#>>>>> choose options:
X### -DDIGRAPHS digraph support (at the cost of 1.6 Kbyte code)
X### -DNO_ARP do not use arp.library, DOS 2.0 required
X### -DCOMPATIBLE start in vi-compatible mode
X### -DNOBACKUP default is no backup file
X### -DDEBUG output a lot of debugging garbage
X### -DTERMCAP include termcap file support
X### -DNO_BUILTIN_TCAPS do not include builtin termcap entries
X### (use only with -DTERMCAP)
X### -DSOME_BUILTIN_TCAPS include most useful builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)
X### -DALL_BUILTIN_TCAPS include all builtin termcap entries
X### (use only without -DNO_BUILTIN_TCAPS)

X### -DWEBB_COMPLETE include Webb's code for command line completion
X### -DWEBB_KEYWORD_COMPL include Webb's code for keyword completion
X### -DNOTITLE 'title' option off by default

XDEFINES = -DTERMCAP -DDIGRAPHS -DSOME_BUILTIN_TCAPS \


X -DWEBB_COMPLETE -DWEBB_KEYWORD_COMPL
X
X#>>>>> if TERMCAP is defined obj/termlib.o has to be used

XTERMLIB = obj/termlib.o
X#TERMLIB =

X
X#>>>>> end of choices
X###########################################################################
X

XCFLAGS = -c -DAMIGA $(DEFINES)
X
XINCL = vim.syms
XPRE = -H${INCL}=vim.h
XLIBS = -lmanx -la
XCC = dcc
XLD = dcc
X
X.c.o:
X ${CC} ${PRE} ${CFLAGS} $*.c -o $@


X
XOBJ = obj/alloc.o obj/amiga.o obj/buffer.o obj/charset.o obj/cmdcmds.o obj/cmdline.o \
X obj/csearch.o obj/digraph.o obj/edit.o obj/fileio.o obj/getchar.o obj/help.o \
X obj/linefunc.o obj/main.o obj/mark.o obj/memfile.o obj/memline.o obj/message.o obj/misccmds.o \
X obj/normal.o obj/ops.o obj/param.o obj/quickfix.o obj/regexp.o \
X obj/regsub.o obj/screen.o obj/search.o \
X obj/tag.o obj/term.o obj/undo.o obj/window.o $(TERMLIB)
X

X/Vim: $(OBJ) version.c
X ${CC} $(CFLAGS) version.c -o obj/version.o
X ${LD} -o /Vim $(OBJ) obj/version.o $(LIBS)
X
Xdebug: $(OBJ) version.c
X ${CC} $(CFLAGS) version.c -o obj/version.o
X ${LD} -s -o /Vim $(OBJ) obj/version.o $(LIBS)
X


Xctags:
X csh -c ctags *.c *.h
X
X# can't use delete here, too many file names
Xclean:

X csh -c rm -f $(OBJ) obj/version.o obj/mkcmdtab.o /Vim $(INCL) mkcmdtab cmdtab.h
X
X$(INCL) : vim.h globals.h keymap.h macros.h ascii.h term.h amiga.h structs.h
X delete $(INCL)
X
X###########################################################################
X
Xobj/alloc.o: alloc.c $(INCL)
X
Xobj/amiga.o: amiga.c $(INCL) amiga.h
X
Xobj/buffer.o: buffer.c $(INCL)
X
Xobj/charset.o: charset.c $(INCL)
X
Xobj/cmdcmds.o: cmdcmds.c $(INCL)
X
Xobj/cmdline.o: cmdline.c $(INCL) cmdtab.h
X
Xobj/csearch.o: csearch.c $(INCL) regexp.h
X
Xobj/digraph.o: digraph.c $(INCL)
X
Xobj/edit.o: edit.c $(INCL)
X
Xobj/fileio.o: fileio.c $(INCL)
X
Xobj/getchar.o: getchar.c $(INCL)
X
Xobj/help.o: help.c $(INCL)
X
Xobj/linefunc.o: linefunc.c $(INCL)
X
Xobj/main.o: main.c
X ${CC} ${CFLAGS} main.c -o main.o
X
Xobj/mark.o: mark.c $(INCL)
X
Xobj/memfile.o: memfile.c $(INCL)
X
Xobj/memline.o: memline.c $(INCL)
X
Xobj/message.o: message.c $(INCL)
X
Xobj/misccmds.o: misccmds.c $(INCL)
X
Xobj/normal.o: normal.c $(INCL) ops.h
X
Xobj/ops.o: ops.c $(INCL) ops.h
X
Xobj/param.o: param.c $(INCL)
X# Because of a bug in DC1 2.06.40, initialisation of unions does not
X# work correctly. dc1-21 is DC1 2.06.21 which does work.
X rename dc1-21 dc1
X ${CC} ${CFLAGS} param.c -o param.o
X rename dc1 dc1-21
X
Xobj/quickfix.o: quickfix.c $(INCL)
X
Xobj/regexp.o: regexp.c $(INCL) regexp.h
X
Xobj/regsub.o: regsub.c $(INCL) regexp.h
X
Xobj/screen.o: screen.c $(INCL)
X
Xobj/search.o: search.c $(INCL) regexp.h
X
Xobj/tag.o: tags.c $(INCL)
X
Xobj/termlib.o: termlib.c $(INCL)
X
Xobj/undo.o: undo.c $(INCL)
X
Xobj/window.o: window.c $(INCL)


X
Xcmdtab.h: cmdtab.tab mkcmdtab
X mkcmdtab cmdtab.tab cmdtab.h
X
Xmkcmdtab: obj/mkcmdtab.o

X ${LD} -o mkcmdtab obj/mkcmdtab.o
END_OF_FILE
if test 3750 -ne `wc -c <'vim/src/makefile.dice'`; then
echo shar: \"'vim/src/makefile.dice'\" unpacked with wrong size!
fi
# end of 'vim/src/makefile.dice'
fi
if test -f 'vim/src/param.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/param.h'\"
else
echo shar: Extracting \"'vim/src/param.h'\" \(8458 characters\)
sed "s/^X//" >'vim/src/param.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * param.h: definition of global variables for settable parameters
X *
X * EXTERN is only defined in main.c (and vim.h)


X */
X
X#ifndef EXTERN
X# define EXTERN extern
X# define INIT(x)
X#else
X# ifndef INIT
X# define INIT(x) x

X# endif
X#endif
X
X/*

X * The following are actual variabables for the parameters
X */
X
XEXTERN int p_aw INIT(= FALSE); /* auto-write */
XEXTERN long p_bs INIT(= 0); /* backspace over newlines in insert mode */
X#if defined(COMPATIBLE) || defined(NOBACKUP)
XEXTERN int p_bk INIT(= FALSE); /* make backups when writing out files */
X#else
XEXTERN int p_bk INIT(= TRUE); /* make backups when writing out files */
X#endif
X#ifdef MSDOS
XEXTERN int p_biosk INIT(= TRUE); /* Use bioskey() instead of kbhit() */
X#endif
X#ifdef UNIX
XEXTERN char_u *p_bdir INIT(= (char_u *)BACKUPDIR); /* directory for backups */
X#endif
XEXTERN long p_ch INIT(= 1L); /* command line height */
XEXTERN int p_cp INIT(= FALSE); /* vi-compatible */
X#ifdef DIGRAPHS
XEXTERN int p_dg INIT(= FALSE); /* enable digraphs */
X#endif /* DIGRAPHS */
XEXTERN char_u *p_dir INIT(= (char_u *)DEF_DIR); /* directory for swap file */
XEXTERN char_u *p_ep INIT(= (char_u *)"indent"); /* program name for '=' command */
XEXTERN int p_ea INIT(= TRUE); /* make windows equal height */
XEXTERN int p_ed INIT(= FALSE); /* :s is ed compatible */
XEXTERN int p_eb INIT(= FALSE); /* ring bell for errors */
X#ifdef AMIGA
XEXTERN char_u *p_ef INIT(= (char_u *)"AztecC.Err"); /* name of errorfile */
X#else
XEXTERN char_u *p_ef INIT(= (char_u *)"errors"); /* name of errorfile */
X#endif
X#ifdef AMIGA
XEXTERN char_u *p_efm INIT(= (char_u *)"%f>%l:%c:%t:%n:%m");/* error format */
X#else
X# ifdef ARCHIE
XEXTERN char_u *p_efm INIT(= (char_u *)"%f:%l:%m"); /* error format */
X# else
XEXTERN char_u *p_efm INIT(= (char_u *)"\"%f\",%*[^0123456789]%l: %m"); /* error format */
X# endif
X#endif
X#ifdef COMPATIBLE
XEXTERN int p_ek INIT(= FALSE); /* function keys with ESC in insert mode */
X#else
XEXTERN int p_ek INIT(= TRUE); /* function keys with ESC in insert mode */
X#endif
XEXTERN int p_exrc INIT(= FALSE); /* read .exrc in current dir */
XEXTERN char_u *p_fp INIT(= (char_u *)""); /* name of format program */
XEXTERN int p_gd INIT(= FALSE); /* /g is default for :s */
X#ifdef MSDOS
XEXTERN int p_gr INIT(= TRUE); /* display graphic characters */
X#else
XEXTERN int p_gr INIT(= FALSE); /* display graphic characters */
X#endif
XEXTERN int p_icon INIT(= FALSE); /* put file name in icon if possible */
XEXTERN long p_hi INIT(= 20); /* command line history size */
XEXTERN char_u *p_hf INIT(= (char_u *)VIM_HLP); /* name of help file */
XEXTERN int p_hid INIT(= FALSE); /* buffers can be hidden */
XEXTERN char_u *p_hl INIT(= (char_u *)"db,es,hs,rs,vi,si");
X /* which highlight mode to use */
XEXTERN int p_ic INIT(= FALSE); /* ignore case in searches */
XEXTERN int p_im INIT(= FALSE); /* start editing in input mode */
XEXTERN int p_wi INIT(= FALSE); /* inversion of text is weird */
XEXTERN char_u *p_kp INIT(= (char_u *)"ref"); /* keyword program */
XEXTERN int p_js INIT(= TRUE); /* use two spaces after period with Join */
XEXTERN long p_ls INIT(= 1); /* last window has status line */
XEXTERN int p_magic INIT(= TRUE); /* use some characters for reg exp */
XEXTERN char_u *p_mp INIT(= (char_u *)"make"); /* program for :make command */
XEXTERN long p_mm INIT(= MAXMEM); /* maximal amount of memory for buffer */
XEXTERN long p_mmt INIT(= MAXMEMTOT); /* maximal amount of memory for Vim */
XEXTERN long p_mls INIT(= 5); /* number of mode lines */
X#ifdef COMPATIBLE
XEXTERN int p_more INIT(= FALSE); /* wait when screen full when listing */
X#else
XEXTERN int p_more INIT(= TRUE); /* wait when screen full when listing */
X#endif
XEXTERN int p_nb INIT(= FALSE); /* screen output not buffered (for testing) */
XEXTERN int p_paste INIT(= FALSE); /* paste mode */
X#ifdef AMIGA
XEXTERN char_u *p_path INIT(= (char_u *)"."); /* path for "]f" and "^Wf" */
X#else
X# ifdef MSDOS
XEXTERN char_u *p_path INIT(= (char_u *)"."); /* path for "]f" and "^Wf" */
X# else
XEXTERN char_u *p_path INIT(= (char_u *)". /usr/include"); /* path for "]f" and "^Wf" */
X# endif
X#endif
XEXTERN char_u *p_pm INIT(= (char_u *)""); /* patchmode file suffix */
XEXTERN char_u *p_para INIT(= (char_u *)"IPLPPPQPP LIpplpipbp"); /* paragraphs */
XEXTERN int p_remap INIT(= TRUE); /* remap */
XEXTERN long p_report INIT(= 2); /* minimum number of lines for report */
XEXTERN int p_ru INIT(= FALSE); /* show column/line number */
XEXTERN int p_ri INIT(= FALSE); /* reverse direction of insert */
XEXTERN int p_secure INIT(= FALSE); /* do .exrc and .vimrc in secure mode */
XEXTERN long p_sj INIT(= 1); /* scroll jump size */
XEXTERN char_u *p_sections INIT(= (char_u *)"SHNHH HUnhsh"); /* sections */
X#ifdef MSDOS
XEXTERN char_u *p_sh INIT(= (char_u *)"command"); /* name of shell to use */
X#else
X# ifdef ARCHIE
XEXTERN char_u *p_sh INIT(= (char_u *)"gos"); /* name of shell to use */
X# else
XEXTERN char_u *p_sh INIT(= (char_u *)"sh"); /* name of shell to use */
X# endif
X#endif
X#ifdef UNIX
X# ifdef ARCHIE
XEXTERN char_u *p_sp INIT(= (char_u *)"2>"); /* string for output of make */
X# else
XEXTERN char_u *p_sp INIT(= (char_u *)"| tee"); /* string for output of make */
X# endif
X#else
XEXTERN char_u *p_sp INIT(= (char_u *)">"); /* string for output of make */
X#endif
XEXTERN long p_ss INIT(= 0); /* sideways scrolling offset */
XEXTERN long p_st INIT(= 0); /* type of shell */
XEXTERN int p_sr INIT(= FALSE); /* shift round off (for < and >) */
XEXTERN int p_sb INIT(= FALSE); /* split window backwards */
X#if defined(COMPATIBLE) || defined(UNIX)
XEXTERN int p_sc INIT(= FALSE); /* show command in status line */
X#else
XEXTERN int p_sc INIT(= TRUE); /* show command in status line */
X#endif
XEXTERN int p_sm INIT(= FALSE); /* showmatch */
X#if defined(COMPATIBLE)
XEXTERN int p_smd INIT(= FALSE); /* show mode */
X#else
XEXTERN int p_smd INIT(= TRUE); /* show mode */
X#endif
XEXTERN int p_sta INIT(= FALSE); /* smart-tab for expand-tab */
XEXTERN char_u *p_su INIT(= (char_u *)".bak.o.h.info.swp"); /* suffixes for wildcard expansion */
XEXTERN long p_tl INIT(= 0); /* used tag length */
XEXTERN char_u *p_tags INIT(= (char_u *)"tags"); /* tags search path */
X#if defined(COMPATIBLE)
XEXTERN int p_ta INIT(= FALSE); /* auto textmode detection */
X#else
XEXTERN int p_ta INIT(= TRUE); /* auto textmode detection */
X#endif
XEXTERN int p_terse INIT(= FALSE); /* terse messages */
XEXTERN int p_tf INIT(= FALSE); /* terminal fast I/O */
XEXTERN int p_to INIT(= FALSE); /* tilde is an operator */
X#if defined(COMPATIBLE)
XEXTERN int p_tr INIT(= FALSE); /* tag file name is relative */
X#else
XEXTERN int p_tr INIT(= TRUE); /* tag file name is relative */
X#endif
XEXTERN int p_timeout INIT(= TRUE); /* mappings entered within one second */
XEXTERN long p_tm INIT(= 1000); /* timeoutlen (msec) */
X#ifdef NOTITLE
XEXTERN int p_title INIT(= FALSE); /* set window title if possible */
X#else
XEXTERN int p_title INIT(= TRUE); /* set window title if possible */
X#endif
XEXTERN int p_ttimeout INIT(= FALSE); /* key codes entered within one second */
X#ifdef COMPATIBLE
XEXTERN long p_ul INIT(= 0); /* number of Undo Levels */
XEXTERN long p_uc INIT(= 0); /* update count for swap file */
X#else
XEXTERN long p_ul INIT(= 100); /* number of Undo Levels */
XEXTERN long p_uc INIT(= 200); /* update count for swap file */
X#endif
XEXTERN long p_ut INIT(= 4000); /* update time for swap file */
XEXTERN int p_vb INIT(= FALSE); /* visual bell only (no beep) */
XEXTERN int p_warn INIT(= TRUE); /* warn for changes at shell command */
XEXTERN int p_ws INIT(= TRUE); /* wrap scan */
X#ifdef COMPATIBLE
XEXTERN long p_ww INIT(= 0); /* which keys wrap to next/prev line */
X#else
XEXTERN long p_ww INIT(= 3); /* which keys wrap to next/prev line */
X#endif
X#ifdef COMPATIBLE
XEXTERN long p_wc INIT(= Ctrl('E')); /* character for wildcard exapansion */
X#else
XEXTERN long p_wc INIT(= TAB); /* character for wildcard exapansion */
X#endif
XEXTERN long p_wh INIT(= 0); /* desired window height */
XEXTERN int p_wa INIT(= FALSE); /* write any */
X#if defined(COMPATIBLE) || defined(NOBACKUP)
XEXTERN int p_wb INIT(= FALSE); /* write backup files */
X#else
XEXTERN int p_wb INIT(= TRUE); /* write backup files */
X#endif
XEXTERN int p_ye INIT(= FALSE); /* Y yanks to end of line */
END_OF_FILE
if test 8458 -ne `wc -c <'vim/src/param.h'`; then
echo shar: \"'vim/src/param.h'\" unpacked with wrong size!
fi
# end of 'vim/src/param.h'
fi
if test -f 'vim/src/unix.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/unix.h'\"
else
echo shar: Extracting \"'vim/src/unix.h'\" \(3085 characters\)
sed "s/^X//" >'vim/src/unix.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Unix system-dependent filenames
X */
X
X#ifndef SYSEXRC_FILE
X# define SYSEXRC_FILE "$HOME/.exrc"
X#endif
X
X#ifndef SYSVIMRC_FILE
X# define SYSVIMRC_FILE "$HOME/.vimrc"
X#endif
X
X#ifndef EXRC_FILE
X# define EXRC_FILE ".exrc"
X#endif
X
X#ifndef VIMRC_FILE
X# define VIMRC_FILE ".vimrc"
X#endif
X
X#ifndef DEFVIMRC_FILE
X# define DEFVIMRC_FILE "/usr/local/etc/vimrc"
X#endif
X
X#ifndef VIM_HLP
X# define VIM_HLP "/usr/local/lib/vim.hlp"
X#endif
X
X#ifndef BACKUPDIR
X# define BACKUPDIR "$HOME"
X#endif
X
X#ifndef DEF_DIR
X# define DEF_DIR "/tmp"
X#endif
X
X#define TMPNAME1 "/tmp/viXXXXXX"
X#define TMPNAME2 "/tmp/voXXXXXX"
X#define TMPNAMELEN 15
X
X#ifndef MAXMEM
X# define MAXMEM 512 /* use up to 512Kbyte for buffer */
X#endif
X#ifndef MAXMEMTOT
X# define MAXMEMTOT 2048 /* use up to 2048Kbyte for Vim */
X#endif
X
X#define BASENAMELEN (MAXNAMLEN - 5)
X
X#define stricmp vim_stricmp
X
X/*
X * prototypes for functions not in unix.c
X */
X#ifdef SCO
Xint chmod __ARGS((const char *, mode_t));
X#endif
X#if !defined(linux) && !defined(__NeXT) && !defined(M_UNIX) && !defined(ISC) && !defined(USL) && !defined(SOLARIS)
Xint remove __ARGS((const char *));
X/*
X * If you get an error message on "const" in the lines above, try
X * adding "-Dconst=" to the options in the makefile.
X */
X
X# if 0 /* should be in unistd.h */
Xvoid sleep __ARGS((int));
X# endif
X
Xint rename __ARGS((const char *, const char *));
X#endif
X
Xint stricmp __ARGS((char *, char *));
X
X/* memmove is not present on all systems, use our own version or bcopy */
X#if !defined(SCO) && !defined(SOLARIS) && !defined(AIX) && !defined(UTS4) && !defined(USL) && !defined(MIPS) && !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(linux) && !defined(UNISYS)
X# ifdef SYSV_UNIX
X# define MEMMOVE
Xvoid *memmove __ARGS((void *, void *, int));
X# else
X# define memmove(to, from, len) bcopy(from, to, len)
X# if !(defined(hpux) && defined(__STDC__))
X# ifdef linux
Xextern void bcopy __ARGS((const void *, void *, int));
X# else
Xextern void bcopy __ARGS((char *, char *, int));


X# endif
X# endif
X# endif
X#endif
X

X#if defined(BSD_UNIX) && !defined(__STDC__)
X# define strchr(ptr, c) index((ptr), (c))
X# define strrchr(ptr, c) rindex((ptr), (c))
X#endif
X
X#ifdef BSD_UNIX
X# define memset(ptr, c, size) bsdmemset((ptr), (c), (size))
Xchar *bsdmemset __ARGS((char *, int, long));
X#endif
X
X/*
X * Most unixes don't have these in include files.
X * If you get a "redefined" error, delete the offending line.
X */
X#if !defined(__NetBSD__) && !defined(__FreeBSD__)
X extern int ioctl __ARGS((int, int, ...));
X#endif
Xextern int fsync __ARGS((int));
Xextern char *getwd __ARGS((char *));
X#if !defined(__NetBSD__) && !defined(__FreeBSD__)
X# ifdef linux
X extern void bzero __ARGS((void *, int));
X# else
X extern void bzero __ARGS((char *, int));
X# endif
X#endif
X#if defined(system_that_does_not_have_access_in_an_include_file)
Xextern int access __ARGS((char *, int));
X#endif
END_OF_FILE
if test 3085 -ne `wc -c <'vim/src/unix.h'`; then
echo shar: \"'vim/src/unix.h'\" unpacked with wrong size!
fi
# end of 'vim/src/unix.h'
fi
if test -f 'vim/termcap' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/termcap'\"
else
echo shar: Extracting \"'vim/termcap'\" \(2694 characters\)
sed "s/^X//" >'vim/termcap' <<'END_OF_FILE'
X#
X# Demonstration of a termcap file
X#
Xsx|ansi|any ansi terminal with pessimistic assumptions:\
X :co#80:li#24:cl=50\E[;H\E[2J:bs:am:cm=\E[%i%d;%dH:\
X :nd=\E[C:up=\E[A:ce=\E[K:ho=\E[H:pt:
XMu|sun|Sun Microsystems Workstation console:\
X :am:bs:km:mi:ms:pt:li#34:co#80:cl=^L:cm=\E[%i%d;%dH:\
X :ce=\E[K:cd=\E[J:\
X :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:rs=\E[s:\
X :md=\E[1m:mr=\E[7m:me=\E[m:\
X :al=\E[L:dl=\E[M:im=:ei=:ic=\E[@:dc=\E[P:\
X :AL=\E[%dL:DL=\E[%dM:IC=\E[%d@:DC=\E[%dP:\
X :up=\E[A:nd=\E[C:ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:\
X :k1=\E[224z:k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:\
X :k6=\E[229z:k7=\E[230z:k8=\E[231z:k9=\E[232z:
XM-|sun-e|sun-nic|sune|Sun Microsystems Workstation without insert character:\
X :ic@:im@:ei@:tc=sun:
XMu|sun-s|Sun Microsystems Workstation window with status line:\
X :hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun:
XMu|sun-e-s|sun-s-e|Sun Microsystems Workstation with status hacked for emacs:\
X :hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun-e:
XM0|sun-48|Sun 48-line window:\
X :li#48:co#80:tc=sun:
XM1|sun-34|Sun 34-line window:\
X :li#34:co#80:tc=sun:
XM2|sun-24|Sun 24-line window:\
X :li#24:co#80:tc=sun:
XM3|sun-17|Sun 17-line window:\
X :li#17:co#80:tc=sun:
Xv9|925a|tvi925a|TeleVideo Model 925:\
X :al=\EE:am:bs:bt=\EI:bw:cd=\EY:ce=\ET:cl=^Z:cm=\E=%+ %+ :co#80:dc=\EW:\
X :dl=\ER:do=^V:ei=:ic=\EQ:if=/usr/share/lib/tabset/std:im=:kb=^H:kd=^V:\
X :kh=^^:kl=^H:kn#12:kr=^L:ku=^K:li#24:nd=^L:pt:se=\EG0:sg#1:so=\EG4:\
X :ue=\EG0:ug#1:ul:up=^K:us=\EG8:is=\El\
X :vb=\Eb\200\200\200\200\200\200\200\200\200\200\200\200\200\200\Ed:\
X :ve=\E.4:vs=\E.2:
Xd0|vt100|vt100-am|vt100am|dec vt100:\
X :do=^J:co#80:li#24:cl=50\E[;H\E[2J:sf=5\ED:\
X :le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
X :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
X :md=2\E[1m:mr=2\E[7m:mb=2\E[5m:me=2\E[m:is=\E[1;24r\E[24;1H:\
X :rf=/usr/share/lib/tabset/vt100:\
X :rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
X :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
X :ho=\E[H:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:pt:sr=5\EM:vt#3:xn:\
X :sc=\E7:rc=\E8:cs=\E[%i%d;%dr:
X# Amiga termcap by Bram Moolenaar
XAA|amiga|Amiga ANSI:\
X :co#80:li#25:am:do=\E[B:ce=\E[K:cd=\E[J:\
X :cl=\014:ku=\233A:kd=\233B:kl=\233D:kr=\233C:kb=^H:\
X :#4=\233 A:%i=\233 @:%1=\233?~:\
X :k1=\2330~:k2=\2331~:k3=\2332~:k4=\2333~:k5=\2334~:\
X :k6=\2335~:k7=\2336~:k8=\2337~:k9=\2338~:k;=\2339~:\
X :F1=\23310~:F2=\23311~:F3=\23312~:F4=\23313~:F5=\23314~:\
X :F6=\23315~:F7=\23316~:F8=\23317~:F9=\23318~:FA=\23319~:\
X :al=\E[L:AL=\E[%dL:dl=\E[M:DL=\E[%dM:le=^H:cm=\E[%i%d;%dH:\
X :nd=\E[C:RI=\E[%dC:up=\E[A:\
X :ce=\E[K:ho=\E[H:dc=\E[P:ic=\E[@:vi=\E[0 p:ve=\E[1 p:\
X :so=\E[2m:se=\E[m:us=\E[4m:ue=\E[m:mr=\E[7m:mb=\E[7;2m:me=\E[m:
X#
X# END OF TERMCAP
X#
END_OF_FILE
if test 2694 -ne `wc -c <'vim/termcap'`; then
echo shar: \"'vim/termcap'\" unpacked with wrong size!
fi
# end of 'vim/termcap'
fi
echo shar: End of archive 24 \(of 26\).
cp /dev/null ark24isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:04:07 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 44
Archive-name: vim/part25

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh


# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/README vim/credits.txt vim/doc/archie.doc
# vim/doc/unix.doc vim/macros/hanoi/hanoi.mac.UU
# vim/macros/hanoi/poster vim/macros/maze/README
# vim/macros/maze/maze_ansi.c vim/macros/maze/poster
# vim/macros/urm/README vim/macros/urm/examples
# vim/macros/urm/urm.UU vim/poster vim/src/amiga.h vim/src/charset.c
# vim/src/keymap.h vim/src/macros.h vim/src/mkcmdtab.c
# vim/src/msdos.h vim/src/ops.h vim/src/proto.h
# vim/src/proto/amiga.pro vim/src/proto/getchar.pro
# vim/src/proto/memfile.pro vim/src/proto/memline.pro
# vim/src/proto/misccmds.pro vim/src/proto/msdos.pro
# vim/src/proto/ops.pro vim/src/proto/screen.pro
# vim/src/proto/search.pro vim/src/proto/term.pro
# vim/src/proto/unix.pro vim/src/proto/window.pro
# vim/src/ptx_stdlib.h vim/src/regexp.h vim/src/sun_stdlib.h
# vim/tutor/poster
# Wrapped by kent@sparky on Mon Aug 15 21:44:16 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 25 (of 26)."'
if test -f 'vim/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/README'\"
else
echo shar: Extracting \"'vim/README'\" \(2187 characters\)
sed "s/^X//" >'vim/README' <<'END_OF_FILE'
XREADME for version 3.0 of Vim: Vi IMproved.
X
XVim is an almost compatible version of the UNIX editor vi. Only the 'Q'
Xcommand is missing (you don't need it). Many new features have been added:
Xmulti level undo, command line history, filename completion, block operations,
Xetc. See difference.doc.
X
XThis editor is very useful for editing programs and other plain ASCII files.
XAll commands are given with normal keyboard characters, so those who can type
Xwith ten fingers can work very fast. Additionally function keys can be defined
Xby the user.
X
XVim currently runs under Amiga DOS, MSDOS, Windows NT and many UNIX versions.
XThere are some things included for the Archimedes, but it does not work yet.
XPorting to other systems should not be very difficult.
X
XDocumentation:
X tutor/readme - one hour training course for beginners
X reference.doc - complete reference of all Vim commands
X difference.doc - summarizes the differences with UNIX vi
X windows.doc - reference for the multi windows and buffer commands
X index - alfabetical list of commands
X amiga.doc - remarks for Amiga
X unix.doc - remarks for unix
X msdos.doc - remarks for MSDOS
X winnt.doc - remarks for Windows NT
X archie.doc - remarks for Archimedes
X
XVim is Charityware. You can copy it as much as you like. Please read
Xuganda.txt for details.
X
X
XCompiling:
X cd src
X cp makefile.<system> makefile
X make
X
XWhen using makefile.unix you MUST uncomment three lines for your system!
X
XThe makefile offers some compilation options. If you do not use digraphs, you
Xcan save some memory by recompiling without the DIGRAPHS option. The Amiga
Xand MS-DOS versions are compiled for a limited number of supported terminals.
XIf you want to use Vim with other terminals you can recompile with the
XTERMCAP option. See the makefiles for further options.
X
XPlease send comments, bug reports and suggestions to:
X
Xstable address: Bram Moolenaar UUCP E-mail: mo...@oce.nl
X molenstraat 2
X 2162 HP Lisse Fax: +31 2521 16381
X The Netherlands Tel: +31 2521 13037
X
XSeptember 1994 - August 1995:
XKibaale Children's Centre Tel: +256 481 21033
Xp.o. box 1658, Masaka, Uganda, East Africa Fax: +256 481 20514
END_OF_FILE
if test 2187 -ne `wc -c <'vim/README'`; then
echo shar: \"'vim/README'\" unpacked with wrong size!
fi
# end of 'vim/README'
fi
if test -f 'vim/credits.txt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/credits.txt'\"
else
echo shar: Extracting \"'vim/credits.txt'\" \(1170 characters\)
sed "s/^X//" >'vim/credits.txt' <<'END_OF_FILE'
XCredits for Vim - Vi Improved
X
XMost of Vim was written by Bram Moolenaar.
X
XParts of reference.doc come from several Vi manuals, written by:
X W.N. Joy
X Alan P.W. Hewett
X Mark Horton
X
XThe editor Vim is based on Stevie and includes (ideas from) other software,
Xworked on by:
X Tim Thompson Stevie
X Tony Andrews Stevie
X G. R. (Fred) Walter Stevie
X Henry Spencer regular expressions
X Steve Kirkendall Elvis
X Juergen Weigert Lattice version, AUX improvements, UNIX and
X MSDOS ports
X Robert Webb Command line completion and other patches
X Olaf Seibert DICE version and regexp improvements
X Peter da Silva termlib
X Chris & John Downey xvi (ideas for multi windows version)
X Loic Grenie xvim (ideas for multi windows version)
X Keith Bostic nvi
X Berkeley DB(3) ideas for swap file
X Ralf Brown SPAWNO library for MSDOS
X
XI must thank all the people that sent me bug reports and suggestions. The
Xlist is too long to mention them all here. And mentioning only a few of them
Xwould be an insult to the others, so I'll don't mention anybody. But Vim
Xwould not be the same without the ideas from all these people. They keep Vim
Xalive!
END_OF_FILE
if test 1170 -ne `wc -c <'vim/credits.txt'`; then
echo shar: \"'vim/credits.txt'\" unpacked with wrong size!
fi
# end of 'vim/credits.txt'
fi
if test -f 'vim/doc/archie.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/archie.doc'\"
else
echo shar: Extracting \"'vim/doc/archie.doc'\" \(1866 characters\)
sed "s/^X//" >'vim/doc/archie.doc' <<'END_OF_FILE'
XThis file contains the particularities for the Archimedes version of Vim.
X
X============================================================================
XThe Archimedes version has not been tested. It probably doesn't work at the
Xmoment, because only patches for Vim version 2.0 were available.
X============================================================================
X
Xvim.hlp needs to be saved as Lib:vimhlp (you should set Lib$Path to be a
Xpath to the directory you want to save this. Your system vimrc file should
Xbe named vimrc in this directory too.)
X
XAnother path to set is Tmp$Path This should be the directory you want vim to
Xuse when it does pipes.
X
XUnixLib's translations means that local .vimrc files should really be named
X/vimrc. Of course vim does these translations, so vim .vimrc will create the
Xfile /vimrc.
X
XYou need a termcap file - I haven't built this in. To install the termcap
Xfile, you need to assign a variable, UnixLib$/etc to your "/etc" directory
Xand copy the file "arctermcap" as "/etc/termcap" You also need your TERM
Xvariable to be set to acorn0 before you use vim. Note also that I've set the
X"cl" command, clear screen to clear to green screen. You can change this if
Xyou want.
X
XErrorfile handling may not work properly. This is not vim's fault, but
XUnixLib's system() and exec() handling. It may be OK for Acorn's cc, but gcc
Xuses exec() and loses redirections, so gcc -c fred.c 2> errorfile doesn't
Xgenerate a valid errorfile. Problem is that this is a biggy within UnixLib
Xto fix, I think.
X
XWhen you call a shell up with :sh and ^Z, you'll get a GOS shell by default.
XThis means that running another application will exit GOS and throw you back
Xinto vim. I'm working on a bash-like shell for the Arc which will get round
Xthis.
X
XIf I've missed anything, please drop me a line and I'll try to fix it.
X
XAlun Jones, a...@aber.ac.uk
END_OF_FILE
if test 1866 -ne `wc -c <'vim/doc/archie.doc'`; then
echo shar: \"'vim/doc/archie.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/archie.doc'
fi
if test -f 'vim/doc/unix.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/doc/unix.doc'\"
else
echo shar: Extracting \"'vim/doc/unix.doc'\" \(796 characters\)
sed "s/^X//" >'vim/doc/unix.doc' <<'END_OF_FILE'
XThis file contains the particularities for the UNIX version of Vim.
X
XThe default help filename is "/usr/local/lib/vim.hlp"
XThe files "$HOME/.vimrc" and "$HOME/.exrc" are used instead of "s:.vimrc" and
X"s:.exrc". Additionally "/usr/local/etc/vimrc" is used first.
X
XTemporary files (for filtering) are put in "/tmp".
X
XWith wildcard expansion you can use <~> (home directory) and <$>
X(environment variable).
X
XBecause terminal updating under UNIX is often slow (e.g. serial line
Xterminal, shell window in suntools), the 'showcommand' and 'ruler' options
Xare default off. If you have a fast terminal, try setting them.
X
XThe file Vim132 is a shell script that can be used to put Vim in 132 column
Xmode on a vt100 and lookalikes.
X
XThe *.info files are for the Amiga. You don't need them with unix.
END_OF_FILE
if test 796 -ne `wc -c <'vim/doc/unix.doc'`; then
echo shar: \"'vim/doc/unix.doc'\" unpacked with wrong size!
fi
# end of 'vim/doc/unix.doc'
fi
if test -f 'vim/macros/hanoi/hanoi.mac.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/hanoi/hanoi.mac.UU'\"
else
echo shar: Extracting \"'vim/macros/hanoi/hanoi.mac.UU'\" \(1557 characters\)
sed "s/^X//" >'vim/macros/hanoi/hanoi.mac.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/hanoi/hanoi.mac
XM<V5T(')E;6%P"G-E="!N;W1E<G-E"G-E="!W<F%P<V-A;@HB('1O('-E="!T
XM:&4@:&5I9VAT(&]F('1H92!T;W=E<BP@8VAA;F=E('1H92!D:6=I="!I;B!T
XM:&4@9F]L;&]W:6YG"B(@='=O(&QI;F5S('1O('1H92!H96EG:'0@>6]U('=A
XM;G0@*'-E;&5C="!F<F]M(#$@=&\@.2D*;6%P('0@-PIM87 A('0@-PIM87 @
XM3" Q1R]T#5@O7C -)% Q1THD06XD0D=#,&4D6#!%,$8D6"]4#4!F#4!H#21!
XM,4=*0&8P;"18;B1050IM87 @9R!)3 H*;6%P($H@+UXP6UYT72HD#0IM87 @
XM6"!X"FUA<"!0(' *;6%P(%4@3 IM87 @02 B9GEL"FUA<"!"(")H>6P*;6%P
XM($,@(F9P"FUA<"!E(")F>3)L"FUA<"!%(")H< IM87 @1B B:'DR; H*(B!I
XM;FET:6%L:7-A=&EO;G,Z"B(@2TT)8VQE86YU<"!B=69F97(*(B!9"6-R96%T
XM92!T;W=E<B!O9B!D97-I<F5D(&AE:6=H= HB($Y/40EC;W!Y(&ET(&%N9"!I
XM;G-T97(@82!4"B(@3D\)8V]P>2!T:&ES(&]N90HB(%,)8VAA;F=E(&QA<W0@
XM8VAA<B!I;G1O(&$@) HB(%()8VAA;F=E(&QA<W0@8VAA<B!I;B!P<F5V:6]U
XM<R!L:6YE(&EN=&\@82!N"B(@5 EI;G-E<G0@='=O(&QI;F5S(&-O;G1A:6YI
XM;F<@82!Z97)O"B(@5@EA9&0@82!L87-T(&QI;F4@8V]N=&%I;FEN9R!A(&)A
XM8VMS;&%S: IM87 @22!+35E.3U%.3U-K4E16"@HB8W)E871E(&5M<'1Y(&QI
XM;F4*;6%P($L@,4=O&PH*(F1E;&5T92!T;R!E;F0@;V8@9FEL90IM87 @32!D
XM1PH*(GEA;FL@;VYE(&QI;F4*;6%P($X@>7D*"B)P=70*;6%P($\@< H*(F1E
XM;&5T92!M;W)E('1H86X@:&5I9VAT+6]F+71O=V5R(&-H87)A8W1E<G,*;6%P
XM('$@=&QL1 H*(F-R96%T92!A('1O=V5R(&]F(&1E<VER960@:&5I9VAT"FUA
XM<"!9(&\P,3(S-#4V-S@Y6ALP<0H*(FEN<V5R="!A(%0@:6X@8V]L=6UN(#$*
XM;6%P(%$@,&E4&PH*(G-U8G-T:71U=&4@;&%S="!C:&%R86-T97(@=VET:"!A
XM(&X*;6%P(%(@)')N"@HB<W5B<W1I='5T92!L87-T(&-H87)A8W1E<B!W:71H
XM(&$@) IM87 @4R D<B0*"B)I;G-E<G0@='=O(&QI;F5S(&-O;G1A:6YI;F<@
XM82!Z97)O"FUA<"!4(&MO, TP#0T;"@HB861D(&$@8F%C:W-L87-H(&%T('1H
X192!E;F0*;6%P(%8@1V\O&PHP
X
Xend
END_OF_FILE
if test 1557 -ne `wc -c <'vim/macros/hanoi/hanoi.mac.UU'`; then
echo shar: \"'vim/macros/hanoi/hanoi.mac.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/hanoi/hanoi.mac'\" \(1097 characters\)
cat vim/macros/hanoi/hanoi.mac.UU | uudecode
if test 1097 -ne `wc -c <'vim/macros/hanoi/hanoi.mac'`; then
echo shar: \"'vim/macros/hanoi/hanoi.mac'\" uudecoded with wrong size!
else
rm vim/macros/hanoi/hanoi.mac.UU
fi
fi
# end of 'vim/macros/hanoi/hanoi.mac.UU'
fi
if test -f 'vim/macros/hanoi/poster' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/hanoi/poster'\"
else
echo shar: Extracting \"'vim/macros/hanoi/poster'\" \(1259 characters\)
sed "s/^X//" >'vim/macros/hanoi/poster' <<'END_OF_FILE'
XArticle 2913 of alt.sources:
XPath: oce-rd1!hp4nl!mcsun!uunet!munnari.oz.au!metro!cluster!swift!softway!otc!gregm
XFrom: gr...@otc.otca.oz.au (Greg McFarlane)
XNewsgroups: comp.sources.d,alt.sources,comp.editors
XSubject: VI SOLVES HANOI
XMessage-ID: <23...@otc.otca.oz>
XDate: 19 Feb 91 01:32:14 GMT
XSender: ne...@otc.otca.oz
XReply-To: gr...@otc.otca.oz.au (Greg McFarlane)
XOrganization: OTC Development Unit, Australia
XLines: 80
XXref: oce-rd1 comp.sources.d:5702 alt.sources:2913 comp.editors:2313
X
XSubmitted-by: gr...@otc.otca.oz.au
XArchive-name: hanoi.vi.macros/part01
X
XEveryone seems to be writing stupid Tower of Hanoi programs.
XWell, here is the stupidest of them all: the hanoi solving vi macros.
X
XSave this article, unshar it, and run uudecode on hanoi.vi.macros.uu.
XThis will give you the macro file hanoi.vi.macros.
XThen run vi (with no file: just type "vi") and type:
X :so hanoi.vi.macros
X g
Xand watch it go.
X
XThe default height of the tower is 7 but can be easily changed by editing
Xthe macro file.
X
XThe disks aren't actually shown in this version, only numbers representing
Xeach disk, but I believe it is possible to write some macros to show the
Xdisks moving about as well. Any takers?
X
X(For maze solving macros, see alt.sources or comp.editors)
X
XGreg
END_OF_FILE
if test 1259 -ne `wc -c <'vim/macros/hanoi/poster'`; then
echo shar: \"'vim/macros/hanoi/poster'\" unpacked with wrong size!
fi
# end of 'vim/macros/hanoi/poster'
fi
if test -f 'vim/macros/maze/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/README'\"
else
echo shar: Extracting \"'vim/macros/maze/README'\" \(1666 characters\)
sed "s/^X//" >'vim/macros/maze/README' <<'END_OF_FILE'
XTo prove that you can do anything in vi, I wrote a couple of macros that
Xallows vi to solve mazes. It will solve any maze produced by maze.c
Xthat was posted to the net recently.
X
XJust follow this recipe and SEE FOR YOURSELF.
X 1. run uudecode on the file "maze.vi.macros.uu" to
X produce the file "maze.vi.macros"
X (If you can't wait to see the action, jump to step 4)
X 2. compile maze.c with "cc -o maze maze.c"
X 3. run maze > maze.out and input a small number (for example 10 if
X you are on a fast machine, 3-5 if slow) which
X is the size of the maze to produce
X 4. edit the maze (vi maze.out)
X 5. include the macros with the vi command:
X :so maze.vi.macros
X 6. type the letter "g" (for "go") and watch vi solve the maze
X 7. when vi solves the maze, you will see why it lies
X 8. now look at maze.vi.macros and all will be revealed
X
XTested on a sparc, a sun and a pyramid (although maze.c will not compile
Xon the pyramid).
X
XAnyone who can't get the maze.c file to compile, get a new compiler,
Xtry maze.ansi.c which was also posted to the net.
XIf you can get it to compile but the maze comes out looking like a fence
Xand not a maze and you are using SysV or DOS replace the "27" on the
Xlast line of maze.c by "11"
XThanks to John Tromp (tr...@piring.cwi.nl) for maze.c.
XThanks to ant...@nntp-server.caltech.edu (Bill T. Cat) for maze.ansi.c.
X
XAny donations should be in unmarked small denomination bills :^)=.
X
X ACSnet: gr...@otc.otca.oz.au
XGreg McFarlane UUCP: {uunet,mcvax}!otc.otca.oz.au!gregm
X|||| OTC || Snail: OTC R&D GPO Box 7000, Sydney 2001, Australia
X Phone: +61 2 287 3139 Fax: +61 2 287 3299
X
X
END_OF_FILE
if test 1666 -ne `wc -c <'vim/macros/maze/README'`; then
echo shar: \"'vim/macros/maze/README'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/README'
fi
if test -f 'vim/macros/maze/maze_ansi.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/maze_ansi.c'\"
else
echo shar: Extracting \"'vim/macros/maze/maze_ansi.c'\" \(441 characters\)
sed "s/^X//" >'vim/macros/maze/maze_ansi.c' <<'END_OF_FILE'
Xchar*M,A,Z,E=40,J[80],T[3];main(C){for(M=J+E,*J=A=scanf("%d",&
XC) ;-- E;J [E ]=M
X[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|"
X) , A = 39 ,C --
X) ; Z || printf (T ))T[Z]=Z[A-(E =A[J-Z])&&!C
X& A == M[ A]
X|6<<11<rand()||!C&!Z?J[M[E]=M[A]]=E,J[M[A]=A-Z]=A,"_.":" |"];}
END_OF_FILE
if test 441 -ne `wc -c <'vim/macros/maze/maze_ansi.c'`; then
echo shar: \"'vim/macros/maze/maze_ansi.c'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/maze_ansi.c'
fi
if test -f 'vim/macros/maze/poster' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/poster'\"
else
echo shar: Extracting \"'vim/macros/maze/poster'\" \(1562 characters\)
sed "s/^X//" >'vim/macros/maze/poster' <<'END_OF_FILE'
XArticle 2846 of alt.sources:
XPath: oce-rd1!hp4nl!mcsun!uunet!munnari.oz.au!metro!otc!gregm
XFrom: gr...@otc.otca.oz.au (Greg McFarlane)
XNewsgroups: alt.sources
XSubject: VI SOLVES MAZE (commented macros)
XMessage-ID: <22...@otc.otca.oz>
XDate: 10 Feb 91 23:31:02 GMT
XSender: ne...@otc.otca.oz
XReply-To: gr...@otc.otca.oz.au (Greg McFarlane)
XOrganization: OTC Development Unit, Australia
XLines: 464
X
XSubmitted-by: gr...@otc.otca.oz.au
XArchive-name: maze_solving_vi_macros
X
XA real working model. See it walk the maze in front of your very own eyes.
X
XTo prove that you can do anything in vi, I wrote a couple of macros that
Xallows vi to solve mazes. It will solve any maze produced by maze.c
Xthat was posted to the alt.sources last month. (Maze.c is also included
Xin this posting as well as an example of its output.)
X
XThe uncommented version of the macros was sent to alt.sources last month.
XHowever, so many people mailed me requesting the commented version of the
Xmacros that I decided to post it. I have made some modifications to the
Xoriginal macros to make them easier to follow and also after I learnt
Xthat you can escape the special meaning of '|' in macros by using '^V|'.
X
XSave this article and unshar it. Then read maze.README.
X
XAfter studying these macros, anyone who cannot write an emacs emulator
Xin vi macros should just curl up and :q!.
X
XComing soon to a newsgroup near you: "Vi macros solve Tower of Hanoi",
Xand a repost of the original "Turing Machine implemented in Vi macros"
X
XAnyone who has a version of these macros for edlin or nroff, please post.
END_OF_FILE
if test 1562 -ne `wc -c <'vim/macros/maze/poster'`; then
echo shar: \"'vim/macros/maze/poster'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/poster'
fi
if test -f 'vim/macros/urm/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/urm/README'\"
else
echo shar: Extracting \"'vim/macros/urm/README'\" \(1651 characters\)
sed "s/^X//" >'vim/macros/urm/README' <<'END_OF_FILE'
XThis is another proof that vim is perfectly compatible with SYSV-vi.
XThe URM macro package was written by Rudolf Koenig ("Rudi")
X(rfko...@immd4.uni-erlangen.de) for hpux-vi in August 1991.
X
XGetting started:
X
Xtype
Xin your shell: vim urm<RETURN>
Xin vim: :so urm.mac<RETURN>
Xin vim: * (to load the registers and boot the URM-machine :-)
Xin vim: g (for 'go') and watch the fun. Per default, 3 and 4
X are multiplied. Watch the Program counter, it is
X visible as a komma moving around.
X
XThis is a "standard URM" (Universal register machine) interpreter. The URM
Xconcept is used in theoretical computer science to aid in theorem proving.
XHere it proves that vim is a general problem solver (if you bring enough
Xpatience).
X
XThe interpreter begins with register 1 (not 0), without macros and more-lines
Xcapability. A dot marks the end of a program. (Bug: there must be a space
Xafter the dot.)
X
XThe registers are the first few lines, beginning with a '>' .
XThe program is the first line after the registers.
XYou should always initialize the registers required by the program.
X
XOutput register: line 2
XInput registers: line 2 to ...
X
XCommands:
Xa<n> increment register <n>
Xs<n> decrement register <n>
X<x>;<y> execute command <x> and then <y>
X(<x>)<n> execute command <x> while register <n> is nonzero
X. ("dot blank") halt the machine.
X
XExamples:
X
XAdd register 2 to register 3:
X (a2;s3)3.
XMultiply register 2 with register 3:
X (a4;a5;s2)2; ((a2;s4)4; s3; (a1;a4;s5)5; (a5;s1)1)3.
X
XThere are more (complicated) examples in the file examples.
XNote, undo may take a while after a division.
X
END_OF_FILE
if test 1651 -ne `wc -c <'vim/macros/urm/README'`; then
echo shar: \"'vim/macros/urm/README'\" unpacked with wrong size!
fi
# end of 'vim/macros/urm/README'
fi
if test -f 'vim/macros/urm/examples' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/urm/examples'\"
else
echo shar: Extracting \"'vim/macros/urm/examples'\" \(1092 characters\)
sed "s/^X//" >'vim/macros/urm/examples' <<'END_OF_FILE'
XNote that enough temporary registers should be provided for each example.
XAll should be initialised to 0.
X
XInitial register values for benchmarking: 0,8,3,0,...
X
XPerformed on a Xenix 386/16:
XOperation [sec, kbyte tmp space]: program
X
XAsym. Diff.[ 7, 4]: (s2;s3)3.
XAbs. Diff. [90,81]: (a1;a4;s2)2; (a2;s1)1; (a1;a5;s3)3; (a3;s1)1; (s2;s3)3; (s5;s4)4; (a2;s5)5.
XAdd [ 7, 4]: (a2;s3)3.
XMult [227, 161]: (a4;a5;s2)2; ((a2;s4)4; s3; (a1;a4;s5)5; (a5;s1)1)3.
XCopy [ 48, 25]: (a1;a3;s2)2; (a2;s1)1.
Xsign [ 30, 17]: (a3;s2)2; (a2;(s3)3)3.
X!sign[ 36, 28]: (a3;s2)2; (a2;(s3)3)3; a3; (s3;s2)2; (s3;a2)3.
XDiv [630,1522]: (a9;s2)2; (a2;a10;s3)3; (a3;s2)2; (a2;(s3)3)3; a3; (s3;s2)2; (s3;a2)3; (a2)2;(a2;s9)9;(a3;s10)10; (a9;a10;s2)2; (a11;a12;s3)3; (a2;s12)12; (a3;s9)9; (s2;s3)3; (a3;s2)2; (a2;(s3)3)3; a3; (s3;s2)2; (s3;a2)3; (a1;s2)2; (a2;s10)10; (a3;s11)11; ((a12;a13;s3)3; (a3;s13)13; (s2;s3)3; (a3;s12)12; a14; (s1)1; (a9;a10;s2)2; (a11;a12;s3)3; (a2;s12)12; (a3;s9)9; (s2;s3)3; (a3;s2)2; (a2;(s3)3)3; a3; (s3;s2)2; (s3;a2)3; (a1;s2)2; (a2;s10)10; (a3;s11)11)1; (s2)2; (a2;s14)14.
END_OF_FILE
if test 1092 -ne `wc -c <'vim/macros/urm/examples'`; then
echo shar: \"'vim/macros/urm/examples'\" unpacked with wrong size!
fi
# end of 'vim/macros/urm/examples'
fi
if test -f 'vim/macros/urm/urm.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/urm/urm.UU'\"
else
echo shar: Extracting \"'vim/macros/urm/urm.UU'\" \(903 characters\)
sed "s/^X//" >'vim/macros/urm/urm.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/urm/urm
XM/C */C,*/C0*/C */C */C **&$T.V$U.W,R*3([("@H83([<S0I-#L@<S,[
XM("AA,3MA-#MS-2DU.R H834[<S$I,2DS+B *7U]?7U]?7U]?"D\).R ]>' @
XM*" ]>"5H<" I($!L(&$@0&1B(',@0&1T("X@/7@P>&MD9#IR96%D>2!?96YD
XM7PIO"3 @,2 R(#,@-" U(#8@-R X(#D@, I?7U]?7U]?7U\*24Y)5"!M86EN
XM*&LI+"!L+"!B+"!C+"!T+"!U+"!Q+"!D( H-(FM4#2)L5 TB8E0-(F-4#2)T
XM5 TB=50-(G%4#2)D5 H];$8G=V$O3Q8-9AMP87<B>F1T(&AP0'H;,")X1$!X
XM0&L*/3)L9'=H<"=W:4=4)W=P&S!0,")Y1$!Y82 ]>&QW4" ^," ]>"5P(!M)
XM(!MK+SXP#7=W(GED=" P1$!Y"B=W82]O%@UF=T8G=W!I8&%R%AL;8&%&)W=F
XM9G P(G9$0'8P(G9$<# S>$!V)W=A($!C(# @," ;,$D@&V8P=R)W9'0@,$1
XM=PI@86AM848G=V$@("=A83$6&R ^($!B(!LP<#!F/G<B=F1T(#!$0'8*)W=A
XM+V\6#7=F8D8G=W!I8&%R%AL;8&%&)W=F9G P(G9$0'8P(G9$<# S>$!V)W=A
XM($!U(#D@," ;,$D@&V8Y=R)W9'0@,$1 =PI@86AM848G=V$@(&!A;'(P(#X@
XM0'$@&S!P,&8^=R)V9'0@,$1 =@I@86AY,FPG=V$@(&!A>" ^,2! =" ;,' P
XM+SXQ#7=W(FED=" P1$!I"CUX=VAP8FQD=VAP)W=P84<D;6$;,")Y1$!Y0 H*
X
Xend
END_OF_FILE
if test 903 -ne `wc -c <'vim/macros/urm/urm.UU'`; then
echo shar: \"'vim/macros/urm/urm.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/urm/urm'\" \(630 characters\)
cat vim/macros/urm/urm.UU | uudecode
if test 630 -ne `wc -c <'vim/macros/urm/urm'`; then
echo shar: \"'vim/macros/urm/urm'\" uudecoded with wrong size!
else
rm vim/macros/urm/urm.UU
fi
fi
# end of 'vim/macros/urm/urm.UU'
fi
if test -f 'vim/poster' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/poster'\"
else
echo shar: Extracting \"'vim/poster'\" \(1584 characters\)
sed "s/^X//" >'vim/poster' <<'END_OF_FILE'
XVim - Vi IMproved. A clone of the UNIX text editor Vi. Very useful for
Xediting programs and other plain ASCII text. Full Vi compatibility (except Q
Xcommand, you don't need it). Includes most Ex commands.
X
XExtra features above Vi: Multilevel undo, command line history, improved
Xcommand line editing, command typeahead display, command to display yank
Xbuffers, possibility to edit binary files, line wrapping can be switched off,
Xfile name stack, can be adjusted to understand error messages from any
Xcompiler, shows current file name in window title, on-line help, etc.
X
XVersion 2.0, update to 1.27. Most important changes:
X- 'wrap' option to switch line wrapping on/off
X- filename completion is more like other programs and adjustable
X- automatic detection of CR/LF line separator
X- '-b' command line option to make editing binary files more easy
X- added abbreviation
X- :make command for quickly jumping to errors
X- MSDOS version uses bios calls for screen output, ansi.sys not needed
X- many small changes to make Vim more vi-compatible
X
XPortability: Runs on MSDOS, Amiga and several UNIX versions.
X
XDistribution:
Xcomp.binaries.ibm.pc: vim_dos.zip: MSDOS binary and documentation
X
Xcomp.binaries.amiga: vim_bin.lha: Amiga binary and documentation
X
Xcomp.sources.misc: shell archive with sources and documentation
X
XThe documentation is almost the same for all systems. For MSDOS CR-LF is used
Xfor line separator. For Amiga .info files are included. For the shell archive
Xsome files are uuencoded because of unprintable characters.
X
XVim is charityware. Read uganda.txt for details.
END_OF_FILE
if test 1584 -ne `wc -c <'vim/poster'`; then
echo shar: \"'vim/poster'\" unpacked with wrong size!
fi
# end of 'vim/poster'
fi
if test -f 'vim/src/amiga.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/amiga.h'\"
else
echo shar: Extracting \"'vim/src/amiga.h'\" \(972 characters\)
sed "s/^X//" >'vim/src/amiga.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Amiga Machine-dependent things
X */
X
X/*
X * Names for the EXRC, HELP and temporary files.
X * Some of these may have been defined in the makefile.
X */
X
X#ifndef SYSVIMRC_FILE
X# define SYSVIMRC_FILE "s:.vimrc"
X#endif
X
X#ifndef SYSEXRC_FILE
X# define SYSEXRC_FILE "s:.exrc"


X#endif
X
X#ifndef VIMRC_FILE
X# define VIMRC_FILE ".vimrc"
X#endif
X
X#ifndef EXRC_FILE
X# define EXRC_FILE ".exrc"
X#endif
X

X#ifndef VIM_HLP
X# define VIM_HLP "vim:vim.hlp"
X#endif
X
X#ifndef DEF_DIR
X# define DEF_DIR "t:"
X#endif
X
X#define TMPNAME1 "t:viXXXXXX"
X#define TMPNAME2 "t:voXXXXXX"
X#define TMPNAMELEN 12
X
X#ifndef MAXMEM
X# define MAXMEM 256 /* use up to 256Kbyte for buffer */
X#endif
X#ifndef MAXMEMTOT
X# define MAXMEMTOT 0 /* decide in set_init */
X#endif
X
X#define BASENAMELEN 26 /* Amiga */
END_OF_FILE
if test 972 -ne `wc -c <'vim/src/amiga.h'`; then
echo shar: \"'vim/src/amiga.h'\" unpacked with wrong size!
fi
# end of 'vim/src/amiga.h'
fi
if test -f 'vim/src/charset.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/charset.c'\"
else
echo shar: Extracting \"'vim/src/charset.c'\" \(1740 characters\)
sed "s/^X//" >'vim/src/charset.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X#include "vim.h"
X#include "globals.h"
X#include "proto.h"
X#include "param.h"
X
X

X char_u *
Xtranschar(c)
X int c;
X{
X static char_u buf[3];
X
X if (c < ' ' || c == DEL)
X {
X if (c == NL)
X c = NUL; /* we use newline in place of a NUL */
X buf[0] = '^';
X buf[1] = c ^ 0x40; /* DEL displayed as ^? */
X buf[2] = NUL;
X }
X else if (c <= '~' || c > 0xa0 || p_gr)


X {
X buf[0] = c;
X buf[1] = NUL;

X }
X else
X {
X buf[0] = '~';
X buf[1] = c - 0x80 + '@';
X buf[2] = NUL;
X }
X return buf;
X}
X
X/*
X * return the number of characters 'c' will take on the screen
X */
X int
Xcharsize(c)
X int c;
X{
X return ((c >= ' ' && (p_gr || c <= '~')) || c > 0xa0 ? 1 : 2);
X}
X
X/*
X * return the number of characters string 's' will take on the screen
X */
X int
Xstrsize(s)
X char_u *s;
X{
X int len = 0;
X
X while (*s)
X len += charsize(*s++);
X return len;
X}
X
X/*
X * return the number of characters 'c' will take on the screen, taking
X * into account the size of a tab
X */
X int
Xchartabsize(c, col)
X register int c;
X long col;
X{
X if ((c >= ' ' && (c <= '~' || p_gr)) || c > 0xa0)
X return 1;
X else if (c == TAB && !curwin->w_p_list)
X return (int)(curbuf->b_p_ts - (col % curbuf->b_p_ts));


X else
X return 2;

X}
X
X/*
X * return TRUE if 'c' is an identifier character
X */
X int
Xisidchar(c)
X int c;
X{
X return (
X#ifdef __STDC__
X isalnum(c)
X#else
X isalpha(c) || isdigit(c)
X#endif
X || c == '_'
X /*
X * we also accept alhpa's with accents
X */
X#ifdef MSDOS
X || (c >= 0x80 && c <= 0xa7) || (c >= 0xe0 && c <= 0xeb)
X#else
X || (c >= 0xc0 && c <= 0xff)
X#endif
X );
X}
END_OF_FILE
if test 1740 -ne `wc -c <'vim/src/charset.c'`; then
echo shar: \"'vim/src/charset.c'\" unpacked with wrong size!
fi
# end of 'vim/src/charset.c'
fi
if test -f 'vim/src/keymap.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/keymap.h'\"
else
echo shar: Extracting \"'vim/src/keymap.h'\" \(2098 characters\)
sed "s/^X//" >'vim/src/keymap.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * Keycode definitions for special keys
X *
X * On systems that have any of these keys, the routine 'inchar' in the
X * machine-dependent code should return one of the codes here.
X */
X
X/*
X * On MSDOS we use other codes, because the codes 0x80 - 0xb0 are used
X * for special characters. If this is changed also change the numbers in
X * term.h and main.c.
X */
X#ifdef MSDOS
X# define K_OFF 0x30
X#else
X# define K_OFF 0x00
X#endif
X
X#define K_CCIRCM 0x1e /* control circumflex */
X
X/*
X * careful: the next entries must be in the same order as the termcap strings
X * in term.h and the numbers must be consecutive (used by inchar()).
X */
X#define K_UARROW (K_OFF + 0x80)
X#define K_DARROW (K_OFF + 0x81)
X#define K_LARROW (K_OFF + 0x82)
X#define K_RARROW (K_OFF + 0x83)
X#define K_SUARROW (K_OFF + 0x84)
X#define K_SDARROW (K_OFF + 0x85)
X#define K_SLARROW (K_OFF + 0x86)
X#define K_SRARROW (K_OFF + 0x87)
X
X#define K_F1 (K_OFF + 0x88) /* function keys */
X#define K_F2 (K_OFF + 0x89)
X#define K_F3 (K_OFF + 0x8a)
X#define K_F4 (K_OFF + 0x8b)
X#define K_F5 (K_OFF + 0x8c)
X#define K_F6 (K_OFF + 0x8d)
X#define K_F7 (K_OFF + 0x8e)
X#define K_F8 (K_OFF + 0x8f)
X#define K_F9 (K_OFF + 0x90)
X#define K_F10 (K_OFF + 0x91)
X
X#define K_SF1 (K_OFF + 0x92) /* shifted function keys */
X#define K_SF2 (K_OFF + 0x93)
X#define K_SF3 (K_OFF + 0x94)
X#define K_SF4 (K_OFF + 0x95)
X#define K_SF5 (K_OFF + 0x96)
X#define K_SF6 (K_OFF + 0x97)
X#define K_SF7 (K_OFF + 0x98)
X#define K_SF8 (K_OFF + 0x99)
X#define K_SF9 (K_OFF + 0x9a)
X#define K_SF10 (K_OFF + 0x9b)
X
X#define K_HELP (K_OFF + 0x9c)
X#define K_UNDO (K_OFF + 0x9d)
X
X/*
X * NULs cannot be in the input string, therefore CTRL-@ is replaced by K_ZERO.
X * K_NUL is used for MSDOS extended keys (same value used in term.h).
X */
X#define K_NUL (K_OFF + 0x9e) /* for MSDOS: special key follows */
X#define K_ZERO (K_OFF + 0x9f) /* replaces ^@ */
END_OF_FILE
if test 2098 -ne `wc -c <'vim/src/keymap.h'`; then
echo shar: \"'vim/src/keymap.h'\" unpacked with wrong size!
fi
# end of 'vim/src/keymap.h'
fi
if test -f 'vim/src/macros.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/macros.h'\"
else
echo shar: Extracting \"'vim/src/macros.h'\" \(1239 characters\)
sed "s/^X//" >'vim/src/macros.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * macros.h: macro definitions for often used code
X */
X
X/*
X * pchar(lp, c) - put character 'c' at position 'lp'
X */
X#define pchar(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
X
X/*
X * Position comparisons
X */
X#define lt(a, b) (((a).lnum != (b).lnum) \
X ? ((a).lnum < (b).lnum) : ((a).col < (b).col))
X
X#define ltoreq(a, b) (((a).lnum != (b).lnum) \
X ? ((a).lnum < (b).lnum) : ((a).col <= (b).col))
X
X#define equal(a, b) (((a).lnum == (b).lnum) && ((a).col == (b).col))
X
X/*
X * lineempty() - return TRUE if the line is empty
X */
X#define lineempty(p) (*ml_get(p) == NUL)
X
X/*
X * bufempty() - return TRUE if the file buffer is empty
X */
X#define bufempty() (curbuf->b_ml.ml_flags & ML_EMPTY)
X
X/*
X * On some systems toupper()/tolower() only work on lower/uppercase characters
X */
X#if defined(sequent) || defined(DOMAIN) || !defined(__STDC__)
X# define TO_UPPER(c) (islower(c) ? toupper(c) : (c))
X# define TO_LOWER(c) (isupper(c) ? tolower(c) : (c))
X#else
X# define TO_UPPER toupper
X# define TO_LOWER tolower
X#endif
END_OF_FILE
if test 1239 -ne `wc -c <'vim/src/macros.h'`; then
echo shar: \"'vim/src/macros.h'\" unpacked with wrong size!
fi
# end of 'vim/src/macros.h'
fi
if test -f 'vim/src/mkcmdtab.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/mkcmdtab.c'\"
else
echo shar: Extracting \"'vim/src/mkcmdtab.c'\" \(2079 characters\)
sed "s/^X//" >'vim/src/mkcmdtab.c' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * mkcmdtab.c: separate program that reads cmdtab.tab and produces cmdtab.h
X *
X * call with: mkcmdtab cmdtab.tab cmdtab.h


X */
X
X#include "vim.h"
X

X#if defined(UTS4)
X int
X#else
X void
X#endif


Xmain(argc, argv)
X int argc;
X char **argv;
X{

X register int c;
X char buffer[100];
X int count;
X int i;
X FILE *ifp, *ofp;
X
X if (argc != 3)
X {
X fprintf(stderr, "Usage: mkcmdtab cmdtab.tab cmdtab.h\n");
X exit(10);
X }
X ifp = fopen(argv[1], "r");
X if (ifp == NULL)
X {
X perror(argv[1]);
X exit(10);
X }
X ofp = fopen(argv[2], "w");
X if (ofp == NULL)
X {
X perror(argv[2]);
X exit(10);
X }
X
X while ((c = getc(ifp)) != '|' && c != EOF)
X putc(c, ofp);
X fprintf(ofp, "THIS FILE IS AUTOMATICALLY PRODUCED - DO NOT EDIT");
X while ((c = getc(ifp)) != '|' && c != EOF)
X ;
X while ((c = getc(ifp)) != '|' && c != EOF)
X putc(c, ofp);
X
X count = 0;
X while ((c = getc(ifp)) != '|' && c != EOF)
X {
X putc(c, ofp);
X while ((c = getc(ifp)) != '"' && c != EOF)
X putc(c, ofp);
X putc(c, ofp);
X
X i = 0;
X while ((c = getc(ifp)) != '"' && c != EOF)
X {
X putc(c, ofp);
X buffer[i++] = c;
X }
X putc(c, ofp);
X buffer[i] = 0;
X
X while ((c = getc(ifp)) != '\n' && c != EOF)
X putc(c, ofp);
X putc(c, ofp);
X
X switch (buffer[0])
X {
X case '@': strcpy(buffer, "at");
X break;
X case '!': strcpy(buffer, "bang");
X break;
X case '<': strcpy(buffer, "lshift");
X break;
X case '>': strcpy(buffer, "rshift");
X break;
X case '=': strcpy(buffer, "equal");
X break;
X case '&': strcpy(buffer, "and");
X break;
X case '~': strcpy(buffer, "tilde");
X break;
X case '#': strcpy(buffer, "pound");
X break;
X }
X
X fprintf(ofp, "#define CMD_%s %d\n", buffer, count++);
X }
X
X fprintf(ofp, "#define CMD_SIZE %d\n", count);
X
X while ((c = getc(ifp)) != '|' && c != EOF)
X putc(c, ofp);
X
X if (c != '|')
X {
X fprintf(stderr, "not enough |'s\n");
X exit(1);
X }
X exit(0);
X}
END_OF_FILE
if test 2079 -ne `wc -c <'vim/src/mkcmdtab.c'`; then
echo shar: \"'vim/src/mkcmdtab.c'\" unpacked with wrong size!
fi
# end of 'vim/src/mkcmdtab.c'
fi
if test -f 'vim/src/msdos.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/msdos.h'\"
else
echo shar: Extracting \"'vim/src/msdos.h'\" \(1318 characters\)
sed "s/^X//" >'vim/src/msdos.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * MSDOS Machine-dependent things.
X */
X
X/*
X * Names for the EXRC, HELP and temporary files.
X * Some of these may have been defined in the makefile.
X */
X
X#ifndef SYSVIMRC_FILE
X# define SYSVIMRC_FILE "$VIM\\_vimrc"
X#endif
X
X#ifndef SYSEXRC_FILE
X# define SYSEXRC_FILE "$VIM\\_exrc"
X#endif
X
X#ifndef VIMRC_FILE
X# define VIMRC_FILE "_vimrc"
X#endif
X
X#ifndef EXRC_FILE
X# define EXRC_FILE "_exrc"
X#endif
X
X#ifndef VIM_HLP
X# define VIM_HLP "$VIM\\vim.hlp"
X#endif
X
X#ifndef DEF_DIR
X# define DEF_DIR "c:\\tmp"
X#endif
X
X#define TMPNAME1 "viXXXXXX" /* put it in current dir */
X#define TMPNAME2 "voXXXXXX" /* is there a better place? */
X#define TMPNAMELEN 10
X
X#ifndef MAXMEM
X# define MAXMEM 256 /* use up to 256Kbyte for buffer */
X#endif
X#ifndef MAXMEMTOT
X# define MAXMEMTOT 0 /* decide in set_init */
X#endif
X
X#define BASENAMELEN 8 /* length of base of file name */
X
X/*
X * MSDOS Machine-dependent routines.
X */
X
X#ifdef remove
X# undef remove /* MSDOS remove()s when not readonly */
X#endif
X#define remove vim_remove
X
X/* use chdir() that also changes the default drive */
X#define chdir vim_chdir
END_OF_FILE
if test 1318 -ne `wc -c <'vim/src/msdos.h'`; then
echo shar: \"'vim/src/msdos.h'\" unpacked with wrong size!
fi
# end of 'vim/src/msdos.h'
fi
if test -f 'vim/src/ops.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/ops.h'\"
else
echo shar: Extracting \"'vim/src/ops.h'\" \(1805 characters\)
sed "s/^X//" >'vim/src/ops.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * ops.h: things shared between normal.c, cmdline.c and ops.c
X */
X
X/*
X * Operators
X */
X#define NOP 0 /* no pending operation */
X#define DELETE 1
X#define YANK 2
X#define CHANGE 3
X#define LSHIFT 4
X#define RSHIFT 5
X#define FILTER 6
X#define TILDE 7
X#define INDENT 8
X#define FORMAT 9
X#define COLON 10
X#define UPPER 11
X#define LOWER 12
X
X/*
X * operator characters; the order must correspond to the defines above
X */
XEXTERN char_u *opchars INIT(= (char_u *)"dyc<>!~=Q:Uu");
X
X/*
X * When a cursor motion command is made, it is marked as being a character or
X * line oriented motion. Then, if an operator is in effect, the operation
X * becomes character or line oriented accordingly.
X *
X * Character motions are marked as being inclusive or not. Most char. motions
X * are inclusive, but some (e.g. 'w') are not.
X *
X * Generally speaking, every command in normal() should either clear any pending
X * operator (with CLEAROP), or set the motion type variable.
X */
X
X/*
X * Motion types
X */
X#define MBAD (-1) /* 'bad' motion type marks unusable yank buf */
X#define MCHAR 0
X#define MLINE 1
X#define MBLOCK 2
X
XEXTERN int operator INIT(= NOP); /* current pending operator */
XEXTERN int mtype; /* type of the current cursor motion */
XEXTERN int mincl; /* true if char motion is inclusive */
XEXTERN colnr_t startvcol; /* start col for block mode operator */
XEXTERN colnr_t endvcol; /* end col for block mode operator */
XEXTERN long nlines; /* lines between startop and endop + 1 */
XEXTERN int yankbuffer INIT(= 0); /* current yank buffer */
XEXTERN int no_op; /* startop and endop the same */
END_OF_FILE
if test 1805 -ne `wc -c <'vim/src/ops.h'`; then
echo shar: \"'vim/src/ops.h'\" unpacked with wrong size!
fi
# end of 'vim/src/ops.h'
fi
if test -f 'vim/src/proto.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto.h'\"
else
echo shar: Extracting \"'vim/src/proto.h'\" \(1573 characters\)
sed "s/^X//" >'vim/src/proto.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * proto.h: include the (automatically generated) function prototypes
X *
X * the proto/xxx.pro files are automatically generated when using Manx/Aztec C.
X * For other compilers you will have to edit them.
X */
X
X#include "regexp.h" /* for struct regexp */
X
X/*
X * Machine-dependent routines.
X */
X#ifdef AMIGA
X# include "proto/amiga.pro"
X#endif
X#ifdef UNIX
X# include "proto/unix.pro"
X#endif
X#ifdef MSDOS
X# include "proto/msdos.pro"
X#endif
X
X#include "proto/alloc.pro"
X#include "proto/buffer.pro"
X#include "proto/charset.pro"
X#include "proto/cmdcmds.pro"
X#include "proto/cmdline.pro"
X#include "proto/csearch.pro"
X#include "proto/digraph.pro"
X#include "proto/edit.pro"
X#include "proto/fileio.pro"
X#include "proto/getchar.pro"
X#include "proto/help.pro"
X#include "proto/linefunc.pro"
X#include "proto/main.pro"
X#include "proto/mark.pro"
X
X#ifndef MESSAGE
Xvoid smsg __PARMS((char_u *, ...)); /* cannot be produced automatically */
X#endif
X#include "proto/memfile.pro"
X#include "proto/memline.pro"
X#include "proto/message.pro"
X#include "proto/misccmds.pro"
X#include "proto/normal.pro"
X#include "proto/ops.pro"
X#include "proto/param.pro"
X#include "proto/quickfix.pro"
X#include "proto/regexp.pro"
X#include "proto/regsub.pro"
X#include "proto/screen.pro"
X#include "proto/search.pro"
X#include "proto/tag.pro"
X#include "proto/term.pro"
X#include "proto/undo.pro"
X#include "proto/window.pro"
END_OF_FILE
if test 1573 -ne `wc -c <'vim/src/proto.h'`; then
echo shar: \"'vim/src/proto.h'\" unpacked with wrong size!
fi
# end of 'vim/src/proto.h'
fi
if test -f 'vim/src/proto/amiga.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/amiga.pro'\"
else
echo shar: Extracting \"'vim/src/proto/amiga.pro'\" \(1580 characters\)
sed "s/^X//" >'vim/src/proto/amiga.pro' <<'END_OF_FILE'
X/* amiga.c */
Xvoid win_resize_on __PARMS((void));
Xvoid win_resize_off __PARMS((void));
Xvoid mch_write __PARMS((unsigned char *p, int len));
Xint GetChars __PARMS((unsigned char *buf, int maxlen, int time));
Xint mch_char_avail __PARMS((void));
Xvoid sleep __PARMS((int n));
Xlong mch_avail_mem __PARMS((int special));
Xvoid vim_delay __PARMS((void));
Xvoid mch_suspend __PARMS((void));
Xvoid mch_windinit __PARMS((void));
Xvoid check_win __PARMS((int argc, char **argv));
Xvoid fname_case __PARMS((unsigned char *name));
Xvoid mch_settitle __PARMS((unsigned char *title, unsigned char *icon));
Xvoid mch_restore_title __PARMS((int which));
Xint vim_dirname __PARMS((unsigned char *buf, int len));
Xint FullName __PARMS((unsigned char *fname, unsigned char *buf, int len));
Xint isFullName __PARMS((unsigned char *fname));
Xlong getperm __PARMS((unsigned char *name));
Xint setperm __PARMS((unsigned char *name, long perm));
Xint isdir __PARMS((unsigned char *name));
Xvoid mch_windexit __PARMS((int r));
Xvoid mch_settmode __PARMS((int raw));
Xint mch_screenmode __PARMS((unsigned char *arg));
Xint mch_get_winsize __PARMS((void));
Xvoid mch_set_winsize __PARMS((void));
Xint call_shell __PARMS((unsigned char *cmd, int filter, int cooked));
Xvoid breakcheck __PARMS((void));
Xlong Chk_Abort __PARMS((void));
Xint ExpandWildCards __PARMS((int num_pat, unsigned char **pat, int *num_file, unsigned char ***file, int files_only, int list_notfound));
Xvoid FreeWild __PARMS((int num, unsigned char **file));
Xint has_wildcard __PARMS((unsigned char *p));
Xunsigned char *vimgetenv __PARMS((unsigned char *var));
END_OF_FILE
if test 1580 -ne `wc -c <'vim/src/proto/amiga.pro'`; then
echo shar: \"'vim/src/proto/amiga.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/amiga.pro'
fi
if test -f 'vim/src/proto/getchar.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/getchar.pro'\"
else
echo shar: Extracting \"'vim/src/proto/getchar.pro'\" \(1160 characters\)
sed "s/^X//" >'vim/src/proto/getchar.pro' <<'END_OF_FILE'
X/* getchar.c */
Xunsigned char *get_recorded __PARMS((void));
Xunsigned char *get_inserted __PARMS((void));
Xint stuff_empty __PARMS((void));
Xvoid flush_buffers __PARMS((int typeahead));
Xvoid ResetRedobuff __PARMS((void));
Xvoid AppendToRedobuff __PARMS((unsigned char *s));
Xvoid AppendCharToRedobuff __PARMS((int c));
Xvoid AppendNumberToRedobuff __PARMS((long n));
Xvoid stuffReadbuff __PARMS((unsigned char *s));
Xvoid stuffcharReadbuff __PARMS((int c));
Xvoid stuffnumReadbuff __PARMS((long n));
Xvoid copy_redo __PARMS((void));
Xint start_redo __PARMS((long count));
Xint start_redo_ins __PARMS((void));
Xvoid set_redo_ins __PARMS((void));
Xvoid stop_redo_ins __PARMS((void));
Xint ins_typestr __PARMS((unsigned char *str, int noremap));
Xvoid del_typestr __PARMS((int len));
Xint openscript __PARMS((unsigned char *name));
Xvoid updatescript __PARMS((int c));
Xint vgetc __PARMS((void));
Xint vpeekc __PARMS((void));
Xint domap __PARMS((int maptype, unsigned char *keys, int mode));
Xint check_abbr __PARMS((int c, unsigned char *ptr, int col, int mincol));
Xint makemap __PARMS((struct __stdio *fd));
Xint putescstr __PARMS((struct __stdio *fd, unsigned char *str, int set));
END_OF_FILE
if test 1160 -ne `wc -c <'vim/src/proto/getchar.pro'`; then
echo shar: \"'vim/src/proto/getchar.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/getchar.pro'
fi
if test -f 'vim/src/proto/memfile.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/memfile.pro'\"
else
echo shar: Extracting \"'vim/src/proto/memfile.pro'\" \(853 characters\)
sed "s/^X//" >'vim/src/proto/memfile.pro' <<'END_OF_FILE'
X/* memfile.c */
Xstruct memfile *mf_open __PARMS((unsigned char *fname, int new, int fail_nofile));
Xint mf_open_file __PARMS((struct memfile *mfp, unsigned char *fname));
Xvoid mf_close __PARMS((struct memfile *mfp, int delete));
Xstruct block_hdr *mf_new __PARMS((struct memfile *mfp, int negative, int page_count));
Xstruct block_hdr *mf_get __PARMS((struct memfile *mfp, long nr, int page_count));
Xvoid mf_put __PARMS((struct memfile *mfp, struct block_hdr *hp, int dirty, int infile));
Xvoid mf_free __PARMS((struct memfile *mfp, struct block_hdr *hp));
Xint mf_sync __PARMS((struct memfile *mfp, int all, int check_char));
Xint mf_release_all __PARMS((void));
Xlong mf_trans_del __PARMS((struct memfile *mfp, long old));
Xvoid mf_fullname __PARMS((struct memfile *mfp));
Xint mf_need_trans __PARMS((struct memfile *mfp));
Xvoid mf_statistics __PARMS((void));
END_OF_FILE
if test 853 -ne `wc -c <'vim/src/proto/memfile.pro'`; then
echo shar: \"'vim/src/proto/memfile.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/memfile.pro'
fi
if test -f 'vim/src/proto/memline.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/memline.pro'\"
else
echo shar: Extracting \"'vim/src/proto/memline.pro'\" \(959 characters\)
sed "s/^X//" >'vim/src/proto/memline.pro' <<'END_OF_FILE'
X/* memline.c */
Xint ml_open __PARMS((void));
Xvoid ml_open_files __PARMS((void));
Xvoid ml_close __PARMS((struct buffer *buf));
Xvoid ml_close_all __PARMS((void));
Xvoid ml_timestamp __PARMS((struct buffer *buf));
Xvoid ml_recover __PARMS((void));
Xvoid ml_sync_all __PARMS((int check_file));
Xvoid ml_preserve __PARMS((struct buffer *buf, int message));
Xunsigned char *ml_get __PARMS((long lnum));
Xunsigned char *ml_get_pos __PARMS((struct fpos *pos));
Xunsigned char *ml_get_cursor __PARMS((void));
Xunsigned char *ml_get_buf __PARMS((struct buffer *buf, long lnum, int will_change));
Xint ml_line_alloced __PARMS((void));
Xint ml_append __PARMS((long lnum, unsigned char *line, unsigned int len, int newfile));
Xint ml_replace __PARMS((long lnum, unsigned char *line, int copy));
Xint ml_delete __PARMS((long lnum));
Xvoid ml_setmarked __PARMS((long lnum));
Xlong ml_firstmarked __PARMS((void));
Xint ml_has_mark __PARMS((long lnum));
Xvoid ml_clearmarked __PARMS((void));
END_OF_FILE
if test 959 -ne `wc -c <'vim/src/proto/memline.pro'`; then
echo shar: \"'vim/src/proto/memline.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/memline.pro'
fi
if test -f 'vim/src/proto/misccmds.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/misccmds.pro'\"
else
echo shar: Extracting \"'vim/src/proto/misccmds.pro'\" \(1432 characters\)
sed "s/^X//" >'vim/src/proto/misccmds.pro' <<'END_OF_FILE'
X/* misccmds.c */
Xint get_indent __PARMS((void));
Xvoid set_indent __PARMS((int size, int delete));
Xint Opencmd __PARMS((int dir, int redraw, int delspaces));
Xint plines __PARMS((long p));
Xint plines_win __PARMS((struct window *wp, long p));
Xint plines_m __PARMS((long first, long last));
Xint plines_m_win __PARMS((struct window *wp, long first, long last));
Xvoid inschar __PARMS((int c));
Xvoid insstr __PARMS((unsigned char *s));
Xint delchar __PARMS((int fixpos));
Xvoid dellines __PARMS((long nlines, int dowindow, int undo));
Xint gchar __PARMS((struct fpos *pos));
Xint gchar_cursor __PARMS((void));
Xvoid pchar_cursor __PARMS((int c));
Xint inindent __PARMS((void));
Xvoid skipspace __PARMS((unsigned char **pp));
Xvoid skiptospace __PARMS((unsigned char **pp));
Xvoid skiptodigit __PARMS((unsigned char **pp));
Xlong getdigits __PARMS((unsigned char **pp));
Xunsigned char *plural __PARMS((long n));
Xvoid set_Changed __PARMS((void));
Xvoid unset_Changed __PARMS((struct buffer *buf));
Xvoid change_warning __PARMS((void));
Xint ask_yesno __PARMS((unsigned char *str));
Xvoid msgmore __PARMS((long n));
Xvoid beep __PARMS((void));
Xvoid expand_env __PARMS((unsigned char *src, unsigned char *dst, int dstlen));
Xvoid home_replace __PARMS((unsigned char *src, unsigned char *dst, int dstlen));
Xint fullpathcmp __PARMS((unsigned char *s1, unsigned char *s2));
Xunsigned char *gettail __PARMS((unsigned char *fname));
Xint ispathsep __PARMS((int c));
END_OF_FILE
if test 1432 -ne `wc -c <'vim/src/proto/misccmds.pro'`; then
echo shar: \"'vim/src/proto/misccmds.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/misccmds.pro'
fi
if test -f 'vim/src/proto/msdos.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/msdos.pro'\"
else
echo shar: Extracting \"'vim/src/proto/msdos.pro'\" \(1441 characters\)
sed "s/^X//" >'vim/src/proto/msdos.pro' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X

X/* prototypes from msdos.c */
Xlong mch_avail_mem __ARGS((int));
Xvoid vim_delay __ARGS((void));
Xint vim_remove __ARGS((char_u *));
Xvoid mch_write __ARGS((char_u *, int));
Xint GetChars __ARGS((char_u *, int, int));
Xint mch_char_avail __ARGS((void));
Xvoid mch_suspend __ARGS((void));
Xvoid mch_windinit __ARGS((void));
Xvoid check_win __ARGS((int, char **));
Xvoid fname_case __ARGS((char_u *));
Xvoid mch_settitle __ARGS((char_u *, char_u *));
Xvoid mch_restore_title __PARMS((int which));
Xint vim_dirname __ARGS((char_u *, int));
Xint FullName __ARGS((char_u *, char_u *, int));
Xint isFullName __ARGS((char_u *));
Xlong getperm __ARGS((char_u *));
Xint setperm __ARGS((char_u *, long));
Xint isdir __ARGS((char_u *));
Xvoid mch_windexit __ARGS((int));
Xvoid mch_settmode __ARGS((int));
Xint mch_screenmode __ARGS((char_u *));
Xint mch_get_winsize __ARGS((void));
Xvoid set_window __ARGS((void));
Xvoid mch_set_winsize __ARGS((void));
Xint call_shell __ARGS((char_u *, int, int));
Xvoid breakcheck __ARGS((void));
Xchar_u *modname __ARGS((char_u *, char_u *));
Xint has_wildcard __ARGS((char_u *));
Xint ExpandWildCards __ARGS((int, char_u **, int *, char_u ***, int, int));
Xvoid FreeWild __ARGS((int, char_u **));
Xint vim_chdir __ARGS((char_u *));
END_OF_FILE
if test 1441 -ne `wc -c <'vim/src/proto/msdos.pro'`; then
echo shar: \"'vim/src/proto/msdos.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/msdos.pro'
fi
if test -f 'vim/src/proto/ops.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/ops.pro'\"
else
echo shar: Extracting \"'vim/src/proto/ops.pro'\" \(886 characters\)
sed "s/^X//" >'vim/src/proto/ops.pro' <<'END_OF_FILE'
X/* ops.c */
Xvoid doshift __PARMS((int op, int curs_top, int amount));
Xvoid shift_line __PARMS((int left, int round, int amount));
Xint is_yank_buffer __PARMS((int c, int write));
Xint dorecord __PARMS((int c));
Xint doexecbuf __PARMS((int c));
Xint insertbuf __PARMS((int c));
Xvoid dodelete __PARMS((void));
Xvoid dotilde __PARMS((void));
Xvoid swapchar __PARMS((struct fpos *pos));
Xvoid dochange __PARMS((void));
Xvoid init_yank __PARMS((void));
Xint doyank __PARMS((int deleting));
Xvoid doput __PARMS((int dir, long count, int fix_indent));
Xvoid dodis __PARMS((void));
Xvoid dis_msg __PARMS((unsigned char *p, int skip_esc));
Xvoid dodojoin __PARMS((long count, int insert_space, int redraw));
Xint dojoin __PARMS((int insert_space, int redraw));
Xvoid doformat __PARMS((void));
Xvoid startinsert __PARMS((int initstr, int startln, long count));
Xint doaddsub __PARMS((int command, long Prenum1));
END_OF_FILE
if test 886 -ne `wc -c <'vim/src/proto/ops.pro'`; then
echo shar: \"'vim/src/proto/ops.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/ops.pro'
fi
if test -f 'vim/src/proto/screen.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/screen.pro'\"
else
echo shar: Extracting \"'vim/src/proto/screen.pro'\" \(1485 characters\)
sed "s/^X//" >'vim/src/proto/screen.pro' <<'END_OF_FILE'
X/* screen.c */
Xvoid updateline __PARMS((void));
Xvoid updateScreen __PARMS((int type));
Xvoid win_update __PARMS((struct window *wp));
Xvoid status_redraw_all __PARMS((void));
Xvoid win_redr_status __PARMS((struct window *wp));
Xvoid screen_outchar __PARMS((int c, int row, int col));
Xvoid screen_msg __PARMS((unsigned char *msg, int row, int col));
Xvoid screen_start __PARMS((void));
Xint set_highlight __PARMS((int context));
Xvoid start_highlight __PARMS((void));
Xvoid stop_highlight __PARMS((void));
Xvoid screen_fill __PARMS((int start_row, int end_row, int start_col, int end_col, int c1, int c2));
Xvoid comp_Botline_all __PARMS((void));
Xvoid comp_Botline __PARMS((struct window *wp));
Xvoid screenclear __PARMS((void));
Xvoid check_cursor __PARMS((void));
Xvoid cursupdate __PARMS((void));
Xvoid curs_columns __PARMS((int scroll));
Xint getvcol __PARMS((struct window *wp, struct fpos *pos, int type));
Xvoid scrolldown __PARMS((long nlines));
Xvoid scrollup __PARMS((long nlines));
Xint win_ins_lines __PARMS((struct window *wp, int row, int nlines, int invalid, int mayclear));
Xint win_del_lines __PARMS((struct window *wp, int row, int nlines, int invalid, int mayclear));
Xvoid win_rest_invalid __PARMS((struct window *wp));
Xint screen_del_lines __PARMS((int off, int row, int nlines, int end));
Xvoid showmode __PARMS((void));
Xvoid delmode __PARMS((void));
Xvoid showruler __PARMS((int always));
Xvoid win_redr_ruler __PARMS((struct window *wp, int always));
Xint screen_valid __PARMS((void));
END_OF_FILE
if test 1485 -ne `wc -c <'vim/src/proto/screen.pro'`; then
echo shar: \"'vim/src/proto/screen.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/screen.pro'
fi
if test -f 'vim/src/proto/search.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/search.pro'\"
else
echo shar: Extracting \"'vim/src/proto/search.pro'\" \(833 characters\)
sed "s/^X//" >'vim/src/proto/search.pro' <<'END_OF_FILE'
X/* search.c */
Xstruct regexp *myregcomp __PARMS((unsigned char *pat, int sub_cmd, int which_pat));
Xint searchit __PARMS((struct fpos *pos, int dir, unsigned char *str, long count, int end, int message));
Xint dosearch __PARMS((int dirc, unsigned char *str, int reverse, long count, int echo, int message));
Xint searchc __PARMS((int c, int dir, int type, long count));
Xstruct fpos *showmatch __PARMS((int initc));
Xint findfunc __PARMS((int dir, int what, long count));
Xint findsent __PARMS((int dir, long count));
Xint findpar __PARMS((int dir, long count, int what, int both));
Xint startPS __PARMS((long lnum, int para, int both));
Xint fwd_word __PARMS((long count, int type, int eol));
Xint bck_word __PARMS((long count, int type));
Xint end_word __PARMS((long count, int type, int stop));
Xint skip_chars __PARMS((int class, int dir));
END_OF_FILE
if test 833 -ne `wc -c <'vim/src/proto/search.pro'`; then
echo shar: \"'vim/src/proto/search.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/search.pro'
fi
if test -f 'vim/src/proto/term.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/term.pro'\"
else
echo shar: Extracting \"'vim/src/proto/term.pro'\" \(925 characters\)
sed "s/^X//" >'vim/src/proto/term.pro' <<'END_OF_FILE'
X/* term.c */
Xvoid set_term __PARMS((unsigned char *term));
Xchar *tgoto __PARMS((char *cm, int x, int y));
Xvoid termcapinit __PARMS((unsigned char *term));
Xvoid flushbuf __PARMS((void));
Xvoid outchar __PARMS((unsigned int c));
Xvoid outstrn __PARMS((unsigned char *s));
Xvoid outstr __PARMS((unsigned char *s));
Xvoid windgoto __PARMS((int row, int col));
Xvoid setcursor __PARMS((void));
Xvoid ttest __PARMS((int pairs));
Xint inchar __PARMS((unsigned char *buf, int maxlen, int time));
Xint check_termcode __PARMS((unsigned char *buf));
Xvoid outnum __PARMS((long n));
Xvoid check_winsize __PARMS((void));
Xvoid set_winsize __PARMS((int width, int height, int mustset));
Xvoid settmode __PARMS((int raw));
Xvoid starttermcap __PARMS((void));
Xvoid stoptermcap __PARMS((void));
Xvoid cursor_on __PARMS((void));
Xvoid cursor_off __PARMS((void));
Xvoid scroll_region_set __PARMS((struct window *wp));
Xvoid scroll_region_reset __PARMS((void));
END_OF_FILE
if test 925 -ne `wc -c <'vim/src/proto/term.pro'`; then
echo shar: \"'vim/src/proto/term.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/term.pro'
fi
if test -f 'vim/src/proto/unix.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/unix.pro'\"
else
echo shar: Extracting \"'vim/src/proto/unix.pro'\" \(1423 characters\)
sed "s/^X//" >'vim/src/proto/unix.pro' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * functions in unix.c
X */
Xvoid mch_write __ARGS((char_u *, int));
Xint GetChars __ARGS((char_u *, int, int));
Xint mch_char_avail __ARGS((void));
Xlong mch_avail_mem __ARGS((int));
Xvoid vim_delay __ARGS((void));
Xvoid mch_suspend __ARGS((void));
Xvoid mch_windinit __ARGS((void));
Xvoid check_win __ARGS((int, char **));
Xvoid fname_case __ARGS((char_u *));
Xvoid mch_settitle __ARGS((char_u *, char_u *));
Xvoid mch_restore_title __PARMS((int which));
Xint vim_dirname __ARGS((char_u *, int));
Xint FullName __ARGS((char_u *, char_u *, int));
Xint isFullName __ARGS((char_u *));
Xlong getperm __ARGS((char_u *));
Xint setperm __ARGS((char_u *, int));
Xint isdir __ARGS((char_u *));
Xvoid mch_windexit __ARGS((int));
Xvoid mch_settmode __ARGS((int));
Xint mch_screenmode __ARGS((char_u *));
Xint mch_get_winsize __ARGS((void));
Xvoid mch_set_winsize __ARGS((void));
Xint call_shell __ARGS((char_u *, int, int));
Xvoid breakcheck __ARGS((void));
Xint ExpandWildCards __ARGS((int, char_u **, int *, char_u ***, int, int));
Xvoid FreeWild __ARGS((int, char_u **));
Xint has_wildcard __ARGS((char_u *));
Xint have_wildcard __ARGS((int, char_u **));
X#if defined(M_XENIX) || defined(UTS2)
Xint rename __ARGS((char_u *, char_u *));
X#endif
END_OF_FILE
if test 1423 -ne `wc -c <'vim/src/proto/unix.pro'`; then
echo shar: \"'vim/src/proto/unix.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/unix.pro'
fi
if test -f 'vim/src/proto/window.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/window.pro'\"
else
echo shar: Extracting \"'vim/src/proto/window.pro'\" \(869 characters\)
sed "s/^X//" >'vim/src/proto/window.pro' <<'END_OF_FILE'
X/* window.c */
Xvoid do_window __PARMS((int nchar, long Prenum));
Xint win_split __PARMS((long new_height, int redraw));
Xint make_windows __PARMS((int count));
Xvoid win_equal __PARMS((struct window *next_curwin, int redraw));
Xvoid close_window __PARMS((int free_buf));
Xvoid close_others __PARMS((int message));
Xvoid win_init __PARMS((struct window *wp));
Xvoid win_enter __PARMS((struct window *wp, int undo_sync));
Xstruct window *win_alloc __PARMS((struct window *after));
Xvoid win_free __PARMS((struct window *wp));
Xint win_alloc_lsize __PARMS((struct window *wp));
Xvoid win_free_lsize __PARMS((struct window *wp));
Xvoid screen_new_rows __PARMS((void));
Xvoid win_setheight __PARMS((int height));
Xvoid win_comp_scroll __PARMS((struct window *wp));
Xvoid command_height __PARMS((void));
Xvoid last_status __PARMS((void));
Xunsigned char *file_name_at_cursor __PARMS((void));
END_OF_FILE
if test 869 -ne `wc -c <'vim/src/proto/window.pro'`; then
echo shar: \"'vim/src/proto/window.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/window.pro'
fi
if test -f 'vim/src/ptx_stdlib.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/ptx_stdlib.h'\"
else
echo shar: Extracting \"'vim/src/ptx_stdlib.h'\" \(1035 characters\)
sed "s/^X//" >'vim/src/ptx_stdlib.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * ptx_stdlib.h: declarations which are needed for sequent
X */
X
Xextern void free(void *);
X#ifdef SIZE_T /* sys/types.h */
Xextern void *malloc(size_t);
X#else
Xextern void *malloc(unsigned);
X#endif
X
X#ifndef _FCNTL_H_
Xextern int open(char *, int, ...);
X#endif
Xextern int close(int);
Xextern int read(int, char *, unsigned);
Xextern int write(int, char *, unsigned);
Xextern int ioctl(int, int, ...);
Xextern int unlink(char *);
X
Xextern char *getenv(char *);
X
X#ifdef _NFILE /* stdio.h */
Xextern int _filbuf(FILE *);
Xextern int _flsbuf(unsigned char, FILE *);
X#endif
X
X#ifdef _POLL_H_
Xextern int poll(struct pollfd[], unsigned long, int);
X#endif /* _POLL_H_ */
X
Xextern char *getcwd(char *, int);
X
Xextern int chdir(char *);
X
Xextern int atoi (char *);
Xextern long atol(char *);
Xextern long strtol(char *, char **, int);
X
Xextern int isatty(int);
END_OF_FILE
if test 1035 -ne `wc -c <'vim/src/ptx_stdlib.h'`; then
echo shar: \"'vim/src/ptx_stdlib.h'\" unpacked with wrong size!
fi
# end of 'vim/src/ptx_stdlib.h'
fi
if test -f 'vim/src/regexp.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/regexp.h'\"
else
echo shar: Extracting \"'vim/src/regexp.h'\" \(1571 characters\)
sed "s/^X//" >'vim/src/regexp.h' <<'END_OF_FILE'
X/* vi:ts=4:sw=4


X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE

X *


X * This is NOT the original regular expression code as written by
X * Henry Spencer. This code has been modified specifically for use
X * with the VIM editor, and should not be used apart from compiling
X * VIM. If you want a good regular expression library, get the
X * original code. The copyright notice that follows is from the
X * original.
X *
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *

X * Definitions etc. for regexp(3) routines.
X *
X * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
X * not the System V one.
X */
X
X#ifndef _REGEXP_H
X#define _REGEXP_H
X
X#define NSUBEXP 10
Xtypedef struct regexp {
X char_u *startp[NSUBEXP];
X char_u *endp[NSUBEXP];
X char_u regstart; /* Internal use only. */
X char_u reganch; /* Internal use only. */
X char_u *regmust; /* Internal use only. */
X int regmlen; /* Internal use only. */
X char_u program[1]; /* Unwarranted chumminess with compiler. */
X} regexp;
X
X/* regexp.c */
Xregexp *regcomp __ARGS((char_u *));
Xint regexec __ARGS((regexp *, char_u *, int));
X/* int cstrncmp __ARGS((char_u *, char_u *, int)); */
Xchar_u *cstrchr __ARGS((char_u *, int));
X
X/* regsub.c */
Xint regsub __ARGS((regexp *, char_u *, char_u *, int, int));
X
X/* search.c */
Xextern void regerror __ARGS((char_u *));
X
X#ifndef ORIGINAL
Xextern int reg_ic; /* set non-zero to ignore case in searches */
Xextern int reg_magic; /* set zero to disable magicness of .*[~& */
X#endif
X#endif /* _REGEXP_H */
END_OF_FILE
if test 1571 -ne `wc -c <'vim/src/regexp.h'`; then
echo shar: \"'vim/src/regexp.h'\" unpacked with wrong size!
fi
# end of 'vim/src/regexp.h'
fi
if test -f 'vim/src/sun_stdlib.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/sun_stdlib.h'\"
else
echo shar: Extracting \"'vim/src/sun_stdlib.h'\" \(1879 characters\)
sed "s/^X//" >'vim/src/sun_stdlib.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X *
X * VIM - Vi IMproved by Bram Moolenaar
X *
X * Read the file "credits.txt" for a list of people who contributed.
X * Read the file "uganda.txt" for copying and usage conditions.
X */
X
X/*

X * sun_stdlib.h: declararions used on a sun
X */
X
X#ifndef __stdlib_h
Xextern int atoi (char *);
Xextern long atol(char *);
Xextern void free(void *);
Xextern char *getenv(char *);
Xextern void *malloc(unsigned);
Xextern void *realloc(void *, unsigned);
Xextern void *calloc(unsigned, unsigned);
Xextern int read(int, char *, unsigned);
Xextern int write(int, char *, unsigned);
Xextern int unlink(char *);
X#endif
X
X#ifdef __sys_types_h
Xextern off_t lseek(int, off_t, int);
X
X# ifdef _sys_time_h
Xextern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
X# endif _sys_time_h
X
X#else
Xextern long lseek(int, long, int);
X#endif
X
Xextern long tell(int);
Xextern void perror(char *);
X
X#include <fcntl.h>
X
Xextern int close(int);
X
X#ifdef FILE
Xextern int _filbuf(FILE *);
Xextern int _flsbuf(unsigned char, FILE *);
Xextern int fclose(FILE *);
Xextern int fprintf(FILE *, char *, ...);
Xextern int fscanf(FILE *, char *, ...);
Xextern int fseek(FILE *, long, int);
Xextern int fflush(FILE *);
Xextern int fread(char *, int, int, FILE *);
X#else
Xextern char *sprintf(char *, char *, ...);
X#endif
X
Xextern int printf(char *, ...);
X
Xextern int scanf(char *, ...);
Xextern int sscanf(char *, char *, ...);
X
Xextern int system(char *);
X
X#ifndef __sys_unistd_h
Xextern char *getcwd(char *, int);
Xextern int chdir(char *);
Xextern int getuid(void);
Xextern int getgid(void);
X#endif /* __sys_unistd_h */
X
Xextern long strtol(char * , char **, int);
X
Xextern char *memccpy(char *, char *, int, int);
Xextern char *memchr(char *, int, int);
Xextern char *memset(char *, int, int);
X
X#include <string.h>
Xextern int strcasecmp(char *, char *);
X
Xextern int toupper(int);
Xextern int tolower(int);
Xextern int isatty(int);
END_OF_FILE
if test 1879 -ne `wc -c <'vim/src/sun_stdlib.h'`; then
echo shar: \"'vim/src/sun_stdlib.h'\" unpacked with wrong size!
fi
# end of 'vim/src/sun_stdlib.h'
fi
if test -f 'vim/tutor/poster' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tutor/poster'\"
else
echo shar: Extracting \"'vim/tutor/poster'\" \(860 characters\)
sed "s/^X//" >'vim/tutor/poster' <<'END_OF_FILE'
XArticle 3390 of alt.sources:
XXref: oce-rd1 comp.editors:3231 alt.sources:3390
XPath: oce-rd1!venlo!hp4nl!mcsun!uunet!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!csn!pikes!slate!bware
XFrom: bw...@slate.mines.colorado.edu (Ware Bob)
XNewsgroups: comp.editors,alt.sources
XSubject: hands on vi tutor
XKeywords: for new users
XMessage-ID: <1991Jul17.1...@slate.mines.colorado.edu>
XDate: 17 Jul 91 16:13:55 GMT
XSender: bw...@slate.mines.colorado.edu (Ware Bob)
XOrganization: Colorado School of Mines
XLines: 830
X
X
XI posted this a few weeks ago, but a number of people have munged
Xtheir copy, so I am reposting it with better instructions.
X
XThis is a "hand-on" tutor to help new users learn the vi editor.
X
XBob Ware, Colorado School of Mines, Golden, Co 80401, USA
X(303) 273-3987
Xbw...@mines.colorado.edu bw...@slate.mines.colorado.edu bw...@mines.bitnet
END_OF_FILE
if test 860 -ne `wc -c <'vim/tutor/poster'`; then
echo shar: \"'vim/tutor/poster'\" unpacked with wrong size!
fi
# end of 'vim/tutor/poster'
fi
echo shar: End of archive 25 \(of 26\).
cp /dev/null ark25isdone

Bram Moolenaar

unread,
Aug 18, 1994, 3:04:14 PM8/18/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 45
Archive-name: vim/part26

Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".

# Contents: vim/macros/hanoi/click.me vim/macros/keyword.UU
# vim/macros/maze/makefile vim/macros/maze/maze.c vim/macros/readme
# vim/macros/urm/urm.mac.UU vim/src/addcr.c vim/src/proto/alloc.pro
# vim/src/proto/charset.pro vim/src/proto/cmdcmds.pro
# vim/src/proto/csearch.pro vim/src/proto/digraph.pro
# vim/src/proto/edit.pro vim/src/proto/fileio.pro
# vim/src/proto/help.pro vim/src/proto/linefunc.pro
# vim/src/proto/main.pro vim/src/proto/message.pro
# vim/src/proto/param.pro vim/src/proto/quickfix.pro
# vim/src/proto/regexp.pro vim/src/proto/regsub.pro
# vim/src/proto/tag.pro vim/src/proto/termlib.pro
# vim/src/proto/undo.pro vim/src/regmagic.h vim/src/termlib.fix.UU
# vim/src/vim.prj vim/tools/vim132.UU vim/tutor/Readme
# Wrapped by kent@sparky on Mon Aug 15 21:44:17 1994


PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 26 (of 26)."'
if test -f 'vim/macros/hanoi/click.me' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/hanoi/click.me'\"
else
echo shar: Extracting \"'vim/macros/hanoi/click.me'\" \(255 characters\)
sed "s/^X//" >'vim/macros/hanoi/click.me' <<'END_OF_FILE'
X
X
XSee Vim solve the towers of Hanoi!
X
XInstructions:
X type ":so hanoi.mac<RETURN>" to load the macros
X type "g" to start it
X


Xand watch it go.
X

X to quit type ":q!<RETURN>"
Xto interrupt type CTRL-C
X

X(This text will disappear as soon as you type "g")
END_OF_FILE
if test 255 -ne `wc -c <'vim/macros/hanoi/click.me'`; then
echo shar: \"'vim/macros/hanoi/click.me'\" unpacked with wrong size!
fi
# end of 'vim/macros/hanoi/click.me'
fi
if test -f 'vim/macros/keyword.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/keyword.UU'\"
else
echo shar: Extracting \"'vim/macros/keyword.UU'\" \(755 characters\)
sed "s/^X//" >'vim/macros/keyword.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/keyword
XM(B!3;VUE(&AA;F1Y(&ME>7=O<F0M8V]M<&QE=&EO;B!M86-R;W,N"B(@5&AE
XM('=O<F0@:6X@9G)O;G0@;V8@=&AE(&-U<G-O<B!I<R!T86ME;B!A<R!A('-E
XM87)C:"!S=')I;F<L('1H92!P<F5V:6]U<PHB('!A<G1I86QL>2!M871C:&EN
XM9R!W;W)D(&ES(&9O=6YD('=H:6-H('1H96X@<F5P;&%C97,@=&AE('=O<F0@
XM:6X@9G)O;G0*(B!O9B!T:&4@8W5R<V]R+B!4:&4@;6%C<F]S('=O<FL@:6X@
XM:6YS97)T(&UO9&4N"B(*(B!>2R!S96%R8VAE<R!B86-K=V%R9"!F;W(@=&AE
XM(&9I<G-T(&UA=&-H"B(@7DX@<V5A<F-H97,@8F%C:W=A<F0@9F]R('1H92!N
XM97AT(&UA=&-H("AA9G1E<B!>2RD*(B!>4"!S96%R8VAE<R!F;W)W87)D(&9O
XM<B!T:&4@<')E=FEO=7,@;6%T8V@@*&%F=&5R(%Y+*0HB"B(@5&AA;FMS('1O
XM($1A=F4@0V%U9VAE>2X*(@HZ;6%P(2 +(!86%@T;8FUM:3]</!M@;2)N>68-
XM0&YM;B)N>7=@;6-F#1)N"CIM87 A( X@+AM@;FYM;B)N>7=@;6-F+A)N"CIM
X987 A(! @+AM@;DYM;B)N>7=@;6-F+A)N"AM@
X
Xend
END_OF_FILE
if test 755 -ne `wc -c <'vim/macros/keyword.UU'`; then
echo shar: \"'vim/macros/keyword.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/keyword'\" \(520 characters\)
cat vim/macros/keyword.UU | uudecode
if test 520 -ne `wc -c <'vim/macros/keyword'`; then
echo shar: \"'vim/macros/keyword'\" uudecoded with wrong size!
else
rm vim/macros/keyword.UU
fi
fi
# end of 'vim/macros/keyword.UU'
fi
if test -f 'vim/macros/maze/makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/makefile'\"
else
echo shar: Extracting \"'vim/macros/maze/makefile'\" \(104 characters\)
sed "s/^X//" >'vim/macros/maze/makefile' <<'END_OF_FILE'
X#On the amiga with manx C 5.0 we have to use maze.ansi.c
X
Xmaze: maze.ansi.o
X ln maze.ansi.o -o maze -lc
END_OF_FILE
if test 104 -ne `wc -c <'vim/macros/maze/makefile'`; then
echo shar: \"'vim/macros/maze/makefile'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/makefile'
fi
if test -f 'vim/macros/maze/maze.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/maze/maze.c'\"
else
echo shar: Extracting \"'vim/macros/maze/maze.c'\" \(441 characters\)
sed "s/^X//" >'vim/macros/maze/maze.c' <<'END_OF_FILE'
Xchar*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
X-- E; J[ E] =T


X[E ]= E) printf("._"); for(;(A-=Z=!Z) || (printf("\n|"
X) , A = 39 ,C --

X) ; Z || printf (M ))M[Z]=Z[A-(E =A[J-Z])&&!C
X& A == T[ A]
X|6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
END_OF_FILE
if test 441 -ne `wc -c <'vim/macros/maze/maze.c'`; then
echo shar: \"'vim/macros/maze/maze.c'\" unpacked with wrong size!
fi
# end of 'vim/macros/maze/maze.c'
fi
if test -f 'vim/macros/readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/readme'\"
else
echo shar: Extracting \"'vim/macros/readme'\" \(511 characters\)
sed "s/^X//" >'vim/macros/readme' <<'END_OF_FILE'
XThe macros in the maze, hanoi and urm directories can be used to test Vim for
Xvi compatibility. They have been written for vi to show its unlimited
Xpossibilities.
X
XHANOI are macros that solve the tower of hanoi problem.
XMAZE are macros that solve a maze (amazing!).
XURM are macros that simulate a simple computer: "Universal Register Machine"
X
XThey are unmodified.
X
X
XThe other files contain some handy utilities:
X
Xcenter: macros to center current line in 80-character line
Xkeyword: keyword completion macros
END_OF_FILE
if test 511 -ne `wc -c <'vim/macros/readme'`; then
echo shar: \"'vim/macros/readme'\" unpacked with wrong size!
fi
# end of 'vim/macros/readme'
fi
if test -f 'vim/macros/urm/urm.mac.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/macros/urm/urm.mac.UU'\"
else
echo shar: Extracting \"'vim/macros/urm/urm.mac.UU'\" \(173 characters\)
sed "s/^X//" >'vim/macros/urm/urm.mac.UU' <<'END_OF_FILE'
Xbegin 644 vim/macros/urm/urm.mac
XM;6%P("H@,4<O24Y)5!8-:B)I5$!I,4<O24Y)5!8-9$<*;6%P(&<@,4<O7ELH
XM87,[+ET6#6D6#3XL%AMM:VMM=T!K"FUA<"!4('DD"FUA<"!&('EL"FUA<" ]
X&("=K9BP*
X
Xend
END_OF_FILE
if test 173 -ne `wc -c <'vim/macros/urm/urm.mac.UU'`; then
echo shar: \"'vim/macros/urm/urm.mac.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/macros/urm/urm.mac'\" \(96 characters\)
cat vim/macros/urm/urm.mac.UU | uudecode
if test 96 -ne `wc -c <'vim/macros/urm/urm.mac'`; then
echo shar: \"'vim/macros/urm/urm.mac'\" uudecoded with wrong size!
else
rm vim/macros/urm/urm.mac.UU
fi
fi
# end of 'vim/macros/urm/urm.mac.UU'
fi
if test -f 'vim/src/addcr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/addcr.c'\"
else
echo shar: Extracting \"'vim/src/addcr.c'\" \(413 characters\)
sed "s/^X//" >'vim/src/addcr.c' <<'END_OF_FILE'
X/*
X * This program, when compiled with Turbo-C, will make <LF> into <CR><LF>
X */
X
X#include <stdio.h>
X

Xmain(argc, argv)
X int argc;
X char **argv;
X{

X char buffer[1024];
X int len;
X
X while ((len = fread(buffer, 1, 1024, stdin)) > 0)
X fwrite(buffer, 1, len, stdout);
X if (ferror(stdin))
X fprintf(stderr, "Error while reading\n");
X if (ferror(stdout))
X fprintf(stderr, "Error while writing\n");
X}
END_OF_FILE
if test 413 -ne `wc -c <'vim/src/addcr.c'`; then
echo shar: \"'vim/src/addcr.c'\" unpacked with wrong size!
fi
# end of 'vim/src/addcr.c'
fi
if test -f 'vim/src/proto/alloc.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/alloc.pro'\"
else
echo shar: Extracting \"'vim/src/proto/alloc.pro'\" \(456 characters\)
sed "s/^X//" >'vim/src/proto/alloc.pro' <<'END_OF_FILE'
X/* alloc.c */
Xunsigned char *alloc __PARMS((unsigned int size));
Xunsigned char *lalloc __PARMS((unsigned long size, int message));
Xunsigned char *strsave __PARMS((unsigned char *string));
Xunsigned char *strnsave __PARMS((unsigned char *string, int len));
Xvoid copy_spaces __PARMS((unsigned char *ptr, unsigned long count));
Xvoid del_spaces __PARMS((unsigned char *ptr));
Xint vim_strnicmp __PARMS((unsigned char *s1, unsigned char *s2, unsigned long len));
END_OF_FILE
if test 456 -ne `wc -c <'vim/src/proto/alloc.pro'`; then
echo shar: \"'vim/src/proto/alloc.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/alloc.pro'
fi
if test -f 'vim/src/proto/charset.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/charset.pro'\"
else
echo shar: Extracting \"'vim/src/proto/charset.pro'\" \(206 characters\)
sed "s/^X//" >'vim/src/proto/charset.pro' <<'END_OF_FILE'
X/* charset.c */
Xunsigned char *transchar __PARMS((int c));
Xint charsize __PARMS((int c));
Xint strsize __PARMS((unsigned char *s));
Xint chartabsize __PARMS((int c, long col));
Xint isidchar __PARMS((int c));
END_OF_FILE
if test 206 -ne `wc -c <'vim/src/proto/charset.pro'`; then
echo shar: \"'vim/src/proto/charset.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/charset.pro'
fi
if test -f 'vim/src/proto/cmdcmds.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/cmdcmds.pro'\"
else
echo shar: Extracting \"'vim/src/proto/cmdcmds.pro'\" \(428 characters\)
sed "s/^X//" >'vim/src/proto/cmdcmds.pro' <<'END_OF_FILE'
X/* cmdcmds.c */
Xvoid do_align __PARMS((long start, long end, int width, int type));
Xint do_move __PARMS((long line1, long line2, long n));
Xvoid do_copy __PARMS((long line1, long line2, long n));
Xvoid dobang __PARMS((int addr_count, long line1, long line2, int forceit, unsigned char *arg));
Xvoid doshell __PARMS((unsigned char *cmd));
Xvoid dofilter __PARMS((long line1, long line2, unsigned char *buff, int do_in, int do_out));
END_OF_FILE
if test 428 -ne `wc -c <'vim/src/proto/cmdcmds.pro'`; then
echo shar: \"'vim/src/proto/cmdcmds.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/cmdcmds.pro'
fi
if test -f 'vim/src/proto/csearch.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/csearch.pro'\"
else
echo shar: Extracting \"'vim/src/proto/csearch.pro'\" \(189 characters\)
sed "s/^X//" >'vim/src/proto/csearch.pro' <<'END_OF_FILE'
X/* csearch.c */
Xvoid dosub __PARMS((long lp, long up, unsigned char *cmd, unsigned char **nextcommand, int use_old));
Xvoid doglob __PARMS((int type, long lp, long up, unsigned char *cmd));
END_OF_FILE
if test 189 -ne `wc -c <'vim/src/proto/csearch.pro'`; then
echo shar: \"'vim/src/proto/csearch.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/csearch.pro'
fi
if test -f 'vim/src/proto/digraph.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/digraph.pro'\"
else
echo shar: Extracting \"'vim/src/proto/digraph.pro'\" \(188 characters\)
sed "s/^X//" >'vim/src/proto/digraph.pro' <<'END_OF_FILE'
X/* digraph.c */
Xint dodigraph __PARMS((int c));
Xint getdigraph __PARMS((int char1, int char2, int meta));
Xvoid putdigraph __PARMS((unsigned char *str));
Xvoid listdigraphs __PARMS((void));
END_OF_FILE
if test 188 -ne `wc -c <'vim/src/proto/digraph.pro'`; then
echo shar: \"'vim/src/proto/digraph.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/digraph.pro'
fi
if test -f 'vim/src/proto/edit.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/edit.pro'\"
else
echo shar: Extracting \"'vim/src/proto/edit.pro'\" \(437 characters\)
sed "s/^X//" >'vim/src/proto/edit.pro' <<'END_OF_FILE'
X/* edit.c */
Xvoid edit __PARMS((long count));
Xint get_literal __PARMS((int *nextc));
Xvoid insertchar __PARMS((unsigned int c));
Xvoid beginline __PARMS((int flag));
Xint oneright __PARMS((void));
Xint oneleft __PARMS((void));
Xint oneup __PARMS((long n));
Xint onedown __PARMS((long n));
Xint onepage __PARMS((int dir, long count));
Xvoid stuff_inserted __PARMS((int c, long count, int no_esc));
Xunsigned char *get_last_insert __PARMS((void));
END_OF_FILE
if test 437 -ne `wc -c <'vim/src/proto/edit.pro'`; then
echo shar: \"'vim/src/proto/edit.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/edit.pro'
fi
if test -f 'vim/src/proto/fileio.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/fileio.pro'\"
else
echo shar: Extracting \"'vim/src/proto/fileio.pro'\" \(619 characters\)
sed "s/^X//" >'vim/src/proto/fileio.pro' <<'END_OF_FILE'
X/* fileio.c */
Xvoid filemess __PARMS((unsigned char *name, unsigned char *s));
Xint readfile __PARMS((unsigned char *fname, unsigned char *sfname, long from, int newfile, long skip_lnum, long nlines));
Xint buf_write __PARMS((struct buffer *buf, unsigned char *fname, unsigned char *sfname, long start, long end, int append, int forceit, int reset_changed));
Xunsigned char *modname __PARMS((unsigned char *fname, unsigned char *ext));
Xunsigned char *buf_modname __PARMS((struct buffer *buf, unsigned char *fname, unsigned char *ext));
Xint vim_fgets __PARMS((unsigned char *buf, int size, struct __stdio *fp, int *lnum));
END_OF_FILE
if test 619 -ne `wc -c <'vim/src/proto/fileio.pro'`; then
echo shar: \"'vim/src/proto/fileio.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/fileio.pro'
fi
if test -f 'vim/src/proto/help.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/help.pro'\"
else
echo shar: Extracting \"'vim/src/proto/help.pro'\" \(72 characters\)
sed "s/^X//" >'vim/src/proto/help.pro' <<'END_OF_FILE'
X/* help.c */
Xvoid help __PARMS((void));
Xint redrawhelp __PARMS((void));
END_OF_FILE
if test 72 -ne `wc -c <'vim/src/proto/help.pro'`; then
echo shar: \"'vim/src/proto/help.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/help.pro'
fi
if test -f 'vim/src/proto/linefunc.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/linefunc.pro'\"
else
echo shar: Extracting \"'vim/src/proto/linefunc.pro'\" \(309 characters\)
sed "s/^X//" >'vim/src/proto/linefunc.pro' <<'END_OF_FILE'
X/* linefunc.c */
Xvoid coladvance __PARMS((unsigned int wcol));
Xint inc_cursor __PARMS((void));
Xint inc __PARMS((struct fpos *lp));
Xint incl __PARMS((struct fpos *lp));
Xint dec_cursor __PARMS((void));
Xint dec __PARMS((struct fpos *lp));
Xint decl __PARMS((struct fpos *lp));
Xvoid adjust_cursor __PARMS((void));
END_OF_FILE
if test 309 -ne `wc -c <'vim/src/proto/linefunc.pro'`; then
echo shar: \"'vim/src/proto/linefunc.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/linefunc.pro'
fi
if test -f 'vim/src/proto/main.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/main.pro'\"
else
echo shar: Extracting \"'vim/src/proto/main.pro'\" \(87 characters\)
sed "s/^X//" >'vim/src/proto/main.pro' <<'END_OF_FILE'
X/* main.c */
Xvoid main __PARMS((int argc, char **argv));
Xvoid getout __PARMS((int r));
END_OF_FILE
if test 87 -ne `wc -c <'vim/src/proto/main.pro'`; then
echo shar: \"'vim/src/proto/main.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/main.pro'
fi
if test -f 'vim/src/proto/message.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/message.pro'\"
else
echo shar: Extracting \"'vim/src/proto/message.pro'\" \(573 characters\)
sed "s/^X//" >'vim/src/proto/message.pro' <<'END_OF_FILE'
X/* message.c */
Xint msg __PARMS((unsigned char *s));
Xint emsg __PARMS((unsigned char *s));
Xint emsg2 __PARMS((unsigned char *s, unsigned char *a1));
Xvoid wait_return __PARMS((int redraw));
Xvoid msg_start __PARMS((void));
Xvoid msg_pos __PARMS((int row, int col));
Xvoid msg_outchar __PARMS((int c));
Xvoid msg_outnum __PARMS((long n));
Xint msg_outtrans __PARMS((unsigned char *str, int len));
Xvoid msg_prt_line __PARMS((unsigned char *s));
Xvoid msg_outstr __PARMS((unsigned char *s));
Xvoid msg_ceol __PARMS((void));
Xint msg_end __PARMS((void));
Xint msg_check __PARMS((void));
END_OF_FILE
if test 573 -ne `wc -c <'vim/src/proto/message.pro'`; then
echo shar: \"'vim/src/proto/message.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/message.pro'
fi
if test -f 'vim/src/proto/param.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/param.pro'\"
else
echo shar: Extracting \"'vim/src/proto/param.pro'\" \(553 characters\)
sed "s/^X//" >'vim/src/proto/param.pro' <<'END_OF_FILE'
X/* param.c */
Xvoid set_init __PARMS((void));
Xint doset __PARMS((unsigned char *arg));
Xvoid paramchanged __PARMS((unsigned char *arg));
Xint makeset __PARMS((struct __stdio *fd));
Xvoid clear_termparam __PARMS((void));
Xvoid comp_col __PARMS((void));
Xvoid win_copy_options __PARMS((struct window *wp_from, struct window *wp_to));
Xvoid buf_copy_options __PARMS((struct buffer *bp_from, struct buffer *bp_to));
Xvoid set_context_in_set_cmd __PARMS((unsigned char *arg));
Xint ExpandSettings __PARMS((struct regexp *prog, int *num_file, unsigned char ***file));
END_OF_FILE
if test 553 -ne `wc -c <'vim/src/proto/param.pro'`; then
echo shar: \"'vim/src/proto/param.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/param.pro'
fi
if test -f 'vim/src/proto/quickfix.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/quickfix.pro'\"
else
echo shar: Extracting \"'vim/src/proto/quickfix.pro'\" \(187 characters\)
sed "s/^X//" >'vim/src/proto/quickfix.pro' <<'END_OF_FILE'
X/* quickfix.c */
Xint qf_init __PARMS((void));
Xvoid qf_jump __PARMS((int dir, int errornr));
Xvoid qf_list __PARMS((void));
Xvoid qf_mark_adjust __PARMS((long line1, long line2, long inc));
END_OF_FILE
if test 187 -ne `wc -c <'vim/src/proto/quickfix.pro'`; then
echo shar: \"'vim/src/proto/quickfix.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/quickfix.pro'
fi
if test -f 'vim/src/proto/regexp.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/regexp.pro'\"
else
echo shar: Extracting \"'vim/src/proto/regexp.pro'\" \(342 characters\)
sed "s/^X//" >'vim/src/proto/regexp.pro' <<'END_OF_FILE'
X/* regexp.c */
Xunsigned char *skip_regexp __PARMS((unsigned char *p, int dirc));
Xstruct regexp *regcomp __PARMS((unsigned char *exp));
Xint regexec __PARMS((struct regexp *prog, unsigned char *string, int at_bol));
Xint cstrncmp __PARMS((unsigned char *s1, unsigned char *s2, int n));
Xunsigned char *cstrchr __PARMS((unsigned char *s, int c));
END_OF_FILE
if test 342 -ne `wc -c <'vim/src/proto/regexp.pro'`; then
echo shar: \"'vim/src/proto/regexp.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/regexp.pro'
fi
if test -f 'vim/src/proto/regsub.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/regsub.pro'\"
else
echo shar: Extracting \"'vim/src/proto/regsub.pro'\" \(192 characters\)
sed "s/^X//" >'vim/src/proto/regsub.pro' <<'END_OF_FILE'
X/* regsub.c */
Xunsigned char *regtilde __PARMS((unsigned char *source, int magic));
Xint regsub __PARMS((struct regexp *prog, unsigned char *source, unsigned char *dest, int copy, int magic));
END_OF_FILE
if test 192 -ne `wc -c <'vim/src/proto/regsub.pro'`; then
echo shar: \"'vim/src/proto/regsub.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/regsub.pro'
fi
if test -f 'vim/src/proto/tag.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/tag.pro'\"
else
echo shar: Extracting \"'vim/src/proto/tag.pro'\" \(189 characters\)
sed "s/^X//" >'vim/src/proto/tag.pro' <<'END_OF_FILE'
X/* tag.c */
Xvoid dotag __PARMS((unsigned char *tag, int type, int count));
Xvoid dotags __PARMS((void));
Xint ExpandTags __PARMS((struct regexp *prog, int *num_file, unsigned char ***file));
END_OF_FILE
if test 189 -ne `wc -c <'vim/src/proto/tag.pro'`; then
echo shar: \"'vim/src/proto/tag.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/tag.pro'
fi
if test -f 'vim/src/proto/termlib.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/termlib.pro'\"
else
echo shar: Extracting \"'vim/src/proto/termlib.pro'\" \(300 characters\)
sed "s/^X//" >'vim/src/proto/termlib.pro' <<'END_OF_FILE'
X/* termlib.c */
Xint tgetent __PARMS((char *tbuf, char *term));
Xint tgetflag __PARMS((char *id));
Xint tgetnum __PARMS((char *id));
Xchar *tgetstr __PARMS((char *id, char **buf));
Xchar *tgoto __PARMS((char *cm, int col, int line));
Xint tputs __PARMS((char *cp, int affcnt, void (*outc)(unsigned int)));
END_OF_FILE
if test 300 -ne `wc -c <'vim/src/proto/termlib.pro'`; then
echo shar: \"'vim/src/proto/termlib.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/termlib.pro'
fi
if test -f 'vim/src/proto/undo.pro' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/proto/undo.pro'\"
else
echo shar: Extracting \"'vim/src/proto/undo.pro'\" \(555 characters\)
sed "s/^X//" >'vim/src/proto/undo.pro' <<'END_OF_FILE'
X/* undo.c */
Xint u_save_cursor __PARMS((void));
Xint u_save __PARMS((long top, long bot));
Xint u_savesub __PARMS((long lnum));
Xint u_inssub __PARMS((long lnum));
Xint u_savedel __PARMS((long lnum, long nlines));
Xvoid u_undo __PARMS((int count));
Xvoid u_redo __PARMS((int count));
Xvoid u_sync __PARMS((void));
Xvoid u_unchanged __PARMS((struct buffer *buf));
Xvoid u_clearall __PARMS((struct buffer *buf));
Xvoid u_saveline __PARMS((long lnum));
Xvoid u_clearline __PARMS((void));
Xvoid u_undoline __PARMS((void));
Xvoid u_blockfree __PARMS((struct buffer *buf));
END_OF_FILE
if test 555 -ne `wc -c <'vim/src/proto/undo.pro'`; then
echo shar: \"'vim/src/proto/undo.pro'\" unpacked with wrong size!
fi
# end of 'vim/src/proto/undo.pro'
fi
if test -f 'vim/src/regmagic.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/regmagic.h'\"
else
echo shar: Extracting \"'vim/src/regmagic.h'\" \(663 characters\)
sed "s/^X//" >'vim/src/regmagic.h' <<'END_OF_FILE'


X/* vi:ts=4:sw=4
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *
X * This is NOT the original regular expression code as written by
X * Henry Spencer. This code has been modified specifically for use
X * with the VIM editor, and should not be used apart from compiling
X * VIM. If you want a good regular expression library, get the
X * original code. The copyright notice that follows is from the
X * original.
X *
X * NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
X *

X * The first byte of the regexp internal "program" is actually this magic
X * number; the start node begins in the second byte.
X */
X
X#define MAGIC 0234
END_OF_FILE
if test 663 -ne `wc -c <'vim/src/regmagic.h'`; then
echo shar: \"'vim/src/regmagic.h'\" unpacked with wrong size!
fi
# end of 'vim/src/regmagic.h'
fi
if test -f 'vim/src/termlib.fix.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/termlib.fix.UU'\"
else
echo shar: Extracting \"'vim/src/termlib.fix.UU'\" \(86 characters\)
sed "s/^X//" >'vim/src/termlib.fix.UU' <<'END_OF_FILE'
Xbegin 644 vim/src/termlib.fix
XB#2]O=71C*2@I#6QL;&QL875N<VEG;F5D(&EN=!LZ=W$-"@ #
X
Xend
END_OF_FILE
if test 86 -ne `wc -c <'vim/src/termlib.fix.UU'`; then
echo shar: \"'vim/src/termlib.fix.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/src/termlib.fix'\" \(34 characters\)
cat vim/src/termlib.fix.UU | uudecode
if test 34 -ne `wc -c <'vim/src/termlib.fix'`; then
echo shar: \"'vim/src/termlib.fix'\" uudecoded with wrong size!
else
rm vim/src/termlib.fix.UU
fi
fi
# end of 'vim/src/termlib.fix.UU'
fi
if test -f 'vim/src/vim.prj' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/src/vim.prj'\"
else
echo shar: Extracting \"'vim/src/vim.prj'\" \(254 characters\)
sed "s/^X//" >'vim/src/vim.prj' <<'END_OF_FILE'
XALLOC.C
XBUFFERS.C
XCHARSET.C
XCMDLINE.C
XCSEARCH.C
XEDIT.C
XDIGRAPH.C
XFILEIO.C
XHELP.C
XLINEFUNC.C
XMAIN.C
XMARK.C
XMESSAGE.C
XMISCCMDS.C
XMSDOS.C
XNORMAL.C
XOPS.C
XPARAM.C
XQUICKFIX.C
XREGEXP.C
XREGSUB.C
XSCREEN.C
XSCRIPT.C
XSEARCH.C
XSTORAGE.C
XTAG.C
XTERM.C
XUNDO.C
XVERSION.C
END_OF_FILE
if test 254 -ne `wc -c <'vim/src/vim.prj'`; then
echo shar: \"'vim/src/vim.prj'\" unpacked with wrong size!
fi
# end of 'vim/src/vim.prj'
fi
if test -f 'vim/tools/vim132.UU' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tools/vim132.UU'\"
else
echo shar: Extracting \"'vim/tools/vim132.UU'\" \(365 characters\)
sed "s/^X//" >'vim/tools/vim132.UU' <<'END_OF_FILE'
Xbegin 644 vim/tools/vim132
XM(R$@+V)I;B]C<V@*(R!3:&5L;"!S8W)I<'0@9F]R('5S92!W:71H(%5.25@*
XM(R!3=&%R=',@=7 @5FEM('=I=&@@=&AE('1E<FUI;F%L(&EN(#$S,B!C;VQU
XM;6X@;6]D90HC($]N;'D@=V]R:W,@;VX@5E0M,3 P('1E<FUI;F%L<R!A;F0@
XM;&]O:V%L:6ME<PHC"G-E="!O;&1T97)M/21T97)M"F5C:&\@(AM;/S-H(@IS
XM971E;G8@5$5232!V=#$P,"UW( IV:6T@)"H*<V5T('1E<FT])&]L9'1E<FT*
X-96-H;R B&UL_,VPB"C$P
X
Xend
END_OF_FILE
if test 365 -ne `wc -c <'vim/tools/vim132.UU'`; then
echo shar: \"'vim/tools/vim132.UU'\" unpacked with wrong size!
else
echo shar: Uudecoding \"'vim/tools/vim132'\" \(238 characters\)
cat vim/tools/vim132.UU | uudecode
if test 238 -ne `wc -c <'vim/tools/vim132'`; then
echo shar: \"'vim/tools/vim132'\" uudecoded with wrong size!
else
rm vim/tools/vim132.UU
fi
echo shar: \"'vim/tools/vim132.UU'\" unpacked with wrong size!
fi
# end of 'vim/tools/vim132.UU'
fi
if test -f 'vim/tutor/Readme' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'vim/tutor/Readme'\"
else
echo shar: Extracting \"'vim/tutor/Readme'\" \(768 characters\)
sed "s/^X//" >'vim/tutor/Readme' <<'END_OF_FILE'
XVitutor is a "hands on" tutorial for new users of the Vim editor.
X
XMost new users can get through it in less than one hour. The result
Xis that you can do a simple editing task using the Vim editor.
X
XTutor is a file that contains the tutorial lessons. You can simply
Xexecute "vim tutor" and then follow the instructions in the lessons.
XThe lessons tell you to modify the file, so DON'T DO THIS ON YOUR
XORIGINAL COPY.
X
XI have considered adding more advanced lessons but have not found the
Xtime. Please let me know how you like it and send any improvements you
Xmake.


X
XBob Ware, Colorado School of Mines, Golden, Co 80401, USA
X(303) 273-3987
Xbw...@mines.colorado.edu bw...@slate.mines.colorado.edu bw...@mines.bitnet

X
X(This file was modified by Bram Moolenaar for Vim)
END_OF_FILE
if test 768 -ne `wc -c <'vim/tutor/Readme'`; then
echo shar: \"'vim/tutor/Readme'\" unpacked with wrong size!
fi
# end of 'vim/tutor/Readme'
fi
echo shar: End of archive 26 \(of 26\).
cp /dev/null ark26isdone

Bram Moolenaar

unread,
Aug 22, 1994, 9:34:16 AM8/22/94
to
Submitted-by: mo...@oce.nl (Bram Moolenaar)
Posting-number: Volume 44, Issue 45
Archive-name: vim/part26
Environment: UNIX, AMIGA, MS-DOS, Windows NT
Supersedes: vim: Volume 41, Issue 50-75

[Repost due to propagation problems. -Kent+]

0 new messages